4.2 提取印制板元器件信息到电子表格
请见SDK例子\SAMPLES\NO5\API\Spread\ExportComponentInfoToSpread。
此代码示范了如何把当前PCB板中元件信息提取出来并输出到电子表格中。代码中使用了很多涉及到在精通篇有关代码的基础知识,如Windows临时文件夹如何获取,元件信息的提取等内容,请读者仔细研究例子代码。
{....................................................................................}
//获取Windows临时文件夹。
function GetTempDirectory: String;
var
TempDir: array[0..255] of Char;
begin
GetTempPath(255, @TempDir);
Result := StrPas(TempDir);
end;
{....................................................................................}
//把整个存放元件信息列表中的内容输出到本地文本文件。
Procedure ExportComponentInfoToTempFile(TempFileName : TString; TotalInfoList : TStringList);
var
TempFile : TextFile;
i: Integer;
Csr: TSearchRec;
CFileAttrs: Integer;
begin
if FindFirst(GetTempDirectory + TempFileName, CFileAttrs, Csr) = 0 then
DeleteFile(GetTempDirectory + TempFileName);
//查找临时文件,如果找到则删除临时文件
AssignFile(TempFile,GetTempDirectory + TempFileName);//获得临时文件目录。
ReWrite(TempFile);//新建文。件
try
For I:=0 to TotalInfoList.Count-1 do
writeln(TempFile,TotalInfoList.Strings[I]);
finally
Closefile(TempFile);
end;
//把每一层的使用和显示信息输出到临时文件TempFile中。
end;
{....................................................................................}
Function WaitForCommit(BinderHandle : TObjectHandle; Docname :TString) : TObjectHandle;
Var
I : Integer;
Begin
Result := 0;
For I := 1 to 50 Do
Begin
ClientAPI_RepopulateDocumentEntity(BinderHandle,False);
//ClientApi_RepopulateDocumentEntity 过程在封装对象中刷新文档实体的内容依赖于
//Recursive参数值,如果参数为false,当前实体被刷新,否则实体的封装对象被刷新。
//它在当文档被增加到一个封装对象中您需要刷新封装对象来让设计资源管理器知道有新的文档时情况下很有用。
Result := ClientAPI_FindChildDocumentInBinder(Binderhandle,Docname);
//ClientApi_FindChildDocumentInBinder过程返回一个名称为Docname参数的文档,
//ADocumentEntity是包含容器的句柄。在ADocumentEntity句柄所表示的实体中查找名称为Docname的文档。
If Result <> 0 Then Break;
WaitForSingleObject(GetCurrentThread,100);
//GetCurrentThread得到当前的线程。
//WaitForSingleObject等待100毫秒。
End;
End;
{................................................................................}
//CreateASpreadDocument函数创建一工作表。
Function CreateASpreadDocument(Filename : TString) : TSPHandle;
Var
EntityHandle: TObjectHandle;
BinderHandle: TObjectHandle;
NewDocHandle: TObjectHandle;
DocumentEntity : TDocumentEntity;
DDBItem: TDDBItem;
S: TString;
Begin
Result := 0;
EntityHandle :=
ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);
//MessageRouter_GetState_CurrentEditorWindow函数返回当前在项层的文档的窗体句柄。
//当前在项层在文档的窗体句柄。
//ClientApi_FindEntityByDataHandle函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。
If Entityhandle = 0 Then Exit;
BinderHandle := ClientAPI_GetDocumentOwnerBinder(EntityHandle);
//ClientApi_GetDocumentOwnerBinder函数获得在其内部存有文档的封装对象的句柄,
//一个封装对象表现为包含实体的容器,一个实体可为一个设计文档或文件来。
NewDocHandle := ClientAPI_FindChildDocumentInBinder(BinderHandle,Filename);
//ClientApi_FindChildDocumentInBinder过程在容器中查找文档。
If NewDocHandle <> 0 Then ClientApi_DestroyEntity(NewDocHandle);
//文件如果找到,则销毁NewDocHandle句柄。
ClientAPI_GetDocumentEntityAbsoluteAddress(EntityHandle,S);
//ClientApi_GetDocumentEntityAbsoluteAddress在关联的设计数据文档内获得一个文档
//实体的绝对地址,即得到当前文档的绝对地址。
DDBItem:= TDDBItem.Create('Admin',S);//创建一个文件
DDBItem.Address.Offset.Name := Filename;//文件名称为Filename
DDBItem.Address.EditorKind:= 'Spread';//文件类型为Spread
DDBItem.Address.Id:= cUnassignedID;//地址ID为cUnassignedID
DDBItem.Address.Attributes:= 0;
DDBItem.Write;//写。
DDBItem.Free;//释放。
NewDochandle := WaitForCommit(BinderHandle,Filename);
ClientAPI_OpenDocumentEntity(NewDocHandle,False);//打开实体,但不在窗体中。
Result := SpreadAPI_GetCurrentSpreadHandle;
//SpreadAPI_GetCurrentSpreadHandle函数返回一个当前在设计资源管理器99中打开的spread文档的句柄。
End;
{................................................................................}
//ExtractAttributesOfAComponentObject过程把元件的参数加到列表ComponentInfoList中。
Procedure ExtractAttributesOfAComponentObject(ComponentRowNumber : Integer;ComponentHandle : PCBTypes.TObjectHandle;ComponentInfoList : TStringList);
Var
Component: TPCBComponent;
ComponentName: TPCBText; //元件名称文本对象
ComponentComment: TPCBText; //元件备注文本对象
NameHandle: PCBTypes.TObjectHandle;//元件名称文本对象句柄
CommentHandle: PCBTypes.TObjectHandle;//元件备注文本对象句柄
NameContent: TString;//元件名称字符串
CommentContent: TString;//元件备注字符串
Begin
Component := TPCBComponent.Create(0); //创建一个元件对象。
Component.Objecthandle := Componenthandle;
//把查找的元件对象句柄赋予元件的对象句柄属性。
Component.Querydatabase(PCBTypes.eGetstate);
//用内部服务器数据同步外部服务器数据。
NameHandle := Component.Name;//取得元件名称句柄。
ComponentName := TPCBText.Create(NameHandle);//根据元件名称句柄创建文本对象。
ComponentName.Querydatabase(PCBTypes.eGetState);
//用内部服务器数据同步外部服务器数据,即把内部元件的名称信息读取文本对象中。
NameContent := ComponentName.List;//把元件名称字符串内容放到NameContent字符串变量中。
ComponentName.Free;//释放名称文本对象
CommentHandle := Component.Comment;//取得元件备注句柄。
ComponentComment := TPCBText.Create(CommentHandle);//根据元件备注句柄创建文本对象。
ComponentComment.Querydatabase(PCBTypes.eGetState);
//用内部服务器数据同步外部服务器数据,即把内部元件的备注信息读取文本对象中。
CommentContent := ComponentComment.List;//把元件备注字符串内容放到CommentContent字符串变量中。
ComponentComment.Free;//释放备注文本对象。
//Component.Pattern为流水号。
ComponentInfoList.Add('元件: ' + IntToStr(ComponentRowNumber));//元件N
ComponentInfoList.Add('元件名称='+ NameContent);
ComponentInfoList.Add('流水号='+ Component.Pattern);
ComponentInfoList.Add('元件备注='+ CommentContent);
Component.Free;//释放元件对象。
End;
{................................................................................}
// ExportToSpread过程完成把存放元件信息的AComponentList列表中内容输出到一工作图表中,
//并用Tab分隔。SpreadHandle为电子表格句柄,ARow为开始行,AComponentList为存放元件信息的列表。
Procedure ExportComponentInfoToSpread(SpreadHandle : TSPHandle; ARow : Integer; AComponentList : TStringList);
Const
cTab= #9;//换行
cEnter= #13;//回车
var
Buffer: PChar;
TempBuffer: PChar;
I: Integer;
Begin
If SpreadHandle <> 0 Then//当前有电子表。
Begin
GetMem(Buffer,1024); //申请1024字节内存。
GetMem(TempBuffer,1024); //申请1024字节内存。
StrPCopy(TempBuffer,'');//用空字符初始化内存。
StrPCopy(Buffer,''); //用空字符初始化内存。
For I := 0 to AComponentList.Count - 1 do // AComponentList为存放元件信息的列表。
Begin
StrPCopy(TempBuffer,AComponentList.Strings[i]);//把元件列表中信息放在内存中。
StrCat(Buffer,TempBuffer);//把TempBuffer中内存追加到Buffer中。
StrCat(Buffer,cTab);//把Buffer中内容加上换行符。
End;
StrCat(Buffer,cEnter);//元件列表中数据全部输出后,Buffer中追加回车符。
SpreadAPI_InsertTabDelimitedText(SpreadHandle,ARow,1,Buffer);
//把SpreadHandle指向的工作图用TAB来确定界限的文本块分隔,从ARow行,1列开始。
//ARow参数是在当前印制板中第几个元件对象,即第一个元件对象从1行开始,第N个元件对象是N行开始。
FreeMem(TempBuffer,1024);//释放内存。
FreeMem(Buffer,1024); //释放内存。
End;
End;
{................................................................................}
//RefreshDesignDatabase过程初始化Spread。
Procedure RefreshDesignDatabase(SpreadHandle : TObjectHandle);
Var
Binderhandle : TObjecthandle;
Entityhandle : TObjecthandle;
P: PChar;