Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reading Turbo Pascal/DOS "file of record" File

8 views
Skip to first unread message

José Romero

unread,
Dec 10, 2007, 11:03:24 AM12/10/07
to
Hi,
I'm trying to read a file created with an old Turbo Pascal/DOS
application in delphi to do some modifications in records.


With the application is included a fully detailed file with all the
declarations of the records used, ie

RegSplProducto = Record
Case Byte Of
0: ( Conf: RegConfArchivo);
1: ( Codigo: String[KC];
Departa: String[KM];
Descripcion: Array[1..3] Of String[KN];
Refere: String[KR];
Marca: String[20];
Unidad: String[3];
TipoP: Char;
UsoI,
Serial,
ComiDept,
Compuesto: Boolean;
IVAP: Real;
DiasE: Integer;
Exento: Boolean;
NeedBalanza: Boolean;
UsaEmp: Boolean;
EsPorcent: Boolean;
ImpuestoI,
CantPedida,
CantCompro: Real;
CostoPrd: ArrayCosto;
PVP: ArrayPrecio;
FechaUC,
FechaUV: String[8];
ExistMi,
ExistMa,
Existencia: Real;
Estadistics: Array[1..NMes,1..EstI] Of Real;
Empaque,
ExUnidades,
CostoUnidad,
PrecioUnidad: Real;
OUnidad: String[3];
{Dummy2: Array[1..22] Of Byte; !!}
{Cambios del dia 12-9-98 OJO !!!}
FlagContab: Boolean;
CtasContab: Array[1..6] Of String[25];
TieneOferta: Boolean;
Dummy2: Array[1..75] Of Byte;
);
End;

RegProducto = Record
Status: LongInt;
Special: RegSplProducto;
DataArea: Array[1..1] Of Byte;
End;


and an example of reading from a text file and insert these records in
the applications file, ie

Var F: File Of RegProducto;
T: Text;
P: RegProducto;
Line: String;
E: Integer;

Function Trim(S: String): String;
Begin
While S[1]=' ' Do
Delete(S,1,1);
While S[Length(S)]=' ' Do
Delete(S,Length(S),1);
Trim:=S;
End;

Begin
Assign(T,'DATOS.TXT');
Reset(T);

Assign(F,'\SAINT\DATA\APROD.DAT');
Reset(F);
Seek(f,filesize(f));

While Not Eof(T) Do
Begin
Readln(T,Line);
FillChar(P,SizeOf(P),0);
With P, Special Do
Begin
Codigo:= Trim(Copy(Line, 1, 6));
Descripcion[1]:=Trim(Copy(Line, 7,25));
Val( Trim(Copy(Line,32, 4)), Existencia, E);
Val( Trim(Copy(Line,36,12)), PVP[1], E);
Write(F,P);
End;
End;
Close(F);
Close(T);
End.


what I'm trying to do is to read the original file (aprod.dat) and
change all the money fields in the record. I'm trying with:

procedure TForm1.btn1Click(Sender: TObject);
Var F: File Of RegProducto;
//T: Text;
P: RegProducto;
Line: String;
E: Integer;
j : Integer;

Begin
//Assign(T,'DATOS.TXT');
// Reset(T);
j:=0;
AssignFile(F,'C:\DATA\APROD.DAT');
Reset(F);
//Seek(f,filesize(f));
//Seek(f, 0);
While Not Eof(f) do begin
Inc(j);
//FillChar(P,SizeOf(P),0);
Read(f, P);
with P, Special do begin
mmo1.Lines.Add(Special.Codigo);
//Codigo:= Trim(Copy(Line, 1, 6));
//Descripcion[1]:=Trim(Copy(Line, 7,25));
//Val( Trim(Copy(Line,32, 4)), Existencia, E);
//Val( Trim(Copy(Line,36,12)), PVP[1], E);
//Write(F,P);
mmo1.Lines.Add(Codigo+' '+Descripcion);
end;
end;
//Close(F);
//Close(f);
CloseFile(f);
mmo1.Lines.Add('Fin '+IntToStr(j)+ ' Registros');

but it's read just garbage and white spaces, but the counter is fine.
There are 60 records in the file and at the end the j variable is equal
to 60;

What could be wrong? thanxs in advance and excuse my english.

José Romero
Isla de Margarita, Venezuela

yannis

unread,
Dec 10, 2007, 11:51:47 AM12/10/07
to
on 10/12/2007, Jose Romero supposed :

> Hi,
> I'm trying to read a file created with an old Turbo Pascal/DOS application in
> delphi to do some modifications in records.
>
>
> With the application is included a fully detailed file with all the
> declarations of the records used, ie
>
> RegSplProducto = Record
[Snip...]

Well my guess would be the alingment of the record type which has
changed from Turbo Pascal days. In order to read it correctly you have
to declare the record as packed eg


RegProducto = Packed Record


Status: LongInt;
Special: RegSplProducto;
DataArea: Array[1..1] Of Byte;
End;

I did not take a closer look on the rest of the code so there might be
more problems to solve.

Regards
Yannis


Danny Strümpel

unread,
Dec 10, 2007, 11:58:17 AM12/10/07
to
José Romero schrieb:

> I'm trying to read a file created with an old Turbo Pascal/DOS
> application in delphi to do some modifications in records.

The Real data type has changed from Turbo Pascal to Delphi. Try
replacing every Real in your record (and, I guess in ArrayCosto and
ArrayPrecio as well) with Real48, which exists for such compatibility
reasons.

The whole Record must have the exact same size as in Turbo Pascal, then
it will most probably work.

--
When I heated my home with oil, I used an average of 800 gallons a
year. I have found that I can keep comfortably warm for an entire
winter with slightly over half that quantity of beer.
-- Dave Barry, "Postpetroleum Guzzler"

...und wech
Danny <dannys9 (at) gmx (dot) de>

José Romero

unread,
Dec 10, 2007, 11:28:47 AM12/10/07
to
Hi yannis,

I've tested with you suggestions putting packed in both records, in one
or another and the results are the same. Just white spaces and some
garbage. I don't know if the case statement in

RegSplProducto = Record
Case Byte Of <------ HERE


0: ( Conf: RegConfArchivo);
1: ( Codigo: String[KC];
Departa: String[KM];
Descripcion: Array[1..3] Of String[KN];

has something to do in the error.

Thanx

Chris Morgan

unread,
Dec 10, 2007, 12:00:45 PM12/10/07
to

> I did not take a closer look on the rest of the code so there might be
> more problems to solve.

Also, Integer has changed from 2-byte to 4-byte (use SmallInt),
and Real has changed from 6-byte to 8-byte. Use the compatibility
type Real48 instead.

cheers,

Chris


yannis

unread,
Dec 10, 2007, 12:17:52 PM12/10/07
to
It happens that Jose Romero formulated :

> Hi yannis,
>
> I've tested with you suggestions putting packed in both records, in one or
> another and the results are the same. Just white spaces and some garbage. I
> don't know if the case statement in
>
> RegSplProducto = Record
> Case Byte Of <------ HERE
> 0: ( Conf: RegConfArchivo);
> 1: ( Codigo: String[KC];
> Departa: String[KM];
> Descripcion: Array[1..3] Of String[KN];
>
> has something to do in the error.

No just leave it alone for now. Take a look on Chris Morgan's list of
changes that are required also. Declare all record types that are used
as Packed records change the data types acordingly and try again if
this fails also (which I think it should not) then please provide us
with a small test case. When I say a small test case I am referring to
a small sample data file created with the dos program and a few
expected values along with a small reading console application.

I will fix it as needed and send it pack to you with info on what has
been fixed.

Regards
Yannis.


José Romero

unread,
Dec 10, 2007, 11:54:09 AM12/10/07
to
Changing to packet records and using SmallInt and Real48 fix the
problem. Thanx a lot, works like a charm.

Now, I able to read the record and display the info. But I need to
modify the data and write the changes back to the file. I'm using

AssignFile(F,'C:\DATA\APROD.DAT');
Reset(F);

Seek(f, 0);
mmo1.Lines.Clear;
While not Eof(f) do begin
Inc(j);
// Reading the record
Read(f, p);
st:=Format('Código = %s, Descripcion = %s, Costo = %m, Precio1 =
%m, Precio2 = %m, Precio3 = %m',
[P.Special.Codigo, p.Special.Descripcion[1],
p.Special.CostoPrd[1], P.Special.PVP[1], P.Special.PVP[2],
P.Special.PVP[3]]);

mmo1.Lines.Add(st);
// Changing the record info
p.Special.CostoPrd[1]:=p.Special.CostoPrd[1]/1000;
p.Special.CostoPrd[2]:=p.Special.CostoPrd[2]/1000;
p.Special.CostoPrd[3]:=p.Special.CostoPrd[3]/1000;

p.Special.PVP[1]:=p.Special.PVP[1]/1000;
p.Special.PVP[2]:=p.Special.PVP[2]/1000;
p.Special.PVP[3]:=p.Special.PVP[3]/1000;
// Wrinting the changes
Write(f, p);
end;


CloseFile(f);
mmo1.Lines.Add('Fin '+IntToStr(j)+ ' Registros');

but I'm getting duplicates record, the old one without the modification
and the new with the modifications. What is the way of doing the
updates? I've to delete the old record in order to insert the new one?


Thanks in advance

yannis

unread,
Dec 10, 2007, 12:37:08 PM12/10/07
to
Jose Romero explained :

> Changing to packet records and using SmallInt and Real48 fix the problem.
> Thanx a lot, works like a charm.
>
> Now, I able to read the record and display the info. But I need to modify the
> data and write the changes back to the file. I'm using
>
> AssignFile(F,'C:\DATA\APROD.DAT');
> Reset(F);
> Seek(f, 0);
------------------
This line moves the file cursor at the start of the file.

> mmo1.Lines.Clear;
> While not Eof(f) do begin
> Inc(j);
> // Reading the record
> Read(f, p);

---------------------
The above line reads the first record and moves the file cursor to
CurrentLocation+Sizeof(p);


> st:=Format('Código = %s, Descripcion = %s, Costo = %m, Precio1 = %m,
> Precio2 = %m, Precio3 = %m',
> [P.Special.Codigo, p.Special.Descripcion[1],
> p.Special.CostoPrd[1], P.Special.PVP[1], P.Special.PVP[2],
> P.Special.PVP[3]]);
>
> mmo1.Lines.Add(st);
> // Changing the record info
> p.Special.CostoPrd[1]:=p.Special.CostoPrd[1]/1000;
> p.Special.CostoPrd[2]:=p.Special.CostoPrd[2]/1000;
> p.Special.CostoPrd[3]:=p.Special.CostoPrd[3]/1000;
>
> p.Special.PVP[1]:=p.Special.PVP[1]/1000;
> p.Special.PVP[2]:=p.Special.PVP[2]/1000;
> p.Special.PVP[3]:=p.Special.PVP[3]/1000;
> // Wrinting the changes
> Write(f, p);

-------------------------------
The above line over writes the second record leaving the first
unchanged and place the file cursor at the begging of the thrid record,
you need to move the file cursor back one record before writting. The
next loop iteration will read the third record not the second which you
have lost from your file.

> end;
> CloseFile(f);
> mmo1.Lines.Add('Fin '+IntToStr(j)+ ' Registros');
>
> but I'm getting duplicates record, the old one without the modification and
> the new with the modifications. What is the way of doing the updates? I've to
> delete the old record in order to insert the new one?

And you must be missing records as well. My guess is that the new file
after you have changed will be larger from the original by sizeof(P) or
have the same size but you will have lost half your records from it.


José Romero

unread,
Dec 10, 2007, 1:41:17 PM12/10/07
to
Done, just calling Seek(f, FilePos(f)-1); after the Write solve the
problem.

Thanks a lot guys


José Romero
Isla de Margarita, Venezuela

yannis

unread,
Dec 10, 2007, 2:26:26 PM12/10/07
to
Jose Romero wrote :

> Done, just calling Seek(f, FilePos(f)-1); after the Write solve the problem.
>
> Thanks a lot guys
> José Romero
> Isla de Margarita, Venezuela
>

I guess you meen after the read and not the write, correct?

regards
Yannis.


José Romero

unread,
Dec 10, 2007, 1:59:20 PM12/10/07
to
yep, just a typo. ;-)

Thanks a lot again Yannis, a very huge thanks

0 new messages