Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Collections in Klassen

Collections in Klassen
11.10.2005 13:36:56
Stefan
Hallo Excelgemeinde,
ich habe zwei Klassen erstellt. Die eine enthält die Eigenschaften eines Kunden, die zweite ist eine Collection der ersten.
Die Funktionen item und count in die Klasse einzubauen, ist nicht weiter schwer:
Public

Function Item(vntKennung As Variant) As clsCPM2_SatzKunde
On Error Resume Next
Set Item = mcolSammlung(vntKennung)
If Err <> 0 Then Err.Raise vbObjectError + 2601, , "Kunde " & vntKennung & " konnte nicht gefunden werden."
End Function

Public

Function Count() As Long
Count = mcolSammlung.Count
End Function

Allerdings kann ich von außen nicht über For-Each-Schleifen auf die Datensätze zugreifen, sondern nur über Item (Bsp: gobjKdn.Item(Index) bzw. gobjKdn(Index)).
Dieser Zugriff ist wesentlich langsamer als ein for-each-Zugriff.
Wie kann ich die Sammlung von außen zugänglich machen? Oder wie kann ich sonst über for-each zugreifen?
Ist es üblich die Collection als global zu definieren? Oder über eine Property-Eigenschaft den Zugriff zu ermöglichen? Brauche ich dann überhaupt noch Item und Count?
Viele wirre Fragen. Bitte gebt mir Tipps!
Vielen Dank im Voraus
Stefan
Anzeige

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Collections in Klassen
11.10.2005 13:48:32
Nepumuk
Hi,
benutze einfach Property Get um auf die Collection zuzugreifen. (übrigens, Property heißt übersetzt Eigenschaft)
Die Collection musst du nicht Global definieren, die ist ja das Objekt der Klasse und kann darin als Private deklariert werden.
Brauchst du ein Beispiel?
Gruß
Nepumuk

Anzeige
AW: Collections in Klassen
11.10.2005 15:47:17
Stefan
Hallo Neupumuk,
da stellen sich gleich zwei Fragen:
Wenn ich die Collection über eine Property oder Function "Sammlung" zur Verfügung stelle und mittels Attribute Value.VB_UserMemId=0 als Standard definiere, dann ist
1) gobjKdn.Sammlung(strKunde) bzw. gobjKdn(strKunde) der Zugriff auf die Sammlung. Damit entfällt meine o.g. Routine Item.
2) gobjKdn.Sammlung.Add der Zugriff auf die Add-Funktion der Sammlung. Ist dann gobjKdn.Add die Kurzform dieses Zugriffs? Oder greife ich dann doch auf meine eigene Add-Routine zu?
Vielen Dank im Voraus
Stefan
Anzeige
AW: Collections in Klassen
11.10.2005 15:55:58
Stefan
Hallo Nepumuk,
einen habe ich noch:
Kann ich die Verwendung der "falschen" Add oder Count-Funktion der Collection verhindern?
Vielen Dank im Voraus
Stefan
AW: Collections in Klassen
11.10.2005 16:48:35
Nepumuk
Hallo Stefan,
das ganze ist viel einfacher wie du denkst. Beispiel:
' **********************************************************************
' Modul: Modul1 Typ: Allgemeines Modul
' **********************************************************************

Option Explicit

Private objAdressen As clsAdressen

Public Sub prcStart()
    Dim vntAdresse As Variant
    Set objAdressen = New clsAdressen
    Call prcInitAdressen
    With objAdressen
        For Each vntAdresse In .colAdressen
            MsgBox vntAdresse
        Next
    End With
    Set objAdressen = Nothing
End Sub

Private Sub prcInitAdressen()
    With objAdressen.colAdressen
        .Add "ftp://ftp.fernuni-hagen.de/pub/pdf/urz-broschueren/broschueren/a001.pdf"
        .Add "ftp://ftp.fernuni-hagen.de/pub/pdf/urz-broschueren/broschueren/a0019809.pdf"
        .Add "ftp://ftp.fernuni-hagen.de/pub/pdf/urz-broschueren/broschueren/a002.pdf"
        .Add "ftp://ftp.fernuni-hagen.de/pub/pdf/urz-broschueren/broschueren/a0029502.pdf"
        .Add "ftp://ftp.fernuni-hagen.de/pub/pdf/urz-broschueren/broschueren/a003.pdf"
    End With
End Sub

' **********************************************************************
' Modul: clsAdressen Typ: Klassenmodul
' **********************************************************************

Option Explicit

Private mcolAdressen As Collection

Private Sub Class_Initialize()
    Set mcolAdressen = New Collection
End Sub

Private Sub Class_Terminate()
    Set mcolAdressen = Nothing
End Sub

Friend Property Get colAdressen() As Collection
    Set colAdressen = mcolAdressen
End Property

Gruß
Nepumuk

Anzeige
AW: Collections in Klassen
11.10.2005 17:22:04
Stefan
Hallo Nepumuk,
Eine Antwort, noch mehr Fragen:
1) Was ist eine "Friend" - Property?
2) Ich habe festgestellt, dass die Übergabe der ganzen Collection langsamer ist als die Übergabe eines einzelnen Satzes der Collection (teilweise doppelt so lange).
Insofern bleibe ich doch zusätzlich bei meiner Item-Funktion, um einen Satz der Collection zu holen.
3) For-Each ist in der Tat enorm schneller, der Durchlauf durch meine Collection via "Item" dauerte 8,7s mit For each jetzt nur noch 0,047s.
4) Ich habe das Problem, dass die Freigabe der Objekte Set objAdressen=Nothing bei mir zum Einen immer unterschiedlich lange dauert (Warum?), zum Anderen sehr lange dauert. Gibt es da einen Trick? Eventuell durch die Terminate-Funktion?
Vielen Dank im Voraus
Stefan
Anzeige
AW: Collections in Klassen
11.10.2005 17:35:17
Nepumuk
Hi,
1. Eine Eigenschaft, auf die nur das Projekt zugreifen kann, in der die Klasse definiert ist.
2. Das ist abhängig davon, ob du die Items auf einen Schlag, so, wie in meinem Beispiel, oder tröpfchenweise übergibst.
3. Das ist klar, da ich alle Items auf einmal hole, und dann nacheinander aufliste.
4. Das kann ich nicht nachvollziehen, das dauert bei mir weniger als eine Millisekunde.
Gruß
Nepumuk

Anzeige
AW: Collections in Klassen
11.10.2005 18:04:01
Stefan
Hallo Nepumuk,
1. Ich dachte, dass würde man über Instancing = Private tun?
4. Meine Objekte sind etwas größer. ca. 12.000 Datensätze mit 40 Eigenschaften (klar... eigentlich Access-Aufgabe!) Die Freigabe zweier gleich großer Objekte dauert bei dem einen 3s, bei dem zweiten 21s. Vielleicht sollte ich auch mal mehr Hauptspeicher reintun?
Gruß
Stefan
Anzeige
AW: Collections in Klassen
11.10.2005 19:11:19
Nepumuk
Hallo Stefan,
das sind zwei paar Stiefel. Über die Instanz kannst du auf die Klasse und deren öffentliche Eigenschaften zugreifen. Aber eben nicht auf die befreundeten und privaten. Schau dir die Hilfe zu "Friend" an. Mehr zu Klassen findest du hier:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconproperties.asp
Wie du auf eine Klasse in einem anderen Projekt zugreifst, findest du hier:
http://support.microsoft.com/kb/555159/en-us
Gruß
Nepumuk

Anzeige
;
Anzeige
Anzeige

Infobox / Tutorial

Collections in Klassen in Excel VBA


Schritt-für-Schritt-Anleitung

  1. Klasse Erstellen: Erstelle eine neue Klasse in Excel VBA, um die Eigenschaften eines Kunden zu definieren. Nenne sie clsCPM2_SatzKunde.

  2. Collection Erstellen: Erstelle eine zweite Klasse, die eine Collection von Objekten der ersten Klasse hält. Nenne sie clsCollectionKunden.

  3. Funktionen Implementieren:

    • Implementiere die Item- und Count-Funktionen in der Collection-Klasse:
      
      Public Function Item(vntKennung As Variant) As clsCPM2_SatzKunde
      On Error Resume Next
      Set Item = mcolSammlung(vntKennung)
      If Err <> 0 Then Err.Raise vbObjectError + 2601, , "Kunde " & vntKennung & " konnte nicht gefunden werden."
      End Function

    Public Function Count() As Long Count = mcolSammlung.Count End Function

  4. Zugriff über Property Get: Um die Collection von außen zugänglich zu machen, definiere eine Property Get-Methode in der Collection-Klasse:

    Friend Property Get colKunden() As Collection
       Set colKunden = mcolSammlung
    End Property
  5. For Each Schleife: Nutze die For Each-Schleife, um durch die Collection zu iterieren. Beispiel:

    Dim kunde As clsCPM2_SatzKunde
    For Each kunde In gobjKdn.colKunden
       MsgBox kunde.Name
    Next kunde

Häufige Fehler und Lösungen

  • Problem: Kein Zugriff auf die Collection von außen.

    • Lösung: Stelle sicher, dass du die Property Get-Methode korrekt implementiert hast.
  • Problem: For Each-Schleife funktioniert nicht wie erwartet.

    • Lösung: Stelle sicher, dass die Collection korrekt initialisiert ist und die Objekte korrekt hinzugefügt wurden.
  • Problem: Langsame Zugriffszeiten.

    • Lösung: Überprüfe, ob du die Elemente in der Collection effizient speicherst und verwaltest. Nutze die Item-Methode nur, wenn nötig.

Alternative Methoden

  • Direkter Zugriff: Du kannst die Item-Methode verwenden, um auf spezifische Items in der vba collection zuzugreifen, jedoch ist dies oft langsamer als die Nutzung einer For Each-Schleife.

  • Verwendung von Arrays: Statt einer Collection kannst du auch ein Array verwenden, wenn die Anzahl der Elemente feststeht. Arrays sind in der Regel schneller beim Zugriff.


Praktische Beispiele

  1. Kunden Collection:

    Dim gobjKdn As clsCollectionKunden
    Set gobjKdn = New clsCollectionKunden
    gobjKdn.colKunden.Add New clsCPM2_SatzKunde
  2. Zugriff auf Kunden:

    Dim strKunde As String
    strKunde = "Kunde1"
    MsgBox gobjKdn.Item(strKunde).Name

Tipps für Profis

  • Verwende Friend Properties: Mit Friend kannst du den Zugriff auf die vba collection auf das eigene Projekt beschränken, was die Kapselung verbessert.

  • Optimierung der Performance: Wenn du mit großen Datenmengen arbeitest, achte darauf, wie und wann du Objekte initialisierst und freigibst.

  • Fehlerbehandlung: Implementiere eine robuste Fehlerbehandlung in deinen Item-Methoden, um unerwartete Laufzeitfehler zu vermeiden.


FAQ: Häufige Fragen

1. Was ist eine "Friend" - Property?
Eine Friend-Property ist eine Eigenschaft, auf die nur das Projekt zugreifen kann, in dem die Klasse definiert ist. Diese Art der Eigenschaft kann verwendet werden, um die Zugriffsrechte auf sensible Daten zu kontrollieren.

2. Warum ist die Übergabe einer ganzen Collection langsamer als die Übergabe eines einzelnen Items?
Die Übergabe der gesamten vba collection kann langsamer sein, weil alle Items auf einmal verarbeitet werden müssen. Wenn du nur ein einzelnes Item abrufst, ist dieser Prozess in der Regel effizienter.

3. Wie kann ich die Verwendung der Standard-Add oder Count-Funktionen der Collection verhindern?
Du kannst die Collection als Private deklarieren und stattdessen deine eigenen Methoden implementieren, um das Hinzufügen und Zählen von Objekten zu steuern.

4. Gibt es Tricks zur Beschleunigung der Objekterstellung und -freigabe?
Überprüfe, ob du die Objekte effizient verwaltest. Vermeide unnötige Objektinstanzen und prüfe die Verwendung der Terminate-Funktion, um die Freigabe zu optimieren.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige