15. december 2008 - 10:47Der er
28 kommentarer og 2 løsninger
Gemme en record type linie for linie
Jeg har en variabel der er en record type Hvordan gemmer jeg nemmest den i en fil linie for linie. Altså så hver enkelt item står på en linie for sig i filen. Kan man gøre det så universielt at hvis jeg tilføjer et item i recorden så kommer den automatisk med ud i filen.
Det kan godt være det er et begynderspørgsmål men.....
Et tillægsspørgsmål: hvor er det mest korrekt at initialisere sine variable.
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
For at tage det sidste først, så er Delphi programmeret sådan at alle variable er initialiserede (modsat især C++). Du burde altså ikke behøve initialisere dem - men Delphi vil nu alligevel godt have det.
Det afhænger af brugen. Hvis det er en private attribut i din form vil jeg initialisere i OnCreate-eventen, mens hvis den er lokal bør stå lige efter din metodes "begin".
At gemme en recordtype. Om jeg forstår dig ret ville en TStringList kunne gøre det. Jeg ville konvertere den til en streng (hvis recordtypen er en enumering ville jeg bruge enum-navnet, søg på GetEnumName, eks: http://www.techtricks.com/delphi/enumname.php).
For at tage det sidste først, så er Delphi programmeret sådan at alle variable er initialiserede (modsat især C++). Du burde altså ikke behøve initialisere dem - men Delphi vil nu alligevel godt have det. ----- GÆLDER DA KUN FOR dine Object-var, ikke dem på stack ( var erklæret i en procedure ) ???
'Recorden' består af nogle String variable (strAmount, strCurrency m.m.) som jeg skal gemme i den rigtige rækkefølge i en fil. Jeg havde håbet på at man kunne loope på en måde så jeg ikke skal tænke på hvis jeg nu på et tidspunkt tilføjer nogle flere linier.
Der er også den mulighed at du bruger en IniFile til at gemme i, eller du laver :
F : file of MyRecord;
så kan du gemme dine records i en fil, den er dog ikke helt klar tekst, men næsten :-) eller du kan lave en function i din record der gemmer den, eller du kan lave en klasse og så nogle func. på den der evt. bruger RTTI, så kan den selv finde udaf hvad der skal gemmes..
hugo: Jeg tror ikke jeg helt forstår din opgave for det du skriver, læser jeg som aldeles muligt, både på den ene og den anden måde.
Du skriver at recorden består af et vilkårligt antal variable. Bliver nødt til spørge til det: Du har flere records der består at et vilkårligt antal strAmount, strCurrency og lignende?
Hvis det er tilfældet ville jeg lave en objektliste indeholdende stringliste.
Jeg har kun 1 'record' der består af et antal strings som jeg skal gemme i en fil linie for linie som ren text (dette er vigtigt for filen skal hentes ind i et andet program og behandles videre) Jeg ville så bare gerne lave en funktion der tager alle elementer/strings/linier i 'recorden' og gemmer dem i filen. Det ville kunne gøre at jeg ikke om 2 år skal huske at lave gemmefunktionen om også når jeg nu tilføjer en string mere til min 'record'
Så i bund og grund er jeg bare lidt på forkant med et forudsigeligt hukommelsestab:-)
en record danner ikke RTTI, selv om det i Delphi 2009 efterhånden er svært at skælne begrebet record og begrebet class.
Hvis du vil være sikret mod frentidige hukommelsestab skal du bruge en klasse og ikke en record, og så skal du lave alle dine data felter som PUBLISHED propperties.
Det lyder for besværligt til denne lille opgave så det dropper jeg nu nok og køber en portion GeriMax i stedet - så er der en chance for at de hjerneceller overlever :-)
Huggo >> en stibe Strings du skal gemme line for line, så dropper du din record og bruger en TStringList, den er top-tunet til dit formål, du kan endda bruge en med Name=Value hvis du har behov for det, og når du gemmer/læser skriver du savetofile/loadfromfile, den er meget nem at arb. med, så brug en TStringList.
Det kan da godt lyde til at jeg skal til at se på det der stringlist. Det der passer mig godt ved en record er at jeg kan gemme værdier random på 'feltnavne' så jeg ikke behøver at fylde den fra en ende af.
Du vil altid kunne se hvilken type mine variable er ud fra navnet. Jeg har arbejdet med Levensky/Reddick i VBA i mange år og har tillagt mig nogle vaner som jeg har det godt med :-)
Borrisholt: Jeg har lignende posts herude. Min variant håndterer ændringer i datamængden idet data gemmes med et versionsnummer. Har længe villet lave det trick med at løbe published properties igennem vha. RTTI - men den opgave har realistisk været på stand-by indtil mine børn flytter hjemmefra! Sådan nogle små størrelser fylder utroligt meget.
martinlind: Næ, det ved jeg godt, men man skal finde data frem og beslutte hvordan man gennemløber attributterne i ens klasse. Jeg ved hvor det står i mine "mursten", men om aftenen ligner min kode mere og mere blindskrift, for til sidst, at ende med en endeløs række tegn, der hvor mit ansigt har valgt at placere sig på tastaturet.
Kan i øvrigt se at borrisholts løsning er immun overfor ændringer i de publicerede attributter. Min løsning med at gemme hver klasses data med et versionsnummer så indlæsningsmetoden kan differentiere, er altså ikke nødvendig (jeg syntes ellers godt om den).
Har også overvejet at lade klasserne nedarve fra TPersistent (var det ikke dit forslag?), men det objekt kender jeg ikke så godt.
Nemli' ! Og jo det gør du faktisk, for alle delphi forms osv nedarver fra TPersistent, og den har det hele indbygget ( det er det delphi selv bruger til at gemme form-dfm filer med ) så du bruger det faktisk hver dag :-)
martinlind: Jeg ved godt det er en af kerneklasserne, men har aldrig gidet (at kalde en spade for en spade) finde ud af dets funktion. Det som den så nok gør, er vel at lave lidt RTTI-gymnastik og derefter lege med TReader og TWriter-klasserne - umiddelbart er det dog gemt noget væk. Findes det via TFiler-klassen?
borrisholt> jeg har nu haft lidt tid til at kigge på dit forslag. Det ser rigtig smart ud, men desværre løser det ikke min opgave da det gemmer for mange oplysninger i filen. Jeg må kun skrive værdien og den skal sluttes med linieskift. Årsagen er at det program der læser filen læser det som tekst linie for linie. Havde jeg haft mulighed for at rette i det var din løsning super.
Jeg har i stedet lavet min egen løsning med at gemme alle recordtypens data linie for linie i en tekstfil - det er måske ikke helt så elegant, men opgaven bliver løst.
Jeg vil dog have din løsning in mente og nævne det for leverandøren af det andet program om han evt. kunne lave det så han læste en fil på din måde.
Hugo: Jeg er ikke helt sikker på du har forstået at en TStringList er en smart måde at gemme strenge - for du skriver da et sted, at du gemmer strengen, ikke? Det er altså det letteste løsning. Bare "Add" dem til listen og SaveToFile når du er færdig.
hrc> jo den har jeg fanget. Men jeg har ikke afprøvet om den metode kan bruges her. Jeg er som sagt lidt bundet af at data skal bruges af et andet program som jeg ikke har mulighed for at rette i.
Når jeg lige får en halv time vil jeg se om jeg kan finde et eksempel på brugen at sådan en TStringList - lige nu sidder jeg og river mig i håret over at få en combobox til at vise flere kolonner. Det er godt nok omstændigt i forhold til hvad man kan gøre i M$ Access
Det er også meget muligt det er den optimale løsning. Men som sagt har jeg ikke haft tid til at finde et eksempel eller selv lave et det viser om det er det rigtige for mig.
Så tog jeg mig lige tid til her i stormen at afprøve TStringList lidt. Jeg kan godt se en fidus i at det er nemt at gemme nogle strings på den måde. Men med en record har jeg så vidt jeg kan se, lidt mere check på hvor de forskellige strenge er placeret og da de skal komme i en bestemt rækkefølge i filen kan jeg umiddelbart ikke se hvor jeg skal hoppe over hegnet henne for at få det optimale ud af at bruge en TStringList.
Det kom rundt omkring ja - men det er jo også rart :-)
Godt nytår.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.