Skip to content

Instantly share code, notes, and snippets.

@ravngr
Last active June 23, 2025 23:45
Show Gist options
  • Save ravngr/fd43d578277f03312e4da7ee7fe7f8f1 to your computer and use it in GitHub Desktop.
Save ravngr/fd43d578277f03312e4da7ee7fe7f8f1 to your computer and use it in GitHub Desktop.
This is an Altium DelphiScript that creates pin functions from a CSV file.
// Convert CSV to Altium pin functions.
// Contributors: Chris Harrison, René HENKE
Procedure CSV2Functions;
Var
SchLib: ISch_Lib;
SchComponent: ISch_Component;
OpenDialog: TOpenDialog;
PinList: TStringList;
PinEntry : string;
CSVFile: File;
CSVLine, PinName, PinPropList, PinFunctions: string;
i, j, DelimiterPosName, DelimiterPosFct, DelimiterPos: Integer;
PinIterator: ISch_Iterator;
PinItem: ISch_Line;
NoOfEntrys : Integer;
Begin
// Get current document
SchLib := SchServer.GetCurrentSchDocument;
if SchLib = Nil Then
begin
ShowError('Script must be run from an SchLib document.');
Exit;
end;
if (SchLib.ObjectID <> eSchLib) Then
begin
ShowError('Document is not an SchLib.');
Exit;
end;
SchComponent := SchLib.CurrentSchComponent;
if SchComponent = nil then
begin
ShowError('No schematic symbol currently open.');
Exit;
end;
// Prompt for CSV file
OpenDialog := TOpenDialog.Create(nil);
try
OpenDialog.Filter := 'CSV Files|*.csv|All Files|*.*';
OpenDialog.Title := 'Select CSV File';
if not OpenDialog.Execute then
begin
ShowError('No CSV file selected.');
Exit;
end;
// Initialize the pin list
PinList := TStringList.Create;
try
// Open CSV file
try
AssignFile(CSVFile, OpenDialog.FileName);
Reset(CSVFile);
except
Raise('Error opening file: ' + OpenDialog.FileName);
end;
// Parse CSV
while not Eof(CSVFile) do
begin
Readln(CSVFile, CSVLine);
DelimiterPos := Pos(',', CSVLine);
if DelimiterPos > 0 then
begin
// Append to lis
PinList.Add(AnsiReplaceText(CSVLine, ',', '/'));
end;
end;
// Close the CSV file
CloseFile(CSVFile);
// Iterate through component pins
PinIterator := SchComponent.SchIterator_Create;
PinIterator.AddFilter_ObjectSet(MkSet(ePin));
PinItem := PinIterator.FirstSchObject;
while PinItem <> Nil Do
begin
// PinItem.Name
PinName := PinItem.GetState_Designator;
for j := 0 to PinList.Count - 1 do
begin
PinEntry := PinList[j];
if StartsText(PinName + '/', PinList[j]) then
begin
DelimiterPosName := Pos('/', PinList[j]);
PinPropList := Copy(PinList[j], DelimiterPosName + 1, Length(PinList[j]) - DelimiterPosName);
DelimiterPosFct := Pos('/', PinPropList);
PinName := Copy(PinPropList, 1, DelimiterPosFct-1);
PinFunctions := Copy(PinPropList, DelimiterPosFct + 1, Length(PinPropList) - DelimiterPosFct);
if AnsiEndsStr('/', PinFunctions) then
PinFunctions := Copy(PinFunctions, 1, Length(PinFunctions) - 1);
PinItem.SetState_Name(PinFunctions + '/');
PinItem.SetState_FunctionsFromName;
PinItem.SetState_Name(PinName);
PinItem.GraphicallyInvalidate;
break;
end;
end;
PinItem := PinIterator.NextSchObject;
end;
SchComponent.SchIterator_Destroy(PinIterator);
SchLib.GraphicallyInvalidate;
SchServer.ProcessControl.PreProcess(SchLib, '');
SchServer.ProcessControl.PostProcess(SchLib, '');
ShowMessage('Pin functions updated successfully.');
finally
PinList.Free;
end;
finally
OpenDialog.Free;
end;
End;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment