Toon posts:

[VB6] tijdsduur array inlezen duurt lang

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als aanvulling op mijn vorige post omtrent array's het volgende;

Ik vul een array met waarden. De arraygrootte begint bij 0 en loopt op afhankelijk van gevulde textboxen. In de array sla ik het volgende op:

91;2004;5
92;2004;6
93;2004;77
94;2004;80
95;2004;40
96;2004;21
97;2004;33

het eerste getal houdt het dagnummer in t.o.v 1 januari, het tweede getal het jaar en het derde getal de inhoud van de textbox.

Schokkend is het niet....maar toch, wanneer ik van 1 maand alle textboxen gevuld heb duurt het, bij het overschakelen naar een andere maand vrij lang (1 tot 2 seconden) voordat de gegevens opgeslagen/opnieuw getoond worden. Deze tijdsduur loopt op naarmate het aantal ingevulde velden groter wordt.
Om de waarde opnieuw in de textbox te krijgen wordt vergeleken of de 'datediff' van de tooltiptext, van het bij de textbox corresponderende label, gelijk is aan het 1e deel van de variabele...

Heeft iemand enig idee of het misschien sneller is de gegevens tijdelijk op te slaan in een textbestand?

Bedankt,
Richard

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Met welke code vul je het en met welke lees je het uit?

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Private Sub saveDataInArray()

Dim i As Integer, a As Integer

    'sla de gegevens op in de array indien de textvelden niet leeg zijn
    For i = txtMinutes.LBound To txtMinutes.UBound
        If txtMinutes(i).Text <> "" Then
        ReDim Preserve arrData(zWaardeArray)
            arrData(zWaardeArray) = (DateDiff("d", "1/1/" & cboYear.Text, 

lblDagNummer(i).ToolTipText)) & ";" & cboYear.Text & ";" & txtMinutes(i).Text
            If blnLostFocusFieldMinutes = False Then
                txtMinutes(i).Text = ""
            End If
            Debug.Print arrData(zWaardeArray)
            zWaardeArray = zWaardeArray + 1
        End If
    Next i
    
End Sub

Private Sub readDataFromArray()

Dim i As Integer, z As Integer, a As Integer
Dim test As Integer

    If zWaardeArray > 0 Then
        For a = lblDagNummer.LBound To lblDagNummer.UBound
            For i = LBound(arrData) To UBound(arrData)
                arrValue = Split(arrData(i), ";", -1, vbTextCompare)
                If cboYear.Text = arrValue(1) Then
                    If DateDiff("d", "1/1/" & cboYear.Text, lblDagNummer(a).ToolTipText) 

= arrValue(0) Then
                        txtMinutes(a).Text = arrValue(2)
                    End If
                Else
                    If DateDiff("d", "1/1/" & cboYear.Text - 1, 

lblDagNummer(a).ToolTipText) = arrValue(0) Then
                        txtMinutes(a).Text = arrValue(2)
                    End If
                End If
                ReDim arrValue(0)
            Next i
        Next a
    End If
    
End Sub

[ Voor 7% gewijzigd door Verwijderd op 05-04-2004 15:39 ]


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

In plaats van op te slaan v.a. 1 januari, kun je misschien ook opslaan per maand (dus 1 bestand voor januari 2004, 1 bestand voor februari 2004, ..., ... 1 bestand voor januari 2005 etc)

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


Verwijderd

Topicstarter
Het is een tijdelijke opslag. Het formulier heeft 41 textboxen en labels. Afhankelijk van het aantal dagen in de maand en de startdag wordt het formulier opgemaakt. Je ziet dus een kalender echter met textboxen waarboven de labels staan met de dagnummers. Helemaal bovenaan staat maandag, dinsdag ....t/m zondag.

Het formulier start met de tab van de huidige maand als 1e.

Wanneer men van tab verandert, dus bijvoorbeeld van april naar januari dan worden de labels met dagNummers dus anders en worden de textboxen die niet bij die maand horen uitgezet. Dit geld voor zowel de vorige maand als de volgende maand! Afhankelijk van het aantal weken worden de textboxen 36 t/m 42 verborgen.

Wanneer men dus iets op 4 april heeft ingevuld en op 5, 6, 7 en 8 april dan wil je dat die waarden niet verloren gaan als men van tab verandert (van april naar januari bijvoorbeeld!) De waarden sla ik dus op in de array . Klikt men weer op de tab april dan wordt de array doorzocht op dagnummer t.o.v. 1 januari van het gekozen jaar (1 april = 91) en wordt de waarde terug in de textbox geplaatst.

Verlaat men het formulier of kiest men een ander jaartal dan wordt gevraagd of men de ingevulde waarden wil opslaan. Pas DAN worden de waarden met behulp van een INSERT/UPDATE query in een tabel in de database opgeslagen.

Hiermee voorkom je dus dat er veelvuldig de database geraadpleegd wordt.

De waarden worden ook bij het openen van het formulier uit de database gevist en in de juiste textboxen geplaatst.

Nu, wanneer er veel textboxen zijn gevuld loopt de tijd om de array te doorzoeken en de juiste textboxen opnieuw te vullen dramatisch op. Ik heb wat testen gedaan maar wanneer ik van 3 maanden (= ca 90 waarden in de array) de textboxen gevuld heb en wederom een andere maand kies (in de tabbladen) dan duurt het ongeveer 5 a 6 seconden voordat de velden zijn gevuld (en dus het formulier inactief is!)

Ik dacht zelf om er toch maar een multi dimensionele array van te maken.

arrData(12,0) waarbij 12 staat voor jan - dec
Afhankelijk van de maand ga ik dan de waarden opslaan en dus ook doorzoeken.....heb dit alleen nog nooit gedaan.....maar dat is dan ook DE UITDAGING om het voor elkaar te krijgen.....

Misschien zijn er echter andere manieren, zoals bijvoorbeeld tussentijds opslaan in een textbestand maar goed, die moet ook telkens geraadpleegd worden dus dat lijkt mij niet veel sneller ;)

misschien heeft iemand een tip voor mij _/-\o_

bedankt,

Richard

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Je gebruikt nogal wat controls ( textbox, labels ) om variabelen in op te slaan.

Op de meest vreemde plaatsen i may say :
Visual Basic:
1
2
3
ReDim Preserve arrData(zWaardeArray)
arrData(zWaardeArray) = (DateDiff("d", "1/1/" & cboYear.Text,  
lblDagNummer(i).ToolTipText)) & ";" & cboYear.Text & ";" & txtMinutes(i).Text


Schrijf je code eens op zo een manier dat het werkt zonder van die controls gebruik te maken, die zijn alleen voor weergave en invoer namelijk.

Schrijf het eens zo dat het geen gebruik maakt van redim

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
farlane schreef op 06 april 2004 @ 08:59:
Je gebruikt nogal wat controls ( textbox, labels ) om variabelen in op te slaan.

Op de meest vreemde plaatsen i may say :
Visual Basic:
1
2
3
ReDim Preserve arrData(zWaardeArray)
arrData(zWaardeArray) = (DateDiff("d", "1/1/" & cboYear.Text,  
lblDagNummer(i).ToolTipText)) & ";" & cboYear.Text & ";" & txtMinutes(i).Text


Schrijf je code eens op zo een manier dat het werkt zonder van die controls gebruik te maken, die zijn alleen voor weergave en invoer namelijk.

Schrijf het eens zo dat het geen gebruik maakt van redim
Volgens mij gebruik ik die controls niet om variabelen in op te slaan hoor....ik toon het dagnummer in een label. Vervolgens is er een toolTipText die de volledige datum toont. Om vanuit de array te controleren in welk dagnummer de inhoud van het textveld moet worden opgeslagen (of getoond) cerifieër ik uiteindelijk dus weer de tooltiptext. BTW weet ik van te voren niet hoeveel variabelen ik nodig heb dus ben ik vlgs mij genoodzaakt REDIM te gebruiken.....

Ik kan het verkeerd hebben hoor..... O-)

  • Lister
  • Registratie: September 2001
  • Laatst online: 15-02-2022
Het saven kan je volgens mij sneller maken door voor de For-loop eerst een ReDim te doen met de maximale grootte en dan na de loop de niet gebruikte ruimte vrij te geven. Dus eerst een ReDim(txtMinutes.UBound) en later een ReDim Preserve (zWaardeArray), (+1 of -1 moet je zelf maar even testen ;) )
Dan hoeft VB niet voor elke waarde extra geheugen bij te reserveren.

En bij het inlezen doorloop je nu voor elke textbox alle waardes in je array.
Is het niet handiger om alle waardes in je array te doorlopen en waar nodig de textbox te vullen?
Bijvoorbeeld voor februari 2004, txtMinutes(1) staat dan voor 1 februari, dag nummer 32
txtMinutes(29) staat voor 29 februari, dag nummer 60
Dan hoef je alleen maar de waardes uit de array te lezen als het eerste element tussen de 32 en 60 ligt.

Daarnaast zou het naar mijn idee netter opgeslagen kunnen worden in classes in een collectie, maar ik weet niet of je daar ervaring mee hebt?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Verwijderd schreef op 06 april 2004 @ 10:46:
Volgens mij gebruik ik die controls niet om variabelen in op te slaan hoor...
Gebruik maken van de waarde van een tooltip in een datediff, is voor mij precies dat. Ik snap wel waarom je het zo gedaan hebt, ik vind het alleen geen goede contructie. Stel dat je straks vergelijkbare functionaliteit nodig hebt, dan werkt het alleen als je
een combobex hebt die cboYear heet, en labels die lblDagnummer heten en een tooltiptext met daarin een datum. Da is toch niet flex?

Bovendien, het extractebn van een string uit een tooltip zal altijd langzamer zijn dan gebruik maken van een array met data ....

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Bedankt voor jullie reacties 'Lister' en 'Farlane' ;)
Lister schreef op 06 april 2004 @ 20:59:
Is het niet handiger om alle waardes in je array te doorlopen en waar nodig de textbox te vullen?
Bijvoorbeeld voor februari 2004, txtMinutes(1) staat dan voor 1 februari, dag nummer 32
txtMinutes(29) staat voor 29 februari, dag nummer 60
Dan hoef je alleen maar de waardes uit de array te lezen als het eerste element tussen de 32 en 60 ligt.

Daarnaast zou het naar mijn idee netter opgeslagen kunnen worden in classes in een collectie, maar ik weet niet of je daar ervaring mee hebt?
Helaas is dat niet mogelijk. De 1e van de maand heeft een dagnummer waarop gestart wordt. Voor 1 april is dat dagnummer 4 wat inhoud dat (ivm vbMonday as FirstDayOfMonth) deze dag op donderdag valt.

Vandaar dat ik dus ook de index van de velden en labels laat beginnen bij 1.
Het is dus niet zo dat 29 april ook txtMinutes(29) is.
Verder heb ik helaas niet genoeg ervaring om te werken met classes. De test die ik nu ga doen is gewoon ALLE txtVelden aan te laten maken bij FormLoad en de corresponderende data erboven zetten, dan duurt het laden van het form misschien iets langer maar het switchen tussen de maanden gaat sneller.
PS als je wilt stuur ik je een kopie van de test ;)
farlane schreef op 07 april 2004 @ 09:52:
[...]
Ik snap wel waarom je het zo gedaan hebt, ik vind het alleen geen goede contructie. Stel dat je straks vergelijkbare functionaliteit nodig hebt, dan werkt het alleen als je
een combobex hebt die cboYear heet, en labels die lblDagnummer heten en een tooltiptext met daarin een datum. Da is toch niet flex?

Bovendien, het extractebn van een string uit een tooltip zal altijd langzamer zijn dan gebruik maken van een array met data ....
wat betreft extracten uit een string...
Klopt, ik ga dan ook nog een test uitvoeren met een multi dimensionele array arrData(12,0) zodat ik voor elke maand een eigen dimensie heb en dus sneller kan zoeken.

Wat betreft de flexibiliteit, jah daar heb je helemaal gelijk in :X

  • Twee Dee
  • Registratie: Juli 2002
  • Laatst online: 23:05

Twee Dee

Morgen weer een ondertitel.

Volgens mij kun je in jou geval veel beter gebruik maken van een (of meerdere) collecties. Dan hoef je ook niet steeds ReDim te gebruiken (wat volgens mij een groot stuk van de wachttijd uitmaakt).

Ook is
Visual Basic:
1
If len(txtMinutes(i).Text) > 0 Then

sneller dan:

Visual Basic:
1
If txtMinutes(i).Text <> "" Then

Maar dat scheelt maar een fractie :)


Edit:
Lister schreef op 06 april 2004 @ 20:59:
Daarnaast zou het naar mijn idee netter opgeslagen kunnen worden in classes in een collectie, maar ik weet niet of je daar ervaring mee hebt?
Had ik even overheen gelezen, alleen heb ik het alleen over een collectie om de strings in op te slaan, daar zijn geen classes voor nodig (al zou het inderdaad wel netter kunnen zijn).

[ Voor 42% gewijzigd door Twee Dee op 07-04-2004 13:59 ]

Luister nou gewoon naar me, dat voorkomt dat ik later "zie je wel" moet zeggen.


  • Twee Dee
  • Registratie: Juli 2002
  • Laatst online: 23:05

Twee Dee

Morgen weer een ondertitel.

Nog een extra opmerking (voor de overzichtelijkheid maar in een nieuwe post):
In je "Private Sub readDataFromArray()"
Voer je deze code herhaaldelijk uit;
Visual Basic:
1
arrValue = Split(arrData(i), ";", -1, vbTextCompare)


Beter kun je 1 maal de strings splitten en die vervolgens even in een collectie bewaren. Dat ziet er dan ongeveer zo uit:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dim colSplitValues  As Collection
Set colSplitValues = New Collection

For i = LBound(arrData) To UBound(arrData)
    arrValue = Split(arrData(i), ";", -1, vbTextCompare)
    Call colSplitValues.Add(arrValue)
Next i

For a = lblDagNummer.lBound To lblDagNummer.uBound

    For i = 1 To UBound(arrData) - LBound(arrData)
        arrValue = colSplitValues.Item(i)
        If cboYear.Text = arrValue(1) Then
            If DateDiff("d", "1/1/" & cboYear.Text, lblDagNummer(a).ToolTipText) = arrValue(0) Then
                txtMinutes(a).Text = arrValue(2)
            End If
        Else
            If DateDiff("d", "1/1/" & cboYear.Text - 1, lblDagNummer(a).ToolTipText) = arrValue(0) Then
                txtMinutes(a).Text = arrValue(2)
            End If
        End If
        ReDim arrValue(0)
    Next i
Next a

Je hebt nu wel een extra loop, maar je voorkomt nu dat je steeds dezelfde strings opnieuw moet splitten.

offtopic:
Een tijdsduur kan niet lang duren...

[ Voor 7% gewijzigd door Twee Dee op 07-04-2004 14:24 ]

Luister nou gewoon naar me, dat voorkomt dat ik later "zie je wel" moet zeggen.


Verwijderd

Topicstarter
Twee Dee schreef op 07 april 2004 @ 14:18:

[code=vb]
Dim colSplitValues As Collection
Set colSplitValues = New Collection

For i = LBound(arrData) To UBound(arrData)
arrValue = Split(arrData(i), ";", -1, vbTextCompare)
Call colSplitValues.Add(arrValue)
Next i

Je hebt nu wel een extra loop, maar je voorkomt nu dat je steeds dezelfde strings opnieuw moet splitten.

offtopic:
Een tijdsduur kan niet lang duren...
hehehe......correct, ik sluit me daar volledig bij aan!
Laat ik nou net ff bezig zijn met coll en coll.add dus dat kwam ff mooi uit.
Ik heb jouw/jullie verschillende opmerkingen toegevoegd echter maar qua tijdsduur maakt dat geen verschil (althans, gevoelsmatig niet merkbaar ).

Ik ben dan nu bezig een formulier te maken die alle txtBoxen voor het hele jaar toevoegd en per maand in de 'eigen' tabbladen en frames maar wil dan uiteraard wel de controls in een collectie krijgen zodat ze in een index aanspreekbaar zijn.
Ik ben ook nog aan het nadenken om de TAGS van de controls te vullen met de dagnummers, dat maakt het zoeken al weer iets sneller. De TAGS worden op dit moment toch niet gebruikt.

Ik stel het dan ook ZÉÉR op prijs dat jullie met mij meedenken....bedankt!

Richard

Verwijderd

Je kan als alternatief van arrays ook het dictionary object gebruiken, is aanzienlijk sneller als je met grote hoeveelheden data werkt.

Verwijderd

Topicstarter
Wow.....dies nieuw voor mij :?

Ik heb geen flauw benul van wat je daarmee bedoelt, sorry.... :? Kun je dat in het kort ff toelichten?

Verder heb ik nog een nieuw idee. Het is natuurlijk mogelijk om een collection te maken die het gehele jaar omvat (op dateDiff) en dan als het txtMinutes veld gevult is deze te toe te voegen op het juiste collection-nummer....
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Option explicit
Private colDateDiff as Collection

Sub insertValue(V as variant)
Dim i as variant
Dim j as variant
Dim k as variant

i = 1
j = colDateDiff.Count

If colDateDiff.Count = 0 Then
    colDateDiff.Add V (het dateDiffNummer)
    Exit Sub
End If

'het bereik van de collectie opvragen
i = 1
j = colDateDiff.Count

'controleren of de waarde voor of naa het eerste item moet worden toegevoegd
If V <= colDateDiff.Item(i) Then
    colDateDiff.Add V, before:=i
    Exit Sub
End If

Do until j - i <= 1
    k = (i + j) \ 2
    If colDateDiff.Item(k) < V Then
        i = k
    Else
        j = k
    End If
Loop

'het item op de juiste plaats invoegen
colDateDiff.Add V, before:=j
End Sub


Zou dat wat zijn om de tijdsduur te verkorten??


//////EDIT

Heb al gezocht op WWW en wat gevonden op msdn.....;) thx, ga dat ook gelijk ff proberen....het eerste proefje is al gelukt....nu de rest nog. ;) Grappig hoor, ff zo'n "input-kalender" bouwen..... ;)

[ Voor 13% gewijzigd door Verwijderd op 07-04-2004 15:47 ]


Verwijderd

Zie: http://www.devguru.com/Te.../quickref/dictionary.html
voor meer info over het dictionary object. (kan dus veel beter overweg met grote hoeveelheden data dan array's in vbscript)
Pagina: 1