|
HændelserAuto-hændelser
En hændelse er noget, der indtræffer i fx skærmbillede, regneark eller brugerdefinerede formularer mm. En definition er, at "en hændelse er et begreb, der bruges om en meddelelse, der sendes fra Windows til et program, når noget bestemt indtræffer". Klikker jeg fx med min mus på printknappen i Excel, sender Windows en besked til Excel om, at et "museklik" har fundet sted i forbindelse med objektet "Print knap". Nu kan Excel så reagere på hændelsen og udføre den funktion, der er forbundet med knappen. Der er mange forskellige hændelser, der kan indtræffe i Excel. Alle sendes fra Windows til Excel, men Excel reagerer kun på nogle af dem. Et dobbeltklik med musen i Statuslinjen vil således ikke medføre nogen reaktion fra Excel, mens et højreklik samme sted vil vise en genvejsmenu. Der er formodentlig langt flere hændelser, der ikke medfører en reaktion, end det omvendte.
NB! Det er ikke kun "eksterne" påvirkninger, der udløser hændelser. Det kan interne ting også gøre, fx at Excel udfører en beregning.
Der findes en lang række hændelser som ikke umiddelbart medfører en reaktion, men som alligevel opfanges. I disse tilfælde kan man så selv programmere en procedure, som gør et eller andet, når hændelsen indtræffer. En sådan procedure, som udføres som reaktion på en hændelse, kaldes en hændelsesprocedure.
Excel har et større antal hændelser, som der kan knyttes hændelsesprocedurer til. Disse hændelser kan være knyttet til projektmappen, et enkelt ark i en mappe, kontrolelementer i et ark, brugerdefinerede formularer, elementer i formularer osv. Herudover har Excel et antal såkaldte "On" nøgleord. Også disse anvendes til at knytte kode til hændelser. Endelig har Excel et antal såkaldte "Auto" procedurer, som igen udføres når bestemte ting indtræffer. Forskellen på disse nøgleords- og autoprocedurer og andre hændelsesprocedurer er, at nøgleords- og autoprocedurerne gemmes i almindelige moduler, mens de øvrige hændelsesprocedurer skal gemmes i særlige klassemoduler.
"Auto"-hændelserAlle "Auto" funktionerne er altid knyttet til hele projektmappen. Der findes fire af slagsen: Auto_Open, Auto_Close, Auto_Activate, og Auto_Deactivate. De pågældende hændelser indtræffer når en projektmappe åbnes, lukkes, aktiveres eller deaktiveres.
Prøv at skrive følgende kode i et almindeligt modul. Gem og luk projektmappen og åbn den så igen:
Sub Auto_Open() MsgBox "Så er den åbnet" End Sub
Auto_Open bruges ofte til at indstille de forskellige "On" funktioner. Ret ovenstående kode til:
Sub Auto_Open() Application.OnKey "{a}", "Mbox" End Sub
I samme modul skriver du så
Sub Mbox() MsgBox "Du har trykket på a-tasten" End Sub
Gem og luk igen mappen. Åbn den og prøv at trykke på a-tasten. Husk at slette koden igen inden du gemmer og lukker. Ellers får du problemer med a-tasten i den projektmappe fremover :-)
"On…"De 12 "on" nøgleord, der kan bruges i Excel er
For disse kodeord skal virke, skal de altså være aktiveret via en anden makro, typisk Auto_Open, men det kan også være andre makroer. Søg på de pågældende nøgleord i VBA hjælpen for at lære syntaksen for de enkelte ord. Specielt omkring OnKey skal man være opmærksom på, at en række knapper "fanges" ved at skrive navnet på knappen, og disse er ikke alle lige gennemskuelige. Fx fanges Pil Ned med {DOWN}, ikke med {DOWN ARROW}. Læg også mærke til at navnene på tasterne, med en enkelt undtagelse, altid skrives mellem tuborgparenteser og i øvrigt pakkes ind i anførselstegn. Vær specielt opmærksom på, at Enter tasten på det numeriske tastatur fanges med {ENTER}. Undetagelsen fra reglen om Tuborg-prarenteserne er Enter-tasten på skrivemaskinetastaturet, der fanges med ~ (accent tilde). Af én eller anden for mig ukendt grund skal netop denne kommando IKKE i tuborgparenteser.
Skal man bruge tastekombinationer som Skift+noget, Alt+noget eller Ctrl+noget, bruger man et eller flere foranstillede tegn, der står uden for tuborgparentesen. "+" for Skift, "^" for Ctrl og "%" for Alt.
Betyder altså at proceduren MText udføres, hvis der trykkes på Skift+Ctrl+Insert.
Workbook-hændelserUdover de allerede omtalte Auto-procedurer og On-kommandoer, har Excel en lang række hændelser, der alle er knyttet til såkaldte klassemoduler. Jeg vil vende tilbage til, hvordan man selv kan oprette og bruge klassemoduler i en senere artikel. I denne omgang vil jeg nøjes med at se på de klassemoduler, som allerede findes i Excel.
Hvis man starter Visual Basic editoren i en tom projektmappe, vil man typisk se noget der ligner følgende i venstre side af skærmen. Dette ses i den såkaldte Project Explorer. Er denne ikke vist, skal du vælge View – Project Explorer. Her ses mappens ark. Har du omdøbt arkene, vil dine navne stå i parentesen i stedet for fx Ark1. Til hvert ark, er der knyttet et klassemodul. Det samme er der til hele projektmappen. Klassemodulet til hele projektmappen er det, der hedder ThisWorkbook. Dobbeltklik på det klassemodul, du vil arbejde med.
I første omgang vil jeg se nærmere på ThisWorkbook, senere vender jeg tilbage til arkene. Når der dobbeltklikkes på ThisWorkbook, åbnes et modul, der ligner alle andre moduler. På en enkelt undtagelse nær. Når man klikker på ruden, hvor der står General i et almindeligt modul, er det, det eneste der står. I et klassemodul er der yderligere en valgmulighed. Hvilken afhænger af om klassemodulet vedrører ThisWorkbook eller et ark.
I dette tilfælde ses punktet Workbook. Vælges dette punkt, vil der blive indsat en procedurestart/slut, og i ruden ved siden af, vil der blive vist Open.
Private Sub Workbook_Open()
End Sub
I ruden, hvor der står Open kan der nu vælges et antal hændelser, der er knyttet til projektmappen. Skal man ikke bruge den hændelsesprocedure, der vises, sletter man bqre de to kodelinjer. Der kan vælges mellem næsten 30 forskellige hændelser, og det vil føre alt for vidt at komme ind på dem alle i denne sammenhæng. Jeg vil derfor nøjes med at komme ind på et par af de mest almindeligt brugte hændelser. Et problem med brugen af hændelser, kan være at flere hændelser tilsyneladende kan optræde samtidigt, og derfor kan man være i tvivl om, hvilken hændelse man skal anvende. Imidlertid er der ingen hændelser, der optræder samtidigt. De optræder alle i rækkefølge. Er man i tvivl om, hvilken hændelse af to, der indtræffer først, kan man undersøge det, ved at anvende begge hændelser og lade dem vise en forskellig meddelelsesboks. Så kan man se, hvilken af disse, der bliver vist først. På den måde kan man fx konstatere at Workbook_Open indtræffer før Auto_Open, og at Sheet_Change indtræffer før Sheet_SelectionChange.
Workbook_Open indtræffer når projektmappen åbnes. Denne hændelse kan man bruge til fx at bede brugerne om at gøre noget eller til at iværksætte ”ON”-kommandoer osv.
Private Sub Workbook_Open() Sheets(1).(Range("A1").Value = InputBox("Indtast dit navn og klik OK") End Sub
Når projektmappen åbnes bliver brugeren bedt om at indtaste sit navn. Dette skrives i celle A1 i det først ark.
Workbook_BeforeClose indtræffer, når brugeren klikker på Luk-knappen eller vælger Luk i menuen. Hændelsen indtræffer lige inden der lukkes, og det kan så udnyttes til forskellige ting.
Private Sub Workbook_BeforeClose(Cancel As Boolean) Application.EnableEvents = False If IsEmpty(Range("a1")) Then MsgBox "Du skal udfylde celle A1 og gemme igen inden du lukker" Cancel = True End If Application.EnableEvents = True End Sub
Sikrer at celle A1 er udfyldt inden der lukkes. Linjerne Application.EnableEvents = False og Application.EnableEvents = True samt Cancel = True, sikrer at hændelsen ikke indtræffer efter at koden er udført, hvis A1 faktisk er tom. Er disse linjer ikke tilstede, vises meddelelsesboksen godt nok, men derefter indtræffer hændelsen alligevel og regnearket lukkes selv om A1 er tom.
Workbook_Activate og Workbook_Deactivate indtræffer når projektmappen aktiveres/ deaktiveres. Disse er interesante hvis brugeren kan skifte til en anden projektmappe og tilbage igen.
Workbook_BeforePrint indtræffer når brugeren vil udskrive projektmappen og indtræffer lige inden udskriften finder sted. Dette kan bruges til at styre forhold omkring udskrift. Under makroer, kan du finde et eksempel der udnytter BeforePrint hændelsen til at ændre baggrundsfarve i et regneark, inden der printes.
Worksheet-hændelserDer er altså mange andre hændelser, der kan bruges i en projektmappe, men jeg vil lade det ligge ved dette, og så vende mig mod de enkelte ark.
For at komme ind i et enkelt arks klassemodul, skal man dobbeltklikke på arknavnet i Project Explorer. Ellers er metoden den samme som anført for ThisWorkbook, bortset fra at man skal vælge Worksheet i stedet for Workbook i ruden øverst til venstre over modulet. Standardhændelsen, der vælges, er Worksheet_SelectionChange. På arkniveau er der kun ni hændelser, der kan anvendes. Jeg vil også her gennemgå nogle udvalgte og så overlade resten til egen nysgerrighed J.
Worksheet_Activate indtræffer når der skiftes mellem ark i mappen, og det ark, som indeholder koden, aktiveres. I koden nedenfor vises bare en meddelelsesboks, der fortæller brugeren, at arket er aktivt. Worksheet_Deactivate indtræffer modsætningsvis når arket gøres inaktivt ved at man skifter til et andet ark.
Private Sub Worksheet_Activate() MsgBox (ActiveSheet.Name & " er aktivt") End Sub
Har jeg en Deactivate i Ark2 og en Activate i Ark1, vil et lille forsøg vise, at når der skiftes fra Ark2 til Ark1, indtræffer Deactivate før Activate.
Worksheet_BeforeDoubleClick indtræffer når der dobbeltklikkes i en celle og Worksheet_BeforeRightClick indtræffer på samme måde når der højreklikkes. Begge dele indtræffer umiddelbart før den hændelse, der ellers er forbundet med aktiviteten. Fx vil et dobbeltklik i en celle aktivere cellen for indtastning. Også her kan man med fordel anvende Application.EnableEvents osv. til at ”annullere” den oprindelige hændelse, hvis det er nødvendigt.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) MsgBox "Du har dobbeltklikket" End Sub
Koden her vil vise meddelelsesboksen uanset hvilken celle, der klikkes i. Det er man sjældent interesseret i. Derfor indbygger man ofte en test på, hvilken celle, der er dobbeltklikket på eller om cellen der dobbeltklikkes på ligger inden for et bestemt celleområde. Dette kan gøres på flere forskellige måder, men de udnytter alle den ”indbyggede” variabel Target. Denne indeholder netop oplysninger om den celle, som hændelsen udføres på. De metoder, jeg skitserer nedenfor kan tilsvarende bruges i alle andre hændelser, hvor der skal testes på Target.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Address = "$A$1" Then MsgBox "Du har dobbeltklikket" End If End Sub
Koden her undersøger om der er dobbeltklikket i A1 og i det tilfælde udløses koden. Target.Row = 1 eller Target.Column = 3 udløser meddelelsesboksen i hele række 1 eller kolonne 3. De to kan selvfølgelig også parres: If Target.Row = 1 Or Target.Column = 3 Then…
Der er altså mange måder at opnå det samme på. En sidste mulighed, hvis der er tale om et større område er at bruge kommandoen Intersect. Den bruges til at undersøge sammenfald mellem to områder. Den kan bruges som følger:
If Not Intersect(Target, Range("A1:D100")) Is Nothing Then
og undersøger om Target ligger inden for det område der specificeres i Range. Intersect undersøger sammenfaldet. ”Is Nothing” indtræffer, hvis der ikke er sammenfald og Not vender det om. Det vil altså sige, at vi siger ”hvis der ikke, ikke er sammenfald” skal der ske noget. Se eksemplet nedenfor under Worksheet_Change.
Worksheet_Calculate indtræffer, når der er foretaget en ændring i regnearket, der forårsager en genberegning. Det sker fx hvis der ændres i en celle, der påvirker en formel.
Worksheet_SelectionChange indtræffer når markøren flyttes fra en celle til en anden. Target er her den celle som der skiftes til. Flytter jeg cellemarkøren fra A2 til A1, er det A1, der er Target.
Worksheet_Change indtræffer, når der ændres i en celle. Selve hændelsen indtræffer først, når indtastningen ”accepteres” fx ved tryk på Enter. Target er her den celle, der ændres i.
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("A2:B10")) Is Nothing Then If Target.Value <> "" Then If IsNumeric(Target.Value) Then Target.Offset(0, 1).Value = Target.Offset(0, 1).Value + Target.Value End If Target.Value = "" End If End If End Sub
Ovenstående kode undersøger først om der tastes i området A2 til B10. Er det tilfældet undersøges om det, der tastes er ”tomt”. Tastes der faktisk en værdi, undersøges om der er tale om et tal. Hvis der er tale om et tal, vil tallet blive lagt til i C-kolonnen ud for den række, hvor der er tastet i enten A- eller B-kolonnen. Står der fx 7 i C3 vil en indtastning af 3 i enten A3 eller B3 blive lagt til i C3, så der nu står 10 her. Indtastes der en tekst eller ingenting, sker der heller ingenting. Under alle omstændigheder slettes indtastningen så A2:B10 altid er tomme.
Et spørgsmål, som man ofte stilles overfor, er om ikke der er en hændelse, der indtræffer MENS man taster i en celle i stedet for først når der trykkes Enter. Svaret på det er ganske kort: Nej! Der findes ikke en sådan hændelse og der kan i det hele taget slet ikke afspilles kode mens en celle er under redigering. Derimod er det muligt at få afspillet kode, når der tastes i en tekstboks i en brugerdefineret formular.
Udover de hændelser, der kan knyttes til ark og projektmapper, kan der også knyttes hændelser til kontrolelementer og brugerdefinerede formularer. Koden til kontrolelementer i ark gemmes i arkets klassemodul. Kode til kontrolelementer i brugerdefinerede formularer gemmes i et klassemodul tilhørende den konkrete formular. Jeg vil ikke komme yderligere ind på disse hændelser på nuværende tidspunkt, men vender tilbage til dem senere i en artikel om opbygning af applikationer.
- Til Top -
|