Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: Probleema

Sivun loppuun

Wizard [10.01.2004 16:35:16]

#

Minulla on hakutaulu jossa on esim. 3 arvoa eli Suomi, Suomi ja Ruotsi.

Sitten on listaus:

'Lisään comboboxiin valtioiden nimet
For i = 1 To dblHakuMaara
    If tblHakuTaulu(2, i) = "" Then
    ElseIf cboValtio.ListCount > 0 Then
        For j = 1 To cboValtio.ListCount
            If cboValtio.List(j) = tblHakuTaulu(4, i) Then
            Else
            cboValtio.AddItem tblHakuTaulu(4, i)
            End If
        Next j
    Else
    cboValtio.AddItem tblHakuTaulu(4, i)
    End If
Next i

Eli ideana on saada kukin valtio näkymään vain yhden KERRAN combossa, ei kahta kertaa (tai useampaa).

Äy sanon minä kun ei toimi eikä jymmärrä taas...

setä [10.01.2004 17:41:48]

#

Käy ensin koko lista läpi. Jos löytyy sama nimi, tulet silmukasta ulos. Ellei nimeä löydy, olet mennyt silmukan loppuun. Jos silmukkalaskuri on ListCount (For-lause oltava:
For j = 1 to cboValtio.ListCount - 1 ), lisätään uusi nimi.

Wizard [10.01.2004 18:55:04]

#

Combon list numerointi alkaa luvusta 0 eikä 1. Eli kun muotoilin koodin uusiksi siltä osin ja pistin koodiksi:

For i = 1 To dblHakuMaara
    If tblHakuTaulu(2, i) = "" Then
    ElseIf cboValtio.ListCount > 0 Then
        For j = 0 To cboValtio.ListCount
            If cboValtio.List(j) = tblHakuTaulu(4, i) Then
            Exit For
            Else
            cboValtio.AddItem tblHakuTaulu(4, i)
            End If
        Next j
    Else
        cboValtio.AddItem tblHakuTaulu(4, i)
    End If
Next i

, niin nyt toimii kuten pitääkin.

Wizard [10.01.2004 19:06:25]

#

Tai sitten ei. Iloitsin liian varhain sillä listaan kun lisää sekalaisesti Suomi, Ruotsi, Suomi, Ruotsi, Ruotsi, Suomi niin aina tulee kaksin kappalein jossain vaiheessa. Voi kettu ja pari muuta sano...

Wizard [10.01.2004 19:52:05]

#

No niin jos joku törmää joskus samaan pulmaan, niin ratkaisu on tässä:

Dim Listassa as Boolean
For i = 1 To dblHakuMaara
    If tblHakuTaulu(2, i) = "" Then
    ElseIf cboValtio.ListCount > 0 Then
        For j = 0 To cboValtio.ListCount
            If cboValtio.List(j) = tblHakuTaulu(4, i) Then
            Listassa = True
            Exit For
            End If
        Next j
    If Not Listassa Then cboValtio.AddItem tblHakuTaulu(4, i)
    Listassa = False
    Else
        cboValtio.AddItem tblHakuTaulu(4, i)
    End If
Next i

Jos joku saa muuten kehiteltyä tuosta nopeamman koodin, niin otan mieluiten ehdotuksia vastaan. Nyt kun käydään läpi 8000-10000 arvoakin "parhaimmillaan", niin se ei ole aina ihan kovin nopeaa. Arvoja voi periaatteessa olla enemmänkin, riippuen käyttökohteestani.

setä [10.01.2004 21:14:26]

#

Jäi tuo nolla huomaamatta. tarkoitin tallaista ratkaisua:

For i = 1 To dblHakuMaara
       If tblHakuTaulu(2, i) = "" Then
       ElseIf cboValtio.ListCount > 0 Then
           For j = 0 To cboValtio.ListCount - 1
               If cboValtio.List(j) = tblHakuTaulu(4, i) Then
                   Exit For
               End If
           Next j
           If J = cboValtio.ListCount Then
               cboValtio.AddItem tblHakuTaulu(4, i)
           End If
       End If
   Next i

Wizard [10.01.2004 21:43:29]

#

Äkkiä katsottuna toimiva, mutta viimeinen else puuttuu. Ilman sitä listaan ei tule yhtään nimeä, koska ei ole koskaan olemassa sitä combon ensimmäistäkään arvoa. Sehän on se viimeinen mahdollisuus jos taulussa on dataa, mutta combossa ei vielä yhtään (jolloin siis lisätään ensimmäinen arvo taulusta comboon).

Antti Laaksonen [10.01.2004 22:05:54]

#

Tässä on toinen toteutustapa, joka tuntuu olevan noin kolme kertaa nopeampi. Ideana on se, että maitten nimet tallennetaan merkkijonoon, josta sitten katsotaan, onko maata jo laitettu listaan.

Dim laitetut As String
For i = 1 To dblHakuMaara
    If tblHakuTaulu(2, i) <> "" Then
        If InStr(laitetut, tblHakuTaulu(4, i)) = 0 Then
            cboValtio.AddItem tblHakuTaulu(4, i)
            laitetut = laitetut & "#" & tblHakuTaulu(4, i)
        End If
    End If
Next

Parempiakin toteutustapoja on varmaan olemassa. :)

setä [10.01.2004 22:58:15]

#

lainaus:

Äkkiä katsottuna toimiva, mutta viimeinen else puuttuu. Ilman sitä listaan ei tule yhtään nimeä, koska ei ole koskaan olemassa sitä combon ensimmäistäkään arvoa. Sehän on se viimeinen mahdollisuus jos taulussa on dataa, mutta combossa ei vielä yhtään (jolloin siis lisätään ensimmäinen arvo taulusta comboon).

Kokeilitko koodia? Jos ListCount = 0, niin J:n arvoksi jää 0 jolloin ensimmäinen data lisätään.

Wizard [11.01.2004 00:30:56]

#

lainaus:

Kokeilitko koodia? Jos ListCount = 0, niin J:n arvoksi jää 0 jolloin ensimmäinen data lisätään.

Korjatkaa jos olen väärässä, mutta jos ListCount on nolla, niin Elseif hypätään yli, koska ehto ei täyty. Sen jälkeen tulee end if...

Edit: kokeilin koodia ja comboon ei tule yhtään arvoa. Eli ei voi tulla, koska jos combossa ei ole yhtään arvoa, niin mikään ehto ei täyty. Eli se viimeinen else pitää siellä olla pakosti.

Antin antama koodi tosin toimii hyvin, kunhan pääsen testaamaan noita kahta käytännössä suurilla arvoilla (tietokannat syöttävät taulukoihin noin miljoona arvoa tietyissä tapauksissa), niin tiedän suoraan kumpi on nopeampi.

setä [11.01.2004 02:41:29]

#

For i = 1 To dblHakuMaara
    If tblHakuTaulu(2, i) > "" Then
        For j = 0 To cboValtio.ListCount - 1
            If cboValtio.List(j) = tblHakuTaulu(4, i) Then
                Exit For
            End If
        Next j
        If J = cboValtio.ListCount Then
            cboValtio.AddItem tblHakuTaulu(4, i)
        End If
    End If
Next i

Olit aivan oikeassa. Tuota koodin alkua en sen tarkemmin tutkinut, kopioin sen vain. Eihän tuota elseiffiä tarvita lainkaan. Eli noin sen pitäisi toimia siten kuin alunperin ajattelin. Antin koodi on toinen vaihtoehto. Nopeus riippuu varmaan nimien pituudesta. Jos todella nopeutta vaaditaan, niin silloin kannattaa kehitellä Antin koodia siten, että tutkitan InStr-funktiolla ensin alkukirjain, luodaan merkkijonotaulikko toisen kirjaimen mukaan ja loppuosasta 2-ulotteinen taulukko. Uskoisin nopeuden kasvavan merkittävästi, jos listassa on satoja tai jopa tuhansia nimiä. Kiinnostava juttu, taidan testailla itsekin.

setä [11.01.2004 04:02:23]

#

Testasin noiden kahden nopeutta ja antin koodi näyttää olevan ainakin 16 kertaa nopeampi. InStr-funktio on todella nopea. Testasin VB5CCE-versiolla kun sitä muutenkin testailen. Nimet oli generoitu 4 ... 15 merkin pituisiksi. 100 erilaista, yhteensä 500. Ajat 0,29 s ja Antin koodilla 0,018 s

setä [11.01.2004 12:46:43]

#

Eipä nuo taulukot näytä nopeuttavan kuin vasta erittäin pitkillä nimillä (>50 merkkiä) eikä silloinkaan merkittävästi. Mutta kuinka nuo valtioiden nimet on alun perin tietokannassa. Voiko nimen sijasta käyttää jotain avainta tai indeksiä. Silloin nopeutta saa rutkasti lisää.

Wizard [11.01.2004 13:22:19]

#

lainaus:

Eipä nuo taulukot näytä nopeuttavan kuin vasta erittäin pitkillä nimillä (>50 merkkiä) eikä silloinkaan merkittävästi. Mutta kuinka nuo valtioiden nimet on alun perin tietokannassa. Voiko nimen sijasta käyttää jotain avainta tai indeksiä. Silloin nopeutta saa rutkasti lisää.

Tokihan kaikki perusavaimet ovat indeksoitu. Mutta käytän samaa rutiinia myös muissa kohteissa kuten varaston tutkimisessa jne.

Tosin tuota rutiinia voisi nopeuttaa jos käyttäisi vertailuun vain Hakutaulun kolmatta saraketta josta löytyy valtion numeroindeksi eli tietokannan avain. Sitten tulostaisi vain lopuksi pelkät nimet... Mutta tuota rutiinia pitäisi hieman muuttaa myös.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta