Въведение.
Последните няколко седмици се научихме как да използваме User-Defined Type (UDT), като създадем сложна структура от данни и вече знаем силата или слабостта на UDT, повече или по-малко. Ако не сте преминали през тези статии, можете да ги посетите. Използвайте следните връзки:
- Дефинирани от потребителя тип данни-2
- Дефинирани от потребителя тип данни-3
В Microsoft Access има два типа VBA модули.
- Стандартни модули
- Модули за клас
Работили сме с модули за клас върху формуляри и Отчети на Microsoft Access. Програмите на модула за клас формуляри/отчет са предимно управлявани от събития (кликвания върху бутони, преди актуализиране, формуляр/отчет за текущо събитие и т.н.) малки рутинни програми.
По-сериозните програми за обработка на данни ще бъдат написани в стандартни модули. Няколко програми, които не са непременно свързани, могат да бъдат написани в един стандартен модул, за да изпълняват различни задачи.
Класовите модули са различни. Те се използват за изграждане на персонализирани обекти и един модул на клас се използва само за един обект.
Основите на самостоятелния модул за клас.
Нека създадем прост модул за клас от нулата и да научим основите.
- Стартирайте Microsoft Access и отворете база данни или създайте нова. Ако е нова база данни, тогава я запазете в съществуващото доверено местоположение (папка) или добавете новото местоположение към списъка с надеждни местоположения. Щракнете върху бутона Office –> Опции за достъп –> Център за доверие –> Настройки на Центъра за доверие. Добавете папката на базата данни в списъка и щракнете върху OK.
- Отворете прозореца за редактиране на VBA (Alt+F11).
- Щракнете върху Вмъкване Меню и изберете Модул за клас от списъка. Вмъква се нов модул за клас.
Забележка: Името на класа:ClsArea стане името на обекта. Това означава, че където и да използваме този обект, той ще бъде като нормална декларация на променлива:Dim xyz As ClsArea . Написахме подобно изявление за декларациите за потребителски дефинирани типове данни.
След това ще добавим три свойства (променливи) на обекта (за описание, дължина, и Ширина ) в горната част на модула, под Опция за сравнение на база данни и Изрична опция линии. Въведете следните редове в модула за клас.
Опция Сравнете DatabaseOption ExplicitPublic p_Desc като StringPublic p_Length като DoublePublic p_Width като Double
Тези променливи се идентифицират като свойства на VBA Custom Class Object. Запазете модула на класа.
Забележка: Нашият обект на клас модул и редове код няма да са толкова прости. Той ще претърпи промени с няколко реда код. По-добре бъдете готови да ги следвате стъпка по стъпка, без да губите следата на всеки етап от промените. Това е прост клас за изчисляване на площ (площ =дължина * ширина ), толкова просто. Той постепенно ще претърпява промени, така че да знаете защо тези промени са необходими.
Ще напишем малка програма в стандартен модул, за да тестваме новия ни клас модул. Поставете стандартен модул от менюто Insert. Можете да въведете или копирате и поставите следния код в стандартния модул, като презапишете съществуващия ред в модула:
Опция Compare DatabaseOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.Set oArea =NothingEnd Function
Затъмнение оператор декларира променлива, както правим за нормална променлива, като Dim Desc като String. Но това не е обикновена променлива, ние задаваме препратка към нашия обект Class Module ClsArea . Тъй като това е обект, само прост израз на Dimension не е достатъчен, защото няма да задели никакво пространство в паметта за съхраняване на стойности в нашия локално дефиниран обект oArea Свойства.
Наборът изявление в следващия ред с Ново необходима ключова дума, за да създадете екземпляр на обект извън ClsArea в паметта с името на екземпляр на обект oArea . Можем да отворим няколко екземпляра на един и същ обект на класа в паметта по този начин, ако е необходимо, (ще научим за тях през следващите седмици), за да можем да съхраняваме стойности в неговите свойства (p_Desc, p_Length, p_Width). p_ префиксът към променливите е индикатор, че обхватът на променливите е частен, т.е. променливите не се виждат извън модула на класа, ако променливата е декларирана с ключовата дума Private, но сега тя е декларирана като публична. Името на променливата може да бъде всяко валидно име.
Забележка: Все още не сме го декларирали като частен. Ние сме на път към тази промяна.
Веднага след ключовата дума Set името на локалния обект (можете да изберете подходящо име, което предпочитате, но то трябва да отговаря на нормалните правила за име на променлива), последвано от знак за равенство и ключовата дума Ново и Името на модула на класа (ClsArea) за да създадете екземпляр на обекта clsArea в паметта с всички негови свойства (променливи).
Има пряк път за този двуредов код. Действията на двата реда код могат да бъдат постигнати с едно изявление, както е показано по-долу:
Dim oArea като ClsAreaSet oArea =New ClsArea'прекият път към горните два оператораDim oArea като нова ClsArea
Когато въведете следващия ред oArea последвано от точка (. ) ще се появи следният дисплей, за да се покаже списъкът с наличните свойства на персонализирани обекти, от които да избирате.
Ако не се появи, отидете в диалоговия прозорец Опции от полето на менюто Инструменти и поставете отметка в Автоматични членове на списъка в раздела Редактор.
Преди да излезете от функцията, последният израз трябва да бъде Set oArea =Nothing . Този израз изрично освобождава паметта, заета от екземпляра на персонализирания обект, така че да има повече памет за други програми. Това е отговорна операция за почистване от нашата програма.
Каквото и да правим с инстанциирания персонализиран обект, трябва да бъде кодирано между първия и последния набор изявления.
Програмата за тест за обект на клас ClsArea.
Попълненият програмен код за тестване на клас е даден по-долу:
Опция Compare DatabaseOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.p_Desc ="Carpet"oArea.p_Length =25oArea.p_Width"",PrintLonthDebuntg",PrintLDebunth",PrintLhDebunth",Print oArea.p_Desc, oArea.p_Length, oArea.p_WidthSet oArea =NothingEnd функция
Щракнете някъде в средата на кода и натиснете F5 за да стартирате програмата. Работата на програмата е дадена по-долу за справка.
Описание Дължина ШиринаКилим 25 15
Обществен|Частен обхват на свойствата на обекта.
Нашият прост обект Class Module има няколко недостатъка и ние ще ги поправим.
Първото е, че сме декларирали всички променливи (или свойства) с Public Обхват. Поради това те са видими за други VBA програми и могат да променят стойността си директно. Вторият проблем е, че ще приеме всякакви невалидни стойности, като отрицателни или нулеви стойности, което не е подходящо за нашия Class Object. Трябва да включим някои проверки за валидиране, преди да приемем стойностите в променливите.
Първият проблем, който можем да решим лесно, като променим декларациите на променливите от Public на Private . Когато правим това, трябва да имаме някакъв индиректен метод за съхраняване и извличане на стойности от частните променливи. Това е целта на Вземете и Нека Процедури за свойства, за всяко свойство на обекта. Нека направим тези промени в модула за клас.
Отворете клас модул ClsArea. Променете думата Public на Private и за трите променливи.
Създаване на процедури за собственост
Изберете Процедура от Вмъкване Меню, въведете strDesc в Име текстов контрол, изберете Свойство в Тип Група опции и Обществени в Обхват група опции. Щракнете върху OK, за да вмъкнете процедурите за собственост за Private p_Desc Променлива (свойство).
Option Compare DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width Като DoublePublic Property Вземете strDesc() Като String strDesc =p_Desc 'връщане на стойността от p_DescEnd PropertyPublic p_Length As DoublePrivate p_Width Като DoublePublic Property Вземете strDesc() Като String strDesc =p_Desc 'връщане на стойността от p_DescEnd PropertyPublic PropertyPublic в str. p_DescEnd Property
И двете Вземи Процедура и Нека Процедурата е декларирана като Публична . Имената на двете процедури са еднакви strDesc. По подразбиране върната типът данни е Вариант в Вземете Процедурата и типът данни за параметър също се вмъкват като Variant в Let Процедура. Те можем да променим на конкретни типове според нуждите, което направихме и променихме на String Тип. Първите три букви str в strDesc дава на потребителя намек, че свойството очаква стойност за тип данни String. Променете Let Процедура за свойство Параметър Име на променлива vNewValue до strNewValue
Когато вмъкнем процедурата за свойство, те винаги се вмъкват с Вземи и Нека Процедурни двойки за променлива.
Сега разгледайте внимателно израза, който сме написали в Вземете Процедура. Лявата страна на = Подпишете името на процедурата за получаване strDesc действа като променлива за връщане на стойността, копирана от частната променлива p_Desc към програмата за извикване.
Нека Процедура strDesc приема стойност на низ в параметър Променлива strNewValue . Входната стойност се прехвърля в нашата частна променлива p_Desc.
Тук трябва да се отбележи, че няма директен достъп до нашата частна променлива p_Desc до външния свят. Превоз на ценностиОт/До променливата (свойство) p_Desc винаги се насочва през Get/Let Само процедури за собственост и подлежат на проверки за валидиране (все още не е внедрен), По-късно ще въведем проверки за валидиране на въведените стойности (Let Procedure) в свойството.
Get/Let Процедурите се изпълняват автоматично в зависимост от това какво правим със свойството Object в израз във VBA програми.
Вземете процедурата се изпълнява, когато използваме името на свойството в израз по следния начин:
‘ Чете стойността от p_Desc към PrintDebug.Print oArea.strDescOR‘ Чете стойността от p_Desc и я присвоява на променливата XX =oArea.strDesc
Нека Процедурата за свойство се изпълнява, когато се опитваме да присвоим стойност в Името на свойството. Проверете примерния израз в нашата тестова програма по-долу:
oArea.strDesc =„Килим“
В по-ранни книги за BASIC Language можете да видите използването на ключовата дума LET.
LET X =25 ‘ LET е по избор
Тъй като беше по избор, операторът работи без него и изобщо спря да го използва.
Тук, ако само четете някаква стойност от променлива и да не съхранявате нищо в нея директно, тогава можете да пропуснете процедурата Let и да използвате само Get Процедура.
Това правило важи и за процедурата Let. Можете да използвате само Let Процедура, ако виназначаватете някаква стойност в частна променлива, но не чете нищо обратно от същата променлива, след което пропуснете процедурата Get.
Вземете и Нека Процедурите ще се изпълняват една след друга, ако нашият израз е нещо като следното:
oArea.strDesc =oArea.strDesc &„ – King Size.“
В горния израз ще Получаваме съществуващата стойност от частната променлива p_Desc и променете описанието и го съхранете обратно в същата променлива. Накратко сизразо ако използвате името на свойството вдясно от знака за равенство (= ) Вземете Процедурата се извиква и Нека Процедурата се изпълнява, когато името на процедурата за свойство на обекта се появи вляво от равното (= ) знак.
Вмъкнете два набора от процедури за свойства за променливите p_Length и p_Width. Когато дадете имената на процедурите в Име контрол дайте името dblLength и dblWidth за да дадете намек на потребителя, че тези свойства очакват числа с двойна точност като вход.
Обект на клас ClsArea с неговите процедури за свойства.
Завършеният код до момента с процедурите за свойства на dblLength и dblWidth е даден по-долу за справка и за актуализиране на вашия код.
Option Compare DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'copy the value from p_DescEnd PropertyPublic Property Let strDesc(ByVal strNewValue As String) p_Desc =strNewValueEnd PropertyPublic Property Get dblLength( ) As Double dblLength =p_LengthEnd PropertyPublic Property Let dblLength(ByVal dblNewValue As Double) p_Length =dblNewValueEnd PropertyPublic Property Get dblWidth() As Double dblWidth =p_WidthEnd PropertyPublic Property Let dblWidth(ByVal dblNewValue As Double) p_Width =dblNewValueEnd Property
Тестовата програма с промени.
Ако сте завършили горния код, оставете ни да направим промени в нашата тестова програма, за да отразим промените, които направихме тук. Модифицираният примерен код е даден по-долу.
Опция Compare DatabaseOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsArea'Property Let процедурите, извикани hereoArea.strDesc ="Carpet"oArea.dblLength =25oWidtha,PriblLength =25oWidtha,PriblLength =25oWidtha. Свойство "Width"' Вземете процедури, извикани тук, за да printDebug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidthSet oArea =NothingEnd Function
Когато въведете точка (.) непосредствено след името на обекта oArea (oArea.), списъкът с имена на процедурите за свойства се показва от VBA IntelliSense и можете да изберете желания от списъка, без да го въвеждате ръчно.
Целта на този клас обект е да се изчисли площта на нещо, като площ на стая, килим, подова плочка или какъвто и да е материал, които имат стойности на дължина и ширина. Това означава, че имаме нужда от публична функция, за да изчислим площта на стойностите на дължината, ширината и описанието на всеки елемент, въведени в обекта на класа.
Метод на обект ClsArea:Area()
Ето Кодекса за обществените функции:
Обществена функционална зона() като двойна площ =Me.dblLength * Me.dblWidthEnd функция
Можете да вмъкнете тази функция от Вмъкване Меню с въвеждане на Област в Име Контролирайте, като изберете Функция от Тип група опции и Обществен като Обхват в модула за клас ClsArea. Завършете функцията, като въведете реда в средата.
Можем директно да адресираме p_Length и p_Width променливи (защото функцията Area() е част от модула на класа) в израза за изчисляване на Площта. Но ние поемаме правилния маршрут и извикваме Get Procedures dblLength и dblWidth за изчисление. Може да сте забелязали препратката Аз използва се за квалифициране на dblLength, dblWidth Get Procedures, както писахме в модулите на класа на формуляр/отчет, за да се позовава на текущия обект в паметта и неговите свойства. Както казах по-рано, нашият Custom Class Object може да има няколко екземпляра на обект, отворени в паметта едновременно и Me ключова дума се отнася до текущия екземпляр, към който принадлежи Функционалната област().
Тестовата функция с модификация.
Променете нашата тестова функция ClassTest1(), за да включите изхода на функцията Area(), както е по-долу:
Опция Compare DatabaseOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.strDesc ="Carpet"oArea.dblLength =25oArea.dblWidth",Area.dblLength =25oArea.dblWidth,Area.dblLength,Area.dblLength,Area.dblLength,Area.dblLength,Area.dblLength,Area.dblLength. „Debug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidth, oArea.AreaSet oArea =NothingEnd Function
Промяната е само в операторите Debug.Print. Изпълнете кода и проверете резултата в прозореца за отстраняване на грешки.
Има две процедури за събития, необходими в модулите за персонализиран клас:Class_Initialize() и Class_Terminate() .
Методи за автоматично изпълнение.
Class_Initialize() програмата се изпълнява автоматично, когато инстанцираме обект с Нов Ключова дума. Тази програма може да се използва за задаване на стойности по подразбиране в променливи или за създаване на други обекти в паметта. Един обект на клас може да използва други класове като дъщерен обект(и) и трябва да бъде инстанциран. Този аспект ще проучим допълнително и ще научим как да го направим по-късно.
Class_Terminate() програмата се стартира, когато се опитаме да изчистим обекта от паметта, когато Нищо ключовата дума се изпълнява в израза Задайте oArea =нищо . Когато програмата, която използва Class Object, приключи, екземплярът на обекта в паметта се премахва по подразбиране. Но е добра практика за програмиране, че използваме Set oArea =Nothing оператор като последния изпълним оператор в нашите програми за изчистване на обекта от паметта.
Ще добавим горните програми в нашия клас модул. Добавете следния код в края на вашия модул за клас:
Private Sub Class_Initialize() p_Del
Ако искате да тествате тези две подпрограми, тогава премахнете символа за коментар и направете MsgBox активен. Стартирайте тестовата си програма още веднъж. Ще намерите Инициализиране съобщението се появява в началото (Щракнете върху OK, за да продължите) и Прекратяване съобщение се появява в края на тестовата програма.
Знам какво си мислите досега, като „толкова много код за умножаване на две променливи заедно“. От тази гледна точка е вярно, но е много вероятно да сме писали код за подобни проблеми при решаване на проблеми всеки път, дублирайки код за проверки за валидиране и за други предпазни мерки за логически грешки.
Тук ние не пишем обикновена програма, а разработваме персонализиран обект, който може да се използва много пъти или може да бъде част от други обекти, където и да ни трябва, без да се притесняваме как работи, от гледна точка на потребителя. Microsoft Access има много вградени обекти/функции, които използваме през цялото време, без да се притесняваме как работи, като зададем техните свойства или параметри и свършим работата.
Имаме още един проблем, за който трябва да се погрижим, проверките за валидиране на стойности, въведени в dblNewValue Параметър в Let Процедури за свойства на dblLength() и dblWidth(), за да се гарантира, че валидните стойности се присвояват на свойствата на обекта p_Length и p_Width .
Въведените отрицателни или нулеви стойности се считат за невалидни и ние трябва да вземем предпазни мерки, за да видим, че правилната стойност е въведена от Потребителя.
Извършване на проверки за валидиране.
Модифицираният Let По-долу са дадени сегментите на процесуалния кодекс за собственост. Направете съответните промени в кода си.
Public Property Let dblLength(ByVal dblNewValue As Double) Do While dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values Invalid:", "dblLength()", 0) Loop p_LengthVelty(dblEublicWind) dblNewValue As Double) Направете Докато dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values Invalid:", "dblwidth()", 0) Loop p_Width =dblNewValueEnd Property
Прави докато. . . Примката изпълнява многократно, докато валидна стойност (по-голяма от 0) не бъде въведена в dblNewValue от потребителя
Проверки за валидиране в публичния метод:Area()
Нуждаем се от още една проверка за валидиране в Area() Функция. Ако потребителят извика функцията Area() без първо да въведе валидни стойности за дължина и ширина, тогава потребителят трябва да бъде информиран за това. Ще проверим дали променливите p_Length и p_Width имат валидни стойности, преди да стартираме израза за изчисляване на площ. Ето кода:
Public Function Area() As Double If (Me.dblLength> 0) И (Me.dblWidth> 0) Тогава Area =Me.dblLength * Me.dblWidth Друга област =0 MsgBox „Грешка:Стойност(и) на дължина/ширина ) Невалидно. Програмата е прекъсната." Край на функцията IfEnd
Пълният код на обекта ClsArea.
Напълно попълненият код на нашия клас модул ClsArea е даден по-долу:
Option Compare DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'copy the value from p_DescEnd PropertyPublic Property Let strDesc(ByVal strNewValue As String) p_Desc =strNewValueEnd PropertyPublic Property Get dblLength( ) As Double dblLength =p_LengthEnd PropertyPublic Property Нека dblLength(ByVal dblNewValue As Double) Do While dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values Invalid:", "dblLengthPer Property" (dblLengthP) Get dblWidth() As Double dblWidth =p_WidthEnd PropertyPublic Property Нека dblWidth(ByVal dblNewValue As Double) Do While dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values Invalidth:", "dblNewValue Invalidth:", "dblNewValue" =InputBox("Negative/0 Values Invalidth:", "dblNewValue"). Функция Area() като двойно If (Me.dblLength> 0) и (Me.dblWidth> 0) Тогава Area =Me.dblLength * Me.dblWidth Друга област =0 MsgBox "Грешка:Стойност(и) на дължина/ширина е невалидна. Програмата е прекратена." Край IfEnd FunctionPrivate Sub Class_Initialize() p_Length =0 p_Width =0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()"End SubPrivate Sub Class_Terminate() 'MsgBox "TerminateT, "C vbste_Information.", "C vbste_Information.", "C vbs_Information." /предварително>Процедури и методи за тестване на свойства.
Можете да тествате нашия Custom Class Object, като въведете отрицателни или 0 стойности като вход в dblLength, dblWidth Properties.
В тестовата програма Коментирайте редовете (oArea.dblLength=25 и oArea.dblWidth=15), за да тествате функцията Area(). Той трябва да покаже съобщението за грешка, което сме написали във функцията.
Нашият модул за клас за изчисляване на площ вече се счита за завършен и ние тествахме и установихме, че работи правилно. Можете да го тествате допълнително за всякакви логически грешки, които съм пренебрегнал. Ако попаднете на нещо, което не съм очаквал, моля, споделете го с мен.
Бъдещ план за тестване.
Тествахме Class Object само за един елемент. Трябва да изчислим площта на няколко елемента (да речем площта на 5 спални или 10 килима с различни размери и т.н. Казват ни, че след като даден обект е разработен, можем да го инстанцираме няколко пъти в паметта, присвоявайки различен набор от стойности във всеки екземпляр на обекта и може да работи с тях.
Освен това, този обект може да се използва като част от други обекти, които разработваме с по-малък код, тъй като част от нашия нов клас обект вече е разработен в модула за клас ClsArea.
Следващата седмица ще научим как да създадем масив от персонализирани обекти, за да изчислим площта на няколко елемента.
- Модул за MS-Access Class и VBA
- Обектни масиви от клас VBA на MS-Access
- Основен клас на MS-Access и производни обекти
- Базов клас на VBA и производни обекти-2
- Варианти на основен клас и производен обект
- Ms-Access Recordset and Class Module
- Достъп до модул за класове и класове за обвивка
- Преобразуване на функционалност на класа на обвивката
- Основи на Ms-Access и колекция обекти
- Модул за клас Ms-Access и обект на колекция
- Записи в таблицата в обект и форма на колекция
- Основи на обекта на речника
- Основи на обекта на речника-2
- Сортиране на ключове и елементи в речника
- Показване на записи от речник към формуляр
- Добавяне на обекти на клас като елементи от речника
- Актуализиране на елемент от речника на обект на клас във формуляра