Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Moniulotteinen dynaaminen taulukko

Sivun loppuun

Sinis [30.11.2005 11:54:54]

#

Miten VB:llä pystyy tekemään otsikon mukaisen taulukon? Tarkoituksena olisi lukea txt- tiedostosta riveittäin neljä arvoa (erotettu välilyönnillä) taulukkoon, jonka rivien määrää ei tiedetä. Yritin alla olevalla, mutta ei toiminut. Missä mättää??

Private Sub CommandButton1_Click()

Dim taulukko() As Variant
Dim koko, x, y As Integer

koko = 0
x = 1

    Open "c:\temp\koe.txt" For Input As #1

    Do While Not EOF(1)
        For y = 1 To 4
            Input #1, taulukko(x, y)
        Next y

        x = x + 1
        koko = koko + 1
    Loop

    Close #1

    ReDim taulukko(1 To koko, 1 To 4) As variant

End Sub

BadSource [30.11.2005 12:33:58]

#

Et voi sijoittaa taulukkoon, ennen kuin olet sen esitellyt...

Private Sub Command1_Click()
    Dim taulukko() As Variant
    Dim y As Integer

    'taulukon esittely, että sitä päästään jatkossa tarkastelemaan. Ensin "sarakkeet" ja sitten "rivit"
    ReDim taulukko(0 To 3, 0 To 0)
    Open "c:\test.txt" For Input As #1

    Do While Not EOF(1)
        'Jos viimeisin "rivi" taulukosta ei ole tyhjä, niin lisätään uusi "rivi" taulukkoon
        If Not IsEmpty(taulukko(1, UBound(taulukko, 2))) Then _
          ReDim Preserve taulukko(0 To 3, 0 To UBound(taulukko, 2) + 1)
        For y = 0 To 3
            Input #1, taulukko(y, UBound(taulukko, 2))
        Next y
    Loop

    Close #1
End Sub

Sinis [30.11.2005 13:49:50]

#

Kiitoksia, mutta voitko selventää, mitä tuo:

If Not IsEmpty(taulukko(1, UBound(taulukko, 2))) Then _

tarkemmin ottaen tekee. Mikä on ,2:n merkitys?

Toi IsEmpty lienee antaa TRUE -arvon jos solu on tyhjä, mutta toi Ubound ei oikein avaudu.

Antti Laaksonen [30.11.2005 14:22:56]

#

Funktio LBound (lower bound) kertoo taulukon pienimmän tunnuksen ja UBound (upper bound) kertoo taulukon suurimman tunnuksen. Toista parametria käytetään silloin, kun taulukossa on monta ulottuvuutta. Siis UBound(taulukko, 2) ilmoittaa taulukon toisen ulottuvuuden suurimman tunnuksen. Jos toista parametria ei ilmoita, se on 1 eli ensimmäinen ulottuvuus.

Tässä on vielä selventävä esimerkki:

Dim testi(5, 2 To 7, -10 To 10)

MsgBox UBound(testi)    ' 5
MsgBox UBound(testi, 1) ' 5
MsgBox UBound(testi, 2) ' 7
MsgBox UBound(testi, 3) ' 10

BadSource [30.11.2005 15:02:10]

#

Ehdin hieman miettimään tuota antamaani esimerkkiä. Tuota uuden rivin lisäämistä ei kannata tässä tapauksessa hoitaa noin. Jos teksti-tiedoston rivillä sattuu olemaan tyhjä (kaksi pilkkua peräkkäin) juuri tuolla kohdalla, josta "tyhjä" rivi tarkistetaan, niin uutta riviä ei lisätä, vaan rivin tiedot ylikirjoitetaan. Mieluummin käyttää vaikkapa Boolean-muuttujaa, joka vaihdetaan todeksi ensimmäisen kierroksen jälkeen.

Private Sub Command1_Click()
    Dim taulukko() As Variant
    Dim MuutKierrokset As Boolean
    Dim y As Integer

    'taulukon esittely, että sitä päästään jatkossa tarkastelemaan. Ensin "sarakkeet" ja sitten "rivit".
    'Järjestys tämä, sillä vain viimeistä dimensiota voi muuttaa dynaamisessa taulukossa.
    ReDim taulukko(0 To 3, 0 To 0)
    Open "c:\test.txt" For Input As #1

    Do While Not EOF(1)
        'Ekalla kierroksella ei tarvitse lisätä uutta "riviä", sillä vasta esitelty on vielä tyhjä
        If MuutKierrokset Then ReDim Preserve taulukko(0 To 3, 0 To UBound(taulukko, 2) + 1)
        MuutKierrokset = True 'lopuilla kierroksilla uusi "rivi" lisätään
        For y = 0 To 3
            Input #1, taulukko(y, UBound(taulukko, 2))
        Next y
    Loop

    Close #1
End Sub

Sinis [30.11.2005 15:35:25]

#

"...sillä vain viimeistä dimensiota voi muuttaa dynaamisessa taulukossa."

Ihme kun ei väkerrykset toimineet...

Ja kiitokset myös Antille rautalangan vääntämisestä.

Kun tässä on kuitenkin jo jonkin matkaa menty perse edellä puuhun niin kysäisenpä, onko käytännössä mitään merkitystä käyttää dynaamisia taulukoita esim. tapauksessa, jossa rivimäärä on joitain tuhansia? Määrittelee alussa taulukon kooksi esim. (1 to 5000, 1 to 4) ja sillä selvä vai? Rivimäärän lasku silmukan sisään. Metsäänkö menossa?

Antti Laaksonen [30.11.2005 15:56:59]

#

Voit ihan hyvin määritellä saman tien riittävän ison taulukon, jos esim. rivejä on varmasti korkeintaan 5000.

tuomas [30.11.2005 21:17:20]

#

Kannattaa mieluummin määritellä taulukon koko niiden rivien määrän mukaan. Kuluttaa vähemmän muistia ja eliminoi mahdollisen virhetilanteen, jossa yritetään viitata taulukon ulkopuolelle.

Ja koska käsittelet tekstitiedostoa, kannattaa taulukot määritellä string tyyppisiksi, variant kun kuluttaa muistia paljon enemmän ja on paljon hitaampi käsitellä.


Sivun alkuun

Vastaus

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

Tietoa sivustosta