Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: Error 9: Subscript out of range

Sivun loppuun

miiro [14.05.2005 12:29:13]

#

No nyt koodini pukkaa erroria:
Koodini on tällainen:

Dim filu
filu = App.Path & "\" & App.EXEName & ".txt"

Form1.Hide

Open filu For Input As #1
Do
Input #1, luerivi
rivi = rivi + 1
Loop Until EOF(1)
Dim taulukko() As String
Dim rivit
rivit = 0
Do
rivit = rivit + 1
t$ = HaeRivi(rivit, filu)
taulukko = Split(t$, ",")
Dim enimi
Dim snimi
Dim ssana
Dim luokk
Dim email
enimi = taulukko(0)
snimi = taulukko(1)
ssana = taulukko(2)
luokk = taulukko(3)
email = taulukko(4)
Shell App.Path & "\" & App.EXEName & ".bat " & enimi & " " & snimi & " " & ssana & " " & luokk & " " & email, vbHide
Form1.Show
Frame2.Visible = False
Loop While rivit = rivi
End If

Ja rivi, mikä pukkaa erroria 9: Subscript out of range on tällainen:

enimi = taulukko(0)

sqwiik [14.05.2005 12:37:37]

#

Ennen suoraa sijoitusta kannattaa tarkistaa, sisältääkö taulukko lainkaan dataa ja mitkä sen rajat ovat. Nämä saa kätevästi UBound ja LBound-funktioilla. Ubound palauttaa taulukon maksimisolun arvon, LBound minimin. Virheestä voisi kuvitella että pienin soluindeksi olisi 1 eikä 0?

Antti Laaksonen [14.05.2005 12:40:40]

#

Virhe lienee siinä, että taulukon rajoja ei ole määritelty lainkaan. Kirjoita ne siis Dim-lauseeseen sulkujen sisään.

tuomas [14.05.2005 12:45:25]

#

Esittele kaikki muuttujat koodin alussa. Määrittely myös niiden tyypit. Avaat koodissa tiedoston muttet sulje sitä. Tuossa tiedoston lukemis koodissa et laita mitään talteen?
kokeile näin:

dim r as integer, filu as string, rivi as string, dim taulu(1 to 100) as string
open filu for input as #1
     do until eof(1)
        line input #1, rivi
        r = r + 1
        taulu(r) = rivi
        doevents
     loop
close #1

Koodin lopussa on End if vaikka et aloita if - lausetta missään.

miiro [14.05.2005 13:22:07]

#

Yksinkertaistin koodia ongelmien vuoksi, mutta rivi
taulu(r) = Split(t, ",")
valittaa. Type miscmatch eli error 13. Apua!

Form1.Hide

Dim r As Integer, t As String, filu As String, rivejatehty As Integer, rivi As Integer, taulu(1 To 1000) As String
filu = App.Path & "\" & App.EXEName & ".txt"
rivi = 2
Do
rivejatehty = rivejatehty + 1
t = HaeRivi(rivejatehty, filu)
taulu(r) = Split(t, ",")
Dim enimi
Dim snimi
Dim ssana
Dim luokk
Dim email
enimi = taulu(1)
snimi = taulu(2)
ssana = taulu(3)
luokk = taulu(4)
email = taulu(5)
Shell App.Path & "\" & App.EXEName & ".bat " & enimi & " " & snimi & " " & ssana & " " & luokk & " " & email, vbNormalFocus

Loop Until rivejatehty > rivi
Form1.Show

sqwiik [14.05.2005 13:49:20]

#

Rivin tulee olla muodossa taulu = Split(t$, ","). Lisäksi kannattaa laittaa kaikkien muuttujien määrittely (Dim-lauseet) funktion alkuun, ei silmukan sisään. Ja vielä, missä määrittelet t$-muuttujan? Koodissa käytteöet sekaisin t- ja t$-muuttujia...

miiro [14.05.2005 13:51:33]

#

Sqwiik: nyt se valittaa rivistä
taulu = Split(t, ",")
että Can't assign to tray ...
Ja tuossa alemmassa koodissa ei ole enää t$ :ä vaan pelkästään t.

sqwiik [14.05.2005 14:01:21]

#

Johtuu siitä, että taulu tulee alustaa dynaamisena taulukkona:

Dim taulu() As String

miiro [14.05.2005 14:04:10]

#

Mutta nyt tuli taas subscript out of range. Ja jos taulu():n muuttaa taulu(1 to 1000):ksi niin tulee taas Can't assign to tray...

Antti Laaksonen [14.05.2005 14:40:04]

#

Onko tarkoitus, että t-merkkijonossa olevat tiedot jaetaan taulukkoon? Kirjoita silloin:

taulu = Split(t, ",")

Kun käytetään Split-funktiota, taulukon rajoja ei määritellä etukäteen.

sqwiik [14.05.2005 14:54:07]

#

miiro: katso ennen sijoittamista, montako alkiota sijoietussa taulukossa on (UBound, LBound).

miiro [14.05.2005 14:55:46]

#

Eli? En osaa käyttää noita... En siis taulukkoja ollenkaan.

Gaxx [14.05.2005 15:13:13]

#

Kokeileppa tätä:

Dim data() As String
Dim tietojono As String

tietojono = "Sakari Soosi,Rapakujantie 3,12345 Uinula"
data = Split(tietojono, ",")

For c = 0 To 2
    Print data(c)
Next c

sqwiik [14.05.2005 15:16:18]

#

Oletko varma, että tiedostosta lukiessa rivi on oikeassa muodossa? Ja mitkä ovat taulukon rajat tuon Split-funktion jälkeen? Kokeile laittaa tuo Split-funkkarin jälkeen tarkistaaksesi taulukkosi ulottovuudet...

MsgBox "Taulukon alin alkio = " & Str(LBound(taulu)) & " ja korkein = " & Str(UBound(taulu))

...eli taulukkoa käytettäessä alkion indeksi ei saa olla alle LBoundin eikä yli UBoundin.

miiro [14.05.2005 15:46:51]

#

GAXX:

For c = 0 To 2
    Print data(c)
Next c

Toi tekee "periaatteessa" näin:

Print "Sakari Soosi"
Print "Rapakujantie 3"
Print "12345 Uinula"

Kun tarkoitus olisi tehdä näin:

Shell "tiedot.bat " & "Sakari Soosi" & " " & "Rapakujantie 3" & " " & "12345 Uinula"

Gaxx [14.05.2005 15:51:15]

#

miiro kirjoitti:

Kun tarkoitus olisi tehdä näin:
Shell "tiedot.bat " & "Sakari Soosi" & " " & "Rapakujantie 3" & " " & "12345 Uinula"

Ai tuoko ongelmasi olikin? Korvaa se for looppi sitten seuraavalla:

dim params as string
for c = 0 to 2
    params = params + " "
    params = params + data(c)
next c
shell "tiedot.bat" & params

miiro [14.05.2005 16:03:14]

#

Gaxx: Kiitos paljon, mutta tietoja on paljon. Tekstitiedostosta mistä haetaan on useampikin rivi. Nykyinen koodi:

Form1.Hide
Dim data() As String
Dim tietojono As String

rivit = 0
Do
filu = App.Path & "\" & App.EXEName & ".txt"
tietojono = HaeRivi(rivit, filu)
data = Split(tietojono, ",")
Dim params As String
For c = 0 To 4
    params = params + " "
    params = params + data(c)
Next c
Shell App.Path & "\" & App.EXEName & ".bat" & params
Form1.Show

Ja tekstifilu voi olla esim tällainen:

Jaska,Jokunen,Jas69ka,9,jaska.jokunen@kuumaposti.kom
Matti,Meikäläinen,Mat56ti,III,matti.meikalainen@jahhuu.kom
Joe,Doe,Joe123,I,j0ed0e@koomeili.kom

Eli miten saan noita monta kerrallaan
Jos käytän looppia, tulee aina error 9 elikkä Subscript out of range.

Gaxx [14.05.2005 16:11:23]

#

For c = LBound(data) To UBound(data)

Lykkää toi paikalleen

Edit: En tainnu ymmärtää kysymystäsi, vai?

miiro [14.05.2005 16:15:38]

#

Juu, et ymmärtänyt... en tarvitse tota ubound juttua kun tekstien pituudet on vakiona.

Mutta haluan monta riviä.
Siis että tapahtuisi näin:
Ohjelma käynnistää batin parametreilla Jaska Jokunen Sas69ka 9 jaska.jokunen@kuumaposti.kom
Sitten se avaa uuden batin komennoilla Matti Meikäläinen Mat56ti III Ja Niin Edelleen... (Vrt. alimpaan koodiruutuun mitä on)

Ohhoh. Ja nyt se valittaa taas vaikken muokannut mitään...äsken se vielä toimi. Siis koodi

Form1.Hide
Dim data() As String
Dim tietojono As String

filu = App.Path & "\" & App.EXEName & ".txt"
tietojono = HaeRivi(rivit, filu)
data = Split(tietojono, ",")
Dim params As String
For c = 0 To 4
    params = params + " "
    params = params + data(c)
Next c
Shell App.Path & "\" & App.EXEName & ".bat" & params
Form1.Show

Ja sitten valitus: Subscript out of range ja valituksen aiheena on tällakertaa rivi params = params + data(c)

Gaxx [14.05.2005 16:23:29]

#

Olisi varmaankin parasta, että lykkäät koko koodin nähtäville, sillä tuossa on vain osa siitä ja ratkaisevia hommia voi löytyä sen ulkopuolelta.

Eli pistä näytille koodia kunnolla — ainakin tuo looppi kokonaisuudessaan!

Edit: Muista alustaa se params funktio joka kerta!

miiro [14.05.2005 16:24:29]

#

Gaxx: tässäpä koko koodi.
Ohopps, nyt se ei valitakkaan siitä error 9:stä mutta näyttää vain yhden rivin. Syyllinen on tottakai
tietojono = HaeRivi(1, filu)
mutta miten saan haettua monta riviä?

Function HaeRivi(rivi, filu)

    On Error Resume Next 'jos tiedostoa ei ole
    FiluNro = FreeFile 'seuraava vapaa filu avattavaksi
    Open filu For Input As #FiluNro 'avataan tiedosto
    If Err = 53 Then Exit Function 'jos tiedostoa ei ole niin poistutaan
    Do Until EOF(1) 'luupataan tiedoston loppuun asti
        r = r + 1 'lisätään rivicountteria yhdellä
        Line Input #FiluNro, teksti 'haetaan yksi rivi tiedostosta
        If r = rivi Then 'jos ollaan sillä rivillä mikä pitää hakea...
            HaeRivi = teksti 'niin kerrotaan oikea rivi
            Close 'ja suletaan tiedosto
            Exit Function 'ja poistutaan
        End If
    Loop 'seuraava rivi...
    Close #FiluNro 'sule tiedosto. jos tässä kohtaa ollaan niin haettava rivinumero on niin iso ettei sitä ole tiedostossa, koska exit sub tuolla toteutuu jos löytyy...

End Function

Private Sub Command1_Click()
End
End Sub


Private Sub Form_Load()
Form1.Hide
Dim data() As String
Dim tietojono As String

filu = App.Path & "\" & App.EXEName & ".txt"
tietojono = HaeRivi(1, filu)
data = Split(tietojono, ",")
Dim params As String
For c = 0 To 4
    params = params + " "
    params = params + data(c)
Next c
Shell App.Path & "\" & App.EXEName & ".bat" & params
Form1.Show
End Sub

Gaxx [14.05.2005 16:35:38]

#

Jos tiedät, montako riviä pitää hakea, for looppi on kova sana. Jos taas et, do loop.

Eli:

Dim laskuri as integer
laskuri = 1 'do loopille
Do / For i = alku To loppu
-lue laskurin osoittama rivi tiedostosta
-Splittaa se
-Avaa tiedosto parametreillä
laskuri = laskuri + 1 'do loopille
Loop / Next i

Edit: Sähelisin vähän, pitäs olla korjattu

miiro [14.05.2005 16:43:23]

#

GAXX: Nyt on tällainen koodi

Form1.Hide
Dim data() As String
Dim tietojono As String
Dim laskuri As Integer
laskuri = 1 'do loopille
For i = 1 To 3
filu = App.Path & "\" & App.EXEName & ".txt"
tietojono = HaeRivi(1, filu)
data = Split(tietojono, ",")
Dim params As String
For c = 0 To 4
    params = params + " "
    params = params + data(c)
Next c
Shell App.Path & "\" & App.EXEName & ".bat" & params
laskuri = laskuri + 1 'do loopille
Next i
Form1.Show

Mutta
Shell App.Path & "\" & App.EXEName & ".bat" & params
on muka invalid procedure call or argument

sqwiik [14.05.2005 16:51:25]

#

...eikö olisi yksinkertaisempaa lukea rivi tiedostosta, parsia se ja kutsua Shell:iä?

Dim rivi As String, tiedot() As String, filu As Integer
filu = FreeFile
Open tiedosto For Input As #filu
  Do Until EOF(filu)
    Line Input #filu, rivi
    tiedot = Split(rivi, ",")
    Shell mitä_tässä_nyt_olikaan
  Loop
Close #1

...miksi turhaan monimutkasitaa asioita?
EDIT - rivin kuului olla string, ei integer ^^

miiro [14.05.2005 16:58:03]

#

sqwiik:

Line Input #filu, rivi

rivissä on vikaa; Type miscmatch

Ja edelleen joku voi yrittää korjata tuota "monimutkainsempaa" koodia

Gaxx [14.05.2005 17:07:46]

#

Päätimpä nyt sitten korjata tuon koodisi sellaiseksi, että se avaa jokaisen tiedostossa olevan rivin "avulla" batin.

Pitäis toimia :)

Option Explicit

Function HaeRivi(rivi As Integer, filu As String) As String

    On Error Resume Next 'jos tiedostoa ei ole
    Dim FiluNro As Integer
    Dim r As Integer
    Dim teksti As String
    FiluNro = FreeFile 'seuraava vapaa filu avattavaksi
    Open filu For Input As #FiluNro 'avataan tiedosto
    If Err = 53 Then Exit Function 'jos tiedostoa ei ole niin poistutaan
    Do Until EOF(1) 'luupataan tiedoston loppuun asti
        r = r + 1 'lisätään rivicountteria yhdellä
        Line Input #FiluNro, teksti 'haetaan yksi rivi tiedostosta
        If r = rivi Then 'jos ollaan sillä rivillä mikä pitää hakea...
            HaeRivi = teksti 'niin kerrotaan oikea rivi
            Close #FiluNro 'ja suletaan tiedosto
            Exit Function 'ja poistutaan
        End If
    Loop 'seuraava rivi...
    Close #FiluNro 'sule tiedosto. jos tässä kohtaa ollaan niin haettava rivinumero on niin iso ettei sitä ole tiedostossa, koska exit sub tuolla toteutuu jos löytyy...
    HaeRivi = "error"

End Function

Private Sub Command1_Click()
End
End Sub


Private Sub Form_Load()
    Dim filu As String
    Dim data() As String
    Dim tietojono As String
    Dim laskuri As Integer
    Dim c As Integer
    Dim params As String

    filu = App.Path & "\" & App.EXEName & ".txt"
    laskuri = 1

    Do
        tietojono = HaeRivi(laskuri, filu)
        If tietojono = "error" Then
            Exit Do
        End If

        data = Split(tietojono, ",")
        params = ""
        For c = LBound(data) To UBound(data)
            params = params + " "
            params = params + data(c)
        Next c
        Shell App.Path & "\" & App.EXEName & ".bat" & params
        laskuri = laskuri + 1
    Loop
End Sub

miiro [14.05.2005 17:14:39]

#

Gaxx: Kiitos

Dim kiitokset
Do
kiitokset = kiitokset + 1000000000000000000000000000000
Loop

Noin paljon, mitä tuo skripti sitten saakaan aikaiseksi...no joo, jumittaa koneen, mutta siis periaatteessa. Eli loputtomasti kiitoksia, Gaxx!


Sivun alkuun

Vastaus

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

Tietoa sivustosta