RulleRimfrost Skrevet 23. mars 2007 Del Skrevet 23. mars 2007 Hei. Siden det er lettere å lære VB her enn på Google, prøver jeg på denne Følgende kode looper gjennom worksheets i aktiv Excel arbeidsbok, og rekalkulerer alle celler med lysegul bakgrunn. Har dog et problem med at om den møter et tom ark (ws) kommer det en feilmelding om at den "ikke finner noen celler", og debugger går til linje 2 i denne koden... Finnes det en sjekk som kan flytte meg til "next ws" om ws.UsedRange ikke inneholder noen celler ? Noe ala "if ws.UsedRange = 0 Then Next ws" For Each ws In wb.Worksheets For Each cell In ws.UsedRange.SpecialCells(xlCellTypeConstants, 1) If cell.Value <> 0 And cell.Interior.ColorIndex = 19 _ Then cell.Value = cell.Value / kurs Next cell Next ws Lenke til kommentar
aadnk Skrevet 23. mars 2007 Del Skrevet 23. mars 2007 Først, endre koden din til følgende: For Each ws In wb.Worksheets For Each cell In GetSpecialCells(ws.UsedRange) If cell.Value <> 0 And cell.Interior.ColorIndex = 19 Then cell.Value = cell.Value / kurs End If Next Next Legg så til denne prosedyren i en tilgjengelig modul (helst den samme): Private Function GetSpecialCells(Range As Range) As Object ' Hopper over alle linjer som invokerer en feilmelding On Error Resume Next ' Ved å sette returverdien FØR den usikre koden kjører, kan vi ' forsikre oss at vi alltid vil returnere et objekt. Collection ' brukes bare ettersom den støtter IEnumVARIANT. Set GetSpecialCells = New Collection Set GetSpecialCells = Range.SpecialCells(xlCellTypeConstants, 1) End Function Lenke til kommentar
Harald Staff Skrevet 23. mars 2007 Del Skrevet 23. mars 2007 (endret) Hei igjen Dette er litt tuklete, men veldig nyttig. Det du gjør er å tilordne alle tallceller til en variabel mens du tillater at koden feiler en liten stund. Så sjekker du om variabelen inneholder noe i det hele tatt, hvilket den ikke gjør der tallceller ikke finnes. Sub test() Dim wb As Workbook Dim ws As Worksheet Dim MyRange As Range Dim cell As Range Set wb = ActiveWorkbook For Each ws In wb.Worksheets On Error Resume Next Set MyRange = Nothing Set MyRange = ws.UsedRange.SpecialCells(xlCellTypeConstants, 1) On Error GoTo 0 If Not MyRange Is Nothing Then For Each cell In MyRange 'If cell.Value <> 0 And cell.Interior.ColorIndex = 19 _ 'Then cell.Value = cell.Value / kurs Next cell Else 'MsgBox "Ingenting i " & ws.Name End If Next ws End Sub Jeg vet det tar litt tid å venne seg til en logikk a la If Not MyRange Is Nothing Then men så... HTH. Beste hilsen Harald Endret 23. mars 2007 av Harald Staff Lenke til kommentar
RulleRimfrost Skrevet 23. mars 2007 Forfatter Del Skrevet 23. mars 2007 Takker begge to. Jeg skal nok prøve å forstå det etterhvert, men akkurat nå tok jeg en klipp og lim, og det funket som en kule. VB er mer gøy enn man skulle tro. Kode : Klikk for å se/fjerne innholdet nedenfor Option ExplicitPrivate Sub UserForm_Initialize() 'Setter standardverier i input-skjemaet txtKurs.Value = "1,0000" With cboValg .AddItem "Svensk" .AddItem "Norsk" End With cboValg.Value = "Svensk" txtKurs.SetFocus End Sub Private Sub cmdAvslutt_click() Unload Me End Sub Private Sub cmdKonverter_click() Dim ws As Worksheet, wb As Workbook, cell As Range Dim valg As String, kurs As Double Set wb = ActiveWorkbook Set ws = ActiveSheet kurs = Me.txtKurs.Value valg = Me.cboValg.Value 'Om startbeløpene er svenske dividerer vi alle gule celler med kursen Select Case valg Case "Svensk" For Each ws In wb.Worksheets For Each cell In GetSpecialCells(ws.UsedRange) If cell.Value <> 0 And cell.Interior.ColorIndex = 19 Then cell.Value = cell.Value / kurs End If Next Next Me.cboValg = "Norsk" 'Om startbeløpene er norske multipliserer vi dem med kursen Case "Norsk" For Each ws In wb.Worksheets For Each cell In GetSpecialCells(ws.UsedRange) If cell.Value <> 0 And cell.Interior.ColorIndex = 19 Then cell.Value = cell.Value * kurs End If Next Next Me.cboValg = "Svensk" 'Just in case... Case Else MsgBox "Gyldig kurs - ikke funnet" End Select End Sub Private Function GetSpecialCells(Range As Range) As Object ' Hopper over alle linjer som invokerer en feilmelding On Error Resume Next ' Ved å sette returverdien FØR den usikre koden kjører, kan vi ' forsikre oss at vi alltid vil returnere et objekt. Collection ' brukes bare ettersom den støtter IEnumVARIANT. Set GetSpecialCells = New Collection Set GetSpecialCells = Range.SpecialCells(xlCellTypeConstants, 1) End Function Lenke til kommentar
RulleRimfrost Skrevet 23. mars 2007 Forfatter Del Skrevet 23. mars 2007 For ikke å ødelegge den vakre posten hiver jeg inn en dobbel her. Harald: Ser du benytter "On Error Resume Next" der jeg prøvde "if ws.UsedRange = 0 Then Next ws" (Miljøskadet da jeg lærer php parallelt) Vil "On Error" kunne overkjøre alle feil i en For-Each loop, og slik benyttes som sikkerhet i alle løkker som ikke skal reagere på exeptions (.. en slags "best practice" i VB) ? Lenke til kommentar
aadnk Skrevet 23. mars 2007 Del Skrevet 23. mars 2007 (endret) Vil "On Error" kunne overkjøre alle feil i en For-Each loop, og slik benyttes som sikkerhet i alle løkker som ikke skal reagere på exeptions (.. en slags "best practice" i VB) ? 8220335[/snapback] Problemet med On Error Resume Next er at den fører til at programmet hopper over linjen der en feil inntreffer, ikke blokken den definerer. La meg illustrere dette med et eksempel. La oss si en funksjon Bar alltid invokerer en feil. I følgende kode vil kodelinje Item.DoAction (som da vil referere til Foo) kjørt, selv om en muligens skulle tro programmet hopper over hele FOR EACH-kodeblokken: On Error Resume NextDim Item As Object Set Item = Foo For Each Item In Bar Item.DoAction Next Endret 23. mars 2007 av aadnk Lenke til kommentar
Harald Staff Skrevet 23. mars 2007 Del Skrevet 23. mars 2007 Jeg er ikke sikker på at jeg skjønner spørsmålet helt. On Error Resume Next gjør at programmet tillater feil -feil både som at jeg programmerer elendig og som at programmet bes å utføre meningsløse absurditeter. I det virkelige liv, hvor man ikke alltid kan forutse enhver tenkelig situasjon, utgjør resume next gjerne forskjellen mellom å gjøre dårlig arbeid eller å krasje. Noen ganger er det ene å foretrekke, andre ganger det andre. Ja, du kan sette On Error resume Next og så kode nærmest hvasomhelst. Du får et tregt og dårlig program, men krasje, det gjør det i hvert fall ikke. I kontrollerte forhold ber du programmet om å gjøre det umulige, og så sjekker du hvordan det gikk. Dermed vet du om påfunnet er umulig eller ikke, f.eks. i betydningen "hent alle tall i et miljø helt uten tall". Kommandoen On Error GoTo 0 nullstiller denne liberalistiske holdningen til påfunn -det krasjer altså ved senere feil. HTH. Beste hilsen Harald Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå