ВБА - Неподударање типа (грешка у току рада 13)

Шта је грешка неусклађености типа?

Грешка неусклађености често може да се појави када покренете ВБА код. Грешка ће зауставити потпуни рад вашег кода и означити га помоћу оквира за поруку који ову грешку треба решити

Имајте на уму да ако нисте у потпуности тестирали свој код пре дистрибуције корисницима, ова порука о грешци ће бити видљива корисницима и изазваће велики губитак поверења у вашу Екцел апликацију. Нажалост, корисници често раде необичне ствари за апликацију и често су то ствари које ви као програмер никада нисте узели у обзир.

Грешка у неслагању типова се јавља јер сте дефинисали променљиву користећи израз Дим као одређени тип, нпр. цео број, датум и ваш код покушава да додели вредност променљивој која није прихватљива, нпр. текстуални низ додељен променљивој целог броја као у овом примеру:

Ево примера:

Кликните на Отклањање грешака и линија кода која је увредљива биће означена жутом бојом. Не постоји опција за наставак искачућег прозора грешке, јер је ово велика грешка и не постоји начин да се код може покренути даље.

У овом конкретном случају, решење је да промените израз Дим у тип променљиве који ради са вредношћу коју додељујете променљивој. Код ће радити ако промените врсту променљиве у „Стринг“, а вероватно бисте желели да промените и име променљиве.

Међутим, за промену типа променљиве биће потребно ресетовање вашег пројекта, па ћете морати поново да покренете свој код од почетка, што може бити веома досадно ако је у питању дугачка процедура

Грешка неусклађености узрокована прорачуном радног листа

Горњи пример је врло једноставан како се може направити грешка неусклађености и, у овом случају, лако се отклања

Међутим, узрок грешака неусклађености је обично далеко дубљи од овога и није толико очигледан када покушавате да отклоните грешке у коду.

Као пример, претпоставимо да сте написали код да покупите вредност на одређеној позицији на радном листу и да она садржи друге ћелије у прорачуну зависне од радне свеске (Б1 у овом примеру)

Радни лист изгледа као овај пример, са формулом за проналажење одређеног знака унутар низа текста

Са становишта корисника, ћелија А1 је слободног формата и могу унети било коју вредност коју желе. Међутим, формула тражи појаву карактера 'Б', ау овом случају се не налази па ћелија Б1 има вредност грешке.

Доњи тестни код ће произвести грешку неусклађености јер је погрешна вредност унета у ћелију А1

1234 Суб ТестМисматцх ()Дим МиНумбер Ас ИнтегерМиНумбер = Табеле ("Лист1"). Распон ("Б1"). ВредностЕнд Суб

Вредност у ћелији Б1 је произвела грешку јер је корисник унео текст у ћелију А1 који није у складу са очекивањима и не садржи знак „Б“

Код покушава да додели вредност променљивој „МиНумбер“ која је дефинисана тако да очекује цео број, тако да добијате грешку неусклађености.

Ово је један од ових примера у којима пажљива провера кода неће дати одговор. Такође морате погледати на радном листу одакле долази вредност да бисте сазнали зашто се то дешава.

Проблем је заправо на радном листу, а формулу у Б1 је потребно променити како би се решиле вредности грешака. То можете учинити помоћу формуле „ИФЕРРОР“ да бисте задали задану вредност 0 ако знак за претрагу није пронађен

Затим можете укључити код да бисте проверили да ли има нулту вредност и приказали поруку упозорења кориснику да је вредност у ћелији А1 неважећа

12345678 Суб ТестМисматцх ()Дим МиНумбер Ас ИнтегерМиНумбер = Табеле ("Лист1"). Распон ("Б1"). ТекстАко је МиНумбер = 0 ТадаМсгБок "Вредност у ћелији А1 је неважећа", вбЦритицалЕкит СубКрај АкоЕнд Суб

Такође бисте могли да користите проверу података (група Алатке за податке на картици Подаци на траци) у табели да бисте спречили корисника да ради све што му се допада и изазвали грешке на радном листу. Дозволите им само да унесу вредности које неће изазвати грешке на радном листу.

Могли бисте написати ВБА код на основу догађаја Промена на радном листу да бисте проверили шта је унето.

Закључавање и лозинка штите радни лист тако да се неважећи подаци не могу унијети

Грешка неусклађености узрокована унетим вредностима ћелије

Грешке неусклађености могу бити узроковане у вашем коду уносом нормалних вредности са радног листа (без грешке), али где је корисник унео неочекивану вредност, нпр. текстуална вредност када сте очекивали број. Можда су одлучили да уметну ред у низ бројева како би могли да унесу белешку у ћелију која објашњава нешто о броју. На крају крајева, корисник нема појма како ваш код функционише и да су управо избацили целу ствар из колица уношењем белешке.

Пример у наставку ствара једноставан низ под називом „МиНумбер“ дефинисан целобројним вредностима

Код затим понавља кроз низ ћелија од А1 до А7, додељујући вредности ћелија у низу, користећи променљиву „Цоун“ за индексирање сваке вредности

Када код достигне текстуалну вредност, долази до грешке у неподударању и све се зауставља

Кликом на „Отклањање грешака“ у искачућем прозору грешке видећете ред кода у коме је проблем истакнут жутом бојом. Преласком курсора изнад било које инстанце променљиве „Цоун“ унутар кода, моћи ћете да видите вредност „Цоун“ где код није успео, што је у овом случају 5

Гледајући радни лист, видећете да је 5тх ћелија доле има текстуалну вредност и то је довело до грешке кода

Код можете променити постављањем услова који прво проверава нумеричку вредност пре него што додате вредност ћелије у низ

12345678910111213 Суб ТестМисматцх ()Дим МиНумбер (10) Ас Интегер, Цоун Ас ИнтегерЦоун = 1УрадитиАко је Цоун = 11, изађите из ДоАко је нумерички (листови ("лист1"). Ћелије (бројач, 1). Вредност) тадаМиНумбер (Цоун) = Схеетс ("схеет1"). Целлс (Цоун, 1) .ВредностИначеМиНумбер (Цоун) = 0Крај АкоЦоун = Цоун + 1ЛоопЕнд Суб

Код користи функцију „ИсНумериц“ да провери да ли је вредност заправо број, а ако јесте, уноси је у низ. Ако није број, онда уноси вредност нула.

Ово осигурава да се индекс низа одржава у складу са бројевима редова ћелија у табели.

Такође можете додати код који копира оригиналну вредност грешке и детаље локације на радни лист „Грешке“ тако да корисник може видети шта је учинио погрешно када се ваш код покрене.

Нумерички тест користи цео код ћелије, као и код за додељивање вредности низу. Могли бисте тврдити да ово треба доделити променљивој како се не би стално понављао исти код, али проблем је у томе што бисте морали да дефинишете променљиву као „варијанту“, што није најбоље учинити.

Такође вам је потребна потврда података на радном листу и заштита радног листа лозинком. Ово ће спречити корисника да уноси редове и уноси неочекиване податке.

Грешка неусклађености узрокована позивањем функције или потпрограма помоћу параметара

Када се функција позове, обично прослеђујете параметре функцији користећи типове података које је функција већ дефинисала. Функција може бити она која је већ дефинисана у ВБА, или може бити функција коју дефинише корисник коју сте сами направили. Подпрограм такође понекад може захтевати параметре

Ако се не придржавате конвенција о томе како се параметри преносе у функцију, добићете грешку неусклађености

12345678 Суб ЦаллФунцтион ()Дим Рет Ас ИнтегерРет = МиФунцтион (3, "тест")Енд СубФункција МиФунцтион (Н као цео број, Т као низ) као низМиФунцтион = Т.Завршна функција

Овде постоји неколико могућности за грешку неусклађености

Повратна променљива (Рет) је дефинисана као цео број, али функција враћа стринг. Чим покренете код, он неће успети јер функција враћа стринг, а то не може да уђе у целобројну променљиву. Занимљиво је да покретање програма Дебуг на овом коду не открива ову грешку.

Ако ставите наводнике око првог параметра који се прослеђује (3), он се тумачи као низ, који не одговара дефиницији првог параметра у функцији (цео број)

Ако други параметар у позиву функције претворите у нумеричку вредност, он неће успети са неусклађеношћу јер је други параметар у низу дефинисан као низ (текст)

Грешка неусклађености узрокована коришћењем функција конверзије у ВБА Нетачно

Постоји низ функција конверзије које можете користити у ВБА за претварање вредности у различите типове података. Пример је „ЦИнт“ који претвара низ који садржи број у целобројну вредност.

Ако стринг који треба да се конвертује садржи било који алфа знак, добићете грешку неусклађености, чак и ако први део низа садржи нумеричке знакове, а остатак су алфа знакови, нпр. „123абц“

Општа превенција грешака неусклађености

У горе наведеним примерима видели смо неколико начина суочавања са потенцијалним грешкама неусклађености у вашем коду, али постоји низ других начина, иако они можда нису најбоље опције:

Дефинишите своје променљиве као тип варијанте

Тип варијанте је подразумевани тип променљиве у ВБА. Ако не користите израз Дим за променљиву и једноставно почнете да је користите у свом коду, тада јој се аутоматски даје тип варијанте.

Варијабла варијанте ће прихватити било коју врсту података, било да се ради о целобројном, дугачком целом броју, броју двоструке прецизности, логичкој вредности или текстуалној вредности. Ово звучи као дивна идеја и питате се зашто сви не постављају све своје променљиве на варијанту.

Међутим, варијантни тип података има неколико лоших страна. Прво, заузима много више меморије од осталих типова података. Ако дефинишете веома велики низ као варијанту, он ће прогутати огромну количину меморије када је ВБА код покренут, и лако би могао изазвати проблеме са перформансама

Друго, перформансе су генерално спорије него ако користите одређене типове података. На пример, ако правите сложене прорачуне користећи бројеве с помичним децималним зарезом, прорачуни ће бити знатно спорији ако бројеве складиштите као варијанте, а не бројеве двоструке прецизности

Коришћење варијантног типа сматра се траљавим програмирањем, осим ако за то постоји апсолутна потреба.

Користите наредбу ОнЕррор за решавање грешака

Наредба ОнЕррор може бити укључена у ваш код ради решавања проблема са хватањем грешака, тако да ако се грешка икада догоди, корисник види значајну поруку уместо стандардног искачућег прозора ВБА грешке

1234567 Суб ЕррорТрап ()Дим МиНумбер Ас ИнтегерУкључено Грешка Иди на Ерр_ХандлерМиНумбер = "тест"Ерр_Хандлер:МсгБок "Дошло је до грешке" & Ерр.Опис & "дошло је"Енд Суб

Ово ефикасно спречава грешку да заустави несметан рад вашег кода и омогућава кориснику да се опорави од ситуације са грешком.

Рутина Ерр_Хандлер могла би показати додатне информације о грешци и коме се обратити у вези с њом.

Са програмске тачке гледишта, када користите рутину за руковање грешкама, прилично је тешко лоцирати ред кода на којем је грешка. Ако корачате кроз код помоћу Ф8, чим се изврши линија кода која је увредљива, прелази у рутину за руковање грешкама и не можете проверити где греши.

Заобилазни начин је постављање глобалне константе која је Тачна или Нетачна (Боолеан) и помоћу ње укључите или искључите рутину за руковање грешкама користећи наредбу „Ако“. Када желите да тестирате грешку, све што требате учинити је поставити глобалну константу на Фалсе и руковатељ грешком више неће радити.

1 Глобал Цонст ЕррХандлинг = Нетачно
1234567 Суб ЕррорТрап ()Дим МиНумбер Ас ИнтегерАко је ЕррХандлинг = Тачно, онда грешка Грешка Иди на Ерр_ХандлерМиНумбер = "тест"Ерр_Хандлер:МсгБок "Дошло је до грешке" & Ерр.Опис & "дошло је"Енд Суб

Једини проблем са овим је што омогућава кориснику да се опорави од грешке, али остатак кода унутар подрутине се не покреће, што може имати огромне последице касније у апликацији

Користећи ранији пример петље кроз низ ћелија, код би дошао до ћелије А5 и погодио грешку која се не подудара. Корисник би видео оквир са поруком који даје информације о грешци, али ништа од те ћелије па надаље у опсегу неће бити обрађено.

Помоћу команде ОнЕррор уклоните грешке

Ово користи команду „Он Еррор Ресуме Нект“. Ово је врло опасно укључити у ваш код јер спречава приказивање накнадних грешака. То у основи значи да ће се, док се ваш код извршава, ако дође до грешке у реду кода, извршење само прећи на следећу доступну линију без извршавања линије грешке и наставити нормално.

Ово може решити потенцијалну грешку, али ће и даље утицати на сваку будућу грешку у коду. Можда ћете тада помислити да ваш код не садржи грешке, али заправо није и делови вашег кода не раде оно што мислите да би требало да ради.

Постоје ситуације у којима је потребно користити ову команду, на пример ако бришете датотеку помоћу команде 'Убиј' (ако датотека није присутна, доћи ће до грешке), али хватање грешака увек треба да се врати назад укључено одмах након што би потенцијална грешка могла настати користећи:

1 Грешка при укључивању Иди на 0

У ранијем примеру петља кроз низ ћелија, помоћу 'Он Еррор Ресуме Нект', ово би омогућило наставак петље, али ћелија која узрокује грешку неће се пренети у низ, а елемент низа за тај одређени индекс би имао нулту вредност.

Претварање података у тип података који одговара декларацији

Можете користити ВБА функције за промену типа података долазних података тако да се подудара са типом података пријемне променљиве.

То можете учинити приликом преношења параметара у функције. На пример, ако имате број који се чува у стринг променљивој и желите да га проследите као број функцији, можете користити ЦИнт

Постоји низ ових функција конверзије које се могу користити, али ево главних:

ЦИнт - претвара низ који има нумеричку вредност (испод + или - 32,768) у целобројну вредност. Имајте на уму да се овим скраћују све децималне тачке

ЦЛнг - Претвара низ који има велику нумеричку вредност у дугачак цео број. Децималне тачке се скраћују.

ЦДбл - Претвара низ који садржи број с помичним децималним зарезом у број двоструке прецизности. Укључује децималне тачке

ЦДате - Претвара низ који садржи датум у променљиву датума. Делимично зависи од подешавања на Виндовс контролној табли и вашег језика од начина на који се датум тумачи

ЦСтр - Претвара нумеричку или датумску вредност у низ

Приликом претварања из низа у број или датум, низ не сме да садржи ништа осим бројева или датума. Ако су присутни алфа знакови, то ће довести до грешке у неслагању. Ево примера који ће произвести грешку неусклађености:

123 Под Тест ()МсгБок ЦИнт ("123абц")Енд Суб

Тестирање променљивих у оквиру вашег кода

Можете проверити променљиву да бисте сазнали који је тип података пре него што је доделите променљивој одређеног типа.

На пример, могли бисте да проверите низ да бисте видели да ли је нумерички помоћу функције „ИсНумериц“ у ВБА

1 МсгБок ИсНумериц ("123тест")

Овај код ће вратити Фалсе јер иако низ почиње нумеричким знаковима, он такође садржи текст па не успева тест.

1 МсгБок ИсНумериц ("123")

Овај код ће вратити Труе јер су сви нумерички знакови

У ВБА постоји низ функција за тестирање различитих типова података, али ово су главне:

ИсНумериц - тестира да ли је израз број или није

ИсДате - тестира да ли је израз датум или није

ИсНулл - тестира да ли је израз нула или не. Нулта вредност се може ставити само у варијантни објекат, у супротном ћете добити грешку „Неважећа употреба нуле“. Оквир за поруку враћа нулту вредност ако га користите за постављање питања, па повратна променљива мора бити варијанта. Имајте на уму да ће сваки прорачун који користи нулл вриједност увијек вратити резултат нулл.

ИсАрраи - тестира да ли израз представља низ или не

ИсЕмпти - тестира да ли је израз празан или не. Имајте на уму да празно није исто што и нулл. Променљива је празна када се први пут дефинише, али није нулл вредност

Изненађујуће, не постоји функција за ИсТект или ИсСтринг, што би било заиста корисно

Грешке објеката и неусклађености

Ако користите објекте као што су опсег или лист, добићете грешку неусклађености у време компајлирања, а не у време извођења, што вас упозорава да ваш код неће радити

123456 Под ТестРанге ()Дим МиРанге Ас Ранге, И Ас ЛонгПостави МиРанге = Распон ("А1: А2")И = 10к = УсеМиРанге (И)Енд Суб
12 Функција УсеМиРанге (Р као опсег)Завршна функција

Овај код има функцију која се зове „УсеМиРанге“ и параметар који се преноси као објекат опсега. Међутим, параметар који се преноси је Лонг Интегер који се не подудара са типом података.

Када покренете ВБА код, он се одмах компајлира и видећете ову поруку о грешци:

Увредљиви параметар биће означен плавом позадином

Генерално, ако правите грешке у ВБА коду користећи објекте, видећете ову поруку о грешци, уместо поруке о неусклађености типа:

Ви ће помоћи развој сајта, дељење страницу са пријатељима

wave wave wave wave wave