Initial commit - Delphi MES client project

This commit is contained in:
Developer
2026-05-07 20:25:34 +08:00
commit 819b4824f6
466 changed files with 1176403 additions and 0 deletions
+985
View File
@@ -0,0 +1,985 @@
unit uDM;
{
================================================
数据模块单元 - uDM.pas
================================================
【模块说明】
本单元是应用程序的核心数据模块(TDataModule),负责:
- 管理主从表结构的数据操作
- 提供内存表(MemTable)的CRUD功能
- 处理业务数据的持久化和加载
- 管理工单和批次记录
【数据结构】
- FDMemMain: 主表,存储工单批次等核心业务数据
- FDMemDetail: 从表,存储详细生产记录
- FDMemTable1: 配置表,存储系统配置和键值对
【主要功能】
- 主从表数据插入、删除、更新操作
- 内存表数据加载和保存
- 配置信息的读写管理
- 后台数据同步线程
【使用注意】
- 使用FireDAC内存表支持离线操作
- 数据变更后需要调用SaveMain/SaveDetail保存
- 线程安全:TDbSoapThread用于后台数据同步
【版本信息】
- 创建时间: 2024年
- 最后修改: 2026年4月
- 版本: 1.0
================================================
}
interface
uses
System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,System.Variants,
FireDAC.DApt.Intf, FireDAC.Stan.StorageBin, FireDAC.Stan.StorageJSON, Data.DB,
FireDAC.Comp.DataSet, FireDAC.Comp.Client,FMX.TabControl,FMX.Grid,System.JSON,
System.ImageList, FMX.ImgList,uKsoap,Winapi.ActiveX,uSafelog,FMX.Dialogs,
Vcl.ImgList, Vcl.Controls, uExceptionHandler;
type
TDbSoapThread = class(TThread)
private
protected
procedure Execute; override;
public
constructor Create;
end;
TDM = class(TDataModule)
FDMemTable1: TFDMemTable;
FDMemTable1ID: TIntegerField;
FDMemTable1TabName: TStringField;
FDMemTable1KeyName: TStringField;
FDMemTable1KeyDesc: TStringField;
FDMemTable1KeyValue: TStringField;
FDStanStorageJSONLink1: TFDStanStorageJSONLink;
ImageList1: TImageList;
FDStanStorageBinLink1: TFDStanStorageBinLink;
FDMemMain: TFDMemTable;
FDMemDetail: TFDMemTable;
procedure DataModuleCreate(Sender: TObject);
private
function CreateMainTable():boolean;
function CreateDetailTable():boolean;
public
MainUI,DataOpline,Operate:Integer;
procedure MemTableLoadTab(TabName:string;GridFrame:TStringGrid);
procedure MemTableSaveTab(GridFrame:TStringGrid);
procedure MemTableReadTabList(var Strings: TStrings);
function MemTableReadKeyValue(TabName,KeyName:string):string;
procedure MemTableWriteKeyValue(TabName,KeyName,Value:string);
procedure MemTableWriteKey(TabName,KeyName:string);
procedure ClearBlankTab();
function TabNameExists(TabName:string):boolean;
//主从表
function InsertDetail(vId:Integer;DetailRecord:TDetailRecord):boolean;
function InsertMain(var vId:Integer;LotNoRecord:TLotNoRecord;IsOnlyMain:boolean=false):boolean;
function InsertQtyTime(vID,vP_ID,vP_ACT_QTY,vP_LINE_SPEED,vP_BK1,vP_BK2,vP_BK3:string):boolean;
function UpdateMainId(vID:Integer;vP_ID:string;Inserted:boolean):boolean;
function DeleteDetailById(vID:Integer):boolean;
function DeleteMainById(vID:Integer):boolean;
function SaveMain():boolean;
function SaveDetail():boolean;//从表
function LoadMain():boolean;
function LoadDetail():boolean; //从表
procedure Tim_Timer(sText: String);
// function SaveMainToRecord(var LotNoRecord:TLotNoRecord);
// function SaveDetailToRecord(var DetailRecord:TDetailRecord);
//InsertLotEntity(null, FACTORY_CODE, mWorkNum, mLotNum, PROCESS, PRODUCT_LINE, LINE_NUM, LOT_TYPE, "Y", ID, false);
end;
var
DM: TDM;
implementation
Uses System.StrUtils;
{%CLASSGROUP 'FMX.Controls.TControl'}
{$R *.dfm}
function TDM.CreateMainTable():boolean;
begin
FDMemMain.Close;
with FDMemMain.FieldDefs do
begin
Clear;
Add('ID', ftAutoInc);
Add('P_ORG_CODE',ftString,30,false);
Add('P_NUM',ftString,30,false);
Add('P_LOT',ftString,30,false);
Add('P_PC',ftString,30,false);
Add('P_LINE',ftString,30,false);
Add('P_LINE_NUM',ftString,30,false);
Add('P_LOT_TYPE',ftString,30,false);
Add('P_BKfile',ftString,30,false);
Add('P_Buffer',ftString,30,false);
Add('P_DIE_NAME',ftString,30,false);
Add('P_Enable',ftString,30,false);
Add('P_MESH',ftString,30,false);
Add('P_COUNTERPOINT_MODE',ftString,30,false);
Add('P_SHORT_CIRCUIT',ftString,30,false);
Add('P_CREATION_DATE',ftString,30,false);
Add('P_TROLLEY_NUM',ftString,30,false);
Add('P_TROLLEY_FLAG',ftString,30,false);
Add('P_COPPER_MODEL',ftString,30,false);
Add('P_COMP_PROGRAM',ftString,30,false);
Add('P_COMP_AREA',ftString,30,false);
Add('P_PLATE_WIDTH',ftString,30,false);
Add('P_PLATE_HEIGHT',ftString,30,false);
Add('P_JET_FLOW',ftString,30,false);
Add('P_SIDE',ftString,30,false);
Add('P_DRY_FILM_TYPE',ftString,30,false);
Add('P_NEGATIVE',ftString,30,false);
Add('P_ID',ftString,30,false);
Add('P_LINE_SPEED',ftSingle,0,false);
Add('P_ELE_CUR_DENSITY',ftSingle,0,false);
Add('P_ELE_AREA1',ftSingle,0,false);
Add('P_ELE_AREA2',ftSingle,0,false);
Add('P_COM_TEMPERATURE',ftSingle,0,false);
Add('P_PRODUCT_PRESSURE',ftSingle,0,false);
Add('P_PREHEATING_SEC',ftSingle,0,false);
Add('P_COMPRESS_SEC',ftSingle,0,false);
Add('P_STAMPING_DEPTH',ftSingle,0,false);
Add('P_DIE_USE_NUM',ftSingle,0,false);
Add('P_NUM_PER_ARR',ftSingle,0,false);
Add('P_UPPER_PRESSURE',ftSingle,0,false);
Add('P_DOWN_PRESSURE',ftSingle,0,false);
Add('P_SLICKER_ANGLE',ftSingle,0,false);
Add('P_INK_KNIFE_ANGLE',ftSingle,0,false);
Add('P_SLICKER_SPEED',ftSingle,0,false);
Add('P_INK_KNIFE_SPEED',ftSingle,0,false);
Add('P_NET_SPACING',ftSingle,0,false);
Add('P_EXPOSURE_TIME',ftSingle,0,false);
Add('P_SLAB_THICKNESS',ftSingle,0,false);
Add('P_JE_SETUP',ftSingle,0,false);
Add('P_EXPOSURE_ENERGY',ftSingle,0,false);
Add('P_DEVELOP_PRESSURE',ftSingle,0,false);
Add('P_ETCH_FACTOR',ftSingle,0,false);
Add('P_RESOLUTION',ftSingle,0,false);
Add('P_SLICKER_PRESSURE',ftSingle,0,false);
Add('P_INK_KNIFE_PRESSURE',ftSingle,0,false);
Add('P_OFF_NET',ftSingle,0,false);
Add('P_SLICKER_DEPTH',ftSingle,0,false);
Add('P_INK_RETURN_KNIFE_DEPTH',ftSingle,0,false);
Add('Inserted',ftBoolean,0,false);
Add('IsOnlyMain',ftBoolean,0,false);
end;
FDMemMain.CreateDataSet();
end;
function TDM.CreateDetailTable():boolean;
begin
FDMemDetail.Close;
with FDMemDetail.FieldDefs do
begin
Clear;
Add('ID', ftAutoInc);
Add('ParentID',ftInteger,0,false);
Add('P_ORG_CODE',ftString,30,false);
Add('P_BC',ftString,30,false);
Add('P_LOT',ftString,30,false);
Add('P_PC',ftString,30,false);
Add('P_LINE',ftString,30,false);
Add('P_LINE_NUM',ftString,30,false);
Add('P_LOT_TYPE',ftString,30,false);
Add('P_ID',ftString,30,false);
Add('P_TROLLEY_NUM',ftString,30,false);
Add('P_COPPER_MODEL',ftString,30,false);
Add('P_BUFFER_TYPE',ftString,30,false);
Add('P_CREATION_DATE',ftString,30,false);
Add('iNum',ftInteger,0,false); //当前记数
Add('Style',ftInteger,0,false); // 1=明细, 2=最后提交更新
Add('P_BK1',ftString,30,false);
Add('P_BK2',ftString,30,false);
Add('P_BK3',ftString,30,false);
Add('P_ACT_QTY',ftString,30,false);
Add('P_END_TIME',ftString,30,false);
Add('P_LINE_SPEED',ftString,30,false);
end;
FDMemDetail.CreateDataSet();
end;
function TDM.SaveMain():boolean;
begin
FDMemMain.CachedUpdates;
FDMemMain.CommitUpdates;
FDMemMain.SaveToFile(ExtractFilePath(Paramstr(0))+'tmpdb/main.dat',sfBinary);
end;
function TDM.SaveDetail():boolean;//从表
begin
FDMemDetail.CachedUpdates;
FDMemDetail.CommitUpdates;
FDMemDetail.SaveToFile(ExtractFilePath(Paramstr(0))+'tmpdb/Detail.dat',sfBinary);
end;
function TDM.LoadMain():boolean;
var
sFileName, FLogFileDir:string;
begin
FLogFileDir := ExtractFilePath(Paramstr(0))+'tmpdb';
if not DirectoryExists(FLogFileDir) then
if not ForceDirectories(FLogFileDir) then //创建目录
begin
RaiseDataException('tmpdb路径错误,数据类对象不能被创建', 1001);
end;
sFileName:=ExtractFilePath(Paramstr(0))+'tmpdb/main.dat';
if FileExists(sFileName) then
begin
FDMemMain.LoadFromFile(sFileName,sfBinary);
WorkLog.MessageInfo('主表记录数:%d',[FDMemMain.RecordCount]);
end;
end;
function TDM.LoadDetail():boolean; //从表
var
sFileName:string;
begin
sFileName:=ExtractFilePath(Paramstr(0))+'tmpdb/Detail.dat';
if FileExists(sFileName) then
begin
FDMemDetail.LoadFromFile(ExtractFilePath(Paramstr(0))+'tmpdb/Detail.dat',sfBinary);
WorkLog.MessageInfo('从表记录数:%d',[FDMemDetail.RecordCount]);
end;
end;
function TDM.TabNameExists(TabName:string):boolean;
begin
Result:=FDMemTable1.Locate('TabName',TabName);
end;
procedure TDM.DataModuleCreate(Sender: TObject);
begin
if FileExists(ExtractFilePath(Paramstr(0))+'system.json') then
FDMemTable1.LoadFromFile(ExtractFilePath(Paramstr(0))+'system.json');
FDMemTable1.LogChanges := False;
FDMemTable1.Active:=true;
FDMemTable1.DisableControls;
with FDMemMain do
begin
LogChanges := False;
CachedUpdates:=false;
fetchoptions.RecsMax:=300000;
resourceoptions.SilentMode:=true;
UpdateOptions.LockMode:=lmNone;
UpdateOptions.LockPoint:=lpDeferred;
UpdateOptions.FetchGeneratorsPoint:=gpImmediate;
DisableControls;
CreateMainTable();
Active:=true;
end;
with FDMemDetail do
begin
LogChanges := False;
CachedUpdates:=false;
fetchoptions.RecsMax:=300000;
resourceoptions.SilentMode:=true;
UpdateOptions.LockMode:=lmNone;
UpdateOptions.LockPoint:=lpDeferred;
UpdateOptions.FetchGeneratorsPoint:=gpImmediate;
DisableControls;
CreateDetailTable();
Active:=true;
end;
end;
function TDM.DeleteDetailById(vID:Integer):boolean;
begin
System.MonitorEnter(FDMemDetail);
try
with FDMemDetail do //标记已插入
begin
if Locate('ID',vID) then
begin
delete;
SaveDetail;
end;
end;
finally
System.MonitorExit(FDMemDetail);
end;
end;
function TDM.DeleteMainById(vID:Integer):boolean;
begin
System.MonitorEnter(FDMemMain);
try
with FDMemMain do //标记已插入
begin
if Locate('ID',vID) then
begin
delete;
SaveMain;
end;
end;
finally
System.MonitorExit(FDMemMain);
end;
end;
procedure TDM.MemTableLoadTab(TabName:string;GridFrame:TStringGrid);
var
i:integer;
begin
with FDMemTable1 do
begin
First;
GridFrame.BeginUpdate;
i:=0;
while not Eof do
begin
if FieldByName('TabName').AsString=TabName then
begin
GridFrame.Cells[0,i]:=FieldByName('Id').AsString;
GridFrame.Cells[1,i]:=FieldByName('KeyName').AsString;
GridFrame.Cells[2,i]:=FieldByName('KeyDesc').AsString;
GridFrame.Cells[3,i]:=FieldByName('KeyValue').AsString;
inc(i);
end;
Next;
end;
GridFrame.EndUpdate;
end;
end;
procedure TDM.ClearBlankTab(); //当9个键值都为空时,删除掉整个TAB面的数据
var
TmpTabName:TStrings;
i:integer;
begin
with FDMemTable1 do
begin
TmpTabName:=TStringlist.Create;
MemTableReadTabList(TmpTabName);
for i := TmpTabName.Count-1 downto 0 do //去掉有数据的Tab
begin
First;
while not Eof do
begin
if FieldByName('TabName').AsString=TmpTabName.Strings[i] then
begin
if (FieldByName('KeyName').AsString<>'') or (FieldByName('KeyDesc').AsString<>'')
or (FieldByName('KeyValue').AsString<>'') then //有数据
begin
TmpTabName.Delete(i);
break;
end;
end;
Next;
end;
end;
//删除无数据的Tab
for i := TmpTabName.Count-1 downto 0 do //去掉有数据的Tab
begin
First;
while not Eof do
begin
if FieldByName('TabName').AsString=TmpTabName.Strings[i] then
begin
delete;
end;
Next;
end;
end;
end;
end;
procedure TDM.MemTableSaveTab(GridFrame:TStringGrid);
var
i:integer;
begin
for i := 0 to GridFrame.RowCount-1 do
begin
with FDMemTable1 do
begin
if trim(GridFrame.Cells[0,i])<>'' then
if Locate('id',GridFrame.Cells[0,i]) then
begin
Edit;
FieldByName('KeyName').AsString:=Trim(GridFrame.Cells[1,i]);
FieldByName('KeyDesc').AsString:=Trim(GridFrame.Cells[2,i]);
FieldByName('KeyValue').AsString:=Trim(GridFrame.Cells[3,i]).Replace('',',');
Post;
//if (FieldByName('KeyName').AsString='') and (FieldByName('KeyDesc').AsString='')
//and (FieldByName('KeyValue').AsString='') then
//delete;
end;
end;
end;
ClearBlankTab;
FDMemTable1.MergeChangeLog;
FDMemTable1.ApplyUpdates(0);
end;
procedure TDM.MemTableWriteKey(TabName,KeyName:string);
begin
with FDMemTable1 do
begin
Append;
FieldByName('TabName').AsString:=TabName;
FieldByName('KeyName').AsString:=KeyName;
Post;
end;
end;
function TDM.MemTableReadKeyValue(TabName,KeyName:string):string;
begin
Result:='';
if (TabName<>'') and (KeyName<>'') then
begin
if FDMemTable1.Locate('TabName;KeyName',vararrayof([TabName,KeyName]),[]) then
Result:=FDMemTable1.FieldByName('KeyValue').AsString;
end;
end;
procedure TDM.MemTableWriteKeyValue(TabName,KeyName,Value:string);
begin
if (TabName<>'') and (KeyName<>'') and (Value<>'') then
begin
if FDMemTable1.Locate('TabName;KeyName',vararrayof([TabName,KeyName]),[]) then
begin
FDMemTable1.Edit;
FDMemTable1.FieldByName('KeyValue').AsString:= Value;
FDMemTable1.Post;
fdmemtable1.SaveToFile(ExtractFilePath(Paramstr(0))+'system.json');
WorkLog.MessageInfo(Value+',数据保存成功');
end;
end;
end;
procedure TDM.MemTableReadTabList(var Strings: TStrings);
begin
FDMemTable1.First;
Strings.Clear;
while not FDMemTable1.Eof do
begin
if Strings.IndexOf(FDMemTable1.FieldByName('TabName').AsString)<0 then
Strings.Add(FDMemTable1.FieldByName('TabName').AsString);
FDMemTable1.Next;
end;
end;
procedure JsonToDataSet(AJson: string; ADataset: TDataSet);
var
jDataSet: TJSONArray;
jRecord: TJSONObject;
i, j: Integer;
begin
if (AJson = '') or (ADataset = nil) or (not ADataset.Active) then Exit;
jDataSet := TJSONObject.Create.ParseJSONValue(AJson, True) as TJSONArray;
for i :=0 to jDataSet.Size -1 do
begin
ADataset.Append;
jRecord := jDataSet.Get(i) as TJSONObject;
for j :=0 to ADataset.FieldCount -1 do
ADataset.Fields[j].Text := jRecord.GetValue(ADataset.Fields[j].FieldName).ToString;
ADataset.Post;
end;
end;
function DataSetToJson(ADataset: TDataSet): string;
var
LRecord: string;
LField: TField;
i: integer;
begin
Result := '';
if (not ADataset.Active) or (ADataset.IsEmpty) then Exit;
Result := '[';
ADataset.First;
while not ADataset.Eof do
begin
for i :=0 to ADataset.FieldCount -1 do
begin
LField := ADataset.Fields[i];
if LRecord = '' then
LRecord := '{"' + LField.FieldName + '":"' + LField.Text + '"'
else
LRecord := LRecord + ',"' + LField.FieldName + '":"' + LField.Text + '"';
if i = ADataset.FieldCount -1 then
begin
LRecord := LRecord + '}';
if Result = '[' then
Result := Result + LRecord
else
Result := Result + ',' + LRecord;
LRecord := '';
end;
end;
ADataset.Next;
end;
Result := Result + ']';
end;
function TDM.InsertQtyTime(vID,vP_ID,vP_ACT_QTY,vP_LINE_SPEED,vP_BK1,vP_BK2,vP_BK3:string):boolean;
begin
System.MonitorEnter(FDMemDetail);
try
WITH FDMemDetail DO
BEGIN
Append;
FieldbyName('P_ID').AsString:=vP_ID;
FieldbyName('P_LINE_SPEED').AsString:=vP_LINE_SPEED;
FieldbyName('P_BK1').AsString:=vP_BK1;
FieldbyName('P_BK2').AsString:=vP_BK2;
FieldbyName('P_BK3').AsString:=vP_BK3;
FieldbyName('P_ACT_QTY').AsString:=vP_ACT_QTY;
FieldbyName('P_END_TIME').AsString:=FormatDateTime('yyyymmdd hh:mm:ss',Now);
FieldbyName('Style').AsInteger:=2;
FieldByName('ParentId').AsString:=vID;
Post;
END;
finally
SaveDetail();
System.MonitorExit(FDMemDetail);
end;
end;
function TDM.InsertDetail(vId:Integer;DetailRecord:TDetailRecord):boolean; //
begin
System.MonitorEnter(FDMemDetail);
try
WITH FDMemDetail DO
BEGIN
Append;
FieldbyName('ParentID').AsInteger:=vId;
FieldbyName('P_ORG_CODE').AsString:=DetailRecord.P_ORG_CODE;
FieldbyName('P_BC').AsString:=DetailRecord.P_BC;
FieldbyName('P_LOT').AsString:=DetailRecord.P_LOT;
FieldbyName('P_PC').AsString:=DetailRecord.P_PC;
FieldbyName('P_LINE').AsString:=DetailRecord.P_LINE;
FieldbyName('P_LINE_NUM').AsString:=DetailRecord.P_LINE_NUM;
FieldbyName('P_LOT_TYPE').AsString:=DetailRecord.P_LOT_TYPE;
FieldbyName('P_ID').AsString:=DetailRecord.P_ID;
FieldbyName('P_TROLLEY_NUM').AsString:=DetailRecord.P_TROLLEY_NUM;
FieldbyName('P_COPPER_MODEL').AsString:=DetailRecord.P_COPPER_MODEL;
FieldbyName('P_BUFFER_TYPE').AsString:=DetailRecord.P_BUFFER_TYPE;
FieldbyName('P_CREATION_DATE').AsString:=DetailRecord.P_CREATION_DATE;
FieldbyName('Style').Index:=1;
Post;
END;
finally
SaveDetail();
System.MonitorExit(FDMemDetail);
end;
END;
function TDM.InsertMain(var vId:Integer;LotNoRecord:TLotNoRecord;IsOnlyMain:boolean=false):boolean;
BEGIN
Result:=false;
System.MonitorEnter(FDMemMain);
try
WITH FDMemMain DO
BEGIN
Append;
FieldByName('P_ORG_CODE').AsString:=LotNoRecord.P_ORG_CODE;
FieldByName('P_NUM').AsString:=LotNoRecord.P_NUM;
FieldByName('P_LOT').AsString:=LotNoRecord.P_LOT;
FieldByName('P_PC').AsString:=LotNoRecord.P_PC;
FieldByName('P_LINE').AsString:=LotNoRecord.P_LINE;
FieldByName('P_LINE_NUM').AsString:=LotNoRecord.P_LINE_NUM;
FieldByName('P_LOT_TYPE').AsString:=LotNoRecord.P_LOT_TYPE;
FieldByName('P_BKfile').AsString:=LotNoRecord.P_BKfile;
FieldByName('P_Buffer').AsString:=LotNoRecord.P_Buffer;
FieldByName('P_DIE_NAME').AsString:=LotNoRecord.P_DIE_NAME;
FieldByName('P_Enable').AsString:=LotNoRecord.P_Enable;
FieldByName('P_MESH').AsString:=LotNoRecord.P_MESH;
FieldByName('P_COUNTERPOINT_MODE').AsString:=LotNoRecord.P_COUNTERPOINT_MODE;
FieldByName('P_SHORT_CIRCUIT').AsString:=LotNoRecord.P_SHORT_CIRCUIT;
FieldByName('P_CREATION_DATE').AsString:=LotNoRecord.P_CREATION_DATE;
FieldByName('P_TROLLEY_NUM').AsString:=LotNoRecord.P_TROLLEY_NUM;
FieldByName('P_TROLLEY_FLAG').AsString:=LotNoRecord.P_TROLLEY_FLAG;
FieldByName('P_COPPER_MODEL').AsString:=LotNoRecord.P_COPPER_MODEL;
FieldByName('P_COMP_PROGRAM').AsString:=LotNoRecord.P_COMP_PROGRAM;
FieldByName('P_COMP_AREA').AsString:=LotNoRecord.P_COMP_AREA;
FieldByName('P_PLATE_WIDTH').AsString:=LotNoRecord.P_PLATE_WIDTH;
FieldByName('P_PLATE_HEIGHT').AsString:=LotNoRecord.P_PLATE_HEIGHT;
FieldByName('P_JET_FLOW').AsString:=LotNoRecord.P_JET_FLOW;
FieldByName('P_SIDE').AsString:=LotNoRecord.P_SIDE;
FieldByName('P_DRY_FILM_TYPE').AsString:=LotNoRecord.P_DRY_FILM_TYPE;
FieldByName('P_NEGATIVE').AsString:=LotNoRecord.P_NEGATIVE;
FieldByName('P_ID').AsString:=LotNoRecord.P_ID.ToString;
FieldByName('P_LINE_SPEED').AsSingle:=LotNoRecord.P_LINE_SPEED;
FieldByName('P_ELE_CUR_DENSITY').AsSingle:=LotNoRecord.P_ELE_CUR_DENSITY;
FieldByName('P_ELE_AREA1').AsSingle:=LotNoRecord.P_ELE_AREA1;
FieldByName('P_ELE_AREA2').AsSingle:=LotNoRecord.P_ELE_AREA2;
FieldByName('P_COM_TEMPERATURE').AsSingle:=LotNoRecord.P_COM_TEMPERATURE;
FieldByName('P_PRODUCT_PRESSURE').AsSingle:=LotNoRecord.P_PRODUCT_PRESSURE;
FieldByName('P_PREHEATING_SEC').AsSingle:=LotNoRecord.P_PREHEATING_SEC;
FieldByName('P_COMPRESS_SEC').AsSingle:=LotNoRecord.P_COMPRESS_SEC;
FieldByName('P_STAMPING_DEPTH').AsSingle:=LotNoRecord.P_STAMPING_DEPTH;
FieldByName('P_DIE_USE_NUM').AsSingle:=LotNoRecord.P_DIE_USE_NUM;
FieldByName('P_NUM_PER_ARR').AsSingle:=LotNoRecord.P_NUM_PER_ARR;
FieldByName('P_UPPER_PRESSURE').AsSingle:=LotNoRecord.P_UPPER_PRESSURE;
FieldByName('P_DOWN_PRESSURE').AsSingle:=LotNoRecord.P_DOWN_PRESSURE;
FieldByName('P_SLICKER_ANGLE').AsSingle:=LotNoRecord.P_SLICKER_ANGLE;
FieldByName('P_INK_KNIFE_ANGLE').AsSingle:=LotNoRecord.P_INK_KNIFE_ANGLE;
FieldByName('P_SLICKER_SPEED').AsSingle:=LotNoRecord.P_SLICKER_SPEED;
FieldByName('P_INK_KNIFE_SPEED').AsSingle:=LotNoRecord.P_INK_KNIFE_SPEED;
FieldByName('P_NET_SPACING').AsSingle:=LotNoRecord.P_NET_SPACING;
FieldByName('P_EXPOSURE_TIME').AsSingle:=LotNoRecord.P_EXPOSURE_TIME;
FieldByName('P_SLAB_THICKNESS').AsSingle:=LotNoRecord.P_SLAB_THICKNESS;
FieldByName('P_JE_SETUP').AsSingle:=LotNoRecord.P_JE_SETUP;
FieldByName('P_EXPOSURE_ENERGY').AsSingle:=LotNoRecord.P_EXPOSURE_ENERGY;
FieldByName('P_DEVELOP_PRESSURE').AsSingle:=LotNoRecord.P_DEVELOP_PRESSURE;
FieldByName('P_ETCH_FACTOR').AsSingle:=LotNoRecord.P_ETCH_FACTOR;
FieldByName('P_RESOLUTION').AsSingle:=LotNoRecord.P_RESOLUTION;
FieldByName('P_SLICKER_PRESSURE').AsSingle:=LotNoRecord.P_SLICKER_PRESSURE;
FieldByName('P_INK_KNIFE_PRESSURE').AsSingle:=LotNoRecord.P_INK_KNIFE_PRESSURE;
FieldByName('P_OFF_NET').AsSingle:=LotNoRecord.P_OFF_NET;
FieldByName('P_SLICKER_DEPTH').AsSingle:=LotNoRecord.P_SLICKER_DEPTH;
FieldByName('P_INK_RETURN_KNIFE_DEPTH').AsSingle:=LotNoRecord.P_INK_RETURN_KNIFE_DEPTH;
FieldByName('Inserted').asboolean:=false;
FieldByName('IsOnlyMain').asboolean:=IsOnlyMain;
Post;
vId:=FieldByName('ID').AsInteger;
Result:=true;
END;
finally
SaveMain();
System.MonitorExit(FDMemMain);
end;
END;
function TDM.UpdateMainId(vID:Integer;vP_ID:string;Inserted:boolean):boolean;
BEGIN
System.MonitorEnter(FDMemMain);
try
with FDMemMain do //标记已插入
begin
if FDMemMain.Locate('ID',vID) then
begin
Edit;
FieldByName('Inserted').asboolean:=Inserted;
FieldByName('P_ID').AsString:=vP_ID;
Post;
SaveMain;
end;
end;
finally
System.MonitorExit(FDMemMain);
end;
END;
////////////////////////////////////////////////////////////////////////////////////
constructor TDbSoapThread.Create();
begin
inherited Create(True);
FreeOnTerminate := True;
end;
procedure TDbSoapThread.Execute; //提交数据
VAR
vP_ID:Double;
sError:string;
vId:Integer;
bHaveNoSucced:boolean;
LotNoRecord:TLotNoRecord;
DetailRecord:TDetailRecord;
LotNoBuf,DetailBuf:TFDMemTable;
procedure CopyDataSet(AOptions:TFDCopyDataSetOptions);
begin
System.MonitorEnter(dm.FDMemMain);
try
LotNoBuf.CopyDataSet(dm.FDMemMain,AOptions);
finally
System.MonitorExit(dm.FDMemMain);
end;
System.MonitorEnter(dm.FDMemDetail);
try
DetailBuf.CopyDataSet(dm.FDMemDetail,AOptions);
finally
System.MonitorExit(dm.FDMemDetail);
end;
end;
procedure SaveMainToRecord(var vLotNoRecord:TLotNoRecord);
begin
with LotNoBuf do
begin
LotNoRecord.P_ORG_CODE:=FieldByName('P_ORG_CODE').AsString;
LotNoRecord.P_NUM:=FieldByName('P_NUM').AsString;
LotNoRecord.P_LOT:=FieldByName('P_LOT').AsString;
LotNoRecord.P_PC:=FieldByName('P_PC').AsString;
LotNoRecord.P_LINE:=FieldByName('P_LINE').AsString;
LotNoRecord.P_LINE_NUM:=FieldByName('P_LINE_NUM').AsString;
LotNoRecord.P_LOT_TYPE:=FieldByName('P_LOT_TYPE').AsString;
LotNoRecord.P_BKfile:=FieldByName('P_BKfile').AsString;
LotNoRecord.P_Buffer:=FieldByName('P_Buffer').AsString;
LotNoRecord.P_DIE_NAME:=FieldByName('P_DIE_NAME').AsString;
LotNoRecord.P_Enable:=FieldByName('P_Enable').AsString;
LotNoRecord.P_MESH:=FieldByName('P_MESH').AsString;
LotNoRecord.P_COUNTERPOINT_MODE:=FieldByName('P_COUNTERPOINT_MODE').AsString;
LotNoRecord.P_SHORT_CIRCUIT:=FieldByName('P_SHORT_CIRCUIT').AsString;
LotNoRecord.P_CREATION_DATE:=FieldByName('P_CREATION_DATE').AsString;
LotNoRecord.P_TROLLEY_NUM:=FieldByName('P_TROLLEY_NUM').AsString;
LotNoRecord.P_TROLLEY_FLAG:=FieldByName('P_TROLLEY_FLAG').AsString;
LotNoRecord.P_COPPER_MODEL:=FieldByName('P_COPPER_MODEL').AsString;
LotNoRecord.P_COMP_PROGRAM:=FieldByName('P_COMP_PROGRAM').AsString;
LotNoRecord.P_COMP_AREA:=FieldByName('P_COMP_AREA').AsString;
LotNoRecord.P_PLATE_WIDTH:=FieldByName('P_PLATE_WIDTH').AsString;
LotNoRecord.P_PLATE_HEIGHT:=FieldByName('P_PLATE_HEIGHT').AsString;
LotNoRecord.P_JET_FLOW:=FieldByName('P_JET_FLOW').AsString;
LotNoRecord.P_SIDE:=FieldByName('P_SIDE').AsString;
LotNoRecord.P_DRY_FILM_TYPE:=FieldByName('P_DRY_FILM_TYPE').AsString;
LotNoRecord.P_NEGATIVE:=FieldByName('P_NEGATIVE').AsString;
LotNoRecord.P_ID:=FieldByName('P_ID').AsFloat;
LotNoRecord.P_LINE_SPEED:=FieldByName('P_LINE_SPEED').AsSingle;
LotNoRecord.P_ELE_CUR_DENSITY:=FieldByName('P_ELE_CUR_DENSITY').AsSingle;
LotNoRecord.P_ELE_AREA1:=FieldByName('P_ELE_AREA1').AsSingle;
LotNoRecord.P_ELE_AREA2:=FieldByName('P_ELE_AREA2').AsSingle;
LotNoRecord.P_COM_TEMPERATURE:=FieldByName('P_COM_TEMPERATURE').AsSingle;
LotNoRecord.P_PRODUCT_PRESSURE:=FieldByName('P_PRODUCT_PRESSURE').AsSingle;
LotNoRecord.P_PREHEATING_SEC:=FieldByName('P_PREHEATING_SEC').AsSingle;
LotNoRecord.P_COMPRESS_SEC:=FieldByName('P_COMPRESS_SEC').AsSingle;
LotNoRecord.P_STAMPING_DEPTH:=FieldByName('P_STAMPING_DEPTH').AsSingle;
LotNoRecord.P_DIE_USE_NUM:=FieldByName('P_DIE_USE_NUM').AsSingle;
LotNoRecord.P_NUM_PER_ARR:=FieldByName('P_NUM_PER_ARR').AsSingle;
LotNoRecord.P_UPPER_PRESSURE:=FieldByName('P_UPPER_PRESSURE').AsSingle;
LotNoRecord.P_DOWN_PRESSURE:=FieldByName('P_DOWN_PRESSURE').AsSingle;
LotNoRecord.P_SLICKER_ANGLE:=FieldByName('P_SLICKER_ANGLE').AsSingle;
LotNoRecord.P_INK_KNIFE_ANGLE:=FieldByName('P_INK_KNIFE_ANGLE').AsSingle;
LotNoRecord.P_SLICKER_SPEED:=FieldByName('P_SLICKER_SPEED').AsSingle;
LotNoRecord.P_INK_KNIFE_SPEED:=FieldByName('P_INK_KNIFE_SPEED').AsSingle;
LotNoRecord.P_NET_SPACING:=FieldByName('P_NET_SPACING').AsSingle;
LotNoRecord.P_EXPOSURE_TIME:=FieldByName('P_EXPOSURE_TIME').AsSingle;
LotNoRecord.P_SLAB_THICKNESS:=FieldByName('P_SLAB_THICKNESS').AsSingle;
LotNoRecord.P_JE_SETUP:=FieldByName('P_JE_SETUP').AsSingle;
LotNoRecord.P_EXPOSURE_ENERGY:=FieldByName('P_EXPOSURE_ENERGY').AsSingle;
LotNoRecord.P_DEVELOP_PRESSURE:=FieldByName('P_DEVELOP_PRESSURE').AsSingle;
LotNoRecord.P_ETCH_FACTOR:=FieldByName('P_ETCH_FACTOR').AsSingle;
LotNoRecord.P_RESOLUTION:=FieldByName('P_RESOLUTION').AsSingle;
LotNoRecord.P_SLICKER_PRESSURE:=FieldByName('P_SLICKER_PRESSURE').AsSingle;
LotNoRecord.P_INK_KNIFE_PRESSURE:=FieldByName('P_INK_KNIFE_PRESSURE').AsSingle;
LotNoRecord.P_OFF_NET:=FieldByName('P_OFF_NET').AsSingle;
LotNoRecord.P_SLICKER_DEPTH:=FieldByName('P_SLICKER_DEPTH').AsSingle;
LotNoRecord.P_INK_RETURN_KNIFE_DEPTH:=FieldByName('P_INK_RETURN_KNIFE_DEPTH').AsSingle;
end;
end;
procedure SaveDetailToRecord(var vDetailRecord:TDetailRecord);
begin
with DetailBuf do
begin
DetailRecord.P_ORG_CODE:=FieldbyName('P_ORG_CODE').AsString;
DetailRecord.P_BC:=FieldbyName('P_BC').AsString;
DetailRecord.P_LOT:=FieldbyName('P_LOT').AsString;
DetailRecord.P_PC:=FieldbyName('P_PC').AsString;
DetailRecord.P_LINE:=FieldbyName('P_LINE').AsString;
DetailRecord.P_LINE_NUM:=FieldbyName('P_LINE_NUM').AsString;
DetailRecord.P_LOT_TYPE:=FieldbyName('P_LOT_TYPE').AsString;
DetailRecord.P_ID:=FieldbyName('P_ID').AsString;
DetailRecord.P_TROLLEY_NUM:=FieldbyName('P_TROLLEY_NUM').AsString;
DetailRecord.P_COPPER_MODEL:=FieldbyName('P_COPPER_MODEL').AsString;
DetailRecord.P_BUFFER_TYPE:=FieldbyName('P_BUFFER_TYPE').AsString;
DetailRecord.P_CREATION_DATE:=FieldbyName('P_CREATION_DATE').AsString;
end;
end;
begin
CoInitialize(nil);
LotNoBuf:=TFDMemTable.Create(nil);
DetailBuf:=TFDMemTable.Create(nil);
try
//dm.LoadMain;
//dm.LoadDetail;
CopyDataSet([coStructure,coRestart, coAppend]);
while not self.Terminated do
begin
Sleep(200);
if (LotNoBuf.RecordCount=0) and (DetailBuf.RecordCount=0) then
begin
Sleep(1000);
CopyDataSet([coRestart, coAppend]);
continue;
end;
if ((LotNoBuf.RecordCount=0) and (DetailBuf.RecordCount>0)) then //处理只有从表数据
begin
DBApiLog.MessageInfo('存在明细表数据没有提交,请处理');
//找到明细数据,并提交
DetailBuf.First;
bHaveNoSucced:=false;
while not DetailBuf.Eof do
begin
SaveDetailToRecord(DetailRecord);
DetailRecord.P_ID:=DetailBuf.FieldByName('ParentID').AsInteger.ToString;
if Ksoap.Insert_cc_wip_lot_bc_history(DetailRecord,sError) then
begin
dm.DeleteDetailById(DetailBuf.FieldByName('ID').AsInteger);
end
else
begin //提交不成功
if sError='連接數據庫服務器失败' then
begin
bHaveNoSucced:=true;
DBApiLog.MessageInfo(sError);
end
else
dm.DeleteDetailById(DetailBuf.FieldByName('ID').AsInteger);
end;
SLEEP(200);
DetailBuf.Next;
end;
continue;
end;
try
LotNoBuf.First;
while not LotNoBuf.Eof do //提交主表
begin
if (LotNoBuf.FieldByName('P_ID').AsString='0') or (LotNoBuf.FieldByName('P_ID').AsString='') then //取ID
begin
vP_ID:=Ksoap.cf_traceability_seq_f(LotNoBuf.FieldByName('P_ORG_CODE').AsString,sError);
//inc(vP_ID);////////////////////////////////
if vP_ID=0 then //取不到ID
begin
Sleep(10000);
LotNoBuf.Next;
continue;
end;
LotNoBuf.Edit;
LotNoBuf.FieldByName('P_ID').AsString:=vP_ID.ToString;
vId:=LotNoBuf.FieldByName('ID').AsInteger;
LotNoBuf.Post;
SaveMainToRecord(LotNoRecord);
LotNoRecord.P_ID:=vP_ID;
dm.UpdateMainId(vId,vP_ID.ToString,false); //更新主表ID
end
else //已有ID的,并且未插入的
begin
vId:=LotNoBuf.FieldByName('ID').AsInteger;
vP_ID:=LotNoBuf.FieldByName('P_ID').AsFloat;
if not LotNoBuf.FieldByName('Inserted').asboolean then //未提交
begin
SaveMainToRecord(LotNoRecord);
LotNoRecord.P_ID:=vP_ID;
end
else
LotNoRecord.P_ORG_CODE:='-1';
end;
//提交主表
if LotNoRecord.P_ORG_CODE<>'-1' then //提交
if Ksoap.Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(LotNoRecord,sError) then //提交主表成功
begin
if LotNoBuf.FieldByName('IsOnlyMain').asboolean then //只有主表
dm.DeleteMainById(vId)
else
dm.UpdateMainId(vId,vP_ID.ToString,True); //更新主表ID
end
else //主表提交未成功
begin
Sleep(1000);
LotNoBuf.Next;
continue;
end;
//找到明细数据,并提交
DetailBuf.First;
bHaveNoSucced:=false;
while not DetailBuf.Eof do
begin
if DetailBuf.FieldByName('ParentID').AsInteger=vId then //提交从表数据
begin
if (DetailBuf.FieldByName('Style').AsInteger=2) and (not bHaveNoSucced) then //最终提交的数据
begin
with DetailBuf do
if Ksoap.Update_qty_time_p(vP_ID.ToString,FieldByName('P_ACT_QTY').AsString,
FieldByName('P_END_TIME').AsString,FieldByName('P_LINE_SPEED').AsString,FieldByName('P_BK1').AsString,
FieldByName('P_BK2').AsString,FieldByName('P_BK3').AsString,sError) then
begin
dm.DeleteDetailById(DetailBuf.FieldByName('ID').AsInteger); //提交成功,删除该记录
dm.DeleteMainById(vId);
end;
end
else
begin
SaveDetailToRecord(DetailRecord);
DetailRecord.P_ID:=vP_ID.ToString;
if Ksoap.Insert_cc_wip_lot_bc_history(DetailRecord,sError) then
begin
dm.DeleteDetailById(DetailBuf.FieldByName('ID').AsInteger);
end
else
begin //提交不成功
if sError='連接數據庫服務器失败' then
bHaveNoSucced:=true
else
dm.DeleteDetailById(DetailBuf.FieldByName('ID').AsInteger);
end;
end;
SLEEP(400);
end;
DetailBuf.Next;
end;
LotNoBuf.Next;
Sleep(200);
end;
LotNoBuf.EmptyDataSet;
DetailBuf.EmptyDataSet;
except
workLog.Error('后台线程提交主从数据出错');
Sleep(20000);
end;
end;
finally
CoUninitialize;
DetailBuf.Free;
LotNoBuf.Free;
end;
end;
procedure TDM.Tim_Timer(sText: String);
var
sPath:string;
begin
//判断整点,就上传日志
if RightStr(sText,5)=':00:00' then //整点
begin
sPath:=TRIM(dm.MemTableReadKeyValue('主要参数','LogBakDir'));
if sPath<>'' then
CopyLogFile(sPath);
end;
end;
end.