Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Datensammlung - Arrays und Collections {Nachgefragt}
zurück: Datensatz Aktualisieren vermeiden weiter: Ordnerpfad aus zwei Feldinhalten erstellen? Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Antwort Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
Stefffano
Dazugelernt


Verfasst am:
15. Feb 2011, 14:48
Rufname:
Wohnort: Chemnitz

Datensammlung - Arrays und Collections {Nachgefragt} - Datensammlung - Arrays und Collections {Nachgefragt}

Nach oben
       Version: (keine Angabe möglich)

Nachfragen zum Thema Datensammlung - Arrays und Collections (Willi Wipp)

Hallo Christian,

ich hab das Problem, daß die Collection nicht vollständig übergeben wird, sondern sich zwischenzeitlich leert, wenn ich die Collection.Items nicht in Strings einpacke.

Ich stell mal ein Beispiel rein.
Vielleicht kannst Du ja den Fehler finden?

_________________
Schöne Grüße,

Stefan



Db_CollectionEmpfaenger_01.zip
 Beschreibung:

Download
 Dateiname:  Db_CollectionEmpfaenger_01.zip
 Dateigröße:  22.64 KB
 Heruntergeladen:  58 mal

Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
15. Feb 2011, 17:28
Rufname:


AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo Stefan,

das ist ein Irrtum: die Collection hat sich nicht geleert, es kommt nur immer darauf an, was man hineingibt.

Die Collection nimmt, wie gesagt, alles entgegen, egal in welcher Reihenfolge, egal welcher Typ, egal ob nur einer oder viele verschiedene Typen. Das macht sie sehr flexibel.

In Deinem Code hast Du im ersten Versuch aus dem Recordset ein Feld hinzugefügt, indem Du es durch das Hinzufügen einfacher Hochkommata implizit in einen String umgewandelt hast. Das ist so nicht notwendig, wie Du ja selbst gemerkt hast, mußtest Du die Hochkommata im Zielformular mit Replace erst wieder mühsam entfernen. Zur Umwandlung in einen String hätte also einfach z.B. gereicht:
Code:
CStr(rs!Feldname)
Im zweiten Versuch hast Du dann die Hochkommata und damit auch die implizite Stringumwandlung weggelassen. Ergebnis ist, daß das Feld schon der Collection hinzugefügt wird, aber nicht dessen Wert, sondern das Feld-Objekt aus der Fields-Collection des Recordsets. Da im Fall von Objekten nur eine Referenz auf ein bestehendes Objekt in einer Collection gespeichert wird, bleibt die Verbindung zum aktuell geöffneten Recordset-Objekt erhalten - auch, nachdem das Objekt schon in die Collection eingefügt wurde. Denn es ist ja nicht das Objekt, sondern eine Referenz darauf.

Ergebnis ist: Im nächsten Schleifendurchlauf werden alle Fields-Objekte des Recordsets mit dem nächsten Datensatz gefüllt - und so ändert sich auch das Fields-Objekt in der Collection, denn es ist immer noch das gleiche Objekt wie das im Recordset. Letztendlich fügst Du in der Schleife nur dreimal eine Referenz auf immer das gleiche Fields-Objekt hinzu (bzw. für jedes Field-Objekt je dreimal, um genau zu sein).

Daher sieht es so aus, als ob am Ende dreimal das gleiche in die Collection kopiert wurde. Ist aber immer das gleiche Fields-Objekt (die gleichen Fields-Objekte).

Das kommt davon, wenn man sich auf Default-Properties verläßt. Das Default-Property für ein Field-Objekt lautet "Value". Wenn Du schreibst:
Code:
    a = rs!Feldname
Dann bekommt a den Wert aus "Feldname" zugewiesen - eine implizite Typumwandlung, da VBA erkennt, daß das Ziel eine Variable ist und damit nur die Default-Eigenschaft "Value" gemeint sein kann, die dann automatisch angewendet wird.

Wenn Du aber schreibst:
Code:
    MeineCollection.Add rs!Feldname
passiert keine Typumwandlung und keine Default-Property wird angewendet - denn der Befehl besagt: "Füge der Collection das Objekt "Feldname" aus der Fields-Collection des Recordset-Objektes hinzu".

Um also das richtige Ergebnis in die Collection zu bekommen, müßtest Du schreiben:
Code:
    MeineCollection.Add rs!Feldname.Value
Dann wird der richtige Wert als Variant in die Collection geschrieben.

Du hast aber auch außerdem eine bunte Mischung unterschiedlicher Informationen in die Collection eingefügt. Das geht natürlich, die Collection erlaubt das, man kann auch damit arbeiten - aber man macht sich das Leben selbst schwer.

Das Interessante an einer Collection ist ja gerade die Möglichkeit, Objekte hineinzulegen und mit einer einfachen For Each-Schleife wieder auszulesen. Das geht natürlich nur, wenn alle hinzugefügten Elemente vom gleichen Typ sind.

Um also die Felder eines Recordsets komfortabel in eine Collection einzufügen, bedient man sich einfach eines Datenklassenmoduls. Das besteht nur aus öffentlichen Variablen mit den entsprechenden Namen und Typen. Diese kann man dann in der Schleife, in der das Recordset ausgelesen wird, einfach zuweisen.

Das Klassenmodul:
Code:
Option Compare Database
Option Explicit

' einfaches Datenobjekt zur sauberen Datenübergabe

Public Nr As Long
Public ID_Kunde As Long
Public ID_Kursteilnehmer As Long
Public BegruessungFormel As String
Public BegruessungInformel As String
Public EMail As String
Und die Schleife, um die Daten hinzuzufügen:
Code:
    Dim objEmpfaenger As clsEmpfaenger
   
    i = 1
    Do While Not rs.EOF
        Set objEmpfaenger = New clsEmpfaenger
        With objEmpfaenger
            .Nr = i
            .ID_Kunde = rs.Fields("idKunde")
            .ID_Kursteilnehmer = rs.Fields("ID_Kursteilnehmer")
            .BegruessungFormel = rs.Fields("BegruessungFormell")
            .BegruessungInformel = rs.Fields("BegruessungInformell")
            .EMail = rs.Fields("txtEmail")
        End With
        colEmpfaengerListe.Add objEmpfaenger, CStr(i)
        i = i + 1
        rs.MoveNext
    Loop
(Hier könnte man alternativ auch wieder "rs!idKunde" schreiben.)

Auch hier kommt wieder die Default-Property "Value" der Fields-Auflistung zum Tragen, aber hier kann es nicht mehr zu Fehlern kommen, da die Werte nun in typgenaue Variablen geschrieben werden.

Das Objekt wird dann der Collection hinzugefügt und dem Zielformular übergeben, das die Werte dann mit einem einfachen For Each wieder auslesen kann:
Code:
    Dim objEmpfaenger As clsEmpfaenger
   
    If Not colEmpfaengerListe Is Nothing Then
        For Each objEmpfaenger In colEmpfaengerListe
            With objEmpfaenger
                Me.FtxtEmpfaengerliste = Me.FtxtEmpfaengerliste & .Nr & ": " & _
                                         .EMail & ";" & vbNewLine
            End With
        Next objEmpfaenger
    End If
In der angehängten Demo habe ich Dir das Formular so angepaßt, daß es einfach als Objekt geöffnet wird, womit die Übergabe der Collection direkt mit einer öffentlichen Methode des Formulars erfolgen kann, damit sind auch keine DoCmd- oder globale Variablen mehr nötig (auch die globale Variable in Mod_Daten könnte man als Private deklarieren).

Gruß

Christian



Db_CollectionEmpfaenger_02.zip
 Beschreibung:

Download
 Dateiname:  Db_CollectionEmpfaenger_02.zip
 Dateigröße:  36.74 KB
 Heruntergeladen:  136 mal

Stefffano
Dazugelernt


Verfasst am:
15. Feb 2011, 22:52
Rufname:
Wohnort: Chemnitz

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo Christian,

danke Dir, das hab ich gerafft Razz
Und nebenbei demonstrierst Du auch gleich noch, wie einfach man das ganze mit einer Klasse umsetzt. Ganz toll oder auch große Klasse Razz

_________________
Schöne Grüße,

Stefan
Kell Conerem
Im Profil kannst Du frei den Rang ändern


Verfasst am:
03. Sep 2011, 01:42
Rufname:

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: Office 2007

Hallo das Auslesen der Collection in deinem Beispiel ist ja schön und gut aber ich habe das Problem das ich beim Auslesevorgang auch den "Key" benötige. Gibt es bei der Collection eine Möglichkeit den Key mitauszulesen, so wie beim Recordset? (Fields.Name)
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
03. Sep 2011, 09:40
Rufname:


AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo,

nein, leider unterstützt die Collection keinen Lesezugriff auf den Key. Alternativ kannst Du das VBScript Dictionary-Objekt verwenden, mit dem das möglich ist (man muß allerdings immer ein externes Objekt einbinden, was ich persönlich vermeide, wenn möglich).
Ich behelfe mir immer damit, daß ich in dem Objekt, das ich in die Collection stelle, ein Key-Feld selbst erstelle und dort den Key speichere.
Wenn das Objekt, das in die Collection soll, keine eigene Klasse ist, so daß es nicht veränderlich ist, dann umgebe ich das Objekt einfach mit einer Wrapperklasse, die das eigentliche Objekt als Property enthält und dann ein zusätzliches Key-Feld bekommt.

Gruß

Christian
Kell Conerem
Im Profil kannst Du frei den Rang ändern


Verfasst am:
03. Sep 2011, 22:31
Rufname:

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Verstehe das ist natürlich schade. Danke für den Hinweis.

Gruss
Kell
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
09. Okt 2011, 15:21
Rufname:

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo,

nebenbei bemerkt hatte ich hier: Array: Wert finden und löschen
schon mal ein Klassenmodul veröffentlicht, mit dem das Dictionary mit einer Collection nachgestellt wird und damit ist es dann auch möglich, auf den Key zuzugreifen. So benötigt man auch kein externes VBScript-Objekt.

Gruß

Christian
Trostlooser
Gast


Verfasst am:
29. Aug 2013, 08:59
Rufname:

Hilfe: Klassenmodul dekl. Variable - Übergabe ByRef - Hilfe: Klassenmodul dekl. Variable - Übergabe ByRef

Nach oben
       Version: Office 2010

Hallo Christian,

vielen Dank zunächst für Dein sehr hilfreiches Tutorial in Sachen Arrays und Collections. Razz Habe es nun erstmals in meiner Programmierung in Excel angewendet und bin eigentlich auch recht zufrieden was die Handhabung angeht. Leider habe ich nun ein Problem: Wenn ich die im Klassenmodul deklarierten Variablen in einer Sub aufgreife kann ich sie per "Zuweisung" direkt ändern. Wenn ich die Variablen aber an eine andere Sub/Function ByRef übergebe, dann wird der Wert beim zurückgeben nicht geändert. Wieso denn bloß...? Confused Gibt es da einen eleganten Workaround?
Code:
    Dim ClassVar As Cls
   
    Set ClassVar = New Cls
    ClassVar.Variable1 = "geht prima"
    Call UnterSub(ClassVar.Variable1)  '- geht nicht!
Danke schon mal für Deine Hilfe!
Gruß
Trostlooser
Nachtrag: Trostlooser am 29. Aug 2013 um 10:36 hat folgendes geschrieben:
Hallo noch einmal,

kurzer Nachtrag zur Deklaration der Variablen:
Im Klassenmodul Cls:
Code:
Option Compare Binary
Option Explicit

Public Variable1 As String
In der Sub/Function:
Code:
Sub UnterSub (ByRef Eingang As String)
    Eingang = "geht nicht zurück"
End Sub
Geht leider trotzdem nicht, wenngleich beide doch als String deklariert wurden... Sad
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
29. Aug 2013, 11:06
Rufname:

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo,

das hat zwar jetzt wenig mit Collections oder Arrays zu tun, aber um Deine Frage zu beantworten: Auf die gezeigte Weise funktioniert es tatsächlich nicht, wobei mir der Grund dafür nicht klar ist, denn mit einem Standardmodul funktioniert es ("Modul1.Variable1" als Übergabe) und das ist ja nur eine Sonderform. Offensichtlich scheint VBA hier die Eigenschaft des Klassenmoduls nicht zu referenzieren, sondern erstellt eine neue String-Variable, die dann übergeben wird, geändert wird, aber beim Beenden dann verworfen wird (es wird nicht erkannt, daß es eine Eigenschaft eines Klassenmoduls ist).

Es gibt zwei Methoden, wie man das anders machen kann:
  1. Verwendung einer Function mit Rückgabewert
    Code:
    Public Function fnChange() As String
        fnChange = "Neuer Wert"
    End Function
    DAS ist normalerweise die richtige Methode, Werte in Variablen zu füllen, so daß der Aufruf dann lauten würde:
    Code:
        Dim obj As clsModule
       
        Set obj = New clsModule
        obj.Variable1 = fnChange
    (Man kann natürlich den Wert als Parameter übergeben, wenn man ihn verändern und nicht einfach neu setzen möchte)

    Die Methode, "ByRef"-Variablen direkt zu ändern, ist eher die anarchische Methode der Windows API...Smile

  2. Übergabe des Objektes
    Es ist noch viel einfacher, das Objekt selbst zu übergeben, da man so Zugriff auf alle Eigenschaften und Methoden des Klassenmoduls hat und nur genau einen Parameter dazu braucht:
    Code:
    Public Sub procChange(obj As clsModule)
        obj.Variable1 = "Neuer Wert
    End Sub
Gruß

Christian
Trostlooser
Gast


Verfasst am:
29. Aug 2013, 11:45
Rufname:

Hilfe: Klassenmodul dekl. Variable - Übergabe ByRef - Hilfe: Klassenmodul dekl. Variable - Übergabe ByRef

Nach oben
       Version: (keine Angabe möglich)

Hallo Christian,

Danke zunächst für Deine schnelle Antwort! Sorry wenn ich meine Frage an der falschen Stelle gepostet habe. Ich habe sie hier gestellt, da es der Ausgangspunkt für meine Programmierung war und ich die Frage an Dich stellen wollte...
Generell geht es bei mir darum, Code in Unter-Prozeduren auszulagern, der sich an verschiedenen Stellen wiederholt. Somit kann ich an den betreffenden Stellen einfach einen Aufruf der Prozedur machen und die Parameter übergeben. Dabei müssen aber immer gleich mehrere Variablen verändert werden. Somit ist die erste Methode (Function fnChange) wahrscheinlich etwas unpraktisch. Ich habe spaßeshalber auch mal probiert, ob das Befüllen der Parameter-Variablen über die fnChange am Ende meiner Unter-Prozedur funktioniert - leider auch hier keine Übernahme der Daten in die aufrufende Sub... Sad
Somit bleibt die zweite Möglichkeit, die als Cls deklarierte Variable als Ganzes zu übergeben und die Unter-Prozedur muß sich dann selbst die einzelnen Variablen rausgreifen, die sie verändern soll - korrekt?

Interessant, dass ich hier auf etwas gestoßen bin, dass selbst Dich verblüfft (Klassenmodul vs. normales Modul...). Shock
Der Interesse halber würde ich mich interessieren, warum die Änderung ByRef als "anarchisch" gesehen wird. Was ist der Nachteil daran...? Rolling Eyes

In jedem Fall aber schon mal Danke für Deine Hilfe!!!
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
29. Aug 2013, 13:58
Rufname:

AW: Datensammlung - Arrays und Collections - AW: Datensammlung - Arrays und Collections

Nach oben
       Version: (keine Angabe möglich)

Hallo,

oh, es vergeht kaum eine Woche, in der ich nicht mal wieder einen Lichtblick in Access oder VBA habe, da gibt es immer noch viel zu entdecken...Smile

Die Methode, das Objekt zu übergeben, ist viel einfacher, als eine lange Liste von Variablen als Parameter zu definieren. Dabei wird auch nicht das Objekt selbst übergeben, sondern lediglich ein Zeiger auf das Objekt (Objekte können nicht ByVal übergeben werden). Somit auch für VBA einfacher, da nur eine Speicheradresse übergeben wird.

In der Unterprozedur kannst Du dann auch wieder bequem das With einsetzen:
Code:
    With obj
        .Variable1 = "Neuer Inhalt"
    End With
und auf diese Weise ist es programmiertechnisch kaum ein Unterschied zu vorher.

Gruß

Christian
judith_21
Neuling


Verfasst am:
04. Apr 2014, 15:12
Rufname:

AW: Datensammlung - Arrays und Collections {Nachgefragt} - AW: Datensammlung - Arrays und Collections {Nachgefragt}

Nach oben
       Version: (keine Angabe möglich)

Hallo,

ich habe den Namen einer Collection in einem Word Lesezeichen stehen und verarbeite den Namen/Inhalt des Lesezeichens in VBA als String Variable.

Wie bekomme ich es hin, auf eine Collection mit ihrem Namen zuzugreifen.
Ich stelle mir so etwas in der Richtung vor wie Collections.Item(strCollectionName).Item(strKey).

Gibt es eine andere Möglichkeit, als die ganze Collection in eine übergeordnete Collection zu packen (wo ich den Namen der Collection als Key hinterlege und es so hinbekomme, mit einer Textvariablen auf die Collection zuzugreifen)?

Danke & Gruß,
Nadine
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
05. Apr 2014, 00:45
Rufname:


AW: Datensammlung - Arrays und Collections {Nachgefragt} - AW: Datensammlung - Arrays und Collections {Nachgefragt}

Nach oben
       Version: (keine Angabe möglich)

Hallo Nadine,

es gibt schon noch andere Möglichkeiten, aber ob die einfacher sind, ist eine andere Frage. Du könntest z.B. eine Public Function in einem Standardmodul anlegen mit Rückgabetyp "Collection" und als Parameter den Namen der Collection. Dann kannst Du z.B. über ein Select Case anhand des Namens in der Stringvariablen die passende Collection zurückgeben.

Gruß

Christian
Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind
GMT + 1 Stunde

Diese Seite Freunden empfehlen

Seite 1 von 1
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen

Verwandte Themen
Forum / Themen   Antworten   Autor   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Access Programmierung / VBA: Form.-Ref. auf UFOs/UFO-Container vereinfacht {Nachgefragt} 6 Gast 189 19. Feb 2014, 18:07
JensFliese66 Form.-Ref. auf UFOs/UFO-Container vereinfacht {Nachgefragt}
Keine neuen Beiträge Access Hilfe: Pgb - Fortschrittsanzeige selbstgemacht {Nachgefragt} 15 Sebix 7155 16. Feb 2014, 19:23
Bitsqueezer Pgb - Fortschrittsanzeige selbstgemacht  {Nachgefragt}
Keine neuen Beiträge Access Hilfe: Auf Globale Variablen/Eigenschaften zugreifen Nachgefragt 19 Gast 5567 14. Jan 2014, 11:38
Gast Auf Globale Variablen/Eigenschaften zugreifen Nachgefragt
Keine neuen Beiträge Access Programmierung / VBA: Automatischer Mailversand ohne Warnmeldung {Nachgefragt} 56 Manuel_ 16295 02. Jan 2014, 12:41
Oliver11 Automatischer Mailversand ohne Warnmeldung {Nachgefragt}
Keine neuen Beiträge Access Formulare: Umgang mit m:n-Beziehungen - nachgefragt 108 stpimi 20111 28. Okt 2013, 21:44
KlausMz Umgang mit m:n-Beziehungen - nachgefragt
Keine neuen Beiträge Access Tipps & Tricks: Datensammlung - Arrays und Collections 1 Bitsqueezer 19711 30. Aug 2013, 06:32
Willi Wipp Datensammlung - Arrays und Collections
Keine neuen Beiträge Access Programmierung / VBA: Kalenderwoche berechnen - Richtige Formel? Kurz nachgefragt 10 Ida maya 181 08. Jul 2013, 13:02
Gast Kalenderwoche berechnen - Richtige Formel? Kurz nachgefragt
Keine neuen Beiträge Access Programmierung / VBA: Popup-Infofenster (Nachgefragt) 1 Paggo 384 30. Okt 2012, 16:11
Bitsqueezer Popup-Infofenster (Nachgefragt)
Keine neuen Beiträge Access Hilfe: DLookup() versus OpenRecordset {Nachgefragt} 28 josa65 5452 23. Jul 2012, 19:29
steffen0815 DLookup() versus OpenRecordset  {Nachgefragt}
Keine neuen Beiträge Access Hilfe: Export nach Excel mit allem Drum und Dran {Nachgefragt} 146 Freeman_6 10909 14. Sep 2011, 15:21
Christine_Steinmeier Export nach Excel mit allem Drum und Dran {Nachgefragt}
Keine neuen Beiträge Access Programmierung / VBA: Textbox wie Combo zum Suchen von DS verwenden (Nachgefragt) 4 RebeccaLiDe 290 02. März 2011, 13:36
RebeccaLiDe Textbox wie Combo zum Suchen von DS verwenden (Nachgefragt)
Keine neuen Beiträge Access Programmierung / VBA: Sortieren eines Listenfeldes mit Werteliste (Nachgefragt) 26 trekking 2435 04. Jan 2010, 15:21
trekking Sortieren eines Listenfeldes mit Werteliste (Nachgefragt)
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: Excel Tipps