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...
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.
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.
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...
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.
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
Ä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).
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. :)
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.
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.
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.
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
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ää.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.