⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs3calccfg.pas

📁 最小二乘相关介绍,最小二乘相关介绍,及其原程序!仔细整理收获不少!
💻 PAS
📖 第 1 页 / 共 3 页
字号:
	RS3Chart.Title.Text.Add(cboxItemName.Items.Strings[Index] + szTitleFix);
  RS3SeriesAfter.Clear;
  RS3SeriesBefore.Clear;
  RS3Chart.BottomAxis.Title.Caption := RS3StringGrid.Cells[0,0];
  RS3Chart.LeftAxis.Title.Caption := '测量/拟合输出(' + FCalcCoef[Index].sUnitOut + ')';
  // 表格和曲线数据
  for i := 0 to FCalcCoef[Index].nDataNums-1 do
  begin
  	RS3StringGrid.Cells[0,i+1] := FormatFloat('0.0000000',FCalcData[Index,i].fDataIn);
    RS3StringGrid.Cells[1,i+1] := FormatFloat('0.0000000',FCalcData[Index,i].fDataOut);
    RS3StringGrid.Cells[2,i+1] := FormatFloat('0.0000000',FCalcData[Index,i].fCalcOut);
    RS3StringGrid.Cells[3,i+1] := FormatFloat('0.0000000',FCalcData[Index,i].fPerError);
    RS3SeriesAfter.AddXY(FCalcData[Index,i].fDataIn,FCalcData[Index,i].fCalcOut);
    RS3SeriesBefore.AddXY(FCalcData[Index,i].fDataIn,FCalcData[Index,i].fDataOut);
  end;
  // 更新显示数据
  RS3ValueListEditor.Strings.Clear;
  for i := 0 to FCalcCoef[Index].nPower do
  begin
  	strTemp := '系数项(A' + IntToStr(i) + ')=';
    strTemp := strTemp + FormatFloat('0.0000000E+00',FCalcCoef[Index].fCoef[i]);
    RS3ValueListEditor.Strings.Add(strTemp);
  end;
  RS3ValueListEditor.Strings.Add('均方根误差=' + FormatFloat('0.0000000E+00(L/h)',FCalcCoef[Index].fError));
  RS3ValueListEditor.Strings.Add('最新拟合时间=' + FCalcCoef[Index].szCalcTime);
  RS3StringGrid.SetFocus;
	// 定位表格新记录
  with DAOTable1 do
  begin
  	if not Active then Open;
	  DAOTable1.Locate('ItemName',VarArrayOf([cboxItemName.Items.Strings[Index]]),[]);
  end;
end;


procedure TRS3CalcForm.FormCreate(Sender: TObject);
var
	i,Index: Integer;
  sDBFile: String;
begin
  FACol := 1;
  FARow := 1;
  Index := 0;
  cboxItemName.Clear;
  // 建立数据库连接
  sDBFile := ExtractFileDir(Application.ExeName) + '\Data.mdb';
  if not FileExists(sDBFile) then
  begin
    Application.MessageBox(PChar('找不到数据库文件:' + sDBFile), '系统初始化错误',MB_OK+MB_ICONERROR);
  	Exit;
  end;
  DAODatabase1.DatabaseName := sDBFile;
  DAODatabase1.Connected := true;
  DAOTable1.TableName := 'CalcCoef';
  DAOTable2.TableName := 'CalcData';
  DAOTable1.Open;
  DAOTable2.Open;
  DBMemo1.DataField := 'Memo';
  // 读取数据库中数据
  with DAOTable1 do
  begin
	  First;
		while not Eof do
	  begin
      cboxItemName.Items.Add(FieldByName('ItemName').AsString);
      FCalcCoef[Index].bModified 	:= false;
      if FieldByName('UnitIn').IsNull then
        FCalcCoef[Index].sUnitIn 		:= ''
	    else
  	    FCalcCoef[Index].sUnitIn 		:= FieldByName('UnitIn').AsString;
      if FieldByName('UnitOut').IsNull then
        FCalcCoef[Index].sUnitOut 	:= ''
      else
	      FCalcCoef[Index].sUnitOut 	:= FieldByName('UnitOut').AsString;
      FCalcCoef[Index].nPower 		:= FieldByName('Power').AsInteger;
      FCalcCoef[Index].fError   	:= FieldByName('Error').AsFloat;
    	FCalcCoef[Index].szCalcTime	:= FieldByName('CalcTime').AsString;
      for i := 0 to FCalcCoef[Index].nPower do
        FCalcCoef[Index].fCoef[i] := FieldByName('COEF' + IntToStr(i)).AsFloat;
      Inc(Index);
      Next;
    end;
  end;
end;

{ 显示窗体,更新数据显示 }
procedure TRS3CalcForm.FormShow(Sender: TObject);
begin
	if cboxItemName.Items.Count > 0 then
  begin
		cboxItemName.ItemIndex := 0;
  	cboxItemNameSelect(Sender);
  end;
end;

{ 关闭窗体,询问用户是否保存数据 }
procedure TRS3CalcForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
	i,j: Integer;
begin
	// 查找尚未保存过的数据并询问用户是否保存
	with TRS3SaveHintForm.Create(Self) do
  try
		for i := 0 to cboxItemName.Items.Count-1 do
  	begin
    	if FCalcCoef[i].bModified then
      begin
      	labItem.Caption := '【' + cboxItemName.Items.Strings[i] + '】';
      	ShowModal;
        case nRes of
        	1:SaveData(i);
          2:begin
	          	for j := 0 to cboxItemName.Items.Count-1 do
              begin
                if FCalcCoef[j].bModified then
                  SaveData(j);
              end;
              Break;
          	end;
          3:Continue;
          4:Break;
        end;
      end;
	  end;
  finally
    Free;
  end;
end;

{ 更新数据显示 }
procedure TRS3CalcForm.cboxItemNameSelect(Sender: TObject);
begin
  ReadData(cboxItemName.ItemIndex);
  DisplayData(cboxItemName.ItemIndex);
end;

{ 对用户提供的计量数据进行拟合 }
procedure TRS3CalcForm.actStartExecute(Sender: TObject);
var
	i,j,nRecNum,Index: Integer;
  y,fTemp: Double;
  bModify: Boolean;
  XYList: array of TDoubleXY;
  si,p,be,al,s: TDoubleArray;
begin
  // 变量初始化
  bModify := false;
  FCalcCoef[Index].nPower := StrToInt(EditPower.Text);
  Index := cboxItemName.ItemIndex;
  // 执行拟合过程(直线拟合),如果给定的数据无效则扔出异常
  try
  	// 计算有效数据对的个数
    for i := 0 to RS3StringGrid.RowCount-1 do
    begin
    	if (RS3StringGrid.Cells[0,i+1] = '') or
      	 (RS3StringGrid.Cells[1,i+1] = '') then
         Break;
      if (FCalcData[Index,i].fDataIn <> StrToFloat(RS3StringGrid.Cells[0,i+1])) or
      	 (FCalcData[Index,i].fDataOut <> StrToFloat(RS3StringGrid.Cells[1,i+1])) then
         bModify := true;
      FCalcData[Index,i].fDataIn := StrToFloat(RS3StringGrid.Cells[0,i+1]);
      FCalcData[Index,i].fDataOut := StrToFloat(RS3StringGrid.Cells[1,i+1]);
    end;
    // 检查拟合数据个数是否符合要求
    if i < FCalcCoef[Index].nPower+1 then
    begin
    	Application.MessageBox('拟合数据个数必须大于或等于7!','提示',MB_OK+MB_ICONWARNING);
      Exit;
    end;
    // 开始拟合,采用i次方程进行拟合。
    nRecNum := i;
    SetLength(XYList,nRecNum);
    for i := 0 to nRecNum-1 do
    begin
      XYList[i].x := FCalcData[Index,i].fDataIn;
      XYList[i].y := FCalcData[Index,i].fDataOut;
    end;
    LSFit(FCalcCoef[Index].nPower,XYList,si,p,be,al,s);
    for i := 0 to FCalcCoef[Index].nPower do
      FCalcCoef[Index].fCoef[i] := p[i];
    // 临时保存拟合结果于FCalcCoef和FCalcData记录中(在内存中)
    fTemp := 0;
    for i := 0 to nRecNum-1 do
    begin
      FCalcData[Index,i].fDataIn := FCalcData[Index,i].fDataIn;
      FCalcData[Index,i].fDataOut:= FCalcData[Index,i].fDataOut;
      FCalcData[Index,i].fCalcOut := p[0];
      for j := 1 to FCalcCoef[Index].nPower do
        FCalcData[Index,i].fCalcOut := FCalcData[Index,i].fCalcOut + p[j]*Power(XYList[i].x,j);
      fTemp := fTemp + Power(XYList[i].y - FCalcData[Index,i].fCalcOut, 2);
    end;
    // 计算均方根误差和相对误差
    FCalcCoef[Index].fError := Sqrt(fTemp/nRecNum);
    for i := 0 to nRecNum-1 do
    begin
      if XYList[i].y <> 0 then
      	FCalcData[Index,i].fPerError := 100*(XYList[i].y-FCalcData[Index,i].fCalcOut)/XYList[i].y
      else
        FCalcData[Index,i].fPerError := 100*(XYList[i].y-FCalcData[Index,i].fCalcOut);
    end;
    // 临时保存拟合结果于FCalcCoef和FCalcData记录中(在内存中)
    FCalcCoef[Index].nDataNums	:= nRecNum;
    FCalcCoef[Index].bModified := bModify;
    FCalcCoef[Index].szCalcTime:= DateTimeToStr(Now);
  except
    raise Exception.Create('给定的拟合数据无效,请仔细检查输入是否有误!');
  end;
  // 更新显示拟合结果
  DisplayData(Index);
end;

{ 将拟合结果提交到数据库表中 }
procedure TRS3CalcForm.actSaveExecute(Sender: TObject);
begin
  SaveData(cboxItemName.ItemIndex);
end;

{ 将所有传感器的拟合结果提交到数据库表中 }
procedure TRS3CalcForm.actSaveAllExecute(Sender: TObject);
var
	i: Integer;
begin
	for i := 0 to cboxItemName.Items.Count-1 do
  begin
  	if FCalcCoef[i].bModified then
    	SaveData(i);
  end;
end;

{ 返回控制中心 }
procedure TRS3CalcForm.actBackExecute(Sender: TObject);
begin
	Close;
end;

{ 清除曲线及表格中的所有数据 }
procedure TRS3CalcForm.actClearTableExecute(Sender: TObject);
var
	i: Integer;
begin
	if MessageBox(Handle,'确定清除曲线及表格中的所有数据?','提示',MB_YESNO+MB_ICONQUESTION) = IDNO then
  	Exit;
  for i := 1 to RS3StringGrid.RowCount-1 do
	  RS3StringGrid.Rows[i].Clear;
  RS3SeriesBefore.Clear;
  RS3SeriesAfter.Clear;
end;

{ 清除当前行中的所有数据 }
procedure TRS3CalcForm.actClearRowExecute(Sender: TObject);
begin
	RS3StringGrid.Rows[FARow].Clear;
end;

{ 清除当前列中的所有数据 }
procedure TRS3CalcForm.actClearColExecute(Sender: TObject);
begin
	RS3StringGrid.Cols[FACol].Clear;
end;

{ 在当前行前插入一行空行 }
procedure TRS3CalcForm.actInsertRowExecute(Sender: TObject);
var
  i: Integer;
begin
  RS3StringGrid.RowCount := RS3StringGrid.RowCount + 1;
  for i := RS3StringGrid.RowCount-2 downto FARow do
    RS3StringGrid.Rows[i+1] := RS3StringGrid.Rows[i];
  RS3StringGrid.Rows[FARow].Clear;
end;

{ 删除当前数据行 }
procedure TRS3CalcForm.actDeleteRowExecute(Sender: TObject);
var
  i: Integer;
begin
  RS3StringGrid.Rows[FARow].Clear;
  for i := FARow to RS3StringGrid.RowCount-2  do
    RS3StringGrid.Rows[i] := RS3StringGrid.Rows[i+1];
  RS3StringGrid.RowCount := RS3StringGrid.RowCount - 1;
end;

{ 打印当前传感器校准数据 }
procedure TRS3CalcForm.actPrintDataExecute(Sender: TObject);
begin
  if not SaveDataToFile(cboxItemName.ItemIndex) then
  begin
    Application.MessageBox('文件在保存过程中出现错误!','错误',MB_OK+MB_ICONERROR);
  	Exit;
  end;
  if PrintDialog1.Execute then
  begin
    with TRichEdit.Create(Self) do
    try
      Parent := Self;
      Visible := false;
      Lines.LoadFromFile(FstrFileName);
      Print('');
    finally
      Free;
    end;
  end;
end;

{ 将当前传感器校准数据以文件形式保存 }
procedure TRS3CalcForm.actSaveAsFileExecute(Sender: TObject);
begin
	if SaveDataToFile(cboxItemName.ItemIndex) then
    Application.MessageBox('文件已经成功保存!','保存文件',MB_OK+MB_ICONINFORMATION)
  else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -