20. december 2001 - 13:06Der er
56 kommentarer og 2 løsninger
Indlæsning af tabel som globale variable
I mine formularer har jeg lavet en funktion der henter alle overskrifterne til formularfelterne i en brugerstyrettabel. Dette gør formularerne meget fleksible.
Jeg henter hvert felt som =overskrift(\"O1\") osv.. Det betyder tabellen med overskrifterne læses ind mange mange, for at få udfyldt en hel formular med overskrifter. Dette kan godt tage et par sekunder.
Mit spørgsmål er: Kan man ved indlæsningen af databasen (eller andet valgt tidspunkt), indlæse alle disse variable overskrifter fra overskriftsstabellen (ca. 100 stk) som nogle globale variable, således tabellen ikke skal åbnes for hver eneste overskrift.
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Brug evt et array! I Et modul laver du følgende kode:
Public Overskrift(100) as String
Public Sub GemOverskrifter Dim rs as DAO.Recordset Set rs = Currentdb.Openrecordset(\"DinOverskrifttabel\") Do Until rs.eof Overskrift(Val(rs![TællerfeltetIDinOverskriftTabel])) = rs!Overskrift rs.movenext loop rs.close set rs = nothing End Sub
Funktionen benytter DAO, så du skal huske en reference hertil.
No, I mean the dlookup is more than likley faster than the current function overskrift, yes I know I didnt think it would be much faster, but we are only talking about 100, so how longs that going to take? OK on a 486 with 8Mb memory, then OK it may make a difference! But then the array is kind of smart!
Okay, hvis din nøgle også indeholder bogstaver, så kan du ikke direkte bruge denne metode (uden at lave en ny tabel, som holder styr på nummereringen, og så er du lige vidt!)
hvornår indlæser du overskrifterne nu? Hver gang formularen åbnes? Eller når databasen åbnes første gang?
Hvorfor ikke bruge et array i 2 dimensioner, 1 til nøglen og 1 til overskriften, så er numereringen uden betydning... Der skal \"bare\" løbes gennem arrayet\'s 1.dimension, for at finde den rigtige værdi, og derefter returneres 2.værdi...
Proaccess har ret i at 2 diminsioner er en god ide. Jeg mangler bare lidt info om hvad der styrer om det er 01 eller 02 der skal bruges? Det er jo ikke det samme hver gang (eller ville der jo ikke være nogen ide i det)....
Public Sub GemOverskrifter Dim iLoop As Integer Dim rs as DAO.Recordset Set rs = Currentdb.Openrecordset(\"DinOverskrifttabel\") Do iLoop=iLoop+1 Overskrift(iLoop,1) = rs!ID Overskrift(iLoop,2) = rs!Overskrift rs.movenext loop Until rs.EOF rs.close set rs = nothing End Sub
Public function getOverskrift(rID As String) As String dim iLoop As Integer For iLoop=1 to 100 If Overskrift(iLoop,1)=rID Then getOverskrift=Overskrift(iLoop,2) exit For End If Next End Function
proaccess, så er jeg ikke helt med længere. Du sendte to eksempler. Det jeg vil er jo een gang at indlæse overskrifterne i 100 variabler og dernæst blot af kunne referere til disse uden at skulle læse disse igen. Jeg er ikke så kvik som I andre...
proaccess. Dit eksempel virker, kan jeg jo konstatere, men kunne jeg undgå at skulle bruge funktionen getoverskrift() jeg ved ikke om det også forsinker opbygningen af formularen, idet getoverskrift jo skal kaldes for hver eneste overskrift???
Så tror jeg jeg har forstået det, så hvis jeg vælger at ændre opslagsværdien fra f.eks. O1 til 1 osv. så kan jeg bruges thomasjepsen´s forslag og derved spare funktionskald for hver oveskrift? Er dette korrekt?
Og er det iorden med pointfordelingen: thomasjepsen 40
proaccess 60
terry jeg betvivler ikke at dlookup også er god, men det var ikke det jeg søgte i mit spørgsmål.
Ok så lige sidste spørgsmål, hvis jeg så kun bruger ID og 1 felt med overskrifterne, får jeg mine variable data lagt i overskrift(1) osv. men hvordan henter jeg dem i min formular =overskrift(1) duer ikke?
Bemærk at dit array skal være erklæret PUBLIC, og ligge i et modul (som ikke må hedde overskrift) Funktionen GemOverskrifter skal køres inden formularen åbnes første gang... evt ved autoexec-macro
terry har da fat i noget af det rigtige. En simpel løsning, der gør at teksterne kun skal læses ind hvis vinduet åbnes. At læse alle teksterne ind i et array er udmærket, men det er da tvivlsomt om en bruger skøjter 100 skærmbilleder igennem. Dermed spildes en masse tid på at læse tekster som ikke vil blive brugt. Ganske vist er dlookup langsom, men hvis opslaget ligger på formens on_open event vil det stadig gå så hurtigt at ingen opdager det. Der er jo ingen grund til at hoppe over hvor gærdet er højest.
Og kør så Thomas\'s kode, når du åbner databasen... (ikke formularen)
Public Sub GemOverskrifter Dim rs as DAO.Recordset Set rs = Currentdb.Openrecordset(\"DinOverskrifttabel\") Do Until rs.eof Overskrift(Val(rs![TællerfeltetIDinOverskriftTabel])) = rs!Overskrift rs.movenext loop rs.close set rs = nothing End Sub
Public Overskrift(0 To 100) As String ------------------------------------------ Public Sub GemOverskrifter() Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset(\"Otabel\") Do Until rs.EOF Overskrift(Val(rs![ID])) = rs![felt2] rs.MoveNext Loop rs.Close Set rs = Nothing End Sub
For lige at forstå det rigtigt, så har du (indtil nu) haft en række teksbokse, hvor der f.eks. har stået: =Overskrift(\"O1\") I den næste kan der så stå f.eks.: =Overskrift(\"S15\")
Ideen er, at du, ved at ændre i tabellen, kan ændre skærmbilledet. Er det forstået korrekt?
Hvis ja, så starter jeg lige forfra: Jeg tror ikke at Array-løsningen er den helt optimale, når ID\'erne ikke er nummeriske.
I stedet forslår jeg følgende løsning:
Du erstatter simpelten din Overskrift-funktion med denne:
Public Function Overskrift(ID As String) As String Static rs As DAO.Recordset If rs Is Nothing Then Set rs = CurrentDb.OpenRecordset(\"Otabel\", dbOpenTable) End If rs.Index = \"ID\" rs.Seek \"=\", ID If rs.NoMatch Then Overskrift = \"\" Else Overskrift = rs!Overskrift End If End Function
Denne funktion burde være væsentlig hurtigere end den du har i forvejen, da den kun initialisere recordsettet én gang. Herefter går søgningerne ret hurtigt. Især fordi der benyttes Seek. Det kræver bare 2 ting: Tabellerne er ikke sammenkædet. Og ID er indekseret.
Såfremt tabellerne er sammenkædet, skal vi lige have lavet koden lidt om. Så må du lige sige til...
Hi Thomas>But according to the comment from fruwille 14:09:26: \"terry jeg betvivler ikke at dlookup også er god, men det var ikke det jeg søgte i mit spørgsmål.\"
then your solution 18:40 isnt what he asked for either! Even though it is more than likley fastare than fruwille\'s own. But I would STILL lik eto see the dLookup speed, just for fun :o)
Thomas & proaccess Jeg siger jer mange tak for hjælpen, jeg har prøvet begge dele i en lille database i Acc97, men mit projekt ligger i Acc2000 og bruger ADO i stedet for DAO, så jeg skal lige have omskrevet jeres tips og prøvet det af i den \"rigtige\" database. Jeg forhøjede pointene ekstra, fordi jeg syntes det var to (flere) meget gode løsninger, så det blev til 70 point til hver.
Så håber jeg der snart er noget jeg kan svare på, idet jeg så har 90 point tilbage.
terry Den løsning jeg har prøvet, som virker bedst er proaccess fra 13:35 og 13:39, men lige så snart jeg får tid til at lægge det ind i \"den store\" database, hvor performanceproblemerne er, vil jeg også dlookup, hvis den er bedre - må du jo have mine sidste point.
Hej fruwille> I am not after your points, but you rejected my idea if the dlookup with the comment that it wasnt what you asked for. Thats fine, and although I cant see which solution you use, Thoams\'s answer isnt what you asked for either! So if its SPEED that your after then you should TEST all solutions before rejecting Dlookup.
The reason you rejected DLookup was, that it wasnt what you asked for!
Terry-> When you use DLookup, Access opens a recordset and searches for the result. It is a forward-only-snapshot, but it still has to open and initialize the recordset everytime you call it.
For at illustrere tidsforskellen, har jeg (på min egen maskine) lavet 2 tests. Én hvor jeg kalder min funktion 20.000 gange og én hvor jeg kalder DLookup 20.000 (på samme tabel) Testen slog den samme værdi op hver gang og skrev den til debug-vinduet.
Min funktion tog 11 sekunder og DLookup tog 1 minut og 30 sekunder! Det er da noget af en forskel.
Jeg tror ikke at Fruwille undgår at lave opslag hver gang - enten i en tabel eller i nogle variabler/arrays. Det afgørende må jo være, hvad der er hurtigst!?
Fruwille, jeg benytter ganske rigtigt DAO. Det gør jeg altid, når jeg ikke ved om folk bruger Access 97 eller 2000/XP (husk derfor altid at opgive dette!) Du kan sagtens bruge DAO samtidig med ADO (blot man husker at skrive DAO.recordset osv). Det kræver bare at du laver en reference til \"Microsoft DAO 3.6 object library\".
Men du kan selvfølgelig også ret let omskrive den til ADO.
thomasjepsen Jeg ved godt jeg også kan bruge DAO, men det er en applikation der skal bruges i 5 lande og alle steder Access 2000 og ADO er brugt alle andre steder, derfor valget.
I am also aware which method is the fastest Thomas, but that wasnt what I was pointing out!
God Jul :o)
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.