Implementering FoxPros Scatter og Samle Memvar i Delphi

Implementing FoxPro er Scatter og Samle Memvar i Delphi. Delphi Developer februar 2001
Copyright Pinnacle Publishing, Inc. Alle rettigheter reserved.Implementing FoxPro er Scatter og Samle Memvar i Delphi Steve Zimmelman
Teknologi er alltid fremover, vanligvis fører til mer produktiv utvikling. Men det er tider når du strekker deg inn i fortiden kan være nyttig, også. Replikere eller sammenligne tabelldata i FoxPro var en ganske enkel oppgave. Steve Zimmelman hevder at kanskje denne teknologien er verdt nå tilbake.
FoxPro er Scatter og samle kommandoer var alltid nyttig for kopiering poster fra en tabell til en annen, sammenligne data, eller ta opp replikering mellom flere tabeller. For de av dere som ikke har hatt gleden av å jobbe med FoxPro, Scatter og samle kommandoer fungerer som this.Suppose du trenger å kopiere en post fra en tabell til en annen. Du ville gjøre noe sånt: Velg Table1Scatter MemvarSelect Table2Gather Memvar
Scatter kommandoen leser alle feltene for currentrecord og plasserer dem inn i minnevariabler. Hver variabel that'screated med Scatter har samme navn som feltet som itoriginated. Den Samle kommandoen oppdaterer den nåværende rekorden med minnevariabler som har navn som tilsvarer feltene. Så hvis Table1 har feltene Navn, adresse og telefonnummer, og variablene navn, adresse og telefonnummer eksisterer, så når Samle kommandoen utføres den oppdaterer posten med verdien som er lagret i de variables.There er mange måter å oppnå dette med Delphi, men det er ingenting opprinnelig leveres i VCL som jobber på TDataSet nivå. I min siste søknad bestrebelse, hadde jeg et behov for den gamle Scatter og samle funksjonalitet. Så jeg endte opp med å skrive min egen ScatterMemvar og GatherMemvar metoder. Opprette Scatter og samle funksjoner
Begge disse metodene er pakkemaskiner til et objekt kalt TMemvar. TMemvar opprettholder et dynamisk utvalg av en rekord som heter TMemVarFields. Hvert element i MemVarFields matrisen inneholder feltnavn, datatype, og verdien av en tilsvarende felt i et datasett. Så hver forekomst av TMemvar inneholder dataene fra en enkelt tabell posten Type MemVarField = Pakket Record feltnavn: String;. Verdi: Variant; Datatype: TFieldType; Slutt; TMemVarFields = Array Of TMemVarField;
Når ScatterMemvar funksjonen aktiveres, skaper det en forekomst av TMemvar og returnerer en peker til den forekomsten. Når TMemvar er opprettet, laster den feltene fra den utpekte datasett inn i matrisen. For å unngå DataSet duplisering, blir hver forekomst av TMemvar identifisert av sin DataSet eiendom. Før en ny forekomst av TMemvar er opprettet, er et søk utført for en matchende datasett i alle eksisterende forekomster av TMemvar. Hvis man blir funnet, den matchende eksempel gjenbrukt. Hvis ikke, er et nytt eksempel opprettet Funksjon ScatterMemvar (datasett: TDataSet):. TMemVar, begynner Hvis (datasett = Null) Deretter Raise Exception.Create ('datasett kan ikke være NIL'); //Gjenbruk objektet hvis det allerede eksisterer. Resultat: = FindMemvarObject (datasett); If (Resultat = Null) da begynne Resultat: = TMemvar.Create (datasett); Avslutt Else Begynn Result.LoadFieldData; Slutt; Enden, Constructor TMemVar.Create (datasett: TDataSet); Begynn FFlds: = Nil; FDataSet: = datasett; If (FDataSet = Null) Deretter Begynn Raise Exception.Create ('datasett kan ikke være NIL'); Slutt; If (FScatterList = Null) Deretter FScatterList: = TList.Create; FScatterList.Add (Selv); LoadFieldData, End, Prosedyre TMemVar.LoadFieldData; Var jeg: Integer; begynner Hvis ikke DataSet.Active Så DataSet.Open; FFlds: = Nil; //Angi lengden på posten array. SetLength (FFlds, FieldCount); For i: = 0 til (DataSet.FieldCount-1) Må begynne med DataSet.Fields [I] Har Begynn FFlds [i] .FieldName: = feltnavn; FFlds [i] .Value: = verdi; FFlds [i] .DataType: = datatype; Slutt; Enden, enden,
Normalt når du oppretter et objekt, er det nødvendig å frigjøre objektet når det ikke lenger er nødvendig. Men den enhet som inneholder koden for dette formål opprettholder sin egen interne liste over TMemvar forekomster og ødelegger dem automatisk når programmet lukkes. Så du kan frigjøre objektene når de ikke trengs, eller ignorere dem og la enheten ta vare på itself.To administrere TMemvar objekter som er opprettet for hvert ScatterMemvar bruk, jeg legge til hver ny forekomst av TMemvar til FScatterList, en type av tListe. Enheten som håndterer all denne koden inneholder initialisering og Avslutnings seksjoner. Den initialisering sørger FScatterList er satt til null. Dette er gjort slik at Lag metoden for TMemvar kan avhøre verdien av FScatterList og opprette en forekomst av det bare når det er nødvendig. Dette holder de ressursene som enheten trenger ned til et minimum. Den Finalizationsection spinner gjennom listen og frigjør noen TMemvar objekter den refererer til Prosedyre FreeScatterList; Var jeg.: Integer; begynner Hvis (FScatterList = Null) Then Exit; Prøv For jeg:. = (FScatterList.Count-1) downto 0 Har Begynn prøve TMemVar (FScatterList.Items [i]) Gratis; Unntatt End; Slutt; Endelig FScatterList.Free; FScatterList: = Nil; Enden, enden, initialisering FScatterList: = Nil; Finalization FreeScatterList;
å unngå potensielle tilgangs unntak, fjerner TMemvar seg fra FScatterList når det er frigjort. Du vil også legge merke til at dersom alle elementer har blitt slettet fra FScatterList, blir listen frigjort. Igjen, dette er gjort for å holde ressursbruken ned Destructor TMemVar.Destroy.; Var i: Integer; Begynn //Clear oppstillingselementene. FFlds: = Nil; For i: = 0 til (FScatterList.Count-1) Har Begynn Prøv Hvis (. TMemvar (FScatterList.Items [i]) datasett = FDataSet) Deretter Begynn FScatterList.Delete (i); Slutt; Unntatt End; Slutt; If (FScatterList.Count = 0), og start FScatterList.Free; FScatterList: = Nil; Slutt; Arvet, End,
Etter ScatterMemvar har blitt brukt til å plassere et datasett i minnet, det bestemte TMemvar objektet kan nås fra enhver enhet i søknaden. Fordi hver forekomst av TMemvar er lagret i FScatterList, kan det betraktes som en global objekt som kan nås av enhver enhet som har en referanse til Memvar enhet i sine bruksområder statement.The metode GatherMemvar brukes til å sette inn data i den samme tabellen fra hvilken den opprinnelig kom, eller, om nødvendig, en annen tabell. GatherMemvar spinner gjennom feltene lagret i TMemvar objektet og oppdaterer målet rekord med felt som samsvarer med feltnavn og datatype. Så feltene i TMemvar objektet ikke trenger å være en eksakt strukturell kamp til målet. Felt som ikke samsvarer med feltnavn og datatype blir ignorert. I tillegg kan TMemvar feltverdier endres før du bruker GatherMemvar, slik at du kan gjenskape litt forskjellige data bør behovet arise.GatherMemvar er implementert i to varianter, med overbelastning direktivet i metoden erklæring: Prosedyre GatherMemVar (Kilde: TMemVar; Target: TDataSet; Alternativer: TGatherOptions); Overbelastning; Prosedyre GatherMemVar (Kilde, Target: TDataSet; Alternativer: TGatherOptions); Load;
Den eneste forskjellen mellom disse to metodene er den første parameteren. Den første gjennomføringen bruker selve TMemvar objekt referanse. Den andre bruker datasettet som ble brukt til å opprette forekomst av TMemvar. Annet enn det, de er begge identiske. Faktisk, den første implementeringen ringer faktisk den andre. Det er også noen alternativer som lar deg kontrollere hvordan GatherMemvar metoden samler dataene. Du kan bytte eller legge data, utstede et innlegg, eller Free objektet når samle er fullført. Hvis nooptions er til stede i parameter, er standard Erstatt theTarget sin datasett posten og la den i redigerings tilstand etter at den endrer feltdata TGatherOption = (goReplace, goAppend, goPost, goFree);. TGatherOptions = Set Of TGatherOption; Prosedyre GatherMemVar (Kilde: TMemVar, Target: TDataSet; Alternativer: TGatherOptions), begynner Hvis (Kilde = Null) Deretter Raise Exception.Create ('Kilde TMemVar objekt kan ikke NIL'); GatherMemVar (Source.DataSet, Target, Alternativer), End, Prosedyre GatherMemVar (Kilde, Mål: TDataSet; alternativer: TGatherOptions); Var i: Integer; iIndex: Integer; MemObj: TMemvar; FR: TMemvarField; Begynn MemObj: = FindMemvarObject (Kilde); If (MemObj = Null) Deretter Begynn Raise Exception.Create ('Kilde datasett (' + Source.Name + ') har ikke vært Spredt!'); Slutt; Hvis (goAppend i opsjoner), og start Target.Append; Avslutt Else begynner Hvis ikke (Target.State I [dsEdit, dsInsert]) Så Target.Edit; Slutt; For i: = 0 til (Target.FieldCount-1) Har Begynn iIndex: = MemObj.FindFieldIndex (Target.Fields [i] .FieldName); Hvis iIndex > = 0 Så begynner Hvis (Target.Fields [i] .DataType = MemObj.Fields [iIndex] .DataType) Så Target.Fields [i] .Value: = MemObj.Fields [iIndex] .Value; Slutt; Slutt; Hvis (goPost I Valg) Så Target.Post; Hvis (goFree I Valg) Så MemObj.Free; End;
Å sette de nye funksjonene for å bruke
Her er et par eksempler på hvordan disse metodene kan være used.Procedure MyExample1 kopier feltdata fra Table1 og føyer til et rekord å Table2 med data fra Tabell1. Alternativene parameter goPost og goFree instruere metoden for å utstede en melding til Table2, deretter frigjøre TMemvar objekt Prosedyre MyExample1.; Var MemObj: TMemvar; Begynn MemObj: = ScatterMemvar (Tabell 1); //≪ gjøre noen tabell ting > //Tilføy en post til Table2, Post it, //deretter frigjøre TMemvar objektet. GatherMemvar (MemObj, Table2, [goAppend, goPost, goFree]), End,
Prosedyre MyExample2 kopier feltdata fra Table1, føyer en rekord til Table2 med data fra Table1, modifiserer deretter navnefeltet før tilføye en post til Table3 . I begge GatherMemvar tilfeller blir posten lagt ut. Den siste frigjør også TMemvar objekt Prosedyre MyExample2.; Var MemObj: TMemvarBegin MemObj: = ScatterMemvar (Tabell 1); //≪ gjøre noen tabell ting > //Tilføy en post til Table2 & Table3, Post it, //deretter frigjøre TMemvar objektet. GatherMemvar (Table1, Table2, [goAppend, goPost]); //Endre en memvar feltverdi før føye //rekord å Table3. MemObj.FieldValue ['navn']: = 'Steve Zimmelman'; GatherMemvar (Table1, Table3, [goAppend, goPost, goFree]); End;