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
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
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.
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
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
"...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?
Voit ihan hyvin määritellä saman tien riittävän ison taulukon, jos esim. rivejä on varmasti korkeintaan 5000.
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ä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.