Hva er en feil som ikke samsvarer med typen?
En feilmelding kan ofte oppstå når du kjører VBA -koden. Feilen vil stoppe koden din fra å kjøre fullstendig og flagge opp ved hjelp av en meldingsboks som denne feilen må sorteres ut
Vær oppmerksom på at hvis du ikke har testet koden din fullt ut før distribusjon til brukere, vil denne feilmeldingen være synlig for brukerne og føre til et stort tap av tillit til Excel -applikasjonen din. Dessverre gjør brukerne ofte veldig særegne ting med en applikasjon og er ofte ting du som utvikler aldri vurderte.
Det oppstår en feil med feil i typen fordi du har definert en variabel ved bruk av Dim -setningen som en bestemt type, f.eks. heltall, dato og koden din prøver å tilordne en verdi til variabelen som ikke er akseptabel, f.eks. tekststreng tilordnet en heltallsvariabel som i dette eksemplet:
Her er et eksempel:
Klikk på Debug og den krenkende linjen med kode vil bli markert med gult. Det er ikke noe alternativ på popup-vinduet for feil å fortsette, siden dette er en stor feil og det er ingen måte at koden kan kjøre videre.
I dette spesielle tilfellet er løsningen å endre Dim -setningen til en variabeltype som fungerer med verdien du tilordner variabelen. Koden vil fungere hvis du endrer variabeltypen til ‘String’, og du vil sannsynligvis også endre variabelnavnet.
For å endre variabeltypen må du imidlertid tilbakestille prosjektet, og du må kjøre koden igjen fra begynnelsen av igjen, noe som kan være veldig irriterende hvis en lang prosedyre er involvert
Uoverensstemmelse feil forårsaket av regnearkberegning
Eksemplet ovenfor er en veldig enkel måte for hvordan en feilmatchingsfeil kan oppstå, og i dette tilfellet kan den lett utbedres
Imidlertid er årsaken til mismatch -feil vanligvis langt dypere enn dette, og er ikke så åpenbar når du prøver å feilsøke koden din.
Anta som et eksempel at du har skrevet kode for å hente en verdi i en bestemt posisjon i et regneark, og den inneholder en beregningsavhengig andre celler i arbeidsboken (B1 i dette eksemplet)
Regnearket ser ut som dette eksemplet, med en formel for å finne et bestemt tegn i en tekststreng
Fra brukerens synspunkt er celle A1 fritt format, og de kan angi hvilken som helst verdi de vil. Formelen leter imidlertid etter en forekomst av tegnet 'B', og i dette tilfellet blir den ikke funnet, så celle B1 har en feilverdi.
Testkoden nedenfor gir en feilmelding fordi feil verdi er angitt i celle A1
1234 | Sub TestMismatch ()Dim MyNumber Som HeltallMyNumber = Ark ("Ark1"). Område ("B1"). VerdiSlutt Sub |
Verdien i celle B1 har produsert en feil fordi brukeren har lagt inn tekst i celle A1 som ikke samsvarer med det som var forventet, og den inneholder ikke tegnet ‘B’
Koden prøver å tilordne verdien til variabelen 'MyNumber' som er definert for å forvente et helt tall, og så får du en feilmelding.
Dette er et av disse eksemplene der nøye kontroll av koden din ikke vil gi svaret. Du må også se på regnearket hvor verdien kommer fra for å finne ut hvorfor dette skjer.
Problemet er faktisk på regnearket, og formelen i B1 må endres slik at feilverdier behandles. Du kan gjøre dette ved å bruke "IFERROR" -formelen for å gi en standardverdi på 0 hvis søketegnet ikke blir funnet
Du kan deretter inkludere kode for å se etter en nullverdi, og for å vise en advarsel til brukeren om at verdien i celle A1 er ugyldig
12345678 | Sub TestMismatch ()Dim MyNumber Som HeltallMyNumber = Ark ("Ark1"). Område ("B1"). TekstHvis MyNumber = 0 DaMsgBox "Verdi i celle A1 er ugyldig", vbCriticalAvslutt SubSlutt omSlutt Sub |
Du kan også bruke datavalidering (gruppen Dataverktøy på fanen Data på båndet) på regnearket for å stoppe brukeren med å gjøre hva de liker og forårsake feil i regnearket i utgangspunktet. Bare la dem skrive inn verdier som ikke forårsaker feil i regnearket.
Du kan skrive VBA -kode basert på Endre -hendelsen i regnearket for å kontrollere hva som er lagt inn.
Lås og passordbeskytt også regnearket, slik at ugyldige data ikke kan legges inn
Uoverensstemmelse feil forårsaket av angitte celleverdier
Uoverensstemmelsesfeil kan skyldes koden din ved å hente inn normale verdier fra et regneark (ikke-feil), men der brukeren har angitt en uventet verdi f.eks. en tekstverdi når du ventet et tall. De kan ha bestemt seg for å sette inn en rad innenfor et tallområde, slik at de kan sette en lapp i en celle som forklarer noe om tallet. Tross alt har brukeren ingen anelse om hvordan koden din fungerer, og at de nettopp har kastet det hele ut av kilter ved å skrive inn notatet.
Eksempelkoden nedenfor lager en enkel matrise kalt 'MyNumber' definert med heltallsverdier
Koden gjentar seg deretter gjennom et område av cellene fra A1 til A7, og tildeler celleverdiene i matrisen ved å bruke en variabel 'Coun' for å indeksere hver verdi
Når koden når tekstverdien, forårsakes en feilmelding av dette, og alt stopper
Ved å klikke på 'Debug' i feilmeldingen, vil du se kodelinjen som har problemet markert med gult. Ved å holde markøren over en forekomst av variabelen "Coun" i koden, vil du kunne se verdien av "Coun" der koden mislyktes, som i dette tilfellet er 5
Når du ser på regnearket, vil du se at 5th cell down har tekstverdien, og dette har forårsaket at koden mislyktes
Du kan endre koden din ved å sette inn en tilstand som sjekker etter en numerisk verdi først før du legger til celleverdien i matrisen
12345678910111213 | Sub TestMismatch ()Dim MyNumber (10) As Integer, Coun As IntegerTelle = 1GjøreHvis Coun = 11, avslutt DoIf IsNumeric (Sheets ("sheet1"). Cells (Coun, 1) .Value) ThenMyNumber (Coun) = Sheets ("sheet1"). Celler (Coun, 1) .ValueEllersMyNumber (Coun) = 0Slutt omCoun = Coun + 1LøkkeSlutt Sub |
Koden bruker "IsNumeric" -funksjonen for å teste om verdien faktisk er et tall, og hvis den er det, legger den den inn i matrisen. Hvis det ikke er tall, angir det verdien på null.
Dette sikrer at matrisindeksen holdes på linje med cellelinjenumrene i regnearket.
Du kan også legge til kode som kopierer den opprinnelige feilverdien og posisjonsdetaljene til et "Feil" -ark, slik at brukeren kan se hva de har gjort feil når koden din kjøres.
Den numeriske testen bruker hele koden for cellen så vel som koden for å tildele verdien til matrisen. Du kan argumentere for at denne bør tilordnes en variabel for ikke å gjenta den samme koden, men problemet er at du må definere variabelen som en ‘variant’, noe som ikke er det beste å gjøre.
Du trenger også datavalidering på regnearket og for å passordbeskytte regnearket. Dette forhindrer brukeren i å sette inn rader og legge inn uventede data.
Uoverensstemmelsesfeil forårsaket av å kalle en funksjon eller en underrutine ved hjelp av parametere
Når en funksjon kalles, sender du vanligvis parametere til funksjonen ved hjelp av datatyper som allerede er definert av funksjonen. Funksjonen kan være en som allerede er definert i VBA, eller det kan være en brukerdefinert funksjon som du har bygd selv. Noen ganger kan en underrutine også kreve parametere
Hvis du ikke holder deg til konvensjonene for hvordan parameterne overføres til funksjonen, får du en feilmelding
12345678 | Sub CallFunction ()Dim Ret As IntegerRet = MyFunction (3, "test")Slutt SubFunksjon MyFunction (N Som Heltall, T Som String) Som StringMyFunction = TSluttfunksjon |
Det er flere muligheter her for å få en feilmelding
Returvariabelen (Ret) er definert som et heltall, men funksjonen returnerer en streng. Så snart du kjører koden, vil den mislykkes fordi funksjonen returnerer en streng, og denne ikke kan gå inn i en heltallsvariabel. Interessant, ikke kjører Debug på denne koden ikke opp denne feilen.
Hvis du setter anførselstegn rundt den første parameteren som passeres (3), tolkes den som en streng, som ikke samsvarer med definisjonen av den første parameteren i funksjonen (heltall)
Hvis du gjør den andre parameteren i funksjonsanropet til en numerisk verdi, mislykkes det med feil samsvar fordi den andre parameteren i strengen er definert som en streng (tekst)
Uoverensstemmelse feil forårsaket av å bruke konverteringsfunksjoner i VBA feil
Det er en rekke konverteringsfunksjoner du kan bruke i VBA for å konvertere verdier til forskjellige datatyper. Et eksempel er 'CInt' som konverterer en streng som inneholder et tall til en heltallsverdi.
Hvis strengen som skal konverteres inneholder noen alfa -tegn, får du en feilmelding, selv om den første delen av strengen inneholder numeriske tegn og resten er alfa -tegn f.eks. '123abc'
Generell forebygging av feilfeil
Vi har sett i eksemplene ovenfor flere måter å håndtere potensielle mismatch -feil i koden din, men det er en rekke andre måter, selv om de kanskje ikke er de beste alternativene:
Definer variablene dine som Variant Type
En varianttype er standard variabeltype i VBA. Hvis du ikke bruker en Dim -setning for en variabel og bare begynner å bruke den i koden din, får den automatisk typen Variant.
En variantvariabel godtar alle typer data, enten det er et heltall, langt heltall, dobbelt presisjonsnummer, boolsk eller tekstverdi. Dette høres ut som en fantastisk idé, og du lurer på hvorfor alle ikke bare setter alle variablene sine til variant.
Variantdatatypen har imidlertid flere ulemper. For det første tar den opp mye mer minne enn andre datatyper. Hvis du definerer et veldig stort utvalg som variant, vil det svelge en enorm mengde minne når VBA -koden kjører, og kan lett forårsake ytelsesproblemer
For det andre er ytelsen generelt tregere enn hvis du bruker spesifikke datatyper. For eksempel, hvis du foretar komplekse beregninger ved hjelp av flytende desimaltall, vil beregningene bli betydelig tregere hvis du lagrer tallene som varianter, i stedet for doble presisjonsnummer
Å bruke varianttypen regnes som slurvet programmering, med mindre det er absolutt nødvendig for det.
Bruk OnError -kommandoen til å håndtere feil
OnError-kommandoen kan inkluderes i koden din for å håndtere feilfanging, slik at hvis en feil oppstår, ser brukeren en meningsfull melding i stedet for standard VBA-feil
1234567 | Sub ErrorTrap ()Dim MyNumber Som HeltallVed feil GoTo Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Feilen" og Err.Description & "har skjedd"Slutt Sub |
Dette forhindrer effektivt at feilen stopper problemfri kjøring av koden og lar brukeren komme seg rent fra feilsituasjonen.
Err_Handler -rutinen kan vise ytterligere informasjon om feilen og hvem du kan kontakte om den.
Fra et programmeringssynspunkt er det ganske vanskelig å finne kodelinjen feilen er på når du bruker en rutine for håndtering av feil. Hvis du går gjennom koden ved å bruke F8, så snart den krenkende linjen er kjørt, hopper den til feilhåndteringsrutinen, og du kan ikke kontrollere hvor den går galt.
En måte å unngå dette på er å sette opp en global konstant som er sann eller usann (boolsk) og bruke denne til å slå rutinen for feilhåndtering på eller av ved hjelp av en 'Hvis' -uttalelse. Alt du trenger å gjøre er å sette den globale konstanten til Falsk når du vil teste feilen, og feilbehandleren vil ikke lenger fungere.
1 | Global Const ErrHandling = Falsk |
1234567 | Sub ErrorTrap ()Dim MyNumber Som HeltallHvis ErrHandling = True Then On Error Gå til Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Feilen" og Err.Description & "har skjedd"Slutt Sub |
Det eneste problemet med dette er at det lar brukeren komme seg etter feilen, men resten av koden i delrutinen kjøres ikke, noe som kan ha enorme konsekvenser senere i applikasjonen
Ved å bruke det tidligere eksemplet på sløyfe gjennom et utvalg av celler, ville koden komme til celle A5 og treffe feilmeldingen. Brukeren vil se en meldingsboks som gir informasjon om feilen, men ingenting fra den cellen og fremover i området vil bli behandlet.
Bruk OnError -kommandoen for å undertrykke feil
Denne bruker kommandoen 'On Error Resume Next'. Dette er veldig farlig å inkludere i koden din, da det forhindrer at eventuelle senere feil vises. Dette betyr i utgangspunktet at når en kode kjøres, hvis en feil oppstår i en kodelinje, vil utførelsen bare gå til neste tilgjengelige linje uten å utføre feillinjen og fortsette som normalt.
Dette kan sortere ut en potensiell feilsituasjon, men det vil fortsatt påvirke alle fremtidige feil i koden. Du kan da tro at koden din er feilfri, men faktisk er den ikke det, og deler av koden din gjør ikke det du synes den burde gjøre.
Det er situasjoner der det er nødvendig å bruke denne kommandoen, for eksempel hvis du sletter en fil ved hjelp av 'Kill' -kommandoen (hvis filen ikke er tilstede, vil det være en feil), men feilfangingen bør alltid byttes tilbake umiddelbart etter der den potensielle feilen kan oppstå ved å bruke:
1 | Ved feil Gå til 0 |
I det tidligere eksemplet på looping gjennom en rekke celler, ved bruk av 'On Error Resume Next', vil dette gjøre det mulig for sløyfen å fortsette, men cellen som forårsaker feilen vil ikke bli overført til matrisen, og array -elementet for den aktuelle indeksen vil ha en nullverdi.
Konvertering av data til en datatype for å matche erklæringen
Du kan bruke VBA -funksjoner til å endre datatypen for innkommende data slik at den samsvarer med datatypen til den mottakende variabelen.
Du kan gjøre dette når du sender parametere til funksjoner. For eksempel, hvis du har et tall som er inneholdt i en strengvariabel og du vil sende det som et tall til en funksjon, kan du bruke CInt
Det er en rekke av disse konverteringsfunksjonene som kan brukes, men her er de viktigste:
CInt - konverterer en streng som har en numerisk verdi (under + eller - 32 768) til en heltallsverdi. Vær oppmerksom på at dette avkorter eventuelle desimaltegn
CLng - Konverterer en streng som har en stor numerisk verdi til et langt heltall. Desimalpunkt er avkortet.
CDbl - Konverterer en streng som holder et flytende desimaltegn til et dobbelt presisjonsnummer. Inkluderer desimaltegn
CDate - Konverterer en streng som holder en dato til en datovariabel. Avhenger delvis av innstillingene i Windows Kontrollpanel og lokaliteten din på hvordan datoen tolkes
CStr - Konverterer en numerisk eller datoverdi til en streng
Når du konverterer fra en streng til et tall eller en dato, må strengen ikke inneholde noe annet enn tall eller en dato. Hvis det finnes alfa -tegn, vil dette føre til en feilmelding. Her er et eksempel som vil gi en feilmelding:
123 | Sub Test ()MsgBox CInt ("123abc")Slutt Sub |
Test av variabler i koden din
Du kan teste en variabel for å finne ut hvilken datatype det er før du tilordner den til en variabel av en bestemt type.
For eksempel kan du sjekke en streng for å se om den er numerisk ved å bruke "IsNumeric" -funksjonen i VBA
1 | MsgBox IsNumeric ("123test") |
Denne koden vil returnere False fordi selv om strengen begynner med numeriske tegn, inneholder den også tekst, så den mislykkes i testen.
1 | MsgBox IsNumeric ("123") |
Denne koden returnerer True fordi den er alle numeriske tegn
Det er en rekke funksjoner i VBA for å teste for forskjellige datatyper, men disse er de viktigste:
IsNumeric - tester om et uttrykk er et tall eller ikke
IsDate - tester om et uttrykk er en dato eller ikke
IsNull - tester om et uttrykk er null eller ikke. En nullverdi kan bare settes inn i et variantobjekt, ellers får du en feilmelding "Ugyldig bruk av null". En meldingsboks returnerer en nullverdi hvis du bruker den til å stille et spørsmål, så returvariabelen må være en variant. Husk at enhver beregning som bruker en nullverdi alltid vil returnere resultatet av null.
IsArray - tester om uttrykket representerer en matrise eller ikke
IsEmpty - tester om uttrykket er tomt eller ikke. Vær oppmerksom på at tomt ikke er det samme som null. En variabel er tom når den først defineres, men den er ikke en nullverdi
Overraskende nok er det ingen funksjon for IsText eller IsString, noe som ville være veldig nyttig
Objekter og feilfeil
Hvis du bruker objekter som et område eller et ark, vil du få en feilmelding ved kompileringstidspunktet, ikke ved kjøretid, noe som gir deg en behørig advarsel om at koden din ikke kommer til å fungere
123456 | Sub TestRange ()Dim MyRange As Range, I As LongAngi MyRange = Range ("A1: A2")Jeg = 10x = UseMyRange (I)Slutt Sub |
12 | Funksjon BrukMyRange (R som område)Sluttfunksjon |
Denne koden har en funksjon som kalles 'UseMyRange' og en parameter som overføres som et områdeobjekt. Parameteren som overføres er imidlertid et langt heltall som ikke samsvarer med datatypen.
Når du kjører VBA -kode, blir den umiddelbart kompilert, og du vil se denne feilmeldingen:
Den krenkende parameteren vil bli markert med en blå bakgrunn
Vanligvis, hvis du gjør feil i VBA -kode ved hjelp av objekter, vil du se denne feilmeldingen, i stedet for en melding om feil samsvar: