VBA - nepodudaranje vrste (pogreška tijekom izvođenja 13)

Što je pogreška neusklađenosti tipa?

Pogreška neusklađenosti često se može pojaviti prilikom pokretanja VBA koda. Pogreška će zaustaviti vaš kôd u potpunosti izvođenje i označiti ga pomoću okvira s porukom koju je potrebno riješiti

Imajte na umu da će, ako niste u potpunosti testirali svoj kôd prije distribucije korisnicima, ova poruka o pogrešci biti vidljiva korisnicima i uzrokovati veliki gubitak povjerenja u vašu Excel aplikaciju. Nažalost, korisnici često rade vrlo neobične stvari za aplikaciju i često su to stvari koje vi kao programer nikada niste uzeli u obzir.

Pojavljuje se pogreška neusklađenosti tipa jer ste definirali varijablu koristeći izraz Dim kao određeni tip, npr. cijeli broj, datum i vaš kôd pokušava dodijeliti vrijednost varijabli koja nije prihvatljiva, npr. tekstualni niz dodijeljen cjelobrojnoj varijabli kao u ovom primjeru:

Evo primjera:

Kliknite na Otklanjanje pogrešaka i redak koda koji vrijeđa bit će označen žutom bojom. Ne postoji opcija za nastavak skočnog prozora s pogreškom, jer je to velika pogreška i ne postoji način da se kôd može pokrenuti dalje.

U ovom konkretnom slučaju rješenje je promijeniti izraz Dim u tip varijable koji radi s vrijednošću koju dodjeljujete varijabli. Kôd će funkcionirati ako promijenite vrstu varijable u "String", a vjerojatno biste htjeli promijeniti i naziv varijable.

Međutim, za promjenu vrste varijable bit će potrebno ponovno postaviti vaš projekt, pa ćete morati ponovo pokrenuti svoj kôd od početka, što može biti vrlo neugodno ako je u pitanju duga procedura

Pogreška neusklađenosti uzrokovana izračunavanjem radnog lista

Gornji primjer vrlo je jednostavan način na koji se može stvoriti pogreška neusklađenosti i u ovom se slučaju lako ispravlja

Međutim, uzrok pogrešaka neusklađenosti obično je daleko dublji od ovoga i nije toliko očit kada pokušavate otkloniti pogreške u kodu.

Kao primjer, pretpostavimo da ste napisali kôd za preuzimanje vrijednosti na određenom mjestu na radnom listu i da sadrži druge ćelije ovisne o izračunu unutar radne knjige (B1 u ovom primjeru)

Radni list izgleda kao ovaj primjer, s formulom za pronalaženje određenog znaka unutar niza teksta

Sa stajališta korisnika, ćelija A1 je slobodnog formata i mogu unijeti bilo koju vrijednost koju žele. Međutim, formula traži pojavu znaka 'B', au ovom slučaju nije pronađena pa ćelija B1 ima vrijednost pogreške.

Testni kôd u nastavku dovest će do pogreške neusklađenosti jer je pogrešna vrijednost unijeta u ćeliju A1

1234 Sub TestMismatch ()Zatamni moj broj kao cijeli brojMyNumber = Listovi ("List1"). Raspon ("B1"). VrijednostKraj podm

Vrijednost u ćeliji B1 proizvela je pogrešku jer je korisnik unio tekst u ćeliju A1 koji nije u skladu s očekivanjima i ne sadrži znak 'B'

Kôd pokušava dodijeliti vrijednost varijabli 'MyNumber' koja je definirana tako da očekuje cijeli broj, pa dobivate pogrešku neusklađenosti.

Ovo je jedan od ovih primjera u kojima pažljiva provjera vašeg koda neće dati odgovor. Također morate pogledati na radnom listu odakle dolazi vrijednost kako biste saznali zašto se to događa.

Problem je zapravo na radnom listu, a formulu u B1 treba promijeniti kako bi se riješile pogreške. To možete učiniti pomoću formule 'IFERROR' kako biste zadali zadanu vrijednost 0 ako znak za pretraživanje nije pronađen

Zatim možete uključiti kôd za provjeru nulte vrijednosti i za prikaz poruke upozorenja korisniku da je vrijednost u ćeliji A1 nevažeća

12345678 Sub TestMismatch ()Zatamni moj broj kao cijeli brojMyNumber = Listovi ("List1"). Raspon ("B1"). TekstAko je MyNumber = 0 TadaMsgBox "Vrijednost u ćeliji A1 je nevažeća", vbCriticalIzlaz iz podvZavrši akoKraj podm

Također možete upotrijebiti provjeru valjanosti podataka (skupina Podatkovni alati na kartici Podaci na vrpci) u proračunskoj tablici kako biste spriječili korisnika da radi sve što mu se sviđa i uzrokovali pogreške na radnom listu. Dopustite im samo unos vrijednosti koje neće uzrokovati pogreške na radnom listu.

Mogli biste napisati VBA kôd na temelju događaja Promjena na radnom listu kako biste provjerili što je unijeto.

Zaključavanje i lozinka štite radni list tako da se nevažeći podaci ne mogu unijeti

Pogreška neusklađenosti uzrokovana unesenim vrijednostima ćelije

Pogreške neusklađenosti mogu se uzrokovati u vašem kodu unosom normalnih vrijednosti s radnog lista (bez pogreške), ali ako je korisnik unio neočekivanu vrijednost, npr. tekstualna vrijednost kada ste očekivali broj. Možda su odlučili umetnuti redak unutar raspona brojeva kako bi mogli staviti bilješku u ćeliju objašnjavajući nešto o broju. Uostalom, korisnik nema pojma kako vaš kôd funkcionira i da su upravo izbacili cijelu stvar iz ubojstva unošenjem svoje bilješke.

Primjer koda u nastavku stvara jednostavan niz pod nazivom "MyNumber" definiran cijelim brojevima

Kôd zatim ponavlja kroz raspon ćelija od A1 do A7, dodjeljujući vrijednosti ćelija u nizu, koristeći varijablu "Coun" za indeksiranje svake vrijednosti

Kad kôd dosegne vrijednost teksta, to uzrokuje pogrešku neusklađenosti i sve se zaustavlja

Klikom na 'Otklanjanje pogrešaka' u skočnom prozoru pogreške vidjet ćete redak koda u kojem je problem označen žutom bojom. Ako zadržite pokazivač miša iznad bilo koje instance varijable "Coun" unutar koda, moći ćete vidjeti vrijednost "Coun" gdje kôd nije uspio, što je u ovom slučaju 5

Gledajući radni list, vidjet ćete da je 5th ćelija dolje ima tekstualnu vrijednost i to je uzrokovalo neuspjeh koda

Kôd možete promijeniti postavljanjem uvjeta koji prvo provjerava brojčanu vrijednost prije dodavanja vrijednosti ćelije u niz

12345678910111213 Sub TestMismatch ()Dim MyNumber (10) Kao cijeli broj, računajte kao cijeli brojBrojanje = 1ČiniAko je Coun = 11, izađite iz DoAko je numerički (listovi ("list1"). Ćelije (brojač, 1). Vrijednost) tadaMyNumber (Coun) = Sheets ("sheet1"). Cells (Coun, 1) .VrijednostDrugoMoj broj (brojač) = 0Završi akoCoun = Coun + 1PetljaKraj podm

Kôd koristi funkciju 'IsNumeric' kako bi provjerio je li vrijednost zapravo broj, a ako jest tada je unosi u niz. Ako nije broj, tada unosi vrijednost nula.

Time se osigurava da se indeks niza održava u skladu s brojevima redaka ćelija u proračunskoj tablici.

Također možete dodati kôd koji kopira izvornu vrijednost pogreške i pojedinosti o lokaciji na radni list "Pogreške" tako da korisnik može vidjeti što je učinio pogrešno pri pokretanju koda.

Numerički test koristi cijeli kôd ćelije, kao i kôd za dodjeljivanje vrijednosti nizu. Mogli biste tvrditi da se to treba dodijeliti varijabli kako se ne bi stalno ponavljao isti kôd, ali problem je u tome što biste morali definirati varijablu kao "Varijantu", što nije najbolje učiniti.

Također vam je potrebna provjera valjanosti podataka na radnom listu i zaštita radnog lista lozinkom. To će spriječiti korisnika da unosi retke i unosi neočekivane podatke.

Pogreška neusklađenosti uzrokovana pozivanjem funkcije ili podprograma pomoću parametara

Kada se funkcija pozove, obično joj prosljeđujete parametre pomoću vrsta podataka koje je funkcija već definirala. Funkcija može biti ona koja je već definirana u VBA -i, ili može biti korisnički definirana funkcija koju ste sami izgradili. Podprogram također ponekad može zahtijevati parametre

Ako se ne pridržavate konvencija o načinu prenošenja parametara u funkciju, dobit ćete pogrešku neusklađenosti

12345678 Sub CallFunction ()Dim Ret kao cijeli brojRet = MyFunction (3, "test")Kraj podmFunkcija MyFunction (N kao cijeli broj, T kao niz) kao nizMoja funkcija = TZavršna funkcija

Ovdje postoji nekoliko mogućnosti za dobivanje pogreške neusklađenosti

Povratna varijabla (Ret) definirana je kao cijeli broj, ali funkcija vraća niz. Čim pokrenete kôd, neće uspjeti jer funkcija vraća niz, a to ne može ući u cjelobrojnu varijablu. Zanimljivo je da pokretanje programa Debug na ovom kodu ne otkriva ovu pogrešku.

Stavite li navodnike oko prvog proslijeđenog parametra (3), on se tumači kao niz koji ne odgovara definiciji prvog parametra u funkciji (cijeli broj)

Ako drugi parametar u pozivu funkcije pretvorite u numeričku vrijednost, neće uspjeti s neusklađenošću jer je drugi parametar u nizu definiran kao niz (tekst)

Pogreška neusklađenosti uzrokovana korištenjem funkcija pretvorbe u VBA Neispravno

Postoje brojne funkcije pretvorbe koje možete koristiti u VBA -i za pretvaranje vrijednosti u različite vrste podataka. Primjer je "CInt" koji pretvara niz koji sadrži broj u cjelobrojnu vrijednost.

Ako niz koji se pretvara sadrži bilo koji alfa znak, dobit ćete pogrešku neusklađenosti, čak i ako prvi dio niza sadrži numeričke znakove, a ostatak su alfa znakovi, npr. "123abc"

Opća prevencija pogrešaka neusklađenosti

U gornjim primjerima vidjeli smo nekoliko načina rješavanja potencijalnih pogrešaka neusklađenosti u vašem kodu, ali postoji niz drugih načina, iako oni možda nisu najbolje opcije:

Definirajte svoje varijable kao tip varijante

Vrsta varijante zadana je varijabla u VBA -i. Ako ne koristite izraz Dim za varijablu i jednostavno je počnete koristiti u svom kodu, tada joj se automatski daje vrsta varijante.

Varijabla varijante prihvaća bilo koju vrstu podataka, bilo da se radi o cijelom broju, dugom cijelom broju, broju dvostruke preciznosti, logičkoj vrijednosti ili tekstualnoj vrijednosti. Ovo zvuči kao izvrsna ideja, pa se pitate zašto svi ne postave sve svoje varijable na varijantu.

Međutim, varijantni tip podataka ima nekoliko loših strana. Prvo, zauzima puno više memorije od ostalih vrsta podataka. Ako definirate vrlo veliki niz kao varijantu, on će progutati ogromnu količinu memorije dok se VBA kôd izvodi, i lako bi mogao uzrokovati probleme s performansama

Drugo, performanse su općenito sporije nego ako koristite određene vrste podataka. Na primjer, ako izrađujete složene izračune pomoću brojeva s pomičnim decimalnim zarezom, izračuni će biti znatno sporiji ako brojeve pohranite kao varijante, a ne brojeve dvostruke preciznosti

Korištenje varijantnog tipa smatra se traljavim programiranjem, osim ako za to postoji apsolutna potreba.

Za rješavanje pogrešaka koristite naredbu OnError

Naredba OnError može se uključiti u vaš kôd kako bi se riješilo hvatanje pogrešaka, tako da ako se greška ikada dogodi, korisnik umjesto značajnog skočnog prozora za pogrešku VBA vidi značajnu poruku

1234567 Sub ErrorTrap ()Zatamni moj broj kao cijeli brojUključeno Greška Idi na Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Pogreška" & Err.Opis & "je došlo"Kraj podm

To učinkovito sprječava pogrešku u zaustavljanju nesmetanog rada vašeg koda i omogućuje korisniku da se potpuno oporavi od situacije pogreške.

Rutina Err_Handler mogla bi pokazati dodatne informacije o pogrešci i kome se obratiti u vezi s njom.

Sa programskog gledišta, kada koristite rutinu za obradu pogrešaka, prilično je teško locirati redak koda na kojem je pogreška. Ako koračate kroz kôd pomoću F8, čim se izvrši redak koji je prekršio, prelazi se na rutinu za rješavanje pogrešaka i ne možete provjeriti gdje griješi.

Zaobilazni način je postaviti globalnu konstantu koja je True ili False (Boolean) i upotrijebiti je za uključivanje ili isključivanje rutine rukovanja pogreškama pomoću izraza "If". Kada želite testirati pogrešku, sve što trebate učiniti je postaviti globalnu konstantu na False i rukovatelj pogreškama više neće raditi.

1 Global Const ErrHandling = Netačno
1234567 Sub ErrorTrap ()Zatamni moj broj kao cijeli brojAko je ErrHandling = Istina, onda greška Uključeno Idi na Err_HandlerMyNumber = "test"Err_Handler:MsgBox "Došlo je do pogreške" & Err.Opis & "došlo je"Kraj podm

Jedini problem s ovim je što omogućuje korisniku da se oporavi od pogreške, ali se ostatak koda unutar podrutine ne pokreće, što može imati ogromne posljedice kasnije u aplikaciji

Koristeći raniji primjer petlje kroz niz ćelija, kôd bi došao do ćelije A5 i pogodio pogrešku koja se ne podudara. Korisnik bi vidio okvir s porukom koji daje informacije o pogrešci, ali ništa od te ćelije nadalje u rasponu neće biti obrađeno.

Upotrijebite naredbu OnError za suzbijanje pogrešaka

Ovo koristi naredbu ‘On Error Resume Next’. To je vrlo opasno uključiti u vaš kôd jer sprječava prikazivanje naknadnih pogrešaka. To u osnovi znači da će se, dok se vaš kôd izvršava, ako dođe do pogreške u retku koda, izvršenje samo premjestiti na sljedeći raspoloživi redak bez izvršavanja retka greške i nastaviti normalno.

Ovo može riješiti potencijalnu pogrešku, ali će i dalje utjecati na svaku buduću pogrešku u kodu. Možda ćete tada pomisliti da vaš kôd ne sadrži greške, ali zapravo nije i dijelovi vašeg koda ne rade ono što mislite da bi trebao raditi.

Postoje situacije u kojima je potrebno koristiti ovu naredbu, primjerice ako brišete datoteku pomoću naredbe 'Ubij' (ako datoteka nije prisutna, doći će do pogreške), ali hvatanje pogrešaka uvijek treba vratiti natrag uključeno odmah nakon što bi se potencijalna pogreška mogla pojaviti pomoću:

1 Uključeno Greška Idi na 0

U ranijem primjeru petlje kroz niz ćelija, pomoću opcije 'On Error Resume Next', to bi omogućilo nastavak petlje, ali ćelija koja uzrokuje pogrešku neće se prenijeti u polje, a element polja za taj određeni indeks ima nultu vrijednost.

Pretvaranje podataka u vrstu podataka kako bi odgovarali deklaraciji

Možete koristiti VBA funkcije za promjenu vrste podataka dolaznih podataka tako da se podudara s tipom podataka varijable koja prima.

To možete učiniti prilikom prosljeđivanja parametara funkcijama. Na primjer, ako imate broj koji se drži u niznoj varijabli i želite ga proslijediti kao broj funkciji, možete koristiti CInt

Postoji niz ovih funkcija pretvorbe koje se mogu koristiti, ali evo glavnih:

CInt - pretvara niz koji ima numeričku vrijednost (ispod + ili - 32,768) u cjelobrojnu vrijednost. Imajte na umu da se ovim skraćuju sve decimalne točke

CLng - Pretvara niz koji ima veliku numeričku vrijednost u dugi cijeli broj. Decimalne točke se skraćuju.

CDbl - Pretvara niz koji sadrži broj s pomičnim decimalnim zarezom u broj dvostruke preciznosti. Uključuje decimalne točke

CDate - Pretvara niz koji sadrži datum u varijablu datuma. Djelomično ovisi o postavkama na upravljačkoj ploči sustava Windows i vašem jeziku o načinu tumačenja datuma

CStr - Pretvara brojčanu ili datumsku vrijednost u niz

Prilikom pretvaranja iz niza u broj ili datum, niz ne smije sadržavati ništa drugo osim brojeva ili datuma. Ako su prisutni alfa znakovi, to će uzrokovati pogrešku neusklađenosti. Evo primjera koji će uzrokovati pogrešku neusklađenosti:

123 Podispit ()MsgBox CInt ("123abc")Kraj podm

Testiranje varijabli unutar vašeg koda

Varijablu možete testirati kako biste saznali o kojoj se vrsti podataka radi prije nego je dodijelite varijabli određene vrste.

Na primjer, mogli biste provjeriti niz da biste vidjeli je li numerički pomoću funkcije 'IsNumeric' u VBA -i

1 MsgBox IsNumeric ("123test")

Ovaj će kôd vratiti vrijednost False jer iako niz počinje numeričkim znakovima, on također sadrži tekst pa ne uspije u testu.

1 MsgBox je numerički ("123")

Ovaj će kôd vratiti vrijednost True jer su svi numerički znakovi

U VBA postoji niz funkcija za testiranje različitih tipova podataka, ali ovo su glavne:

IsNumeric - provjerava je li izraz broj ili nije

IsDate - provjerava je li izraz datum ili nije

IsNull - provjerava je li izraz null ili ne. Nulta vrijednost može se staviti samo u varijantni objekt, u protivnom ćete dobiti pogrešku "Nevažeća upotreba null". Okvir s porukom vraća null vrijednost ako ga koristite za postavljanje pitanja, pa povratna varijabla mora biti varijanta. Imajte na umu da će svaki izračun koji koristi null vrijednost uvijek vratiti rezultat null.

IsArray - provjerava predstavlja li izraz niz ili ne

IsEmpty - provjerava je li izraz prazan ili ne. Imajte na umu da prazno nije isto što i null. Varijabla je prazna kada se prvi put definira, ali nije null vrijednost

Začudo, nema funkcije za IsText ili IsString, što bi bilo jako korisno

Pogreške objekata i neusklađenosti

Ako koristite objekte poput raspona ili lista, dobit ćete pogrešku neusklađenosti u vrijeme sastavljanja, a ne u vrijeme izvođenja, što vas upozorava da vaš kôd neće raditi

123456 Pod testni raspon ()Dim MyRange As Range, I As LongPostavi MyRange = Raspon ("A1: A2")I = 10x = UseMyRange (I)Kraj podm
12 Funkcija UseMyRange (R kao raspon)Završna funkcija

Ovaj kôd ima funkciju pod nazivom "UseMyRange" i parametar koji se prenosi kao objekt raspona. Međutim, parametar koji se prosljeđuje je Long Integer koji ne odgovara tipu podataka.

Kada pokrenete VBA kôd, on se odmah sastavlja i vidjet ćete ovu poruku o pogrešci:

Uvredljivi parametar bit će označen plavom pozadinom

Općenito, ako napravite greške u VBA kodu pomoću objekata, vidjet ćete ovu poruku o pogrešci, a ne poruku o neusklađenosti tipa:

Vi ćete pomoći u razvoju web stranice, dijeljenje stranicu sa svojim prijateljima

wave wave wave wave wave