📄 rs3calccfg.pas
字号:
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 + -