|
Objekter i ExcelExcel (og de øvrige programmer i Office pakken) er objektorienterede. Det betyder, at man kan arbejde med "enkeltdele" af programmerne (programmernes objekter) i sin kode. At gennemgå objektorienteret programmering i detaljer, eller bare gennemgå alle objekterne i Excel er ikke denne artikels hensigt. Jeg vil se på nogle af de mest brugte objekter, og hvordan man kan bruge VBA til at håndtere disse objekter. Men først en kort forklaring på, hvad objekter egentlig er.
Hvad er et
objekt? Hvad er et objekt?Et objekt er et element eller en helhed. Et sådant objekt kan indeholde/bestå af andre objekter, som igen kan indeholde andre objekter og så fremdeles. En bondegård kan fx være et objekt. Bondegården kan indeholde andre objekter, så som stalde, lader, hønsegårde osv. Hønsegården kan indeholde hønsehuse, som igen indeholder redekasser, og sådan kan man fortsætte. Objekter er karakteriseret ved, at de har forskellige egenskaber. Et personobjekt har fx egenskaber så som højde, vægt, skostørrelse, hårfarve, øjenfarve osv. Desuden kan der knyttes såkaldte metoder til objektet. Metoder er handlinger, som objektet kan udføre. Personobjektet kan fx lytte, se, sove, løbe osv. Endelig kan objekter have hændelser, det vil sige begivenheder, som indtræffer i forbindelse med objekterne, og som kan betyde en ændring af objektets egenskaber, iværksættelse af en metode osv. Når hændelsen "forskrække" indtræffer på personobjektet, ændres egenskaben "ansigtskulør" til bleg, og metoden "øg puls" går i gang. I Excel er der mange objekter. Mest overordnet er Excel selv, eller applikationen (Application), som rummer alle de andre objekter. Inde i dette objekt findes så andre objekter som værktøjslinier, projektmapper mm., som så igen kan indeholde objekter i form af knapper, ark osv. I alt er der mere end 100 forskellige objekter i Excel. Du kan se en oversigt over Excels objektmodel ved at starte hjælpen fra VBA editoren og skrive Microsoft Excel Object Model i søgeruden. Her vil jeg dog nøjes med at se på de tre mest anvendte af disse objekter: Workbook objektet, Worksheet objektet og Range objektet. Objekter grupperes i objektsamlinger. Fx kan man tale om Worksheets (i flertal), som samlingen af objekter af typen Worksheet, der findes i et objekt af typen Worksbook. Alle samlinger har en fælles egenskab og en fælles metode. Egenskaben er "antal objekter i samlingen" og metoden er "Tilføj nyt objekt til samlingen". Se nedenfor. Bruge objekter i kodenDet er muligt at adressere objekterne med kode,
men hvordan man gør, afhænger af, hvor man allerede "befinder sig" i forhold til
de objekter, man skal adressere. Hvis jeg fx skal referere til et område i et
ark, der allerede er aktiveret i en projektmappe, der er aktiveret, kan jeg
nøjes med at skrive fx: Range("A1:A10). Skal jeg referer til et område i et ark,
der ikke er aktiveret, må jeg have arknavnet med, fx: Er heller ikke projektmappen aktiveret, må man ty til
Bemærk at de enkelte objekter i objekthierarkiet adskilles med punktum, og at "navne" skrives i anførselstegn. Det er sjældent nødvendigt at sætte Application foran, men der er nogle få undtagelser. Når man skal arbejde med objekter i sin kode, er det typisk for at hente eller ændre et objekts egenskaber, eller bruge objektets metoder. I en række sammenhænge udnytter man også et objekts hændelser til at sætte en proces i gang. Vil jeg undersøge et objekts egenskaber, kan jeg kalde objektet, og vise egenskaberne i en meddelelsesboks, gemme dem i en variabel osv. Sub HentArknavn() viser navnet på det aktive ark i meddelelsesboks. Man kan også ændre en egenskabs værdi: Sub SkiftNavn() ændrer navnet på Ark2 til Jan. Jeg kan udnytte en metode til at udføre en handling på mit objekt. Sub SletArk() udnytter arkets "slettemetode" til at slette et ark. En sletning vil øvrigt generere denne meddelelses, på samme måde som hvis man sletter arket manuelt. Hvis en kode anvendes til at slette et ark, er det imidlertid ofte helt bevidst, og så behøver man ikke at vise dialogboksen. Det kan ændres ved at anvende en af application objektets egenskaber.
Ved at ændre koden til Sub SletArk() undgås dialogboksen. Application.DisplayAlerts = False ændrer den egenskab ved applikationen, at den viser advarsler i en række sammenhænge. Men netop fordi det er en egenskab ved hele applikationen, er det vigtigt at ændre den tilbage igen. Ellers vises der heller ikke advarsler i andre sammenhænge. ObjektvariablerNår man arbejder med objekter har man, som i alle andre sammenhænge, brug for at erklære variabler. I artiklen om datatyper til variabler, kan man læse at der findes en datatype ved navn object, som kan indeholde referencer til objecter. Imidlertid ligger der lidt mere i det end bare som så. Det er korrekt at man kan definere en variabel af typen Object, som kan indeholde referencer til alle typer af objekter. Imidlertid kan man også være mere præcis i sin variabelerklæring, hvis man på forhånd ved, hvilke objekttyper, der er tale om, fx Worksheet eller Range. Variablerne erklæres på samme måde som alle andre erklæringer, fx Dim objMitArk As Object og så videre. Ovenfor ses eksempler på erklæringer med både den generelle datatype som de mere specifikke. Er erklæringerne helt som sædvanligt er tildelingen lidt anderledes. Normalt ville man kunne tildele en værdi til en variabel, fx af datatypen String med strNavn = "Ole Jensen". Ved tildeling af referencer til objektvariabler er man imidlertid nødt til at bruge en såkaldt Set-sætning. Et eksempel på en tildeling kunne være: Set objNytArk = Workbooks("Regnskab2009").Worksheets("Budget_2009") Når først variablerne er oprettede kan man referere til dem i sin kode, og man kan udnytte objekternes egenskaber og metoder ved at referere til variablen i stedet: Sub SkiftNavn2() Mere om Set-sætningen kommer i en senere artikel om automation. Egenskaben Count og metoden AddOvenfor nævnte jeg, at alle samlinger har en egenskab og en metode til fælles. Egenskaben var antallet af objekter i en samling (Count). Og metoden kunne tilføje et nyt objekt til en samling (Add). Her et par eksempler på disse to: For at få returneret antallet af regneark i en projekt mappe, kan man bruge: Sub HvorMangeArk() Denne tæller imidlertid kun regneark. Indeholder mappen også diagramark, tælles disse ikke med. Skal de det, kan man ændre til Sub HvorMangeArk2() der tæller alle ark, uanset hvilken type ark, der er tale om. Vil jeg tilføje et nyt ark, kan jeg gøre det med Sub TilfoejArk() eller Sub TilfoejArk2() Begge varianter tilføjer et nyt regneark. Programmering med objekterI forbindelse med programmering med objekter, er der et par programmeringsfunktioner, der er vigtige at kunne. De er begge "løkke-agtige", omend kun den ene er en rigtig løkke, nemlig For...Each...Next, der minder en hel del om den almindelige For...Next løkke, der er beskrevet her. Den anden struktur, der er interessant er With...End With strukturen. Denne struktur anvendes til at ændre flere egenskaber ved samme objekt, uden at skulle adressere objektet flere gange. Skal jeg fx indstille en række egenskaber for et objekt, i eksemplet nedenfor Application objektet, kan jeg gøre det med Sub IndstilExcel() osv. for hver egenskab, der ønskes ændret. Men det kan også gøres med Sub IndstilExcel2() Skal jeg gennemløbe alle objekter i en samling, kan jeg bruge For...Each...Next, fx Sub RetAlleNavne() der retter alle regneark til at at hedde Jan og en tæller, fx Jan1, Jan2, osv. Men nu til noget lidt mere praktisk med udgangspunkt i de tre valgte objekttyper. Workbook (Projektmappe)Dette objekt repræsenterer en hel projektmappe, som jo er det samme som en fil. En sådan Workbook kan derfor gemmes, åbnes, lukkes, udskrives, der kan oprettes nye projektmapper osv. Alt dette kan også gøres med VBA. Selve Workbook-objekttypen kan adresseres på forskellig måde, afhængig af, hvilket specifikt objekt, der er tale om: Worksbooks("Regnskab2009") for
at adresse en navngiven projektmappe. Nedenstående kode gemmer den aktive projektmappe under et nyt navn: Sub GemNytNavn() Koden her udskriver den projektmappe, som indeholder koden: Sub UdskrivDenne() Her åbnes en projektmappe fra C-drevet: Sub LukOp() Det var altså metoder, men objekter har jo også egenskaber. Man kan fx bruge egenskaben Saved til at undersøge om en projektmappe er gemt efter de sidste ændringer og så handle i forhold til det. Dette kombineres ofte med fx logiske funktioner, som fx nedenstående Sub RettetEllerEj() der undersøger om projektmappen er gemt inden den lukker. Worksheet (Ark)Worksheet-objektet repræsenterer et enkelt ark. Ligesom tilfældet er med Worksbooks, kan man adresse et konkret, navngivent ark eller det aktive ark. Man kan ikke adressere ThisWorksheet, da arket ikke indeholder kode (Og dog. Jeg vender tilbage til dette i næste artikel, som kommer til at handle om om hændelser). Til gengæld kan man anvende en mere generisk form, der adresserer et ark på et bestemt sted i rækkefølge af ark eller man kan anvende arkets "kodenavn". Sub SkiftNavn() skifter navn på Ark2 til "Jan" Her adresseres arkets navn. Sub SkiftNavn2() skifter navn på det ark, som ligger som nummer 2 i ark-rækkefølgen. Her adresseres rækkefølgen af arkene. Sub SkiftNavn3() skifter navn på det aktive ark. Her adresseres det aktive ark. Problemet med eksempel 1 er, at såfremt, der ikke findes et Ark2, fx fordi det er omdøbt, vil koden fejle. I eksempel 2 opstår problemet, hvis det ark, man ønsker at omdøbe ikke læn gere er nummer to i rækkefølgen fordi det er flyttet eller der er indsat eller slettet ark. I så fald vil koden ikke fejle, men ændre navn på det forkerte ark. Her kunne løsningen være at bruge arkets "kodenavn".
Illustrationen til venstre viser et udsnit af objektbrowseren i Visual Basic Editoren.Jeg kan man se arketnes kodenavne, som er Ark1, Ark2 osv, altså det, der står før parentesen.Dette navn ændres ikke selv om arkene omdøbes. Omdøbes fx Per til Niels, vil det stadig være Ar4, men der vil stå Niels i parentesen. Rækkefølgen vil også altid være den samme, selv om der flyttes rundt på arkene i prejktmappen. Skalarket "Hans" omdøbes til "Hendes", kan det gøres med Sub SkiftNavn4() og så er det ligegyldigt, hvad arket hedder i forvejen og hvor i rækkefølgen det står. Flere eksempler Sub SkiftFont() gør alle celler i det aktive ark fede på en gang. For alle de regneark, der er i min projektmappe, vil jeg give cellerne fed, kursiv og grøn skrift på en rød baggrund: Sub SkiftMere() Range (Område)Jeg har gemt det mest anvendte objekt til sidst. Range-objektet anvendes hver gang man skal adressere et område uanset om det består af mange eller kun en enkelt celle. Excel har ikke noget celle-objekt, så Range-objektet er den eneste måde at adressere celler på. Range-objektet kan også indeholde flere adskilte områder, en eller flere hele rækker eller kolonner, eller et område, der går igen over flere ark. Dette objekt har utroligt mange egenskaber og metoder, og det vil simpelthen ikke være muligt at komme ind på dem alle. Du kan se eksempler på nogle af dem, i de kodeeksempler der findes under makroer. Her vil jeg bare vise nogle stykker, for at illustrere, hvordan de virker. Sub Test1() giver celle A1 i det aktive ark værdien 100. Sub Test2() lægger 100 til den værdi, der allerede står i A1 i det aktive ark. Egenskaben Value tildeler altså en værdi, eller aflæser en værdi, Sub Test3() aflæser således værdien i A1 og skriver den i en meddelelsesboks. Sub Test4() Tildeler værdien Jan til den celle, der står en kolonne til højre og en række under den række, som cellemarkøren aktuelt står i. Offset forskyder altså i forhold til et udgangspunkt. Første tal i parentesen er forskydningen i rækker. Negative tal forskyder opad, positive nedad. Det andet tal er forskydningen i kolonner. Negative tal forskyder mod venstre, positive mod højre. Sub Test5() fortæller i en meddelelsesboks, hvor mange celler, der er i det angivne område. Sub Test6() rydder indhold og format fra et område. Sub Test7() rydder kun indhold, men efterlader format. Sub Test8() skriver den anførte formel i cellen. Pas dog på sproget. Ovenstående vil virke, fordi funktion SUM() hedder det samme på både dansk og engelsk. Dette vil imidlertid give en fejl i regnearket: Sub Test9() selv om formlen, der kommer til at stå i regnearket ser rigtig ud, nemlig =Middel(A2:A10). Excel viser dog fejlkoden #NAVN!, som om den ikke genkender funktionsnavnet. Sub Test10() vil derimod sætte MIDDEL()-formlen ind, så den bliver rigtig. Hvis man ikke kender alle de engelske betegnelser for de danske funktionsnavne, kan man i stedet bruge: Sub Test11() Så kan man anvende de danske funktionsnavne i stedet for de engelske. Der er yderligere en række egenskaber, der kan være interessante at nævne, fx Address, Row og Column. De returnerer henholdsvis adressen eller rækken eller kolonnen for en given celle. De er selvfølgelig mest interessante, hvis man ikke på forhånd kender cellen, fx giver Sub Test12() ikke megen mening, mens Sub Test13() gør. Man kan også vælge eller aktivere områder, men det er sjældent nødvendigt, og koster ofte bare ekstra ressourcer. Skal jeg fx kopiere et område, kan jeg bruge følgende kode: Sub Test14() Dette er dog ikke specielt hensigtsmæssigt. En indspillet makro, vil normalt give dette resultat, men bedre er Sub Test15() der både er mere effektivt, og hurtigere at skrive. Selection kræver ekstra ressourcer af pcen og tager derfor længere tid. Der er dog nogle situationer, hvor Select er nødvendig, men de er få. Til sidst et kommenteret eksempel på en For.. Each...Next og en With sætning på et Range-objekt. I cellerne B1 til B10 har jeg bogstavet A og så en værdi (et tal), fx A1. Nu vil jeg gerne af med bogstavet. Samtidigt vil jeg gerne gøre alle cellerne grønne (skriftfarve) og skrive med fed skrift. Tallene formateres med to decimaler. Hver anden række skal farves grå (baggrund). Til sidst skal der indsættes en formel i B12, der beregner gennemsnittet af tallene i området. Sub Test16() Funktionerne MID() og Len() er allerede gennemgået i en tidligere artikel. Funktionen Mod, der virker noget anderledes end andre funktioner finder resten af en division. Først skrives tallet, der skal divideres, så kommer funktionsnavnet og til sidst tallet, der skal divideres med. I dette tilfælde betyder altså Rækkenummer Mod 2, at vi dividerer rækkenummeret med 2. Hvis resten er 0 farves cellen grå, ellers sker der ingenting.
Hvordan finder man så alle de egenskaber og metoder, der kan knyttes til de forskellige objekter? En måde er selvfølgelig at slå op i hjælpen. En anden måde er at indspille en makro, der ændrer en egenskab eller anvender en metode, og så se, hvilken kode, der kommer ud af det. En anden metode er simpelthen at begynde at skrive koden, så hjælper VBA editoren selv videre. Skriver du fx Range("A1"). vil editoren vise en oversigt over de egenskaber og metoder, der er tilgængelige for objektet.
- Til Top - |