Sellainen pulma tilanne tuli eteen, että Excelissä pitäisi joko valita Sheet tai luoda sellainen sen mukaan, onko tietyn niminen jo olemassa vai ei.
Ajattelin, että se hoituisi helposti niin, että pistän For silmukan alkuun On Error GoTo lauselman. Sinne mentäisiin luomaan uusi taulukko, jos virhe tulee eli taulu puuttuu. Luomisen jälkeen sitten palattaisiin takaisin (taas se GoTo).
Moinen purkka nyt ei sitten suostu toimimaan kuin yhden kerran :( Kun samassa silmukassa tulee toinen virhe, tulee Erroria. Niin simppeli virhe ei ole kyseessä, että paluu tapahtuisi On error lauseen jälkeen :-/
Onko tuota mahdollista laittaa toimimaan vai pitääkö käyttää jotain muuta keinoa? Ilmeisestikään virheen jälkeen ei ole enää lupa palata takaisin :(
Edit: Vedetäämpäs takaisin... saattoi sittenkin olla vikana Option Explicitin puuttuminen. En ole ihan varma, kun aloin jo toisen tyyppistä ratkaisua kokeilemaan. Toki otan tiedon mieluusti vastaan, että oliko se virhe muuttujan nimessä vai eikö On Erroria voi laittaa silmukkaan niin, että sinne palattaisiin vielä.
Edit2: Näköjään tuo väärä muuttujan nimi ei ollut syypää, vaan on pakko kehitellä jokin toinen tapa toteuttaa tuo Sheetin lisäys/valinta toimen pide.
Laita koodia niin näkee millaisesta virityksestä on kyse.
Tässä siistitty versio siitä, mitä olin koittamassa:
Sub LataaTiedot() 'päivittää koko työkirjan tiedot Dim i As Integer 'rivien läpi käymiseen... Dim strTaulNimi(1 To 10) As String Dim intTaulNro As Integer: intTaulNro = 1 For i = 1 To 10 'Luetaan taulukoiden nimet strTaulNimi(intTaulNro) = Sheets("Info").Cells(i, 2).Text intTaulNro = intTaulNro + 1 Next For intTaulNro = 1 To 10 Jatkuu: On Error GoTo AddTaulu 'virheen sattuessa mennään lisäämään taulu Sheets(strTaulNimi(intTaulNro)).Select 'valitaan taulu -> virhe jos taulua ei ole 'Call Lataus 'taulukossa suoritettava web-kysely Next Exit Sub AddTaulu: 'taulun puuttuessa luodaan sellainen Sheets("MalliPohja").Copy After:=Sheets(2) ActiveSheet.Name = strTaulNimi(intTaulNro) ActiveSheet.Cells(1, 1) = strTaulNimi(intTaulNro) GoTo Jatkuu End Sub
Ensimmäinen puuttuva taulu syntyy ihan niinkuin sen kuvittelinkin tapahtuvan, mutta toista kertaa tuonne AddTauluun ei enää mennä, vaan tulee taulun puuttumisesta johtuva run-time error 9.
Edit: jos nyt ei silmät pahasti harita, niin tässä esimerkissäni riittäisi yksikin Integer-tyypin muuttuja. Alkuperäisessä tarvittiin useampia. Ehkä tuosta siltikin saa selvää... :)
Tuo ei toimi, koska silmukat eivät yksinkertaisesti toimi noin. Kun hyppäät pois silmukasta, silmukka katkeaa. Kun palaat takaisin, mennään koodista vaan suoraan läpi (arvatakseni; miten tahansa, en usko että tuo toimii).
Voit kuitenkin käyttää muutakin kuin Gotoa: kokeile paluuta Returnilla. Se siis palaa takaisin siihen missä virhe tapahtui. Yleisesti ottaen kannattaa välttää gotoa, ehkä tässäkin parempi olisi tehdä On Error Resume Next ja sitten tarkistaa mikä arvo Err.Numberilla on mahdollisen virherivin jälkeen (If Err.Number <> 0 Then virhe tapahtui). Goton käyttö rikkoo todella hyvin koodin rakenteen ja se löytyy VB:stä historiallisista syistä johtuen.
Kiitosta vain Merri. En ollut millään ymmärtänyt miten tuota resume nextiä pitäisi käyttää... nyt sen sitten kaiketi ymmärsin :)
Toimivaksi sain näin:
Sub LataaTiedot() 'päivittää koko työkirjan tiedot Dim i As Integer 'rivien läpi käymiseen... Dim strTaulNimi(1 To 10) As String Dim intTaulNro As Integer: intTaulNro = 1 For i = 1 To 10 'Luetaan taulukoiden nimet strTaulNimi(intTaulNro) = Cells(i, 2).Text intTaulNro = intTaulNro + 1 Next For intTaulNro = 1 To 10 On Error Resume Next Sheets(strTaulNimi(intTaulNro)).Select 'valitaan taulu -> virhe jos taulua ei ole If Err = 9 Then Sheets("MalliPohja").Copy After:=Sheets(2) ActiveSheet.Name = strTaulNimi(intTaulNro) ActiveSheet.Cells(1, 1) = strTaulNimi(intTaulNro) Err = 0 End If Next Exit Sub End Sub
Oikeassa varmasti, Merri, olet siinä ettei tuota alkuperäistä GoTo rakenteeseen perustuvaa voinut saada toimivaksi. Hiukan vain ihmetytti, miksi se tyssäsi jo ennenkö silmukan olisi tarvinut uudestaan alkaakaan. Yhden askeleen pidemmälle olisi kai päässyt nollaamalla err muuttujan tuossakin versiossa, vai olenko hakoteillä?
Siirrä On Error Resume Next ennen looppia, sitä on turha kymmentä kertaa laittaa toimintaan. Virheet voi tyhjätä Err.Clear -komennolla. Lisäksi käytä ihan vaan Err.Numberia, ihan noin yleisesti on hyvä aina laittaa tarkasti se mihin viittaa (eli älä käytä pelkkää Erriä tai sitten vastaavasti pelkkää Labelin nimeä ja niin edelleen). Parantaa koodin luettavuutta.
Tuon tavan käyttää pelkkää Erriä omaksuin lukemalla Putkan VB-opasta, siellä ei Numberia käytetä. Laitan sen Numberin sitten paikoilleen.
Selvisi muuten sekin, miksi If Err -lauselman alku ehtona kannattaa käyttää Err <> "". Tahtoopi bugit olla kohtalaisen hankalia löytää, jos ne vain jyrätään tylysti...
Mitäs ajatuksia tällainen virheen käsittely herättää:
On Error Resume Next 'blaa... blaa koodia If Err <> "" Then Select Case Err.Number Case 9 'suoritetaan se sheetin lisäys Case Else MsgBox (Err.Number & vbCrLf & Err.Description) End Select Err.Clear End If
E: tuohon alkuunkin taitaisi sopia se number. Eli tuon Err <> "" voisi korvata:
Err.Number <> 0
Aihe on jo aika vanha, joten et voi enää vastata siihen.