-
TTable.Locate
Hallo, ik ervaar een vreemd gedrag met een Locate method op een TTable component. Gegeven de volgende functie:
Code:
function TDMHlpStoffen.StofExists: Integer;
begin
with Self.TblGenStfn do
if Locate('soort;naam', VarArrayOf([FSoort,Self.CDAndereGenStfn.FieldByName('naam').AsVariant]), []) then
Result := FieldByName('nummer').AsInteger
else if Locate('naam', Self.CDAndereGenStfn.FieldByName('naam').AsVariant, []) then
Result := FieldByName('nummer').AsInteger
else
Result := 0;
end;
Daarmee wil ik in de TTable het voorkomen zoeken van een equivalent met een record uit een ClientDataSet. Eerst moet gezocht worden op een exacte overeernkomst in 'soort' en 'naam', als die niet gevonden wordt moet alleen de naam gezocht worden. De equivalente naam wordt gevonden in het tweede if-statement en volgens mij moet Locate dat record dan het actieve record maken. Toch wordt in de vette regel (de tweede toekenning aan Result) het fysiek daarop volgende record uit de tabel geselecteerd. Wat mis ik hier?
De TTable bevat geen expliciete indexen, daarom lijkt het gebruik van Locate hier het éénvoudigst. Ik gebruik Delphi 6 en daarmee heb ik wel ervaren dat Locate op een ClientDataSet i.v.m. een bug onbruikbaar is.
Bedankt voor een reactie,
Hans
-
hij heeft hem wel geselecteerd...
Je loopt alleen behoorlijk hard in een with-val. Je haalt namelijk de regel op uit TblGentfn en je locate in CDSAndereGenStfn....
Die regels lopendus niet gelijk met elkaar
-
De with instinker, die ik gisteren ook had
-
Hallo, bedankt voor jullie reacties en ik heb aan de hand daarvan gemeend de functie te moeten veranderen in:
Code:
function TDMStoffen.NaamExists: Integer;
begin
if Self.TblEneStfn.Locate('soort;naam', VarArrayOf([FSoort,Self.CDAndereStfn.FieldByName('naam').AsVariant]), []) then
Result := Self.TblEneStfn.FieldByName('nummer').AsInteger
else if Self.TblEneStfn.Locate('naam', Self.CDAndereStfn.FieldByName('naam').AsVariant, []) then
Result := Self.TblEneStfn.FieldByName('nummer').AsInteger
else
Result := 0;
end;
Alleen krijg ik nog steeds dezelfde reactie! De functie retourneert bij de tweede if het volgende record in de database tabel op het record dat matcht met de gezochte naam. Doe ik hierbij nog iets anders verkeerd? De functie werd ook binnen een with statementblock aangeroepen, heb ik ook aangepast.
BTW. Ik reageer een beetje laat. Ik ben de halve dag bezig geweest met ergeren aan en zoeken naar de oorzaak van het feit dat mijn Delphi 6 sinds enkele weken bloody irritating lang over compilatie van het project waar mijn collega en ik aan werken doet. Ook de actie die Delphi uitvoert (opmaken RTTI soms?) bij de eerste edit na runnen heeft minstens de belachelijke 2 minuten nodig tegenwoordig...
Hans
-
Het lijkt mij dat het niet aan deze code kan liggen. Je zegt dat Locate op een ClientDataSet buggy is, maar dit is in een TTable toch?
Heeft je Table misschien nog events die ervoor zorgen dat je Table een stapje verder gaat dan verwacht?
Als je deze code in een nieuw project simuleert, heb je dan hetzelfde effect?
Komt de naam die je zoekt maar één keer voor in de Table, of meerdere keren?
-
Deze reactie doet zich, blijkt nu, alleen voor bij mijn DB2 database Marcel. In de uiteindelijke Informix database (ik was diegene met die vraag onlangs over parameters/properties voor DB2 bij gebruik van TTable) krijg ik voor die ene specifieke stof wèl het juiste record terug. De stof komt in het table component maar één keer voor en er zijn geen events gedefinieerd. Misschien moet ik maar helemaal afzien van het gebruik van DB2...
Hans
-
Oei, dan wordt het inderdaad lastig zoeken. Dat zou dan aan de koppeling naar DB2 moeten liggen. Wat gebruik je daarvoor, de BDE?
-
Brrrrrrrrrr. Ik heb 'uitgevonden' dat een TTable.Refresh wonderen doet na Post in een loop... De reden dat de Informix database wel het goede record wist te vinden was dat er eerder in de loop geen nieuw record was toegevoegd in de tabel, zoals in mijn DB2 database wel het geval was. De locate kwam dus blijkbaar wel uit op het juiste tabelrecord, maar dat was door omissie van de Refresh niet gemapt met het juiste record in de dataset.
Heel erg bedankt voor jullie reacties en tot de volgende beginnersfout,
Hans