Jump to content
Developer Wiki and Function Reference Links ×

Using External Files


Assembly

Recommended Posts

I've been working on using an external file to keep and access information for record entries. Specifically a Costing Record.

My process was to create a record file with it's fields.

Created a worksheet to enter different values for the record.

Exported the worksheet as a comma separated file: Costing.txt

The PIO's will generate and self attach the costing record.

The costing record access the external file and brings in the Cost Rates & Labour Rates.

The reading of the file and extracting the wanted data feel like it should be easier.

The CheckForEntry procedure goes through chr by chr to find the comma's. The position of the Commas is kept in an Array.

THe content between the arrays is extracted out.

I wanted to use a TAB separated file but ReadLn and Read seem to read the TAB as a new line.

Anyone have experience with Read on TAB files. Specifically is there an easier way to pull the info?

PROCEDURE GetCostRecordFromExternal;

VAR

NumberOfLines: Integer;

MessageThis: String;

sTemp: STRING;

hRecord:handle;

result: Boolean;

FileText: Array[1..10000] of String;

TabPoint:Array[0..20] of Integer;

RecordHeader: Array[0..10000] Of String;

RecordReturn: Array[0..10000] Of String;

iTemp:Integer;

i,m,n,o,p: Integer;

Procedure PlatformFileName;

VAR

fileName,FileNameWrite :STRING;

major, minor, maintenance, platform :INTEGER;

BEGIN

GetVersion(major, minor, maintenance, platform);

IF platform = 1 THEN

BEGIN

fileName := '/Costing.txt';

END

ELSE

BEGIN

fileName := 'C:\Costing.txt';

END;

Open(FileName);

For i:= 1 TO 10000 DO

Read(FileText);

Close(FileName);

END;

Procedure CheckForEntry;

VAR

CheckForRecord: String;

TheRecord: String;

CurrentLetter: string;

BEGIN;

{Passes the Line into a record and extracts the values between Comma}

TheRecord:=FileText[1];

iTemp:=Len(TheRecord);

FOR m:= 1 to iTemp DO

BEGIN;

CurrentLetter:=Copy(TheRecord,m,1);

IF CurrentLetter=CHR(44) THEN

BEGIN;

TabPoint[n]:=m+1;

n:=n+1;

END;

END;

iTemp:=N;

For P:= 0 to iTemp DO

BEGIN;

RecordHeader[P]:=Copy(TheRecord,TabPoint[p],TabPoint[p+1]-TabPoint[p]-1);

END;

{Checks for an entry and gets the values}

n:=0;

CheckForRecord:='_Carcase_Black Meltica';

iTemp:=Len(CheckForRecord);

FOR i:=1 to 100 DO

BEGIN;

sTemp:=Copy(FileText,1,itemp);

If sTemp=CheckForRecord THEN

BEGIN;

TheRecord:=FileText;

iTemp:=Len(TheRecord);

FOR m:= 1 to iTemp DO

BEGIN;

CurrentLetter:=Copy(TheRecord,m,1);

IF CurrentLetter=CHR(44) THEN

BEGIN;

TabPoint[n]:=m+1;

n:=n+1;

END;

END;

END;

END;

iTemp:=N;

For P:= 0 to iTemp DO

BEGIN;

RecordReturn[P]:=Copy(TheRecord,TabPoint[p],TabPoint[p+1]-TabPoint[p]-1);

MessageThis:=Concat(MessageThis,' ',RecordHeader[P],' ',RecordReturn[P]);

{ SetRField(PIOHandle,'Cost_Detail',RecordHeader[P],RecordReturn[P]);}

END;

END;

Begin;

PlatformFileName;

CheckForEntry;

Message(MessageThis);

END;

Run(GetCostRecordFromExternal);

Link to comment

You can pass multiple variables to Read and ReadLn, and VS will parse the tabs. For example, if your line has three values separated by tabs:

ReadLn(value1, value2, value3);

The only caution I know is VS will read two tabs in a row (an empty value) as a single tab, so if that is a possibility I use a custom parser.

One option for you to look in to is VS's XML functions. VS stores the XML data in memory, so you may find that it's a faster method.

-Josh

Link to comment

Thanks Josh.

ReadLn Makes sense.

XML looks like it might be for me... I've had a read of the documentation. The Functions look not to scary.

I cut and paste the ran the script below.

I don't quite get how the file path works with this.

I presume it still needs the PlatformFileName procedure from above.

Can some one outline what the steps are to set the file path?.

PROCEDURE WriteXML;

{Writes data to an XML file.}

CONST

kAppFolder = 1;

VAR

hXML :LONGINT;

xmlFile :STRING;

result :INTEGER;

elementResult :STRING;

attributeResult :STRING;

pathResult :STRING;

cdata :DYNARRAY [] of CHAR;

BEGIN

ALLOCATE cdata [1..1024];

cdata := Copy('00 01 02 03 04 05 06 07', 1, 23);

cdata := Concat(cdata, Chr(13), '08 09 10 1a 1b 1c 1d 1e');

cdata := Concat(cdata, Chr(13), '1f 20 21 22 23 24 25 26');

hXML := InitXML;

IF hXML <> 0 THEN BEGIN

xmlFile := 'XML Test File.xml';

result := CreateNewXMLDocument(hXML, 'XMLTest');

result := SetElementValue (hXML, '/XMLTest/Tools/Computers/Platform/Macintosh/CPU', 'G4');

result := SetElementValue (hXML, '/XMLTest/Tools/Computers/Platform/Macintosh/Disk', 'SCSI');

result := SetElementValue (hXML, '/XMLTest/Tools/Computers/Platform/Windows/CPU', 'P4');

result := SetElementValue (hXML, '/XMLTest/Tools/Computers/Platform/Windows/Disk', 'EIDE');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Computers/Platform/Windows/CPU', 'Speed', '3.0 GHz');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Computers/Platform/Macintosh/CPU', 'Speed', '1.2 GHz');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Computers/Platform/Windows/Disk', 'Size', '300 GB');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Computers/Platform/Macintosh/Disk', 'Size', '450 GB');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Hardware/Screwdriver/Regular', 'Head', 'Flat');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Hardware/Screwdriver/Philips', 'Head', '4-point');

result := SetElementValue (hXML, '/XMLTest/Tools/Hardware/Wrench/Fixed/Units/Metric', 'mm');

result := SetElementValue (hXML, '/XMLTest/Tools/Hardware/Wrench/Fixed/Units/English', 'inches');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Hardware/Wrench/Non-fixed/Adjustable', 'slide', 'Horizontal');

result := SetAttributeValue(hXML, '/XMLTest/Tools/Hardware/Wrench/Non-fixed/Monkey', 'slide', 'Vertical');

{Write some CDATA strings}

result := SetCDATA(hXML, '/XMLTest/Tools/BinaryData/MiscData', cdata);

result := WriteXMLFile(hXML, kAppFolder, xmlFile);

Message('result: ', result);

result := ReleaseXML(hXML);

END ELSE BEGIN

SysBeep;

Message('Could not initialize XML reader.');

END;

END;

Run(WriteXML);

Link to comment
  • Vectorworks, Inc Employee

For the XML file path you just need to specify the fill path as part of the file name.

xmlFile := "C:\Temp\Projects\xmlfile.xml"

result := WriteXMLFile(hXML, -1, xmlFile);

If you want to let the user pick the folder you can use

"FUNCTION GetFolder(promptStr:STRING;VAR directoryPath:STRING) :INTEGER;"

and then add the actual file name.

Kevin

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...