VBA - tipa neatbilstība (izpildlaika kļūda 13)

Kas ir tipa neatbilstības kļūda?

Palaižot VBA kodu, bieži var rasties neatbilstības kļūda. Kļūda pārtrauks jūsu koda pilnīgu darbību un atzīmēs ar ziņojumu lodziņu, ka šī kļūda ir jānovērš

Ņemiet vērā: ja neesat pilnībā pārbaudījis savu kodu pirms izplatīšanas lietotājiem, šis kļūdas ziņojums būs redzams lietotājiem un radīs lielu uzticības zudumu jūsu Excel lietojumprogrammai. Diemžēl lietotāji bieži lieto lietojumprogrammai ļoti savdabīgas lietas un bieži vien ir lietas, kuras jūs kā izstrādātājs nekad neuzskatījāt.

Tipa neatbilstības kļūda rodas tāpēc, ka esat definējis mainīgo, izmantojot Dim paziņojumu kā noteiktu veidu, piem. vesels skaitlis, datums un jūsu kods mēģina piešķirt mainīgajam vērtību, kas nav pieņemama, piem. teksta virkne, kas piešķirta veselam skaitļa mainīgajam, kā parādīts šajā piemērā:

Šeit ir piemērs:

Noklikšķiniet uz atkļūdošanas, un pārkāpjošā koda rinda tiks iezīmēta dzeltenā krāsā. Kļūdas uznirstošajā logā nav iespējas turpināt, jo tā ir būtiska kļūda, un kods nevar darboties tālāk.

Šajā konkrētajā gadījumā risinājums ir mainīt paziņojumu Dim uz mainīgā veidu, kas darbojas ar vērtību, kuru piešķirat mainīgajam. Kods darbosies, ja mainīsit mainīgā veidu uz “String” un, iespējams, vēlēsities mainīt arī mainīgā nosaukumu.

Tomēr, mainot mainīgā veidu, jūsu projekts būs jāatiestata, un jums būs vēlreiz jāpalaiž kods no sākuma, kas var būt ļoti kaitinoši, ja tiek iesaistīta ilga procedūra

Darblapas aprēķina izraisītā neatbilstības kļūda

Iepriekš minētais piemērs ir ļoti vienkāršs piemērs tam, kā var rasties neatbilstības kļūda, un šajā gadījumā to var viegli novērst

Tomēr neatbilstības kļūdu cēlonis parasti ir daudz dziļāks par šo, un tas nav tik acīmredzams, mēģinot atkļūdot kodu.

Piemēram, pieņemsim, ka esat uzrakstījis kodu, lai noteiktu vērtību atlasītu darblapas pozīcijā, un tajā ir no aprēķiniem atkarīgas citas darbgrāmatas šūnas (šajā piemērā B1)

Darblapa izskatās kā šis piemērs ar formulu, lai atrastu noteiktu rakstzīmi teksta virknē

No lietotāja viedokļa šūna A1 ir brīvā formātā, un viņš var ievadīt jebkuru vēlamo vērtību. Tomēr formula meklē rakstzīmes “B” sastopamību, un šajā gadījumā tā netiek atrasta, tāpēc šūnai B1 ir kļūdas vērtība.

Tālāk norādītais testa kods radīs neatbilstības kļūdu, jo šūnā A1 ir ievadīta nepareiza vērtība

1234 Sub TestMismatch ()Dim MyNumber kā vesels skaitlisMyNumber = Sheets ("Sheet1"). Diapazons ("B1"). VērtībaBeigu apakš

Šūnas B1 vērtība ir radījusi kļūdu, jo lietotājs šūnā A1 ir ievadījis tekstu, kas neatbilst gaidītajam, un tajā nav rakstzīmes “B”

Kods mēģina piešķirt vērtību mainīgajam “MyNumber”, kas ir definēts kā vesels skaitlis, un tādējādi tiek parādīta neatbilstības kļūda.

Šis ir viens no šiem piemēriem, kur rūpīga koda pārbaude nesniegs atbildi. Lai uzzinātu, kāpēc tas notiek, jums arī jāskatās darblapā, no kurienes tiek iegūta vērtība.

Problēma faktiski ir darblapā, un B1 formula ir jāmaina, lai tiktu novērstas kļūdu vērtības. To var izdarīt, izmantojot formulu “IFERROR”, lai noklusējuma vērtība būtu 0, ja meklēšanas rakstzīme netiek atrasta.

Pēc tam varat iekļaut kodu, lai pārbaudītu nulles vērtību un parādītu lietotājam brīdinājuma ziņojumu, ka vērtība šūnā A1 nav derīga

12345678 Sub TestMismatch ()Dim MyNumber kā vesels skaitlisMyNumber = Sheets ("Sheet1"). Diapazons ("B1"). TekstsJa MyNumber = 0 TadMsgBox "Vērtība šūnā A1 nav derīga", vbCriticalIziet no apakšnodaļasBeigas JaBeigu apakš

Varat arī izmantot datu validāciju (datu rīku grupa lentes cilnē Dati) izklājlapā, lai apturētu lietotāju darīt visu, kas viņam patika, un vispirms izraisīt darblapas kļūdas. Ļaujiet viņiem ievadīt tikai tādas vērtības, kas neizraisīs darblapas kļūdas.

Jūs varat rakstīt VBA kodu, pamatojoties uz darblapas notikumu Mainīt, lai pārbaudītu ievadīto.

Arī bloķēšana un parole aizsargā darblapu, lai nederīgos datus nevarētu ievadīt

Neatbilstības kļūda, ko izraisa ievadītās šūnu vērtības

Kodā var rasties neatbilstības kļūdas, ieviešot normālās vērtības no darblapas (bez kļūdām), bet ja lietotājs ir ievadījis neparedzētu vērtību, piem. teksta vērtību, kad gaidījāt skaitli. Iespējams, viņi ir nolēmuši ievietot rindu skaitļu diapazonā, lai šūnā varētu ievietot piezīmi, kas kaut ko paskaidro par numuru. Galu galā lietotājam nav ne jausmas, kā darbojas jūsu kods un ka viņš, ievadot savu piezīmi, ir vienkārši izmetis visu.

Tālāk esošais piemēra kods izveido vienkāršu masīvu ar nosaukumu “MyNumber”, kas definēts ar veselu skaitļu vērtībām

Pēc tam kods atkārto šūnu diapazonu no A1 līdz A7, piešķirot šūnu vērtības masīvam, izmantojot mainīgo “Coun”, lai indeksētu katru vērtību

Kad kods sasniedz teksta vērtību, tas izraisa neatbilstības kļūdu, un viss tiek apturēts

Noklikšķinot uz “Atkļūdot” kļūdas uznirstošajā logā, jūs redzēsit koda rindiņu, kuras problēma ir iezīmēta dzeltenā krāsā. Novietojot kursoru virs jebkura mainīgā “Coun” gadījuma kodā, jūs varēsit redzēt “Coun” vērtību, ja kods nav izdevies, kas šajā gadījumā ir 5

Aplūkojot darblapu, jūs redzēsit, ka 5tūkst šūnai uz leju ir teksta vērtība, un tas ir izraisījis koda kļūmi

Jūs varat mainīt savu kodu, ievietojot nosacījumu, kas vispirms pārbauda skaitlisko vērtību, pirms šūnas vērtības pievieno masīvam

12345678910111213 Sub TestMismatch ()Dim MyNumber (10) Kā vesels skaitlis, Coun kā vesels skaitlisCoun = 1VaiJa Coun = 11, tad izejiet DoIf IsNumeric (Sheets ("sheet1"). Šūnas (Coun, 1). Value) TadMyNumber (Coun) = Sheets ("sheet1"). Šūnas (Coun, 1). VērtībaCitādiMans numurs (Coun) = 0Beigas JaCoun = Coun + 1CilpaBeigu apakš

Kods izmanto funkciju “IsNumeric”, lai pārbaudītu, vai vērtība patiesībā ir skaitlis, un, ja tā, tad tā tiek ievadīta masīvā. Ja tas nav skaitlis, tas ieraksta nulles vērtību.

Tas nodrošina, ka masīva indekss tiek uzturēts atbilstoši izklājlapas šūnu rindu numuriem.

Darblapai “Kļūdas” varat pievienot arī kodu, kas kopē sākotnējo kļūdas vērtību un atrašanās vietas informāciju, lai lietotājs varētu redzēt, ko viņi ir darījuši nepareizi, kad tiek palaists jūsu kods.

Ciparu testā tiek izmantots pilns šūnas kods, kā arī kods, lai piešķirtu vērtību masīvam. Jūs varētu iebilst, ka tas jāpiešķir mainīgajam, lai neatkārtotos viens un tas pats kods, taču problēma ir tāda, ka jums vajadzētu definēt mainīgo kā “variantu”, kas nav labākais risinājums.

Jums ir nepieciešama arī datu validācija darblapā un darblapas aizsardzība ar paroli. Tas neļaus lietotājam ievietot rindas un ievadīt neparedzētus datus.

Neatbilstības kļūda, ko izraisa funkcijas vai apakšprogrammas izsaukšana, izmantojot parametrus

Kad tiek izsaukta funkcija, jūs parasti nododat parametrus funkcijai, izmantojot funkcijas jau definētos datu tipus. Šī funkcija var būt tāda, kas jau ir definēta VBA, vai tā var būt lietotāja definēta funkcija, kuru esat izveidojis pats. Apakšrutīnam dažreiz var būt nepieciešami arī parametri

Ja neievērojat parametru nodošanas funkcijai parastās vienošanās, tiks parādīta neatbilstības kļūda

12345678 Sub CallFunction ()Dim Ret kā vesels skaitlisRet = MyFunction (3, "tests")Beigu apakšFunkcija MyFunction (N kā vesels skaitlis, T kā virkne) kā virkneMana funkcija = T.Beigu funkcija

Šeit ir vairākas iespējas, kā iegūt neatbilstības kļūdu

Atgriešanās mainīgais (Ret) ir definēts kā vesels skaitlis, bet funkcija atgriež virkni. Tiklīdz jūs palaižat kodu, tas neizdosies, jo funkcija atgriež virkni, un tas nevar iekļūt veselā skaitļa mainīgajā. Interesanti, ka atkļūdošanas palaišana šajā kodā šo kļūdu neuzņem.

Ja jūs ievietojat pēdiņas ap pirmo nodoto parametru (3), tā tiek interpretēta kā virkne, kas neatbilst funkcijas (vesels skaitlis) pirmā parametra definīcijai

Ja funkciju izsaukuma otro parametru pārveidojat par skaitlisku vērtību, tas neizdosies ar neatbilstību, jo otrais parametrs virknē ir definēts kā virkne (teksts)

Neatbilstības kļūda, kas radusies, nepareizi izmantojot VBA reklāmguvumu funkcijas

Ir vairākas konvertēšanas funkcijas, kuras varat izmantot VBA, lai vērtības pārvērstu dažādos datu veidos. Piemērs ir “CInt”, kas virkni, kas satur skaitli, pārvērš vesela skaitļa vērtībā.

Ja pārveidojamā virkne satur jebkādas alfa rakstzīmes, jūs saņemsiet neatbilstības kļūdu, pat ja virknes pirmajā daļā ir ciparu rakstzīmes, bet pārējā ir alfa rakstzīmes, piem. “123abc”

Vispārīga neatbilstības kļūdu novēršana

Iepriekš minētajos piemēros mēs esam redzējuši vairākus veidus, kā novērst iespējamās neatbilstības kļūdas jūsu kodā, taču ir arī vairāki citi veidi, lai gan tie var nebūt labākie varianti:

Definējiet savus mainīgos kā varianta veidu

Varianta veids ir noklusējuma mainīgā tips VBA. Ja mainīgajam neizmantojat Dim paziņojumu un vienkārši sākat to izmantot savā kodā, tad tam automātiski tiek piešķirts varianta veids.

Mainīgais variants pieņem jebkāda veida datus, neatkarīgi no tā, vai tas ir vesels skaitlis, garš vesels skaitlis, dubults precizitātes skaitlis, Būla vērtība vai teksta vērtība. Šī izklausās pēc brīnišķīgas idejas, un jūs brīnāties, kāpēc visi ne tikai visus savus mainīgos nosaka uz variantu.

Tomēr varianta datu tipam ir vairākas negatīvas puses. Pirmkārt, tas aizņem daudz vairāk atmiņas nekā citi datu veidi. Ja definējat ļoti lielu masīvu kā variantu, tas norij milzīgu atmiņas apjomu, kad darbojas VBA kods, un var viegli radīt veiktspējas problēmas

Otrkārt, tā darbība parasti ir lēnāka nekā tad, ja izmantojat konkrētus datu veidus. Piemēram, ja veicat sarežģītus aprēķinus, izmantojot peldošus decimāldaļas skaitļus, aprēķini būs ievērojami lēnāki, ja skaitļus saglabāsit kā variantus, nevis dubultus precīzus skaitļus

Varianta veida izmantošana tiek uzskatīta par paviršu programmēšanu, ja vien tā nav absolūti nepieciešama.

Izmantojiet OnError komandu, lai apstrādātu kļūdas

Komandu OnError var iekļaut jūsu kodā, lai novērstu kļūdu uztveršanu, tādēļ, ja kādreiz rodas kļūda, lietotājs redz nozīmīgu ziņojumu, nevis standarta VBA kļūdas uznirstošo logu

1234567 Sub ErrorTrap ()Dim MyNumber kā vesels skaitlisPar kļūdu GoTo Err_HandlerMyNumber = "tests"Err_Handler:MsgBox "Radās kļūda" un Err.Description & "Beigu apakš

Tas efektīvi neļauj kļūdai apturēt jūsu koda nevainojamu darbību un ļauj lietotājam tīri atgūties no kļūdas situācijas.

Err_Handler rutīna varētu parādīt papildu informāciju par kļūdu un ar ko sazināties.

No programmēšanas viedokļa, ja izmantojat kļūdu apstrādes rutīnu, ir diezgan grūti atrast koda rindu, kurā kļūda ir ieslēgta. Ja jūs ejat cauri kodam, izmantojot F8, tiklīdz tiek izpildīta pārkāpjošā koda rinda, tā pāriet uz kļūdu apstrādes kārtību, un jūs nevarat pārbaudīt, kur tas notiek nepareizi.

Viens veids, kā to novērst, ir iestatīt patiesu vai nepatiesu (Būla) globālo konstanti un izmantot to, lai ieslēgtu vai izslēgtu kļūdu apstrādes kārtību, izmantojot paziņojumu “Ja”. Ja vēlaties pārbaudīt kļūdu, viss, kas jums jādara, ir iestatīt globālo konstanti uz False, un kļūdu apstrādātājs vairs nedarbosies.

1 Globālā Const ErrHandling = False
1234567 Sub ErrorTrap ()Dim MyNumber kā vesels skaitlisJa ErrHandling = True, tad uz kļūdu GoTo Err_HandlerMyNumber = "tests"Err_Handler:MsgBox "Radās kļūda" un Err.Description & "Beigu apakš

Viena problēma ir tā, ka tas ļauj lietotājam atgūties no kļūdas, bet pārējais apakšprogrammas kods netiek palaists, kam vēlāk var būt milzīgas sekas lietojumprogrammā

Izmantojot iepriekšējo piemēru par cilpu pārvietošanu pa virkni šūnu, kods nokļūtu šūnā A5 un nokļūtu neatbilstošajā kļūdā. Lietotājs redzēs ziņojumu lodziņu, kurā sniegta informācija par kļūdu, taču nekas no šīs šūnas diapazonā netiks apstrādāts.

Izmantojiet OnError komandu, lai novērstu kļūdas

Tas izmanto komandu “On Error Resume Next”. To ir ļoti bīstami iekļaut savā kodā, jo tas novērš turpmāku kļūdu parādīšanu. Tas būtībā nozīmē, ka, izpildot kodu, ja koda rindā rodas kļūda, izpilde tiks pārvietota uz nākamo pieejamo rindu, neizpildot kļūdas rindu, un turpināsies kā parasti.

Tas var atrisināt iespējamo kļūdu situāciju, taču tas joprojām ietekmēs visas turpmākās koda kļūdas. Tad jūs domājat, ka jūsu kods ir bez kļūdām, bet patiesībā tā nav, un jūsu koda daļas nedara to, kas, jūsuprāt, būtu jādara.

Pastāv situācijas, kad šī komanda ir jāizmanto, piemēram, ja dzēšat failu, izmantojot komandu “Nogalināt” (ja faila nav, tad radīsies kļūda), taču kļūdu uztveršana vienmēr ir jāpārslēdz atpakaļ ieslēdzas tūlīt pēc tam, kad varētu rasties iespējamā kļūda, izmantojot:

1 Kļūda Goto 0

Iepriekšējā piemērā par cilpu pārvietošanu pa virkni šūnu, izmantojot opciju “Ieslēgt kļūdu, atsākt nākamo”, cilne varētu turpināties, bet kļūdu izraisošā šūna netiktu pārnesta uz masīvu, un šī indeksa masīva elements būtu nulles vērtība.

Datu pārvēršana par datu tipu, lai tie atbilstu deklarācijai

Varat izmantot VBA funkcijas, lai mainītu ienākošo datu datu tipu tā, lai tas atbilstu saņemošā mainīgā datu tipam.

To var izdarīt, nododot parametrus funkcijām. Piemēram, ja jums ir skaitlis, kas tiek turēts virknes mainīgajā un vēlaties to nodot funkcijai kā skaitli, varat izmantot CInt

Var izmantot vairākas šādas konvertēšanas funkcijas, taču šeit ir galvenās:

CInt - pārvērš virkni ar skaitlisku vērtību (zem + vai - 32 768) par veselu skaitli. Ņemiet vērā, ka tas saīsina visus ciparus aiz komata

CLng - pārvērš virkni ar lielu ciparu vērtību par garu veselu skaitli. Aiz komata tiek nogriezti.

CDbl - pārvērš virkni ar peldošu decimāldaļskaitli par dubultu precizitātes skaitli. Ietver decimāldaļas

CDate - pārvērš virkni, kurā ir datums, datuma mainīgajā. Daļēji atkarīgs no Windows vadības paneļa iestatījumiem un jūsu lokalizācijas, kā tiek interpretēts datums

CStr - pārvērš skaitlisku vai datuma vērtību virknē

Pārveidojot no virknes par skaitli vai datumu, virknē nedrīkst būt nekas cits kā skaitļi vai datums. Ja ir alfa rakstzīmes, tas radīs neatbilstības kļūdu. Šeit ir piemērs, kas radīs neatbilstības kļūdu:

123 Apakštests ()MsgBox CInt ("123abc")Beigu apakš

Koda mainīgo testēšana

Jūs varat pārbaudīt mainīgo, lai uzzinātu, kāds tas ir datu tips, pirms to piešķirat noteikta veida mainīgajam.

Piemēram, varat pārbaudīt virkni, lai redzētu, vai tā ir skaitliska, izmantojot funkciju “IsNumeric” VBA

1 MsgBox IsNumeric ("123test")

Šis kods atgriezīs nepatiesu, jo, lai gan virkne sākas ar ciparu rakstzīmēm, tajā ir arī teksts, tāpēc tas neiztur pārbaudi.

1 MsgBox IsNumeric ("123")

Šis kods atgriezīs True, jo tas viss sastāv no cipariem

VBA ir vairākas funkcijas, lai pārbaudītu dažādus datu tipus, taču tās ir galvenās:

IsNumeric - pārbauda, ​​vai izteiksme ir skaitlis vai nav

IsDate - pārbauda, ​​vai izteiksme ir datums vai nē

IsNull - pārbauda, ​​vai izteiksme ir nulle vai nav. Nulles vērtību var ievietot tikai objekta variantā, pretējā gadījumā jūs saņemsit kļūdu “Nederīga nulles izmantošana”. Ziņojumu lodziņā tiek atgriezta nulles vērtība, ja to izmantojat jautājuma uzdošanai, tāpēc atgriešanās mainīgajam ir jābūt variantam. Paturiet prātā, ka jebkurš aprēķins, izmantojot nulles vērtību, vienmēr atgriež nulles rezultātu.

IsArray - pārbauda, ​​vai izteiksme attēlo masīvu vai nē

IsEmpty - pārbauda, ​​vai izteiksme ir tukša. Ņemiet vērā, ka tukšs nav tas pats, kas nulle. Mainīgais ir tukšs, kad tas pirmo reizi tiek definēts, taču tā nav nulles vērtība

Pārsteidzoši, IsText vai IsString nav nevienas funkcijas, kas būtu patiešām noderīga

Objekti un neatbilstības kļūdas

Ja izmantojat tādus objektus kā diapazons vai lapa, neatbilstības kļūda tiks parādīta apkopošanas laikā, nevis izpildes laikā, kas brīdina jūs, ka jūsu kods nedarbosies

123456 Sub TestRange ()Dim MyRange As Range, I As LongIestatīt MyRange = Diapazons ("A1: A2")I = 10x = UseMyRange (I)Beigu apakš
12 Funkcija UseMyRange (R kā diapazons)Beigu funkcija

Šim kodam ir funkcija “UseMyRange” un parametrs, kas tiek nodots kā diapazona objekts. Tomēr parametrs, kas tiek pārsūtīts, ir garš vesels skaitlis, kas neatbilst datu tipam.

Palaižot VBA kodu, tas tiek nekavējoties apkopots, un jūs redzēsit šo kļūdas ziņojumu:

Pārkāpjošais parametrs tiks iezīmēts ar zilu fonu

Parasti, ja jūs pieļaujat kļūdas VBA kodā, izmantojot objektus, jūs redzēsit šo kļūdas ziņojumu, nevis tipa neatbilstības ziņojumu:

Jums palīdzēs attīstību vietā, daloties lapu ar draugiem

wave wave wave wave wave