sql >> Databasteknik >  >> RDS >> Access

MS-Access Class Module och VBA

Introduktion.

De senaste veckorna har vi lärt oss hur man använder User-Defined Type (UDT) genom att skapa en komplex datastruktur och vi vet UDT:s styrka eller svaghet, mer eller mindre vid det här laget. Om du inte har gått igenom dessa artiklar kan du besöka dem. Använd följande länkar:

  • Användardefinierad datatyp-2
  • Användardefinierad datatyp-3

I Microsoft Access finns det två typer av VBA-moduler.

  1. Standardmoduler
  2. Klassmoduler

Vi har arbetat med klassmoduler på formulär och Rapporter av Microsoft Access. Form/Rapport Class Module-program är mestadels händelsedrivna (Knapp-Klick, Före-uppdatering, Formulär/Rapportera aktuell händelse, och så vidare) små rutiner.

Mer seriös databehandling Program kommer att skrivas i standardmoduler. Flera program, som inte nödvändigtvis är relaterade, kan skrivas i en standardmodul för att utföra olika uppgifter.

Klassmoduler är olika. De används för att bygga anpassade objekt och en klassmodul används för endast ett objekt.

Grunderna för fristående klassmodul.

Låt oss skapa en enkel klassmodul från grunden och lära oss grunderna.

  1. Starta Microsoft Access och öppna en databas eller skapa en ny. Om det är en ny databas, spara den i den befintliga betrodda platsen (mapp) eller lägg till den nya platsen i listan över betrodda platser. Klicka på Office-knappen -> Åtkomstalternativ -> Trust Center -> Trust Center-inställningar. Lägg till databasmappen i listan och klicka på OK.
  2. Öppna VBA-redigeringsfönstret (Alt+F11).
  3. Klicka på Infoga Meny och välj Klassmodulen från listan. En ny klassmodul är insatt.

  • I den vänstra panelen finns ett namn kontrollera med namnet Klass1.
  • Ändra namnet Klass 1 till ClsArea . Detta är namnet på vårt anpassade objekt.

  • Obs! Klassens namn:ClsArea bli objektnamnet. Det betyder att var vi än använder det här objektet kommer det att vara som en normal variabeldeklaration:Dim xyz As ClsArea . Vi skrev ett liknande uttalande för användardefinierade datatypdeklarationer.

    Därefter lägger vi till tre egenskaper (variabler) för objektet (för Beskrivning, längd, och Bredd ) överst i modulen, under Alternativ Jämför databas och Alternativ Explicit rader. Skriv in följande rader i klassmodulen.

    Alternativ Jämför DatabaseOption ExplicitPublic p_Desc som StringPublic p_Length som DoublePublic p_Width som Double

    Dessa variabler identifieras som egenskaper för VBA Custom Class Object. Spara klassmodulen.

    Obs! Vårt klassmodulobjekt och kodrader kommer inte att vara så enkelt. Den kommer att genomgå ändringar med flera rader kod. Bättre vara beredd att följa dem steg för steg, utan att tappa koll på varje förändringsstadium. Detta är en enkel areaberäkningsklass (area =längd * bredd ), så enkelt. Det kommer gradvis att genomgå förändringar så att du vet varför dessa ändringar blir nödvändiga.

    Vi kommer att skriva ett litet program i en standardmodul för att testa vår nya klassmodul. Infoga en standardmodul från Insert Menu. Du kan skriva eller kopiera och klistra in följande kod i standardmodulen och skriva över den befintliga raden i modulen:

    Alternativ Jämför databasalternativ ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.Set oArea =NothingEnd Function

    Dim uttalande deklarerar en variabel som vi gör för en normal variabel, som Dim Desc som String. Men detta är inte en vanlig variabel, vi sätter en referens till vårt klassmodulobjekt ClsArea . Eftersom det är ett objekt räcker det inte med en enkel dimensionssats ensam eftersom den inte kommer att allokera något minnesutrymme för att lagra värden i vårt lokalt definierade objekt oArea Egenskaper.

    Set uttalande på nästa rad med Ny nyckelord krävs för att skapa en instans av ett objekt från ClsArea i minnet, med objektinstansnamnet oArea . Vi kan öppna flera instanser av samma klassobjekt i minnet på detta sätt om det behövs (vi kommer att lära oss om dem under de kommande veckorna) så att vi kan lagra värden i dess egenskaper (p_Desc, p_Length, p_Width). p_ prefixet till variablerna är en indikator på att omfattningen av variabler är Privat, dvs variablerna är inte synliga utanför klassmodulen om variabeln deklareras med nyckelordet Privat, men nu är den deklarerad som Public. Variabelnamnet kan vara vilket giltigt namn som helst.

    Obs! Vi har inte deklarerat det som privat än. Vi är på väg mot den förändringen.

    Omedelbart efter sökordet Ange det lokala objektnamnet (du kan välja ett lämpligt namn du föredrar men det bör överensstämma med de vanliga reglerna för variabelnamn) följt av ett likhetstecken och nyckelordet Ny och Class Module Name (ClsArea) för att skapa en instans av clsArea-objektet i minnet med alla dess egenskaper (variabler).

    Det finns en genväg för denna tvåraderskod. Åtgärder för båda dessa kodrader kan uppnås med en sats som visas nedan :

    Dim oArea As ClsAreaSet oArea =New ClsArea'genvägen till ovanstående två uttalandenDim oArea As New ClsArea

    När du skriver nästa rad oArea följt av en prick (. ) avgränsare kommer följande display att visas för att visa listan över tillgängliga anpassade objektegenskaper att välja mellan.

    Om det inte visas, gå till dialogrutan Alternativ från menyrutan Verktyg och markera Auto List Members på Editor-fliken.

    Innan du avslutar funktionen bör den sista satsen vara Set oArea =Nothing . Detta uttalande frigör uttryckligen minnet som upptas av instansen av det anpassade objektet, så att mer minne är tillgängligt för andra program. Detta är en ansvarsfull städning av vårt program.

    Vad vi än gör med det instansierade anpassade objektet ska kodas mellan den första och sista uppsättningen uttalanden.

    ClsArea Class Object Test Program.

    Den ifyllda koden för klasstestningsprogram ges nedan:

    Alternativ Jämför DatabasOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.p_Desc ="Carpet"oArea.p_Length =25oArea.p_Width =15Debugth "Print"Descript.Wrint "Debugth.Wrint" oArea.p_Desc, oArea.p_Length, oArea.p_WidthSet oArea =NothingEnd Function

    Klicka någonstans i mitten av koden och tryck på F5 för att köra programmet. Körningen av programmet ges nedan som referens.

    Beskrivning Längd BreddMatta 25 15 

    Offentlig|Privat omfattning av objektegenskaper.

    Vårt enkla klassmodulobjekt har få nackdelar och vi kommer att rätta till dem.

    Den första är att vi har deklarerat alla variabler (eller egenskaper) med Offentliga Omfattning. På grund av det är de synliga för andra VBA-program och kan få sitt värde ändrat direkt. Det andra problemet är att det accepterar alla ogiltiga värden, som negativa eller nollvärden, vilket inte är lämpligt för vårt klassobjekt. Vi måste införliva några valideringskontroller innan vi accepterar värdena i variablerna.

    Det första problemet kan vi enkelt lösa genom att ändra variabeldeklarationerna från Offentlig till Privat . När vi gör det borde vi ha någon indirekt metod för att lagra och hämta värden från de privata variablerna. Det är syftet med Hämta och Låt Egenskapsförfaranden, för varje egendom i Objektet. Låt oss göra dessa ändringar i klassmodulen.

    Öppna klassmodulen ClsArea. Ändra ordet Public till Privat för alla tre variablerna.

    Skapa egendomsprocedurer

    Välj Procedur från Infoga Meny, skriv strDesc i Namn textkontroll, välj Egenskap i Typ Alternativgrupp och Offentlig i Omfattning alternativgrupp. Klicka på OK för att infoga egenskapsprocedurerna för Private p_Desc Variabel (Egenskap).

    Alternativ Jämför DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePublic p_Width As DoublePublic Property Få strDesc() As String strDesc =p_Desc 'returnera värdet från p_DescEnd PropertyPublic Property =Låt strDesc(ByVal-värdet StrDesc(ByVal stringNew String) som p_Desc. p_DescEnd Property

    Både Hämta Procedur och Låt Proceduren deklareras som Offentlig . Båda procedurnamnen är samma strDesc. Som standard är den returnerade datatypen är Variant i Hämta Procedur och parameterdatatyp infogas också som variant i Låt Procedur. Dessa kan vi ändra till specifika typer efter behov, vilket vi gjorde och ändrade till String typ. De tre första bokstäverna str i strDesc ger användaren en hint om att egenskapen förväntar sig ett strängdatatypvärde. Ändra Låt Egenskapsprocedur Parameter Variabelnamn vNewValue till strNewValue

    När vi infogar egenskapsproceduren infogas de alltid med Hämta och Låt Procedurpar för en variabel.

    Ta nu en närmare titt på uttrycket vi har skrivit i Hämta Procedur. Den vänstra sidan av = Skriv under namnet på Get Procedure strDesc fungerar som en variabel för att returnera värdet som kopierats från den privata variabeln p_Desc till anropsprogrammet.

    Låt Procedur strDesc accepterar strängvärde i parameter Variabel strNewValue . Ingångsvärdet överförs till vår privata variabel p_Desc.

    Poängen att notera här är att det inte finns någon direkt tillgång till vår privata variabel p_Desc till omvärlden. Transport av värden Från/Till variabeln (egenskap) p_Desc dirigeras alltid genom Get/Let Endast egendomsförfaranden och föremål för valideringskontroller (ej implementerat ännu), vi kommer att införa valideringskontroller av värden som matas in (Let Procedure) i egenskapen senare.

    Get/Let Procedurer exekveras automatiskt beroende på vad vi gör med objektegenskapen i ett uttryck i VBA-program.

    Hämta proceduren exekveras när vi använder egenskapsnamnet i ett uttryck på följande sätt:

    ‘ Läser värdet från p_Desc till PrintDebug.Print oArea.strDescOR‘ Läser värdet från p_Desc och tilldelar det till variabeln XX =oArea.strDesc

    Låt Egenskapsproceduren körs när vi försöker tilldela ett värde till egenskapsnamnet. Kontrollera exempeluttrycket i vårt testprogram nedan:

    oArea.strDesc ="Matta"

    I tidigare BASIC Language-böcker kan du se användningen av sökordet LET.

    LET X =25 ‘ LET är valfritt

    Eftersom det var valfritt fungerar uttalandet utan det och slutade använda det alls.

    Här, om du bara läser något värde från en variabel och inte lagra något i den direkt, då kan du utelämna låt-proceduren och bara använda Hämta Procedur.

    Denna regel gäller även för Let-förfarandet. Du får endast använda Låt Procedur, om du tilldelar något värde i en privat variabel men inte läser tillbaka något från samma variabel och utelämna sedan Get-proceduren.

    Hämta och Låt Procedurerna körs efter varandra om vårt uttryck är något i stil med följande:

    oArea.strDesc =oArea.strDesc &“ – King Size.”

    I uttrycket ovan kommer vi att det befintliga värdet från den privata variabeln p_Desc och ändra beskrivningen och lagra den tillbaka i samma variabel. Kort sagt i ett uttryck om du använder egenskapsnamnet till höger om likhetstecknet (= ) Hämta Procedur kallas och Låt Proceduren körs när objektegenskapens procedurnamn visas till vänster om lika (= ) tecken.

    Infoga två uppsättningar av egenskapsprocedurer för variablerna p_Length och p_Width. När du ger procedurerna namn i Namn kontroll ge namnet dblLength och dblWidth för att ge användaren en hint om att dessa egenskaper förväntar sig dubbla precisionsnummer som indata.

    ClsArea Class Object med dess egenskapsprocedurer.

    Den färdiga koden hittills med dblLength och dblWidth Property Procedures ges nedan för referens och för att uppdatera din kod.

    Alternativ Jämför DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePublic p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'kopiera värdet från p_DescEnd PropertyPublic Property Låt strDesc(ByVal StringEnV)Ny egenskap strDesc(ByVal strEnVenbl)Ny egenskap strDesc(ByVal strEnVenbl) ) 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 Double dblBW>Ny egenskap dblWidth Double dblBW>pVyVidth Double dblBW> 

    Testprogrammet med ändringar.

    Om du har slutfört koden ovan, låt oss göra ändringar i vårt testprogram för att återspegla de ändringar vi gjorde här. Den modifierade exempelkoden ges nedan.

    Alternativ Jämför DatabasOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =Ny ClsArea'Property Låt procedurer kallas hereoArea.strDesc ="Matta"oArea.dblLength =25oArea.dblLength =25oArea.dblDebuth =25oArea.dbl5Widength =15Debuth =15Debuth. "Width"'Property Hämta procedurer här för att skriva utDebug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidthSet oArea =NothingEnd Function

    När du anger en punkt (.) omedelbart efter objektnamnet oArea (oArea.) visas listan över egenskapsförfarandenamn av VBA IntelliSense och du kan välja den önskade från listan utan att skriva in den manuellt.

    Syftet med detta klassobjekt är att beräkna arean av något, som rumsarea, matta, golvplattor eller vilket material som helst, som har värden på längd och bredd. Det betyder att vi behöver en offentlig funktion för att beräkna arean av objektets längd, bredd och beskrivningsvärden som anges i klassobjektet.

    ClsArea Object Method:Area()

    Här är koden för offentlig funktion:

    Public Function Area() As Double Area =Me.dblLength * Me.dblWidthEnd Function

    Du kan infoga den här funktionen från Infoga Meny genom att gå in i Område i Namn Kontroll, välj Funktion från Typ alternativgrupp och Offentlig som Omfattning i ClsArea Class Module. Slutför funktionen genom att ange raden i mitten.

    Vi kan direkt adressera variablerna p_Length och p_Width (eftersom funktionen Area() är en del av klassmodulen) i uttrycket för beräkning av arean. Men vi tar rätt väg och anropar Get Procedures dblLength och dblWidth för beräkning. Du kanske har lagt märke till referensen Jag. används för att kvalificera dblLength, dblWidth Get-procedurerna, som vi brukade skriva i Form/Report Class Modules, för att referera till det aktuella objektet i minnet och dess egenskaper. Som jag nämnde tidigare kan vårt Custom Class Object ha flera Object-instanser öppna i minnet samtidigt och Me nyckelord hänvisar till den aktuella instansen som Function Area() tillhör.

    Testfunktionen med modifiering.

    Ändra vår testfunktion ClassTest1() för att införliva funktionen Area() enligt nedan:

    Alternativ Jämför DatabasOption ExplicitPublic Function ClassTest1()Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.strDesc ="Carpet"oArea.dblLength =25oArea.dblWidth ="15DebugthArea", "PrintengthArea", "Printength. "Debug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidth, oArea.AreaSet oArea =NothingEnd Function

    Ändringen finns endast i Debug.Print-satserna. Kör koden och kontrollera felsökningsfönstret för resultatet.

    Det finns två händelseprocedurer som krävs i de anpassade klassmodulerna:Class_Initialize() och Class_Terminate() .

    Automatisk exekveringsmetoder.

    Class_Initialize() programmet körs automatiskt när vi instansierar ett objekt med Ny Nyckelord. Detta program kan användas för att ställa in standardvärden i variabler eller instansiera andra objekt i minnet. Ett klassobjekt kan använda andra klasser som underordnade objekt och måste instansieras. Denna aspekt kommer vi att utforska ytterligare och lära oss hur man gör det senare.

    Class_Terminate() programmet körs när vi försöker rensa objektet från minnet när Ingenting nyckelordet körs i satsen Ange oArea =Ingenting . När programmet som använder klassobjektet avslutas tas instansen av objektet i minnet bort som standard. Men det är en bra programmeringspraxis att vi använder Set oArea =Nothing sats som den sista körbara satsen i våra program för att rensa objektet från minnet.

    Vi kommer att lägga till ovanstående program i vår klassmodul. Lägg till följande kod i slutet av din klassmodul:

    Private Sub Class_Initialize() p_Length =0 p_Width =0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()"End SubPrivate Sub Class_Terminate() 'MsgBox "Terminate.", vbInformation, "SubInformation()_Class 

    Om du vill testa dessa två underrutiner, ta bort kommentarsymbolen och aktivera MsgBox. Kör ditt testprogram en gång till. Du hittar Initiera meddelande visas i början (klicka på OK för att fortsätta) och Avsluta meddelande visas i slutet av testprogrammet.

    Jag vet vad du tänker nu, som "så mycket kod för att multiplicera två variabler tillsammans". Det är sant i det perspektivet, men det är mycket troligt att vi har skrivit kod för liknande problemlösningsproblem upprepade gånger varje gång, duplicerat kod för valideringskontroller och för andra logiska felskydd.

    Här skriver vi inte ett vanligt Program utan utvecklar ett Custom Object som kan användas många gånger eller kan ingå i andra Objekt, var vi än behöver det utan att oroa oss för hur det fungerar, ur användarens synvinkel. Microsoft Access har många inbyggda objekt/funktioner som vi använder hela tiden utan att oroa oss för hur det fungerar, genom att ställa in deras egenskaper eller parametrar och få jobbet gjort.

    Vi har ytterligare ett problem att ta hand om, valideringskontrollerna av värden som matas in i dblNewValue Parametern i Låt Egenskapsprocedurer för dblLength() och dblWidth(), för att säkerställa att Giltiga värden tilldelas Objektegenskaper p_Length och p_Width .

    Negativa eller nollvärden som anges anses vara ogiltiga och vi måste vidta försiktighetsåtgärder för att se att det korrekta värdet anges av användaren.

    Utför valideringskontroller.

    Den modifierade Let Segment för egendomsförfarandekod ges nedan. Gör ändringar i din kod i enlighet med detta.

    Public Property Let dblLength(ByVal dblNewValue As Double) Do While dblNewValue <=0 dblNewValue =InputBox("Negativa/0 värden ogiltiga:", "dblLength()", 0) Loop p_Length =dblNewValueB dblWid Property(yblVid PropertyPublic Property dblNewValue As Double) Gör medan dblNewValue <=0 dblNewValue =InputBox("Negativa/0 värden ogiltiga:", "dblwidth()", 0) Loop p_Width =dblNewValueEnd Property

    Gör medan. . . Slinga körs upprepade gånger tills ett giltigt värde (större än 0) anges i dblNewValue av användaren

    Verifieringskontroller i den offentliga metoden:Area()

    Vi behöver ytterligare en valideringskontroll i Area() Fungera. Om användaren anropar Area()-funktionen utan att först ange giltiga värden för Length och Width, måste användaren informeras om det. Vi kommer att kontrollera om variablerna p_Length och p_Width har giltiga värden innan vi kör uttrycket för areaberäkning. Här är koden:

    Public Function Area() As Double If (Me.dblLength> 0) And (Me.dblWidth> 0) Then Area =Me.dblLength * Me.dblWidth Else Area =0 MsgBox "Fel:Length/Width Value(s) ) Ogiltigt., Program avbröts." Avsluta IfEnd-funktionen

    Den kompletta koden för ClsArea Object.

    Den fullständigt ifyllda koden för vår klassmodul ClsArea ges nedan:

    Alternativ Jämför DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePublic p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'kopiera värdet från p_DescEnd PropertyPublic Property Låt strDesc(ByVal StringEnV)Ny egenskap strDesc(ByVal strEnVenbl)Ny egenskap strDesc(ByVal strEnVenbl) ) As Double dblLength =p_LengthEnd PropertyPublic Property Let dblLength(ByVal dblNewValue As Double) Do While dblNewValue <=0 dblNewValue =InputBox("Negativa/0 värden ogiltiga:", "dblLength()", 0) Loop dblNewValue =Property p_NewValue dblWidth() As Double dblWidth =p_WidthEnd PropertyPublic Property Låt dblWidth(ByVal dblNewValue As Double) Gör Medan dblNewValue <=0 dblNewValue =InputBox("Negativa/0 värden ogiltiga:", "dblwidth =()_WidalValueD pblNewValue" Property Funktion Area() As Double If (Me.dblLength> 0) Och (Me.dblWidth> 0) Then Area =Me.dblLength * Me.dblWidth Else Area =0 MsgBox "Fel:Längd/Bred Värde(n) ogiltigt., Program avbröts." End IfEnd FunctionPrivate Sub Class_Initialize() p_Length =0 p_Width =0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()"End SubPrivate Sub Class_Terminate() 'MsgBox "Terminate.", vblass_TminateC /pre> 

    Testa egendomsprocedurer och metoder.

    Du kan testa vårt Custom Class Object genom att ange negativa eller 0 värden som indata till egenskaperna dblLength, dblWidth.

    I testprogrammet kommentera raderna (oArea.dblLength=25 och oArea.dblWidth=15) för att testa Area()-funktionen. Det bör visa felmeddelandet som vi har skrivit i funktionen.

    Vår areaberäkningsklassmodul anses nu vara komplett och vi har testat och funnit att den fungerar korrekt. Du kan testa det ytterligare för eventuella logiska fel som jag har förbisett. Om du stöter på något som jag inte hade förutsett, vänligen dela det med mig.

    Framtidsplan för testning.

    Vi har testat klassobjektet för endast ett föremål. Vi måste beräkna arean av flera föremål (säg arean av 5 sovrum eller 10 mattor i olika storlekar och så vidare. Vi får veta att när ett objekt väl har utvecklats kan vi instansiera det flera gånger i minnet och tilldela en annan uppsättning värden i varje instans av objektet och kan arbeta med dem.

    Utöver det kan detta objekt användas som en del av andra objekt som vi utvecklar med mindre kod eftersom en del av vårt nya klassobjekt redan är utvecklat i ClsArea Class Module.

    Nästa vecka kommer vi att lära oss hur man skapar en array av anpassade objekt för att beräkna arean av flera objekt.

    1. MS-Access Class Module och VBA
    2. MS-Access VBA Class Object Arrays
    3. MS-Access basklass och härledda objekt
    4. VBA-basklass och härledda objekt-2
    5. Basklass- och härledda objektvarianter
    6. Ms-Access Recordset och Class Module
    7. Åtkomst till klassmoduler och omslagsklasser
    8. Omvandling av omslagsklassfunktionalitet
    9. Ms-Access och Collection Object Basics
    10. Ms-Access Class Module och Collection Object
    11. Tabellposter i samlingsobjekt och form
    12. Grundläggande om ordbokobjekt
    13. Dictionary Object Basics-2
    14. Sortera ordboksobjektnycklar och objekt
    15. Visa poster från ordbok till formulär
    16. Lägg till klassobjekt som ordboksobjekt
    17. Uppdatera Class Object Dictionary-objekt på formulär


    1. Hur FORMAT()-funktionen fungerar i SQL Server (T-SQL)

    2. Åtgärda felet "ORA-01789:frågeblocket har felaktigt antal resultatkolumner"

    3. Hur använder man PBKDF2 i Oracle 12c?

    4. Vad är bättre för din big data-applikation, SQL eller NoSQL?