For Each...Next løkker i Excel VBA class collections
Class collections (klassesamlinger) er et formidabelt værktøj til struktureret programmering, når man har mange objekter af samme natur.
Det være sig bøger, kunder, varer, råmaterialer - hvad som helst der kan beskrives på nogenlunde samme måde med egenskaber, metoder og hændelser.
Det har jeg beskrevet på siden Klasser og class collections i Excel VBA, hvor du også kan downloade et regneark med et eksempel.
Det er slet ikke så langhåret, men kan tværtimod gøre programmering til en leg, fordi man ikke skal holde styr på en hulens masse variable.
Der er bare en lille hage: Man kan ikke uden videre gennemløbe sin class collection med den hurtige løkke, For Each...Next, som man kan med Excels egne collections.
Jeg skriver "ikke uden videre," for man kan nemlig godt, det kræver bare lidt snedig "snyd". Mere om dette om et øjeblik.
Gennemløb med Item og en tæller
Forestil dig en class collection, "clKunder", som er en collection af kunder, hvor hver kunde er i en klasse for sig, "clKunde".
Indtil for nylig gennemløb jeg mine egne class collections med en tæller og Item-metoden i stil med dette eksempel, hvor "bBetalt" er en property af datatypen Boolean:
With clKunder
For lCount = 1 to .Count
If .Item(lCount).bBetalt = False Then
End If
Next
End With
Gennemløb med For Each...Next
Det irriterede mig, at jeg ikke kunne bruge den hurtige og enklere For Each...Next løkke, og løsningen fandt jeg på Internet. Fidusen er at eksportere sit klassemodul (her "clKunder"), indlæse filen i en teksteditor (fx Notepad), tilføje en linje med kode, og så importere modulet igen.
Pointen er, at den kodelinje, man tilføjer i Notepad, ikke kan tilføjes i VBA-editoren. Man kan godt, det virker bare ikke.
Når man har tilføjet linjen i Notepad og importeret klassemodulet igen, er linjen ikke synlig i VBA-editoren, men den virker!
Først tilføjede jeg følgende Public Function i klassemodulet:
Public Function NewEnum() As IUnknown
Set NewEnum = clKunder.[_NewEnum]
End Function
Det er altså linjen:
Attribute NewEnum.VB_UserMemID = -4
man skal tilføje i Notepad og selvfølgelig uden apostrof foran.
Det er bare smart. Nu kan jeg gennemløbe mine class collections på denne måde:
Sub Eksempel()
Dim Client as clKunde
For Each Client in clKunder
If Client.bBetalt = False Then
End If
Next
End Sub
Det synes måske ikke af så meget, men når man har store class collections og mange gennemløb, betyder det faktisk noget for hastigheden, og det giver enklere kode.
Relateret:
|