3 Star 12 Fork 16

嘉立创SMT / PnPcustom

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
PnPcoustom.pas 30.18 KB
一键复制 编辑 原始数据 按行查看 历史
嘉立创SMT 提交于 2021-07-03 11:50 . 增加是否SMD元器件功能
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
{==============================================================================}
{ --------------------- Pick & Place custom output ----------------------------}
{------------------------------------------------------------------------------}
{- -}
{- Pick & Place data are exported components -}
{- Units - mm -}
{- Out file - Filename of processed PCB with .csv extension -}
{- -}
{------------------------------------------------------------------------------}
{- Copyright (C) 2018 深圳市嘉立创科技发展有限公司 -}
{- 版权所有。 -}
{- 创建者:WJT -}
{- 最近修改人:WJT -}
{- 最近时间: 2019-6-10 14:20 -}
{- 修改说明: -}
{- 版本:V0.7.1 -}
{==============================================================================}
{- 脚本下载地址:http://club.szlcsc.com/article/details_10024_1.html -}
{==============================================================================}
{..............................................................................}
Function ReplaceSub(str, sub1, sub2: String): String;
var
aPos: Integer;
rslt: String;
begin
aPos := Pos(sub1, str);
rslt := '';
while (aPos <> 0) do begin
rslt := rslt + Copy(str, 1, aPos - 1) + sub2;
Delete(str, 1, (aPos-1) + Length(sub1));
aPos := Pos(sub1, str);
end;
Result := rslt + str;
end;
Function isPointIdentical(P1, P2 :Point) :Boolean;
var
isok :Boolean;
begin
isok := false;
if( (P1.x = P2.x) and (P1.y = P2.y) ) then Begin
isok := true;
end;
Result := isok;
end;
Function getAngle(x1, y1, x2, y2 :Double): Double;
var
len_y,len_x, tan_yx ,Angle : Double;
begin
len_y := Abs(y1-y2);
len_x := Abs(x1-x2);
if (len_x=0) and (y1 < y2) then
Begin
Result := 90.0;
end
else if (len_x=0) and (y1 >= y2) then
Begin
Result := 270.0;
end
else if (len_y=0) and (x1 >= x2) then
Begin
Result := 180;
end
else if (len_y=0) and (x1 < x2) then
Begin
Result := 0;
end
else
Begin
tan_yx := (y1-y2)/(x1-x2);
Angle := (arctan(tan_yx)/3.1415926535)*180;
if Angle < 0 then
Begin
Angle := Angle+360;
end;
Result := Angle;
end;
end;
Function getCircleCente(P1,P2,P3:Point): Point;
var
X, Y : Double;
p : Point;
begin
if( (isPointIdentical(P1,P2) <> true) AND (isPointIdentical(P2,P3) <> true) AND (isPointIdentical(P1,P3) <> true) ) then
Begin
X :=(((((((p1.x*(-1.0))+p2.x)*(p1.x+p2.x)*0.5)+(((p1.y*(-1.0))+p2.y)*(p1.y+p2.y)*0.5))*((p1.y*(-1.0))+p3.y))+(((((p1.x*(-1.0))+p3.x)*(p1.x+p3.x)*0.5)+(((p1.y*(-1.0))+p3.y)*(p1.y+p3.y)*0.5))*(p1.y+(p2.y*(-1.0)))))* Power((((p1.y+(p2.y*(-1.0)))*(p1.x+(p3.x*(-1.0)))*(-1.0))+((p1.y+(p3.y*(-1.0)))*(p1.x+(p2.x*(-1.0))))),(-1.0)));
Y :=(((((((p1.x*(-1.0))+p2.x)*(p1.x+p2.x)*0.5)+(((p1.y*(-1.0))+p2.y)*(p1.y+p2.y)*0.5))*(p1.x+(p3.x*(-1.0))))+(((((p1.x*(-1.0))+p3.x)*(p1.x+p3.x)*0.5)+(((p1.y*(-1.0))+p3.y)*(p1.y+p3.y)*0.5))*(p1.x+(p2.x*(-1.0)))*(-1.0)))* Power((((p1.y+(p2.y*(-1.0)))*(p1.x+(p3.x*(-1.0)))*(-1.0))+((p1.y+(p3.y*(-1.0)))*(p1.x+(p2.x*(-1.0))))),(-1.0)));
p := Point(X,Y);
end
else
Begin
p := Point(0,0);
end;
Result := p;
end;
Function getCenterCoordinates( XmaxPad, XminPad, YmaxPad, YminPad :Point):Point;
var
p1, p2, p3, p4 : Point;
PointItems : TObjectList;
p : Point;
I : Integer;
temp : Integer;
isLineCount : Integer;
isLine : Boolean;
isBeing : Boolean;
begin
p := Point(0,0);
PointItems := TObjectList.Create;
//add XmaxPad
PointItems.Add(XmaxPad);
//add XminPad
isBeing := false;
for I:=0 to PointItems.Count-1 do
begin
p:= PointItems.Items[I];
if(isPointIdentical(p,XminPad)=true) then begin
isBeing := true;
break;
end;
end;
if(isBeing = false) then begin
PointItems.Add(XminPad);
end;
//add YmaxPad
isBeing := false;
for I:=0 to PointItems.Count-1 do
begin
p:= PointItems.Items[I];
if(isPointIdentical(p,YmaxPad)=true) then begin
isBeing := true;
break;
end;
end;
if(isBeing = false) then begin
PointItems.Add(YmaxPad);
end;
//add YminPad
isBeing := false;
for I:=0 to PointItems.Count-1 do
begin
p:= PointItems.Items[I];
if(isPointIdentical(p,YminPad)=true) then
begin
isBeing := true;
break;
end;
end;
if(isBeing = false) then begin
PointItems.Add(YminPad);
end;
if(PointItems.Count >= 4) then
begin
p := Point( (XmaxPad.x+XminPad.x)/2,(YmaxPad.y+YminPad.y)/2 );
end
else if(PointItems.Count = 3) then
begin
isLineCount := 0;
isLine := false;
//isLine X?
temp := PointItems.Items[0].y;
for I:=1 to PointItems.Count-1 do
begin
if( abs( (temp) -(PointItems.Items[I].y) ) <= 10 ) then
begin
isLineCount := isLineCount +1;
end;
end;
if(isLineCount >=2) then
begin
p := Point( (XmaxPad.x +XminPad.x)/2, YmaxPad.y );//isLine X
isLine :=true;
end;
//isLine Y?
isLineCount :=0;
temp :=PointItems.Items[0].x;
for I:=1 to PointItems.Count-1 do
begin
if( abs((temp) - ( PointItems.Items[I].x ) ) <=10 ) then
begin
isLineCount := isLineCount +1;
end;
end;
if(isLineCount >=2) then
begin
p := Point( YmaxPad.x , (YmaxPad.y+YminPad.y)/2 );//isLine Y
isLine :=true;
end;
if (isLine = false) then
begin
p1 := PointItems.Items[0];
p2 := PointItems.Items[1];
p3 := PointItems.Items[2];
p := getCircleCente(P1,P2,P3);
end;
end
else if(PointItems.Count = 2)then
begin
p1 := PointItems.Items[0];
p2 := PointItems.Items[1];
p := Point( ( (p1.x+p2.x)/2 ), ( (p1.y+p2.y)/2 ) );
end;
Result := p;
end;
{..............................................................................}
Procedure DisplayResultsInMessagePanel(Results : TStringList);
Var
WSM : IWorkSpace;
MM : IMessagesManager;
ImageIndex : Integer;
F : Boolean;
I : Integer;
Begin
WSM := GetWorkSpace;
If WSM = Nil Then Exit;
// Obtain the Messages Panel interface
MM := WSM.DM_MessagesManager;
If MM = Nil Then Exit;
// Tick Icon for the lines in the Message panel
ImageIndex := 4;
// Clear out messages from the Message panel...
MM.ClearMessages;
MM.BeginUpdate;
F := False;
For I := 0 to Results.Count - 1 Do
Begin
MM.AddMessage({MessageClass } '提示: ' + IntToStr(I),
{MessageText } Results.Strings[I],
{MessageSource } '',
{MessageDocument } '',
{MessageCallBackProcess } '',
{MessageCallBackParameters} '',
ImageIndex,
F);
End;
MM.EndUpdate;
// Display the Messages panel in Altium Designer.
WSM.DM_ShowMessageView;
End;
Procedure MessagePanelClearMessages();
Var
WSM : IWorkSpace;
MM : IMessagesManager;
Begin
WSM := GetWorkSpace;
If WSM = Nil Then Exit;
// Obtain the Messages Panel interface
MM := WSM.DM_MessagesManager;
If MM = Nil Then Exit;
// Clear out messages from the Message panel...
MM.ClearMessages;
MM.BeginUpdate;
MM.EndUpdate;
// Display the Messages panel in Altium Designer.
WSM.DM_ShowMessageView;
End;
{..............................................................................}
Procedure PickAndPlaceOutput;
var
Board : IPCB_Board; // document board object
Component : IPCB_Component; // component object
Iterator : IPCB_BoardIterator;
ComponentIterator : IPCB_GroupIterator;
Pad : IPCB_Pad;
PnPout : TStringList;
BOMout : TstringList;
BOM_row,BOM_row2 : TstringList;
DuplicateDesignator : TstringList;
ErrorList : TStringList;
Count : Integer;
FileName : TString;
FilePath : TString;
Document : IServerDocument;
X, Y, Rotation, C_Layer : TString;
PadAngle : TString;
Xpad, Ypad, Npad,DDesig : TString;
Xpad2, Ypad2 : TString;
Xref, Yref : TString;
centerX,centerY : Integer;
axisIni : Boolean;
YminPad,YmaxPad : Point;
XminPad,XmaxPad : Point;
CCenter : Point;
Pad_1, Pad_2 : Point;
padX1,padX2,padY1,padY2 : Double;
pinCout : Integer;
Comment_t,Name_t : IPCB_Text;
PadTLayer : TLayer;
PadDifferentLayer : Boolean;
ComponentKind : TComponentKind;
Comment_text,Description_text : TString;
Designator_text,Footprint_text : TString;
LibRef_text,Pins_text : TString;
Quantity_text : TString;
SuppliersPartNumber_text : TString;
r0,r1 : TString;
i,j : Integer;
t_Comment,t_Description : TString;
t_Designator, t_Footprint : TString;
t_LibRef , t_Pins : TString;
Quantity : Integer;
t_SuppliersPartNumber : TString;
t_Comment2,t_Description2 : TString;
t_Designator2, t_Footprint2 : TString;
t_LibRef2 , t_Pins2 : TString;
Quantity2 : Integer;
t_SuppliersPartNumber2 : TString;
BOM_ok,Pick_ok : Boolean;
IsSMD : Boolean;
t_IsSMD : TString;
t_IsSMD2 : TString;
Begin
Board := PCBServer.GetCurrentPCBBoard;
If Not Assigned(Board) Then // check of active document
Begin
ShowMessage('The Current Document is not a PCB Document.');
Exit;
End;
Iterator := Board.BoardIterator_Create;
Iterator.AddFilter_ObjectSet(MkSet(eComponentObject));
Iterator.AddFilter_IPCB_LayerSet(LayerSet.AllLayers);
Iterator.AddFilter_Method(eProcessAll);
Count := 0;
PnPout := TStringList.Create;
BOMout := TStringList.Create;
ErrorList:= TStringList.Create;
Component := Iterator.FirstPCBObject;
PnPout.Add('"Designator","Footprint","Mid X","Mid Y","Ref X","Ref Y","Pad X","Pad Y","Layer","Rotation","Comment","SMD"' );
ErrorList.Add('以下信息为嘉立创的脚本检查出来,不是AD自带的功能,出现提示的这些元件,建议仔细检查');
ErrorList.Add('嘉立创的脚本下载地址:http://club.szlcsc.com/article/details_10024_1.html');
While (Component <> Nil) Do
Begin
ComponentIterator := Component.GroupIterator_Create;
ComponentIterator.AddFilter_ObjectSet(MkSet(ePadObject));
Pad := ComponentIterator.FirstPCBObject;
X := '';
Y := '';
Xpad := '';
Ypad := '';
Xpad2 := '';
Ypad2 := '';
padX1 := 0.0;
padY1 := 0.0;
padX2 := 0.0;
padY2 := 0.0;
PadAngle := '';
C_Layer := '';
centerX := 0;
centerY := 0;
pinCout := 0;
Comment_t := Component.Comment;
Name_t := Component.Name;
Comment_text := trim(Comment_t.Text);
Designator_text := trim(Name_t.Text);
Description_text := trim(Component.SourceDescription);//.SourceDesignator;
Footprint_text := trim(Component.Pattern);
LibRef_text := trim(Component.SourceLibReference);
//Ref xy
Xref := FormatFloat('0.###',FloatToStr(CoordToMMs(Component.X - Board.XOrigin)))+'mm';
Yref := FormatFloat('0.###',FloatToStr(CoordToMMs(Component.Y - Board.YOrigin)))+'mm';
//ComponentKind
ComponentKind := Component.ComponentKind;
//{
if pos(#9,Description_text) <> 0 then
begin
ErrorList.Add('Designatorb包含未知字符,已强制替换为空格. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Description_text := ReplaceSub (Description_text, #9, ' ');
end;
if pos(#10,Description_text) <> 0 then
begin
ErrorList.Add('Designatorb包含未知字符,已强制替换为空格. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Description_text := ReplaceSub (Description_text, #10, ' ');
end;
if pos(#13,Description_text) <> 0 then
begin
ErrorList.Add('Designatorb包含未知字符,已强制替换为空格. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Description_text := ReplaceSub (Description_text, #13, ' ');
end;
//空格
if pos(#32,Designator_text) <> 0 then
begin
ErrorList.Add('Designator包含空格,已强制替换为下划线. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Designator_text := ReplaceSub (Designator_text, ' ', '_');
end;
//减号
//if pos('-',Designator_text) <> 0 then
// begin
// ErrorList.Add('Designator包含减号,为防止识别为区间,已强制替换为下划线. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
// Designator_text := ReplaceSub (Designator_text, '-', '_');
// end;
// "
if pos('"',Comment_text) <> 0 then
begin
ErrorList.Add('Comment包含引号,已强制替换为单引号. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Comment_text := ReplaceSub (Comment_text, '"', '''');
end;
if pos('"',Description_text) <> 0 then
begin
ErrorList.Add('Description包含引号,已强制替换为单引号. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Description_text := ReplaceSub (Description_text, '"', '''');
end;
if pos('"',Designator_text) <> 0 then
begin
ErrorList.Add('Designator包含引号,已强制替换为单引号. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Designator_text := ReplaceSub (Designator_text, '"', '''');
end;
if pos('"',Footprint_text) <> 0 then
begin
ErrorList.Add('Footprint包含引号,已强制替换为单引号. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
Footprint_text := ReplaceSub (Footprint_text, '"', '''');
end;
if pos('"',LibRef_text) <> 0 then
begin
ErrorList.Add('LibRef包含引号,已强制替换为单引号. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
LibRef_text := ReplaceSub (LibRef_text, '"', '''');
end;
//}
//pad xy
PadTLayer := Nil;
PadDifferentLayer := False;
axisIni := false;
IsSMD := false;
While (Pad <> Nil) Do
Begin
Npad := Pad.Name;
If Npad = '1' Then
Begin
padX1 := FloatToStr(CoordToMMs(Pad.x - Board.XOrigin));
padY1 := FloatToStr(CoordToMMs(Pad.Y - Board.YOrigin));
Xpad := FormatFloat('0.###',padX1)+'mm';
Ypad := FormatFloat('0.###',padY1)+'mm';
End
else if Npad = '2' Then
Begin
padX2 := FloatToStr(CoordToMMs(Pad.x - Board.XOrigin));
padY2 := FloatToStr(CoordToMMs(Pad.Y - Board.YOrigin));
Xpad2 := FormatFloat('0.###',padX2)+'mm';
Ypad2 := FormatFloat('0.###',padY2)+'mm';
End;
{
if( Designator_text = 'K2') then Begin
Designator_text := 'K2';
End;
}
centerX := (Pad.x - Board.XOrigin)/10000;
centerY := (Pad.Y - Board.YOrigin)/10000;
if(axisIni = false) then Begin
XmaxPad := Point(centerX,centerY);
XminPad := Point(centerX,centerY);
YmaxPad := Point(centerX,centerY);
YminPad := Point(centerX,centerY);
axisIni := true;
End
else Begin
if( centerX < XminPad.x) then Begin
XminPad := Point(centerX,centerY);
end
else if( centerX > XmaxPad.X) then Begin
XmaxPad := Point(centerX,centerY);
End;
if( centerY > YmaxPad.y) then Begin
YmaxPad := Point(centerX,centerY);
end
else IF(centerY < YminPad.y) then Begin
YminPad := Point(centerX,centerY);
End;
End;
pinCout := pinCout+1;
if(PadTLayer = Nil) then
begin
PadTLayer := Pad.Layer;
end
else if(PadTLayer <> Pad.Layer) then
begin
PadDifferentLayer := True;
end;
if(IsSMD = false) and (CoordToMMs(Pad.HoleSize) < 0.05) then
begin
IsSMD := true;
end;
Pad := ComponentIterator.NextPCBObject;
End;
//mid x,Y,Rotation,Layer
If (pinCout >1) and (length(trim(Designator_text)) > 0) Then
Begin
//mid x,Y
if (pinCout = 3 ) then //SOT-23..
begin
CCenter := getCenterCoordinates( XmaxPad, XminPad ,YmaxPad,YminPad);
end
else
begin
CCenter := Point( (XmaxPad.x+XminPad.x)/2,(YmaxPad.y+YminPad.y)/2 );
end;
X := FormatFloat('0.###',FloatToStr( CoordToMMs(CCenter.x*10000) ))+'mm';
Y := FormatFloat('0.###',FloatToStr( CoordToMMs(CCenter.y*10000) ))+'mm';
//Rotation
Rotation := FormatFloat('0.##',FloatToStr(Component.Rotation));
{
if(Xpad <> '') and (Ypad <> '') and (Xpad2 <> '') and (Ypad2<>'')then
Begin
PadAngle := FormatFloat('0.##',getAngle(padX1, padY1, padX2,padY2) );
End;
}
//Layer
if (PadDifferentLayer = False) then //Some people are in the wrong position,Preferentially according to the pad
begin
case PadTLayer of
eTopLayer: C_Layer := 'T' ;
eBottomLayer: C_Layer := 'B' ;
else
begin
case Component.Layer of
eTopLayer: C_Layer := 'T' ;
eBottomLayer: C_Layer := 'B' ;
end;
end
end;
IF (Component.Layer <> PadTLayer) and ((PadTLayer = eTopLayer)or (PadTLayer = eBottomLayer)) then
begin
// Makes a string list of connections
ErrorList.Add('焊盘层信息可能不正确,已强制使用焊盘层作为元件层. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
end;
end
else
begin
case Component.Layer of
eTopLayer: C_Layer := 'T' ;
eBottomLayer: C_Layer := 'B' ;
end;
end;
if (C_Layer <> '')then
begin
if ComponentKind <> eComponentKind_Standard then
begin
case ComponentKind of
eComponentKind_Mechanical : ErrorList.Add('元件类型是Mechanical,已强制输出BOM和坐标. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
eComponentKind_Graphical : ErrorList.Add('元件类型是Graphical,已强制输出BOM和坐标. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
eComponentKind_NetTie_BOM : ErrorList.Add('元件类型是NetTie_BOM,已强制输出BOM和坐标. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
eComponentKind_NetTie_NoBOM: ErrorList.Add('元件类型是NetTie_NoBOM,已强制输出BOM和坐标. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
else
ErrorList.Add('未知元件类型,已强制输出BOM和坐标. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
end;
end;
Pins_text := IntToStr(pinCout);
PnPout.Add('"'+Designator_text + '","' + Footprint_text + '","'+ X + '","' + Y +'","'+ Xref + '","' + Yref + '","' + Xpad + '","' + Ypad + '","'+ C_Layer + '","' + Rotation +'","' + Comment_text+'","' + booltostr( IsSMD , true) + '"' );
BOMout.Add('"' + Comment_text + '"' +#7+ '"' + Description_text + '"' +#7+ '"' + Designator_text + '"' +#7+ '"' + Footprint_text + '"' +#7+ '"' + LibRef_text + '"' +#7+ '"' + Pins_text + '"' +#7+ '"1"' +#7+ '"' + booltostr( IsSMD , true) + '"' );
Inc(Count);
end
else
begin
// Makes a string list of connections
ErrorList.Add('未导出BOM和坐标,可能层信息不对. Designator:'+ Designator_text+ ' Comment:' +Comment_text + ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
end;
end
else If (pinCout >1) and (length(trim(Designator_text))<= 0 ) then
begin
// Makes a string list of connections
ErrorList.Add('未导出BOM和坐标,Designator 是空的. Comment:' +Comment_text+ ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
end
else If (pinCout <=1) then
begin
// Makes a string list of connections
ErrorList.Add('未导出BOM和坐标,引脚数量少于2个. Designator:'+ Designator_text +' 引脚数为:'+ IntToStr(pinCout)+ ' Comment:' +Comment_text+ ' Ref X:'+ Xref + ' Ref Y:'+ Yref);
End;
Component := Iterator.NextPCBObject;
End;
Board.BoardIterator_Destroy(Iterator);
// Display ErrorList
MessagePanelClearMessages();
if ErrorList.Count > 2 then
begin
DisplayResultsInMessagePanel(ErrorList);
End;
//Format BOM table
for i := 0 to BOMout.Count-1 do
begin
BOM_row := TStringList.Create;
BOM_row.Delimiter := #7;
BOM_row.DelimitedText := BOMout[i];
if BOM_row.Count = 8 then
begin
t_Comment := BOM_row[0];
t_Description := BOM_row[1];
t_Designator := BOM_row[2];
t_Footprint := BOM_row[3];
t_LibRef := BOM_row[4];
t_Pins := BOM_row[5];
Quantity := 1;
//t_SuppliersPartNumber := BOM_row[7];
t_IsSMD := BOM_row[7];
r0 := t_Comment + t_Description + t_Footprint + t_LibRef + t_Pins + t_IsSMD;// + t_SuppliersPartNumber;
DuplicateDesignator := TStringList.Create;
DuplicateDesignator.add( t_Designator );
for j := i+1 to BOMout.Count-1 do
begin
BOM_row2 := TStringList.Create;
BOM_row2.Delimiter := #7;
BOM_row2.DelimitedText := BOMout[j];
//{
if BOM_row2.Count = 8 then
begin
t_Comment2 := BOM_row2[0];
t_Description2 := BOM_row2[1];
t_Designator2 := BOM_row2[2];
t_Footprint2 := BOM_row2[3];
t_LibRef2 := BOM_row2[4];
t_Pins2 := BOM_row2[5];
//t_SuppliersPartNumber2 := BOM_row2[7];
t_IsSMD2 := BOM_row2[7];
r1 := t_Comment2 + t_Description2 + t_Footprint2 + t_LibRef2 + t_Pins2 + t_IsSMD2;// + t_SuppliersPartNumber2;
//{
if r0 = r1 then
begin
Inc(Quantity);
//排除重复的位号
if(DuplicateDesignator.IndexOf(t_Designator2) = -1) then
begin
t_Designator := t_Designator + ',' + t_Designator2;
DuplicateDesignator.add(t_Designator2);
end;
BOMout[j] := '';
//每行不超过200个位号. 2019-9-2
if DuplicateDesignator.Count >= 200 then
begin
break;
end;
end;
//}
end;
//}
BOM_row2.Free;
end;
DuplicateDesignator.free;
BOMout[i] := '"' + t_Comment + '","' + t_Description + '","' + t_Designator + '","'+#31+ + t_Footprint + '","' + t_LibRef + '","' + t_Pins + '","' + t_IsSMD + '","' + IntToStr( Quantity) + '"' ;
end;
BOM_row.Free;
end;
//Delete empty line
i:=BOMout.Count - 1;
while(i>0)do
begin
if Trim(BOMout[i])='' Then
BOMout.Delete(i);
Dec(i);
end;
BOMout.Sort;
BOMout.Insert(0,'"Comment","Description","Designator","Footprint","LibRef","Pins","SMD","Quantity"' );
//Pick&Place report
FilePath := ExtractFilePath(Board.FileName);
FileName := ChangeFileExt(FilePath+'Pick Place for ' + ExtractFileName(Board.FileName),'.csv');
Pick_ok := false;
if IsFileInUse(FileName) = true then
begin
showmessage(FileName + #9 + ' 文件正在被其他程序使用.无法继续保存');
PnPout.Free;
end
else
begin
PnPout.SaveToFile(FileName);
PnPout.Free;
Pick_ok := true;
end;
//BOM report
FileName := ChangeFileExt(FilePath+'BOM for ' + ExtractFileName(Board.FileName),'.csv');
BOM_ok := false;
if IsFileInUse(FileName) = true then
begin
showmessage(FileName + #9 + ' 文件正在被其他程序使用.无法继续保存');
BOMout.Free;
end
else
begin
BOMout.SaveToFile(FileName);
BOMout.Free;
BOM_ok := true;
end;
//ErrorList
if ErrorList.Count > 2 then
begin
FileName := ChangeFileExt(FilePath+'导出BOM和坐标检查日志 ' + ExtractFileName(Board.FileName),'.csv');
if IsFileInUse(FileName) = true then
begin
showmessage(FileName + #9 + ' 文件正在被其他程序使用.无法继续保存');
ErrorList.Free;
end
else
begin
ErrorList.SaveToFile(FileName);
ErrorList.Free;
end;
End;
if (BOM_ok = true) and (Pick_ok = true) then
begin
ShowMessage(IntToStr(Count) + ' 个元件,导出的BOM和坐标存放在:' + #13 + FilePath);
end
else if (BOM_ok = false) and (Pick_ok = true) then
begin
ShowMessage(IntToStr(Count) + ' 个元件,只导出了坐标,文件存放在:' + #13 + FilePath);
end
else if (BOM_ok = true) and (Pick_ok = false) then
begin
ShowMessage(IntToStr(Count) + ' 个元件,只导出了BOM,文件存放在:' + #13 + FilePath);
end;
End;
{..............................................................................}
Function IsFileInUse(fName : string ) : boolean;
var
HFileRes : HFILE;
begin
Result := false;
if not FileExists(fName) then
exit;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;
Delphi
1
https://gitee.com/JLC_SMT/PnPcustom.git
git@gitee.com:JLC_SMT/PnPcustom.git
JLC_SMT
PnPcustom
PnPcustom
master

搜索帮助