Stef Merlijn
asked on
Dynamic Array with multiple values?
Hi,
Let me first explain what I need to do:
I have a table where each record is storing 42 timevalues. The record has also a unique integer number (autoinc).
Record can be added and deleted from this table.
I need to have very quick access to the autoinc-number and the 42 timevalues of all records in the table.
I was thinking about an array of some kind, but I don't know how to add (and later access) the autoinc-number as well as the timevalues.
But when I set it up as I tried below, I get an error, because the autoinc-number will exceed the maximum number allowed for the array (as soon as the autoinc-number is missing one number - 1-2-3-(4 deleted)-5-6-7 in line.
var Werktijden : Array of Array of TTime; // Gebruikt voor de agenda
SetLength(Werktijden,DM.TM edewerkers .RecordCou nt,42);
DM.TMedewerkers.First;
For i := 0 to DM.TMedewerkers.RecordCoun t -1 do
begin
Werktijden[DM.TMedewerkers .FieldByNa me('Persoo nsnr').AsI nteger,0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
// etc. for each timevalue
DM.TMedewerkers.Next;
end;
So I need to be able to quickly get all timevalues of a certain autoinc-number.
Can anybody give me a sample on how to set it up correctly.
Regards,
Stef
Let me first explain what I need to do:
I have a table where each record is storing 42 timevalues. The record has also a unique integer number (autoinc).
Record can be added and deleted from this table.
I need to have very quick access to the autoinc-number and the 42 timevalues of all records in the table.
I was thinking about an array of some kind, but I don't know how to add (and later access) the autoinc-number as well as the timevalues.
But when I set it up as I tried below, I get an error, because the autoinc-number will exceed the maximum number allowed for the array (as soon as the autoinc-number is missing one number - 1-2-3-(4 deleted)-5-6-7 in line.
var Werktijden : Array of Array of TTime; // Gebruikt voor de agenda
SetLength(Werktijden,DM.TM
DM.TMedewerkers.First;
For i := 0 to DM.TMedewerkers.RecordCoun
begin
Werktijden[DM.TMedewerkers
// etc. for each timevalue
DM.TMedewerkers.Next;
end;
So I need to be able to quickly get all timevalues of a certain autoinc-number.
Can anybody give me a sample on how to set it up correctly.
Regards,
Stef
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
let's say you want to access record number 4:
var
p: PTimeRecord;
begin
p := PTimeRecord(List.Items[4]) ;
ShowMessage('Second Time is ' + TimeToStr(p^[2]));
end;
var
p: PTimeRecord;
begin
p := PTimeRecord(List.Items[4])
ShowMessage('Second Time is ' + TimeToStr(p^[2]));
end;
ASKER
? for j := 0 to 41 do
p^[j] := DM.TMedewerkers.Fields[j]. AsDateTime - StrToTime('00:00:01'); // populate each record
How is controled which fields are added to the list?
Table TMedewerkers has a lot more fields (and also datatime-fields like date_of_birth).
So how is j=1 related to f.e. DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
p^[j] := DM.TMedewerkers.Fields[j].
How is controled which fields are added to the list?
Table TMedewerkers has a lot more fields (and also datatime-fields like date_of_birth).
So how is j=1 related to f.e. DM.TMedewerkers.FieldByNam
Erm.. I was just thinking if your fields in the DB are numbered from 0 to 41, then you don't have to write a statement to get the value for each record...
If you want to, you can still use your normal way of doing
p^[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
p^[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1C').AsDa teTime - strToTime('00:00:01');
DragonSlayer.
If you want to, you can still use your normal way of doing
p^[0] := DM.TMedewerkers.FieldByNam
p^[1] := DM.TMedewerkers.FieldByNam
DragonSlayer.
ASKER
Thank you for your help!
Stef
Stef
Glad it helps!
ASKER
Well...
After implementing it, I don't seem te have access to the timetable afterall.
This is what I did do:
// Executed in Afterpost-Event and in OnOpen of TMedewerkers
procedure TDM.AgendaWerktijdenInVari ablenPlaat sen;
var i : Integer;
begin
TijdelijkeInteger := DM.TMedewerkers.FieldByNam e('Persoon snr').AsIn teger;
DM.TMedewerkers.First;
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite ms[i]);
Dispose(MedewerkersRecord) ;
end;
Did I miss something or implemeted it incorrectly?
Regards,
Stef
for i := 0 to DM.TMedewerkers.RecordCoun t -1 do
try
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[2] := DM.TMedewerkers.FieldByNam e('AgendaZ o2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[3] := DM.TMedewerkers.FieldByNam e('AgendaZ o2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[4] := DM.TMedewerkers.FieldByNam e('AgendaZ o3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[5] := DM.TMedewerkers.FieldByNam e('AgendaZ o3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[6] := DM.TMedewerkers.FieldByNam e('AgendaM a1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[7] := DM.TMedewerkers.FieldByNam e('AgendaM a1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[8] := DM.TMedewerkers.FieldByNam e('AgendaM a2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[9] := DM.TMedewerkers.FieldByNam e('AgendaM a2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[10] := DM.TMedewerkers.FieldByNam e('AgendaM a3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[11] := DM.TMedewerkers.FieldByNam e('AgendaM a3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[12] := DM.TMedewerkers.FieldByNam e('AgendaD I1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[13] := DM.TMedewerkers.FieldByNam e('AgendaD I1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[14] := DM.TMedewerkers.FieldByNam e('AgendaD I2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[15] := DM.TMedewerkers.FieldByNam e('AgendaD I2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[16] := DM.TMedewerkers.FieldByNam e('AgendaD I3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[17] := DM.TMedewerkers.FieldByNam e('AgendaD I3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[18] := DM.TMedewerkers.FieldByNam e('AgendaW O1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[19] := DM.TMedewerkers.FieldByNam e('AgendaW O1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[20] := DM.TMedewerkers.FieldByNam e('AgendaW O2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[21] := DM.TMedewerkers.FieldByNam e('AgendaW O2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[22] := DM.TMedewerkers.FieldByNam e('AgendaW O3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[23] := DM.TMedewerkers.FieldByNam e('AgendaW O3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[24] := DM.TMedewerkers.FieldByNam e('AgendaD O1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[25] := DM.TMedewerkers.FieldByNam e('AgendaD O1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[26] := DM.TMedewerkers.FieldByNam e('AgendaD O2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[27] := DM.TMedewerkers.FieldByNam e('AgendaD O2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[28] := DM.TMedewerkers.FieldByNam e('AgendaD O3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[29] := DM.TMedewerkers.FieldByNam e('AgendaD O3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[30] := DM.TMedewerkers.FieldByNam e('AgendaV r1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[31] := DM.TMedewerkers.FieldByNam e('AgendaV r1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[32] := DM.TMedewerkers.FieldByNam e('AgendaV r2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[33] := DM.TMedewerkers.FieldByNam e('AgendaV r2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[34] := DM.TMedewerkers.FieldByNam e('AgendaV r3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[35] := DM.TMedewerkers.FieldByNam e('AgendaV r3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[36] := DM.TMedewerkers.FieldByNam e('AgendaZ a1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[37] := DM.TMedewerkers.FieldByNam e('AgendaZ a1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[38] := DM.TMedewerkers.FieldByNam e('AgendaZ a2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[39] := DM.TMedewerkers.FieldByNam e('AgendaZ a2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[40] := DM.TMedewerkers.FieldByNam e('AgendaZ a3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[41] := DM.TMedewerkers.FieldByNam e('AgendaZ a3E').AsDa teTime - strToTime('00:00:01');
Werktijden.Add(Medewerkers Record);
DM.TMedewerkers.Next;
except
end;
DM.TMedewerkers.Locate('Pe rsoonsnr', TijdelijkeInteger,[]);
end;
In the top of the unit of MainForm:
type
TTimeRecord = array [0 .. 41] of TTime;
PTimeRecord = ^TTimeRecord;
type
TMainForm = class(TForm)
In OnCreat-event of MainForm:
Werktijden := TList.Create;
In OnClose-event of MainForm:
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite ms[i]);
Dispose(MedewerkersRecord) ;
end;
Werktijden.Free;
// Testing if it works .... It doesn't till now.
procedure TFHoofdscherm.Button1Click (Sender: TObject);
begin
// Should give me the value of DM.TMedewerkers.FieldByNam e('AgendaM a1B').AsDa teTime of the first record.
MedewerkersRecord := PTimeRecord(Werktijden.Ite ms[0]);
ShowMessage('Begintijd op maandag: ' + TimeToStr(MedewerkersRecor d^[6]));
end;
After implementing it, I don't seem te have access to the timetable afterall.
This is what I did do:
// Executed in Afterpost-Event and in OnOpen of TMedewerkers
procedure TDM.AgendaWerktijdenInVari
var i : Integer;
begin
TijdelijkeInteger := DM.TMedewerkers.FieldByNam
DM.TMedewerkers.First;
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite
Dispose(MedewerkersRecord)
end;
Did I miss something or implemeted it incorrectly?
Regards,
Stef
for i := 0 to DM.TMedewerkers.RecordCoun
try
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[2] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[3] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[4] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[5] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[6] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[7] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[8] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[9] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[10] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[11] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[12] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[13] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[14] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[15] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[16] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[17] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[18] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[19] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[20] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[21] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[22] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[23] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[24] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[25] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[26] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[27] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[28] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[29] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[30] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[31] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[32] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[33] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[34] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[35] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[36] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[37] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[38] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[39] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[40] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[41] := DM.TMedewerkers.FieldByNam
Werktijden.Add(Medewerkers
DM.TMedewerkers.Next;
except
end;
DM.TMedewerkers.Locate('Pe
end;
In the top of the unit of MainForm:
type
TTimeRecord = array [0 .. 41] of TTime;
PTimeRecord = ^TTimeRecord;
type
TMainForm = class(TForm)
In OnCreat-event of MainForm:
Werktijden := TList.Create;
In OnClose-event of MainForm:
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite
Dispose(MedewerkersRecord)
end;
Werktijden.Free;
// Testing if it works .... It doesn't till now.
procedure TFHoofdscherm.Button1Click
begin
// Should give me the value of DM.TMedewerkers.FieldByNam
MedewerkersRecord := PTimeRecord(Werktijden.Ite
ShowMessage('Begintijd op maandag: ' + TimeToStr(MedewerkersRecor
end;
So instead, what does it show?
ASKER
Always 00:00:01
I don't understand... what is this code for?
procedure TDM.AgendaWerktijdenInVari ablenPlaat sen;
var i : Integer;
begin
TijdelijkeInteger := DM.TMedewerkers.FieldByNam e('Persoon snr').AsIn teger;
DM.TMedewerkers.First;
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite ms[i]);
Dispose(MedewerkersRecord) ;
end;
procedure TDM.AgendaWerktijdenInVari
var i : Integer;
begin
TijdelijkeInteger := DM.TMedewerkers.FieldByNam
DM.TMedewerkers.First;
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite
Dispose(MedewerkersRecord)
end;
ASKER
That is what I do after TMedewerkers is changed.
========================== =======
TijdelijkeInteger := DM.TMedewerkers.FieldByNam e('Persoon snr').AsIn teger;
========================== =======
Will get the current record (Persoonsnr) to locate it after all records are added to the list.
========================== =======
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite ms[i]);
Dispose(MedewerkersRecord) ;
end;
========================== =======
Clears the whole list.
Below is part of the same procedure: TDM.AgendaWerktijdenInVari ablenPlaat sen;
for i := 0 to DM.TMedewerkers.RecordCoun t -1 do
try
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1E').AsDa teTime - strToTime('00:00:01');
etc...
Regards,
Stef
==========================
TijdelijkeInteger := DM.TMedewerkers.FieldByNam
==========================
Will get the current record (Persoonsnr) to locate it after all records are added to the list.
==========================
for i := Werktijden.Count - 1 downto 0 do
begin
MedewerkersRecord := PTimeRecord(Werktijden.Ite
Dispose(MedewerkersRecord)
end;
==========================
Clears the whole list.
Below is part of the same procedure: TDM.AgendaWerktijdenInVari
for i := 0 to DM.TMedewerkers.RecordCoun
try
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam
etc...
Regards,
Stef
after the for loop to dispose, you should also do a
Werktijden.Clear;
Werktijden.Clear;
ASKER
Till here it is working now, however it takes quite some time to save all records into the list.
Is it possible that after an insert/update of a record, only the current record is changed/added to the list?
Is it possible that after an insert/update of a record, only the current record is changed/added to the list?
yea, why not?
if there is an INSERT, you can do
DM.TMedewerkers.Last;
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1E').AsDa teTime - strToTime('00:00:01');
etc
for an update, if you know the record number, say if it is record number 3:
MedewerkersRecord := PTimeRecord(List[2]);
MedewerkersRecord^[0] := // the new updated time, etc etc
if there is an INSERT, you can do
DM.TMedewerkers.Last;
New(MedewerkersRecord);
MedewerkersRecord^[0] := DM.TMedewerkers.FieldByNam
MedewerkersRecord^[1] := DM.TMedewerkers.FieldByNam
etc
for an update, if you know the record number, say if it is record number 3:
MedewerkersRecord := PTimeRecord(List[2]);
MedewerkersRecord^[0] := // the new updated time, etc etc
ASKER
So when I go back to my very first question.
** I need to have very quick access to the autoinc-number and the 42 timevalues of all records in the table.
As the autoInc-number isn't stored I still need to look for it in the table, before I can access it's details.
That was exactly what I was trying to avoid.
** I need to have very quick access to the autoinc-number and the 42 timevalues of all records in the table.
As the autoInc-number isn't stored I still need to look for it in the table, before I can access it's details.
That was exactly what I was trying to avoid.
What database are you using? Seems strange but why don't you get the auto inc number as well?
ASKER
I'm using an MS Access database, but as you know the recordnumber isn't the same as the autoInc-number.
ASKER
How can I get the autoinc-number directly from the List?
Questions:
1. In which instance(s) do you need to use the AutoInc number?
2. If you want to add AutoInc to your List, why not make it a record instead?
type
TMyRecord = record
AutoInc: Integer;
Times: array [0 .. 41] of TTime;
end;
PMyRecord = ^TMyRecord;
and carry on from there?
1. In which instance(s) do you need to use the AutoInc number?
2. If you want to add AutoInc to your List, why not make it a record instead?
type
TMyRecord = record
AutoInc: Integer;
Times: array [0 .. 41] of TTime;
end;
PMyRecord = ^TMyRecord;
and carry on from there?
ASKER
Could you please give some more information?
How do I add both to the list and how do I access both afterwords?
How do I add both to the list and how do I access both afterwords?
ASKER
I load the worktimes to use them in a scheduler.
The worktimes are shown in the scheduler in a different backgroundcolor.
But when I need to load them from a table, it takes too long, so I want them to be accessable from memory.
The autoinc-field is related to the resource in the scheduler. So each employee has it's own workinghours.
The worktimes are shown in the scheduler in a different backgroundcolor.
But when I need to load them from a table, it takes too long, so I want them to be accessable from memory.
The autoinc-field is related to the resource in the scheduler. So each employee has it's own workinghours.
Well, now here are some considerations:
1. Would you mind looping through memory to find the auto-inc number? If you don't mind, you can do this
var
MyRecord: PMyRecord;
begin
for i := 0 to DM.TMedewerkers.RecordCoun t -1 do
try
New(MyRecord);
MyRecord^.AutoInc := DM.TMedewerkers.FieldByNam e('AutoInc ').AsInteg er;
MyRecord^.Times[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
MyRecord^.Times[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1E').AsDa teTime - strToTime('00:00:01');
MyRecord^.Times[2] := DM.TMedewerkers.FieldByNam e('AgendaZ o2B').AsDa teTime - strToTime('00:00:01');
...
and when you need to find that particular record, you can do a
function FindAutoInc(AutoIncNumber: Integer): Integer;
var
i: Integer;
begin
Result := -1;
for i := 0 to List.Count - 1 do
if PMyRecord(List[i])^.AutoIn c = AutoIncNumber then
begin
Result := i;
break;
end;
end;
so, to locate the record for number, say 4827,
var
MyRecord: PMyRecord;
begin
i := FindAutoInc(4827);
if i < 0 then
raise Exception.Create('No matching records!');
MyRecord := PMyRecord(List[i]);
ShowMessage('The 1st time is ' + TimeToStr(MyRecord^.Times[ 0]));
...
2. Instead of using AutoInc, it is also a good idea to populate the database with your own unique number, in this case a GUID. That way, you have full control over what is the next auto-inc number you will be putting in.
1. Would you mind looping through memory to find the auto-inc number? If you don't mind, you can do this
var
MyRecord: PMyRecord;
begin
for i := 0 to DM.TMedewerkers.RecordCoun
try
New(MyRecord);
MyRecord^.AutoInc := DM.TMedewerkers.FieldByNam
MyRecord^.Times[0] := DM.TMedewerkers.FieldByNam
MyRecord^.Times[1] := DM.TMedewerkers.FieldByNam
MyRecord^.Times[2] := DM.TMedewerkers.FieldByNam
...
and when you need to find that particular record, you can do a
function FindAutoInc(AutoIncNumber:
var
i: Integer;
begin
Result := -1;
for i := 0 to List.Count - 1 do
if PMyRecord(List[i])^.AutoIn
begin
Result := i;
break;
end;
end;
so, to locate the record for number, say 4827,
var
MyRecord: PMyRecord;
begin
i := FindAutoInc(4827);
if i < 0 then
raise Exception.Create('No matching records!');
MyRecord := PMyRecord(List[i]);
ShowMessage('The 1st time is ' + TimeToStr(MyRecord^.Times[
...
2. Instead of using AutoInc, it is also a good idea to populate the database with your own unique number, in this case a GUID. That way, you have full control over what is the next auto-inc number you will be putting in.
ASKER
When going for the GUID. There still will be the issue when deleting a record.
Suppose I have GUID 1,2,3 and 4 and GUID is deleted.
I can't reassign GUID's to to all records, as than the reference to the scheduler would be lost.
So then I have the sam problem that I had when using and array to store the times.
When loading the scheduler, the worktimes from each employee will be loaded. All individual appointments (events) in the scheduler are assigned to one employee. This is currently done through the autoinc-number.
Loading the worktimes can easily be done by using this unique employee-number. But changing the GUID, would result in having to change all event assigned to that employee also.
So I guess the find-option is best? Or do you have any other ideas? Did I miss something?
Suppose I have GUID 1,2,3 and 4 and GUID is deleted.
I can't reassign GUID's to to all records, as than the reference to the scheduler would be lost.
So then I have the sam problem that I had when using and array to store the times.
When loading the scheduler, the worktimes from each employee will be loaded. All individual appointments (events) in the scheduler are assigned to one employee. This is currently done through the autoinc-number.
Loading the worktimes can easily be done by using this unique employee-number. But changing the GUID, would result in having to change all event assigned to that employee also.
So I guess the find-option is best? Or do you have any other ideas? Did I miss something?
GUIDs are unique, so you won't need to reassign them.
ASKER
Ok. I will do some testing tomorrow.
Thanks again and goodnight.
Thanks again and goodnight.
ASKER
Hi DragonSlayer.
I've tried to get it to work but ... it didn't happen yet.
The code below gives me a hard time. The LIST-part in function VindMedewerker isn't known? And I don't know if the adding/changing of a record is implemented correctly.
Also I need to cleanup the record(s) from memory after closing the application. How do I do that?
*** unit main ***
type
TMedewerkersRecord = record
NrPersoon : Integer;
Werktijden : Array [0 .. 41] of TTime;
end;
PMedewerkersRecord = ^TMedewerkersRecord;
var
MedewerkersRecord : PMedewerkersRecord;
*** unit Datamodule ***
procedure TDM.AgendaWerktijdenInVari ablenPlaat sen(LoadAl lRecords : Boolean);
// Executed after OnAfterPost-event of the table TMedewerkers -> LoadAllRecords=False.
// Executed after OnAfterOpen-event of the table TMedewerkers -> LoadAllRecords=True.
var i, j : Integer;
procedure LaadMedewerkerInGeheugen;
begin
MedewerkersRecord^.NrPerso on := DM.TMedewerkers.FieldByNam e('Persoon snr').AsIn teger;
MedewerkersRecord^.Werktij den[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[1] := DM.TMedewerkers.FieldByNam e('AgendaZ o1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[2] := DM.TMedewerkers.FieldByNam e('AgendaZ o2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[3] := DM.TMedewerkers.FieldByNam e('AgendaZ o2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[4] := DM.TMedewerkers.FieldByNam e('AgendaZ o3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[5] := DM.TMedewerkers.FieldByNam e('AgendaZ o3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[6] := DM.TMedewerkers.FieldByNam e('AgendaM a1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[7] := DM.TMedewerkers.FieldByNam e('AgendaM a1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[8] := DM.TMedewerkers.FieldByNam e('AgendaM a2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[9] := DM.TMedewerkers.FieldByNam e('AgendaM a2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[10] := DM.TMedewerkers.FieldByNam e('AgendaM a3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[11] := DM.TMedewerkers.FieldByNam e('AgendaM a3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[12] := DM.TMedewerkers.FieldByNam e('AgendaD I1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[13] := DM.TMedewerkers.FieldByNam e('AgendaD I1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[14] := DM.TMedewerkers.FieldByNam e('AgendaD I2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[15] := DM.TMedewerkers.FieldByNam e('AgendaD I2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[16] := DM.TMedewerkers.FieldByNam e('AgendaD I3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[17] := DM.TMedewerkers.FieldByNam e('AgendaD I3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[18] := DM.TMedewerkers.FieldByNam e('AgendaW O1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[19] := DM.TMedewerkers.FieldByNam e('AgendaW O1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[20] := DM.TMedewerkers.FieldByNam e('AgendaW O2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[21] := DM.TMedewerkers.FieldByNam e('AgendaW O2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[22] := DM.TMedewerkers.FieldByNam e('AgendaW O3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[23] := DM.TMedewerkers.FieldByNam e('AgendaW O3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[24] := DM.TMedewerkers.FieldByNam e('AgendaD O1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[25] := DM.TMedewerkers.FieldByNam e('AgendaD O1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[26] := DM.TMedewerkers.FieldByNam e('AgendaD O2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[27] := DM.TMedewerkers.FieldByNam e('AgendaD O2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[28] := DM.TMedewerkers.FieldByNam e('AgendaD O3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[29] := DM.TMedewerkers.FieldByNam e('AgendaD O3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[30] := DM.TMedewerkers.FieldByNam e('AgendaV r1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[31] := DM.TMedewerkers.FieldByNam e('AgendaV r1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[32] := DM.TMedewerkers.FieldByNam e('AgendaV r2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[33] := DM.TMedewerkers.FieldByNam e('AgendaV r2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[34] := DM.TMedewerkers.FieldByNam e('AgendaV r3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[35] := DM.TMedewerkers.FieldByNam e('AgendaV r3E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[36] := DM.TMedewerkers.FieldByNam e('AgendaZ a1B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[37] := DM.TMedewerkers.FieldByNam e('AgendaZ a1E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[38] := DM.TMedewerkers.FieldByNam e('AgendaZ a2B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[39] := DM.TMedewerkers.FieldByNam e('AgendaZ a2E').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[40] := DM.TMedewerkers.FieldByNam e('AgendaZ a3B').AsDa teTime - strToTime('00:00:01');
MedewerkersRecord^.Werktij den[41] := DM.TMedewerkers.FieldByNam e('AgendaZ a3E').AsDa teTime - strToTime('00:00:01');
end;
function VindMedewerker(PersoonsNum mer : Integer): Integer;
var i: Integer;
begin
Result := -1;
for i := 0 to List.Count - 1 do
if PMedewerkersRecord(List[i] )^.NrPerso on = PersoonsNummer then
begin
Result := i;
Break;
end;
end;
begin
Try
If LoadAllRecords then
begin
DM.TMedewerkers.First;
for i := 0 to DM.TMedewerkers.RecordCoun t - 1 do
begin
LaadMedewerkerInGeheugen;
DM.TMedewerkers.Next
end;
end else
begin
j := VindMedewerker(DM.TMedewer kers.Field ByName('Pe rsoonsnr') .AsInteger );
if j < 0 then
New(MedewerkersRecord) // Add new reccord
else
MedewerkersRecord := PMedewerkersRecord(List[j] ); // Update existing record
LaadMedewerkerInGeheugen;
end;
except
end;
end;
Regards,
Stef
I've tried to get it to work but ... it didn't happen yet.
The code below gives me a hard time. The LIST-part in function VindMedewerker isn't known? And I don't know if the adding/changing of a record is implemented correctly.
Also I need to cleanup the record(s) from memory after closing the application. How do I do that?
*** unit main ***
type
TMedewerkersRecord = record
NrPersoon : Integer;
Werktijden : Array [0 .. 41] of TTime;
end;
PMedewerkersRecord = ^TMedewerkersRecord;
var
MedewerkersRecord : PMedewerkersRecord;
*** unit Datamodule ***
procedure TDM.AgendaWerktijdenInVari
// Executed after OnAfterPost-event of the table TMedewerkers -> LoadAllRecords=False.
// Executed after OnAfterOpen-event of the table TMedewerkers -> LoadAllRecords=True.
var i, j : Integer;
procedure LaadMedewerkerInGeheugen;
begin
MedewerkersRecord^.NrPerso
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
MedewerkersRecord^.Werktij
end;
function VindMedewerker(PersoonsNum
var i: Integer;
begin
Result := -1;
for i := 0 to List.Count - 1 do
if PMedewerkersRecord(List[i]
begin
Result := i;
Break;
end;
end;
begin
Try
If LoadAllRecords then
begin
DM.TMedewerkers.First;
for i := 0 to DM.TMedewerkers.RecordCoun
begin
LaadMedewerkerInGeheugen;
DM.TMedewerkers.Next
end;
end else
begin
j := VindMedewerker(DM.TMedewer
if j < 0 then
New(MedewerkersRecord) // Add new reccord
else
MedewerkersRecord := PMedewerkersRecord(List[j]
LaadMedewerkerInGeheugen;
end;
except
end;
end;
Regards,
Stef
erm... List in this case, is your TList.
Let's say you want to add a new record to your database *and* your TList:
1. Scenario 1, using AutoInc
Because we do not know the value of the AutoInc, you would need to post it in the table first, then seek to the last record and populate your TList, e.g.
TMedewerkers.Insert;
TMedewerkers.FieldByName(' AgendaZo1B ').AsDateT ime := DateTimePicker1.Time;
// ... etc etc
TMedewerkers.Post;
TMedewerkers.Last;
New(MedewerkersRecord);
with MedewerkersRecord^ do
begin
NrPersoon := TMedewerkers.FieldByName(' Persoonsnr ').AsInteg er;
Werktijden[0] := DM.TMedewerkers.FieldByNam e('AgendaZ o1B').AsDa teTime - strToTime('00:00:01');
// ... etc etc
end;
List.Add(MedewerkersRecord );
2. Scenario 2, using GUID
uses
ComObj, ActiveX;
function CreateGuid: string;
var
ID: TGUID;
begin
Result := '';
if CoCreateGuid(ID) = S_OK then
Result := GUIDToString(ID);
end;
myGUID := CreateGuid;
// in this case, the unique ID is string, not integer
TMedewerkers.Insert;
TMedewerkers.FieldByName(' Persoonsnr ').AsStrin g := myGUID;
TMedewerkers.FieldByName(' AgendaZo1B ').AsDateT ime := DateTimePicker1.Time;
TMedewerkers.Post;
// no need to call Last, or to refresh the table
New(MedewerkersRecord);
with MedewerkersRecord^ do
begin
NrPersoon := myGUID;
Werktijden[0] := DateTimePicker1.Time;
// ... etc etc
end;
List.Add(MedewerkersRecord );
Let's say you want to add a new record to your database *and* your TList:
1. Scenario 1, using AutoInc
Because we do not know the value of the AutoInc, you would need to post it in the table first, then seek to the last record and populate your TList, e.g.
TMedewerkers.Insert;
TMedewerkers.FieldByName('
// ... etc etc
TMedewerkers.Post;
TMedewerkers.Last;
New(MedewerkersRecord);
with MedewerkersRecord^ do
begin
NrPersoon := TMedewerkers.FieldByName('
Werktijden[0] := DM.TMedewerkers.FieldByNam
// ... etc etc
end;
List.Add(MedewerkersRecord
2. Scenario 2, using GUID
uses
ComObj, ActiveX;
function CreateGuid: string;
var
ID: TGUID;
begin
Result := '';
if CoCreateGuid(ID) = S_OK then
Result := GUIDToString(ID);
end;
myGUID := CreateGuid;
// in this case, the unique ID is string, not integer
TMedewerkers.Insert;
TMedewerkers.FieldByName('
TMedewerkers.FieldByName('
TMedewerkers.Post;
// no need to call Last, or to refresh the table
New(MedewerkersRecord);
with MedewerkersRecord^ do
begin
NrPersoon := myGUID;
Werktijden[0] := DateTimePicker1.Time;
// ... etc etc
end;
List.Add(MedewerkersRecord
To update:
var
RecordNumber: Integer;
// ...
RecordNumber := VindMedewerker(SomeNumber) ;
if RecordNumber < 0 then
begin
// update!
MedewerkersRecord := List[RecordNumber];
with MedewerkersRecord^ do
begin
// perform your update
end;
end;
var
RecordNumber: Integer;
// ...
RecordNumber := VindMedewerker(SomeNumber)
if RecordNumber < 0 then
begin
// update!
MedewerkersRecord := List[RecordNumber];
with MedewerkersRecord^ do
begin
// perform your update
end;
end;
to cleanup, as mentioned earlier:
for i := List.Count - 1 downto 0 do
begin
p := PTimeRecord(List.Items[i]) ;
Dispose(p);
end;
List.Free;
for i := List.Count - 1 downto 0 do
begin
p := PTimeRecord(List.Items[i])
Dispose(p);
end;
List.Free;
ASKER
It seems I got to do some more testing tomorrow. Thank you for now...
ASKER
Hello DragonSlayer,
I've got it to work. Thank you very much for your help.
Regards,
Stef
I've got it to work. Thank you very much for your help.
Regards,
Stef
No probs. Really am happy that it works for you Stef!
ASKER
How do I access the timevalues of a certain record (=autoinc)?