Saving Files with custom Records containing Arrays of Arrays lazarus / 8-Other ---------------------------------------------------------------------- Fr0zn S0ul · 2009-06-29 07:41 Just having a little problem with saving a file that contains a custom record with an array of an array (seen below). The items read properly before the save, but when I try to read them back from the file the secondary array is empty. These are my custom records. There are multiple TJobs used since this is a database system. There are multiple products within each TJob because their will be both different items used during each job and a quantity of labour: Code: [Select]TProduct = record   Name: String;   Index: integer;   Price: Extended; end; TJob = record   JCustomer: TCustomer;   JNum: Integer;   JSubtotal, JGST, JTotal: Extended;   JDescription: String;   JDate: TDate;   JQuantity: Array of Integer;   JProducts: Array of TProduct; end;                            var   Jobs: Array of TJob;              Gathering data from the form and saving to file: Code: [Select]//increase number of existing TJobs by one to save the new data in.   SetLength(Jobs, Length(Jobs) + 1);   SetLength(Jobs[High(Jobs)].JProducts, Length(Product));   SetLength(Jobs[High(Jobs)].JQuantity, Length(Product)); //find which customer is being saved and gather the data.   for i := 0 to High(Customer) do     if Customer[i].LastName + ', ' + Customer[i].FirstName = ComboBox1.Text then begin       Jobs[High(Jobs)].JCustomer := Customer[i];       Break;     end; //gain data from the text fields on the form and save them to the new TJob   with Jobs[High(Jobs)] do begin     JDate := StrToDate(Edit2.Text);     JDescription := Edit4.Text;     JNum := StrToInt(Edit1.Text);     JSubtotal := StrToFloat(Label8.Caption);     JGST := StrToFloat(Label9.Caption);     JTotal := StrToFloat(Label10.Caption);   end; //for each product created, assign it to the TJob   for i := 0 to High(Product) do     with Jobs[High(Jobs)] do begin       JQuantity[i] := Quantity[i].Value;       JProducts[i].Name := Product[i].Text;       JProducts[i].Index := Product[i].ItemIndex;       JProducts[i].Price := StrToFloat(UnitPrice[i].Text); //write to file   AssignFile(IFile, 'IData.DAT');   ReWrite(IFile);   for i := 0 to High(Jobs) do     Write(IFile, Jobs[i]);   CloseFile(IFile);                                      Loading from the file and restoring to the form: Code: [Select]//reset and load the job list from file  SetLength(Jobs, 0);   AssignFile(IFile, 'IData.DAT');   Reset(IFile);   i3 := 0;   While not eof(IFile) do begin     SetLength(Jobs, i3 + 1);     Read(IFile, Jobs[i3]);     i3 := i3 + 1;   end;   CloseFile(IFile); //select which element of the job array to load   i3 := StrToInt(InputBox('Job Num', 'Enter the job number', '')); //load the customers name into the form - works   ComboBox1.Text := Jobs[i3].JCustomer.LastName + ', ' + Jobs[i3].JCustomer.FirstName; //load job number - works   Edit1.Text := IntToStr(Jobs[i3].JNum); //load the date - works when saving as a TDate (not as a string though?)   Edit2.Text := DateToStr(Jobs[i3].JDate); //load description of job - works   Edit4.Text := Jobs[i3].JDescription; //now the problems being   for i2 := 0 to High(Jobs[i3].JProducts) do begin //create a new line for each product, works.     AddLine(Button1); //the name is loading as either '' or as random strings such as [][][]1[][][][][2[][][][][]3[][][][][][][][][][][]2 so there is a problem saving this?     Product[i2].Text := Jobs[i3].JProducts[i2].Name; //not loading     Product[i2].ItemIndex := Jobs[i3].JProducts[i2].Index; //stays at 0 most the time, occasionally set itself to the maximum of 1000 (?)     Quantity[i2].Value := Jobs[i3].JQuantity[i2]; //Didn't actually save these since it can be calculated through a different procedure     UnitPrice[i2].Text := FloatToStrF(Jobs[i3].JProducts[i2].Price, ffFixed, 1, 2);     LinePrice[i2].Text := FloatToStrF(StrToFloat(UnitPrice[i2].Text) * Quantity[i2].Value, ffFixed, 1, 2);   end;                                  So the problem is with the loading (or saving) of the TProduct array within the TJob. An error I seem to get occasionally (or whenever it actually displays one) is 'Invalid floating point operation'. I have not been able to find a lot of info on this problem or locate its source yet. Any help or knowledge would be greatly appreciated! Also if any of you know how to read records from .dat files and such that'd be very useful ---------------------------------------------------------------------- Vincent Snijders · 2009-06-29 08:19 You cannot safe records with dynamic arrays (and ansistrings) to disk directly, because they contain pointers, which are meaningless if you read the records back. Reading records you did, can only work for fixed length records, and you expect a variable length record to be stored. If you really want to hand code saving to file and not use a database like tdbf or sqlite, I recommend to use a TStream (e.g. TFileStream), to read/write the individual data fields to file. ---------------------------------------------------------------------- Fr0zn S0ul · 2009-06-29 08:20 OK thank you very much for this, will look into it