VBA - Type Mismatch (Run -time Error 13)

Hvad er en Type Mismatch -fejl?

En fejlpasning kan ofte opstå, når du kører din VBA -kode. Fejlen forhindrer din kode i at køre fuldstændigt og markeres ved hjælp af en meddelelsesboks, som denne fejl skal sorteres ud

Bemærk, at hvis du ikke har testet din kode fuldt ud før distribution til brugere, vil denne fejlmeddelelse være synlig for brugerne og forårsage et stort tab af tillid til din Excel -applikation. Desværre gør brugere ofte meget ejendommelige ting ved en applikation og er ofte ting, som du som udvikler aldrig overvejede.

Der opstår en fejl i typen, der ikke matcher, fordi du har defineret en variabel ved hjælp af Dim -sætningen som en bestemt type, f.eks. heltal, dato og din kode forsøger at tildele en værdi til variablen, som ikke er acceptabel f.eks. tekststreng tildelt en heltalsvariabel som i dette eksempel:

Her er et eksempel:

Klik på Debug, og den stødende kodelinje fremhæves med gult. Der er ingen mulighed for fejl pop op-vinduet for at fortsætte, da dette er en større fejl, og der er ingen måde, koden kan køre yderligere.

I dette særlige tilfælde er løsningen at ændre Dim -sætningen til en variabeltype, der fungerer med den værdi, du tildeler variablen. Koden fungerer, hvis du ændrer variabeltypen til 'String', og du vil sandsynligvis også gerne ændre variabelnavnet.

Hvis du ændrer variabeltypen, skal dit projekt imidlertid nulstilles, og du bliver nødt til at køre din kode igen lige fra begyndelsen igen, hvilket kan være meget irriterende, hvis en lang procedure er involveret

Fejl i uoverensstemmelse forårsaget af regnearksberegning

Ovenstående eksempel er meget simpelt om, hvordan en mismatch -fejl kan frembringes, og i dette tilfælde kan det let afhjælpes

Imidlertid er årsagen til mismatch -fejl normalt langt dybere end dette og er ikke så indlysende, når du forsøger at fejlsøge din kode.

Antag som et eksempel, at du har skrevet kode for at hente en værdi i en bestemt position på et regneark, og den indeholder en beregningsafhængig andre celler i projektmappen (B1 i dette eksempel)

Regnearket ligner dette eksempel med en formel til at finde et bestemt tegn i en tekststreng

Fra brugerens synspunkt er celle A1 frit format, og de kan indtaste enhver værdi, de vil. Formlen leder imidlertid efter en forekomst af karakteren 'B', og i dette tilfælde findes den ikke, så celle B1 har en fejlværdi.

Testkoden herunder vil producere en fejltilpasningsfejl, fordi der er angivet en forkert værdi i celle A1

1234 Sub TestMismatch ()Dim MyNumber som heltalMyNumber = Sheets ("Sheet1"). Range ("B1"). VærdiAfslut Sub

Værdien i celle B1 har givet en fejl, fordi brugeren har indtastet tekst i celle A1, som ikke er i overensstemmelse med det, der var forventet, og den ikke indeholder tegnet 'B'

Koden forsøger at tildele værdien til variablen 'MyNumber', som er defineret til at forvente et helt tal, og så får du en fejltilpasningsfejl.

Dette er et af disse eksempler, hvor omhyggelig kontrol af din kode ikke vil give svaret. Du skal også se på regnearket, hvor værdien kommer fra, for at finde ud af hvorfor dette sker.

Problemet er faktisk på regnearket, og formlen i B1 skal ændres, så fejlværdier behandles. Du kan gøre dette ved at bruge "IFERROR" -formlen til at angive en standardværdi på 0, hvis søgetegnet ikke findes

Du kan derefter indarbejde kode for at kontrollere, om der er en nulværdi, og for at vise en advarselsmeddelelse til brugeren om, at værdien i celle A1 er ugyldig

12345678 Sub TestMismatch ()Dim MyNumber som heltalMyNumber = Sheets ("Sheet1"). Range ("B1"). TekstHvis MyNumber = 0 SåMsgBox "Værdi ved celle A1 er ugyldig", vbCriticalAfslut SubAfslut HvisAfslut Sub

Du kan også bruge datavalidering (gruppen Dataværktøjer på fanen Data på båndet) på regnearket til at stoppe brugeren med at gøre, hvad de kunne lide og forårsage regnearkfejl i første omgang. Tillad dem kun at indtaste værdier, der ikke forårsager fejl i regnearket.

Du kan skrive VBA -kode baseret på ændringen i regnearket for at kontrollere, hvad der er indtastet.

Lås og adgangskode beskytter også regnearket, så de ugyldige data ikke kan indtastes

Uoverensstemmelsesfejl forårsaget af indtastede celleværdier

Uoverensstemmelsesfejl kan forårsages i din kode ved at indsætte normale værdier fra et regneark (ikke-fejl), men hvor brugeren har indtastet en uventet værdi f.eks. en tekstværdi, da du ventede et tal. De har muligvis besluttet at indsætte en række inden for et talområde, så de kan sætte en note i en celle, der forklarer noget om tallet. Brugeren har jo ingen idé om, hvordan din kode fungerer, og at de lige har smidt det hele ud af kilter ved at indtaste deres note.

Eksempelkoden herunder skaber et simpelt array kaldet 'MyNumber' defineret med heltalsværdier

Koden gentager derefter gennem et område af cellerne fra A1 til A7 og tildeler celleværdierne til arrayet ved hjælp af en variabel 'Coun' til at indeksere hver værdi

Når koden når tekstværdien, skyldes en mismatch -fejl dette, og alt stopper

Ved at klikke på 'Debug' i fejl pop-up, vil du se den kodelinje, der har problemet markeret med gult. Ved at holde markøren over enhver forekomst af variablen 'Coun' inden for koden, vil du kunne se værdien af ​​'Coun', hvor koden er mislykket, hvilket i dette tilfælde er 5

Når du ser på regnearket, vil du se, at 5th cell down har tekstværdien, og dette har fået koden til at mislykkes

Du kan ændre din kode ved at indsætte en betingelse, der kontrollerer en numerisk værdi først, før du tilføjer celleværdien til arrayet

12345678910111213 Sub TestMismatch ()Dim MyNumber (10) As Integer, Coun As IntegerTæller = 1GørHvis Coun = 11 Så afslut DoHvis IsNumeric (Sheets ("ark1"). Celler (Coun, 1) .Værdi) SåMyNumber (Coun) = Sheets ("sheet1"). Celler (Coun, 1). VærdiAndetMyNumber (Coun) = 0Afslut HvisCoun = Coun + 1SløjfeAfslut Sub

Koden bruger funktionen 'IsNumeric' til at teste, om værdien faktisk er et tal, og hvis det er det, indtaster den det i arrayet. Hvis det ikke er et tal, indtaster det værdien nul.

Dette sikrer, at matrixindekset holdes på linje med celle -rækkenumrene i regnearket.

Du kan også tilføje kode, der kopierer den oprindelige fejlværdi og placeringsoplysninger til et 'Fejl' -ark, så brugeren kan se, hvad de har gjort forkert, når din kode køres.

Den numeriske test bruger den fulde kode for cellen samt koden til at tildele værdien til arrayet. Du kan argumentere for, at denne skal tildeles en variabel for ikke at blive ved med at gentage den samme kode, men problemet er, at du bliver nødt til at definere variablen som en 'variant', hvilket ikke er det bedste at gøre.

Du har også brug for datavalidering på regnearket og for at beskytte regnearket med en adgangskode. Dette forhindrer brugeren i at indsætte rækker og indtaste uventede data.

Uoverensstemmelsesfejl forårsaget af opkald til en funktion eller underrutine ved hjælp af parametre

Når en funktion kaldes, sender du normalt parametre til funktionen ved hjælp af datatyper, der allerede er defineret af funktionen. Funktionen kan være en, der allerede er defineret i VBA, eller det kan være en brugerdefineret funktion, som du selv har bygget. En underrutine kan også nogle gange kræve parametre

Hvis du ikke holder dig til konventionerne om, hvordan parametrene overføres til funktionen, får du en fejlpasning

12345678 UnderopkaldFunktion ()Dim Ret As IntegerRet = MyFunction (3, "test")Afslut SubFunktion MyFunction (N som heltal, T som streng) Som strengMyFunction = TAfslut funktion

Der er flere muligheder her for at få en mismatch -fejl

Returvariablen (Ret) defineres som et helt tal, men funktionen returnerer en streng. Så snart du kører koden, mislykkes den, fordi funktionen returnerer en streng, og denne ikke kan gå ind i en heltalsvariabel. Interessant nok kører denne fejl ikke ved at køre Debug på denne kode.

Hvis du sætter anførselstegn omkring den første parameter, der sendes (3), fortolkes det som en streng, der ikke matcher definitionen af ​​den første parameter i funktionen (heltal)

Hvis du laver den anden parameter i funktionsopkaldet til en numerisk værdi, mislykkes det med et uoverensstemmelse, fordi den anden parameter i strengen er defineret som en streng (tekst)

Uoverensstemmelsesfejl forårsaget af forkert brug af konverteringsfunktioner i VBA

Der er en række konverteringsfunktioner, som du kan bruge i VBA til at konvertere værdier til forskellige datatyper. Et eksempel er 'CInt', der konverterer en streng, der indeholder et tal, til en heltalsværdi.

Hvis strengen, der skal konverteres, indeholder et alfa -tegn, får du en fejltilpasningsfejl, selvom den første del af strengen indeholder numeriske tegn, og resten er alfa -tegn f.eks. '123abc'

Generel forebyggelse af uoverensstemmelsesfejl

Vi har set i eksemplerne ovenfor flere måder at håndtere potentielle mismatchfejl i din kode, men der er en række andre måder, selvom de muligvis ikke er de bedste muligheder:

Definer dine variabler som Variant Type

En varianttype er standardvariabeltypen i VBA. Hvis du ikke bruger en Dim -sætning til en variabel og blot begynder at bruge den i din kode, får den automatisk typen Variant.

En variantvariabel accepterer enhver form for data, uanset om det er et helt tal, langt heltal, dobbelt præcisionsnummer, boolsk eller tekstværdi. Dette lyder som en vidunderlig idé, og du spekulerer på, hvorfor alle ikke bare sætter alle deres variabler til variant.

Variantdatatypen har dog flere ulemper. For det første fylder det langt mere hukommelse end andre datatyper. Hvis du definerer et meget stort array som variant, vil det sluge en enorm mængde hukommelse, når VBA -koden kører, og det kan let forårsage ydelsesproblemer

For det andet er det generelt langsommere i ydeevne, end hvis du bruger bestemte datatyper. For eksempel, hvis du foretager komplekse beregninger ved hjælp af flydende decimaltal, vil beregningerne være betydeligt langsommere, hvis du gemmer tallene som varianter frem for dobbelte præcisionsnumre

Brug af varianttypen betragtes som sjusket programmering, medmindre der er en absolut nødvendighed for det.

Brug kommandoen OnError til at håndtere fejl

OnError-kommandoen kan inkluderes i din kode for at håndtere fejlfangning, så hvis der nogensinde opstår en fejl, ser brugeren en meningsfuld besked i stedet for standard VBA-fejl pop-up

1234567 Sub ErrorTrap ()Dim MyNumber som heltalVed fejl GoTo Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Fejlen" & Err.Description & "er opstået"Afslut Sub

Dette forhindrer effektivt fejlen i at stoppe den gnidningsløse drift af din kode og giver brugeren mulighed for at komme sig rent efter fejlsituationen.

Err_Handler -rutinen kunne vise yderligere oplysninger om fejlen, og hvem de skal kontakte om den.

Fra et programmeringssynspunkt er det ret vanskeligt at finde den kodelinje, fejlen er på, når du bruger en rutine til håndtering af fejl. Hvis du træder igennem koden ved hjælp af F8, så snart den overtrædende kodelinje køres, springer den til fejlhåndteringsrutinen, og du kan ikke kontrollere, hvor den går galt.

En vej udenom dette er at oprette en global konstant, der er sand eller falsk (boolsk) og bruge denne til at slå fejlhåndteringsrutinen til eller fra ved hjælp af en 'If' -sætning. Når du vil teste fejlen, skal du blot indstille den globale konstant til Falsk, og fejlhåndtereren fungerer ikke længere.

1 Global Const ErrHandling = Falsk
1234567 Sub ErrorTrap ()Dim MyNumber som heltalHvis ErrHandling = Sand, derefter på fejl Gå til Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Fejlen" & Err.Description & "er opstået"Afslut Sub

Det eneste problem med dette er, at det giver brugeren mulighed for at gendanne fra fejlen, men resten af ​​koden inden for underrutinen køres ikke, hvilket kan have enorme konsekvenser senere i applikationen

Ved at bruge det tidligere eksempel på looping gennem et område af celler, ville koden komme til celle A5 og ramte den fejlparrede fejl. Brugeren ville se en meddelelsesboks med oplysninger om fejlen, men intet fra den celle og frem i området ville blive behandlet.

Brug kommandoen OnError til at undertrykke fejl

Dette bruger kommandoen 'On Error Resume Next'. Dette er meget farligt at inkludere i din kode, da det forhindrer eventuelle efterfølgende fejl i at blive vist. Dette betyder dybest set, at når din kode udføres, og hvis der opstår en fejl i en kodelinje, vil udførelsen bare flytte til den næste tilgængelige linje uden at udføre fejllinjen og fortsætte som normalt.

Dette kan afhjælpe en potentiel fejlsituation, men det vil stadig påvirke enhver fremtidig fejl i koden. Du tror måske, at din kode er fejlfri, men det er den faktisk ikke, og dele af din kode gør ikke, hvad du synes, den burde gøre.

Der er situationer, hvor det er nødvendigt at bruge denne kommando, f.eks. Hvis du sletter en fil ved hjælp af kommandoen 'Dræb' (hvis filen ikke er til stede, vil der være en fejl), men fejlopsamlingen skal altid skiftes tilbage umiddelbart efter, hvor den potentielle fejl kan opstå ved hjælp af:

1 Ved fejl Gå til 0

I det tidligere eksempel på looping gennem en række celler ved hjælp af 'On Error Resume Next', ville dette gøre det muligt for loop'en at fortsætte, men cellen, der forårsager fejlen, ville ikke blive overført til arrayet, og array -elementet for det pågældende indeks ville have en nullværdi.

Konvertering af data til en datatype, der matcher erklæringen

Du kan bruge VBA -funktioner til at ændre datatypen for indgående data, så den matcher datatypen for den modtagende variabel.

Du kan gøre dette, når parametre overføres til funktioner. Hvis du f.eks. Har et tal, der er indeholdt i en strengvariabel, og du vil sende det som et tal til en funktion, kan du bruge CInt

Der er en række af disse konverteringsfunktioner, der kan bruges, men her er de vigtigste:

CInt - konverterer en streng, der har en numerisk værdi (under + eller - 32.768) til en heltalsværdi. Vær opmærksom på, at dette afkorter eventuelle decimaltegn fra

CLng - Konverterer en streng, der har en stor numerisk værdi, til et langt heltal. Decimaltegn afkortes.

CDbl - Konverterer en streng, der holder et flydende decimaltal, til et dobbelt præcisionsnummer. Inkluderer decimaltegn

CDate - Konverterer en streng, der indeholder en dato, til en datovariabel. Delvis afhænger af indstillinger i Windows Kontrolpanel og din lokalitet om, hvordan datoen fortolkes

CStr - Konverterer en numerisk eller datoværdi til en streng

Ved konvertering fra en streng til et tal eller en dato må strengen ikke indeholde andet end tal eller en dato. Hvis der findes alfakarakterer, vil dette forårsage en fejlpasning. Her er et eksempel, der vil producere en mismatch -fejl:

123 Subtest ()MsgBox CInt ("123abc")Afslut Sub

Test af variabler inden for din kode

Du kan teste en variabel for at finde ud af, hvilken datatype det er, før du tildeler den til en variabel af en bestemt type.

For eksempel kan du kontrollere en streng for at se, om den er numerisk ved hjælp af funktionen 'IsNumeric' i VBA

1 MsgBox IsNumeric ("123test")

Denne kode returnerer Falsk, fordi selvom strengen begynder med numeriske tegn, indeholder den også tekst, så den mislykkes testen.

1 MsgBox IsNumeric ("123")

Denne kode returnerer True, fordi den alle er numeriske tegn

Der er en række funktioner i VBA, der skal testes for forskellige datatyper, men disse er de vigtigste:

IsNumeric - tester, om et udtryk er et tal eller ej

IsDate - tester, om et udtryk er en dato eller ej

IsNull - tester, om et udtryk er null eller ej. En nullværdi kan kun sættes i et variantobjekt, ellers får du fejlen 'Ugyldig brug af null'. En meddelelsesboks returnerer en nullværdi, hvis du bruger den til at stille et spørgsmål, så returvariablen skal være en variant. Husk, at enhver beregning, der anvender en nullværdi, altid vil returnere resultatet af null.

IsArray - tester, om udtrykket repræsenterer en matrix eller ej

IsEmpty - tester om udtrykket er tomt eller ej. Bemærk, at tom ikke er det samme som nul. En variabel er tom, når den først defineres, men den er ikke en nullværdi

Overraskende nok er der ingen funktion til IsText eller IsString, hvilket ville være virkelig nyttigt

Objekter og fejlmatch

Hvis du bruger objekter som f.eks. Et område eller et ark, får du en fejltilpasningsfejl på kompileringstidspunktet, ikke ved løbetid, hvilket giver dig en behørig advarsel om, at din kode ikke fungerer

123456 Sub TestRange ()Dim MyRange As Range, I As LongIndstil MyRange = Range ("A1: A2")Jeg = 10x = UseMyRange (I)Afslut Sub
12 Funktion BrugMyRange (R som område)Afslut funktion

Denne kode har en funktion kaldet 'UseMyRange' og en parameter videregivet som et områdeobjekt. Den parameter, der overføres, er imidlertid et langt heltal, der ikke matcher datatypen.

Når du kører VBA -kode, kompileres den straks, og du får vist denne fejlmeddelelse:

Den krænkende parameter vil blive fremhævet med en blå baggrund

Generelt, hvis du laver fejl i VBA -kode ved hjælp af objekter, vil du se denne fejlmeddelelse i stedet for en type mismatch -meddelelse:

Du vil bidrage til udviklingen af ​​hjemmesiden, at dele siden med dine venner

wave wave wave wave wave