Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Liste aller markierten IDs in einem Endlosformular
zurück: Datenbank neu erstellen mit VBA weiter: DB mit mehrsprachigen Formularen Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Tutorial Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
14. Jul 2009, 13:28
Rufname:

Liste aller markierten IDs in einem Endlosformular - Liste aller markierten IDs in einem Endlosformular

Nach oben
       Version: Office 2007

Wenn man ein Endlosformular mit RecordSelector verwendet, hat man die Möglichkeit, mehr als einen Datensatz mit der Maus zu markieren, etwa um alle markierten Datensätze zu löschen.

Man kann sich nun Schritt für Schritt durch das Recordset des Formulars hangeln und für jede Zeile ein Delete anstoßen, was aber nicht besonders performant ist, wenn die Liste länger wird.

Die folgende universelle Funktion gibt für ein beliebiges Endlosformular eine Liste aller markierten IDs zurück:
Code:
' Liest alle markierten IDs des Feldes "strIDFieldName" aus, die mit
' der Maus und dem Record-Selector markiert wurden.
'
Public Function fnGetSelectedIDs(frm As Form, _
                                 strIDFieldName As String) As String
On Error GoTo fnGetSelectedIDs_Error
    Dim i As Long
    Dim rs As DAO.Recordset
    Dim strIDs As String
   
    strIDs = ""
    If frm.NewRecord Then fnGetSelectedIDs = ""
    If frm.SelHeight = 0 Then
        fnGetSelectedIDs = CStr(Nz(frm.Controls(strIDFieldName).Value))
        Exit Function
    End If
    Set rs = frm.RecordsetClone
    With rs
        .MoveFirst
        .Move frm.SelTop - 1
        For i = 1 To frm.SelHeight
            If Not .EOF Then
                strIDs = strIDs & _
                     .Fields(frm.Controls(strIDFieldName).ControlSource) & ","
                .MoveNext
            End If
        Next i
    End With
    fnGetSelectedIDs = Left(strIDs, Len(strIDs) - 1)
    Set rs = Nothing
fnGetSelectedIDs_Exit:
    Exit Function
fnGetSelectedIDs_Error:
    MsgBox "fnGetSelectedIDs:" & Err.Description
    Resume fnGetSelectedIDs_Exit
End Function
In einem Endlosformular kann man dann zum Beispiel mit:
Code:
    strIDs = fnGetSelectedIDs(Me, "MeinIDFeld")
eine kommaseparierte Liste aller IDs zurückerhalten.

("MeinIDFeld" ist der Name der Textbox, die die ID enthält, nicht der Name des ID-Feldes. Wenn beide identisch benannt sind, macht es keinen Unterschied.)

Nun kann man diese Liste zum einen dafür benutzen, eine MsgBox anzuzeigen, die diese Werte anzeigt, um den Benutzer zu warnen, bevor er sie löscht. Aber neben diesem netten Nebeneffekt ist diese Liste für die "IN"-Klausel in SQL verwendbar:
Code:
    strSQL = "DELETE FROM MeineTabelle WHERE In (" & strIDs & ")"
Damit werden nun alle Datensätze mit den entsprechenden IDs in einem Rutsch gelöscht. Da die "IN"-Klausel auch in anderen SQL-Befehlen verwendet werden kann, kann man auf die gleiche Weise natürlich auch andere Dinge mit den IDs machen.

Nebenbei kann man die Funktion auch für eine beliebige andere Datenspalte benutzen, nicht nur für die ID-Spalte.

Viel Spaß damit...

Christian

PS: Getestet mit Access 2007, englische Version, sollte aber problemlos auf älteren Access-Versionen laufen.
jens05
Moderator


Verfasst am:
29. Sep 2009, 20:03
Rufname:
Wohnort: ~~~~~

AW: Liste aller markierten IDs in einem Endlosformular - AW: Liste aller markierten IDs in einem Endlosformular

Nach oben
       Version: Office 2007

Hallo!

Nachfragen zum Thema bitte in Liste aller markierten IDs in einem Endlosformular {Nachgefragt} stellen.

_________________
mfg jens05 Wink
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
16. Feb 2010, 18:49
Rufname:


AW: Liste aller markierten IDs in einem Endlosformular - AW: Liste aller markierten IDs in einem Endlosformular

Nach oben
       Version: Office 2007

Hallo zusammen,

hier ist eine andere Variante des Themas oben.

Problem: In einem Access Projekt (ADP) gibt das Recordset eines Formulars leider nicht die gefilterten Datensätze zurück, sondern unabhängig vom Filter immer das komplette Recordset. Mit MoveNext usw. ist daher hier nichts zu machen.

Außerdem kommt ein anderes Problem hinzu: Wenn man ein sortiertes Endlosformular hat und einen neuen Datensatz mit dem Feld, das das Sortierkriterium darstellt, eingibt, dann bleibt die neue Zeile am Ende der Liste im Formular stehen, bis mit z.B. F5 das Formular aktualisiert wird, erst dann wird die neue Zeile wieder richtig einsortiert.
Trotzdem kann man aber beispielsweise die letzten beiden Zeilen mit dem RecordSelector markieren, um sie zum Beispiel zu löschen.

Verwendet man nun die Methode, aus dem Recordset und dem Recordset-Filter einen SQL-String zusammenzubasteln, um die gefilterten Daten vom Server zu bekommen, hat man zwar die gefilterte Liste, hieraus läßt sich aber nicht mehr ableiten, welche Zeilen im Formular markiert wurden. Da einem das Recordset-Objekt auch nicht weiterhilft, gibt es anscheinend nur noch eine einzige Quelle, die die gewünschten Informationen enthält: Das Formularobjekt selbst. Erstellt man sich eine Kopie des Recordsets, bleibt auch in der Kopie die (noch unsortierte) Reihenfolge des Originalformulars erhalten. Die "MoveNext"-Befehle für das Formular beziehen sich im Gegensatz zu "MoveNext" des Recordsets auf die gefilterten Einträge, so daß man nun mit Hilfe von SelTop und SelHeight herausfinden kann, wie die IDs der markierten Zeilen lauten.

Da es im Formularobjekt leider kein EOF gibt, muß man sich hier wohl mit der häßlichen Methode des Error-Objektes begnügen, um das Ende des Formulars festzustellen.

Hier die passende Funktion, die entweder alle IDs des Formulars (mit und ohne Filter) oder nur die selektierten IDs (auch mit und ohne Filter) als Stringarray zurückgibt, das man dann mit Hilfe von Join auch zu einer kommaseparierten Liste umbauen kann.
Code:
Public Function fnGetFormIDs(frm As Form, strIDFieldName As String, bolSelectedOnly As Boolean) As String()
    Dim strIDs() As String
    Dim i As Long, k As Long
    Dim strDummy As String
   
    On Error Resume Next
    strDummy = Screen.ActiveDatasheet.Name
    If Err.Number = 0 Then Set frm = Screen.ActiveDatasheet.Form
    DoCmd.OpenForm "frmTestFilter", acFormDS, , , acFormReadOnly, acHidden
    With Form_frmTestFilter
        .AllowAdditions = False
        .DataEntry = False
        Set Form_frmTestFilter.Recordset = frm.RecordsetClone
        .Filter = frm.Filter
        .FilterOn = frm.FilterOn
        .ctl1.ControlSource = frm.Controls(strIDFieldName).ControlSource
        DoCmd.GoToRecord acDataForm, "frmTestFilter", acFirst
        On Error Resume Next
        i = 0
        k = 0
        Do
            If bolSelectedOnly Then
                If frm.SelHeight = 0 Then Exit Do
                If (k + 1) >= frm.SelTop And (k + 1) <= (frm.SelTop + frm.SelHeight - 1) Then
                    i = i + 1
                    ReDim Preserve strIDs(i)
                    strIDs(i) = .Recordset.Fields(frm.Controls(strIDFieldName).ControlSource)
                End If
              Else
                i = i + 1
                ReDim Preserve strIDs(i)
                strIDs(i) = .Recordset.Fields(frm.Controls(strIDFieldName).ControlSource)
            End If
            k = k + 1
            DoCmd.GoToRecord acDataForm, "frmTestFilter", acNext
        Loop Until Err.Number = 2105
        fnGetFormIDs = strIDs
        DoCmd.Close acForm, "frmTestFilter"
    End With
End Function
Man benötigt dazu nur ein leeres Formular, dessen DefaultView auf Datasheet und das als Endlosformular eingestellt wird. Auf diesem platziert man eine Textbox und nennt diese "ctl1". Das zugehörige Label kann man löschen.

Das Formular wird unter "frmTestFilter" gespeichert, und damit ist die Funktion oben einsetzbar.

Wenn man nun ein Endlos-Formular z.B. namens "MeinFormular" hat, auf dem es eine versteckte ID-Textbox namens "ctlMeineID" (mit zum Beispiel "MeineID" als ControlSource) gibt, kann man diese Funktion nun so aufrufen:
Code:
    Dim strIDs() As String
   
    strIDs = fnGetFormIDs(Form_MeinFormular.Form, "ctlMeineID", False)
(Die Syntax "Form_MeinFormular" funktioniert nur, wenn das Formular die Einstellung "HasModule" besitzt, ansonsten kann man alternativ "Forms("MeinFormular").Form" benutzen.)

Die Funktion überprüft erst einmal, ob es sich bei dem übergebenen Formular um eine Access 2007 SplitForm handelt. In diesem Fall wird das Formular automatisch auf die Splitview umgelenkt, da Access diese getrennt behandelt.

Dann wird das Formular "frmTestFilter" im Nur-Lese-Modues geöffnet, die Ressourcen des Originalformulars werden diesem zugewiesen und dann, je nach Wahl des dritten Parameters, entweder alle Zeilen der aktuellen (evtl. gefilterten) Ansicht zurückgegeben oder nur die mit dem RecordSelector angewählten Zeilen.

Hierbei wird die Originalreihenfolge beibehalten, und damit kann man nun auch endlich die neu erfaßten, noch nicht einsortierten Datensätze zurückbekommen.

Das Zwischenformular hat den Sinn, im Originalformular den Datensatzzeiger nicht zu verändern. Das hat nämlich neben dem unschönen durchlaufen des Zeigers den Nachteil, daß damit auch ständig "Form_Current" und eventuell dadurch verursachte Funktionen aufgerufen werden, was auch nicht zur Performance beiträgt.
Durch das versteckt geöffnete Zwischenformular gibt es keinerlei optische Effekte und man erhält einigermaßen schnell eine Liste der gesuchten IDs.

Vielleicht kennt ja jemand noch eine praktischere und performantere Methode, an die selektierten IDs zu kommen und ich sehe nur den Wald vor lauter Bäumen nicht. Bisher haben bei mir alle anderen Tests keine Erfolge gebracht, bin aber immer offen für neue Ideen.
Nochmals hinzubemerkt: Diese Probleme treten nur bei Access Projekten auf, in einer normalen Access Datenbank kann man mit dem Recordset auf die gefilterten Datensätze zugreifen.

Viel Spaß beim Ausknobeln

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 Tabellen & Abfragen: Riesentabelle Spalten auslagern - IDs für Relationen? 1 alfajor 385 22. Jan 2011, 13:32
MiLie Riesentabelle Spalten auslagern - IDs für Relationen?
Keine neuen Beiträge Access Tabellen & Abfragen: Liste von Postleitzahlen als PLZ-Blöcke ausgeben 0 Martin Igelmann 493 21. Apr 2010, 14:58
Martin Igelmann Liste von Postleitzahlen als PLZ-Blöcke ausgeben
Keine neuen Beiträge Access Tabellen & Abfragen: Fragebogen mit fixen Fragen für mehrere IDs 2 Blitzableiter 402 21. März 2010, 01:42
Blitzableiter Fragebogen mit fixen Fragen für mehrere IDs
Keine neuen Beiträge Access Tabellen & Abfragen: Zwei Liste abgleichen über mehrere Attribute 2 access_neuuling 907 15. Okt 2009, 18:23
ebs17 Zwei Liste abgleichen über mehrere Attribute
Keine neuen Beiträge Access Tabellen & Abfragen: Navigation über Endlosformular 4 Tranfunsel 496 17. Sep 2009, 10:14
Gast Navigation über Endlosformular
Keine neuen Beiträge Access Tabellen & Abfragen: Problem: endlosformular -> zelle im Währungsformat anzeig 1 Heini_net 894 16. Sep 2009, 20:31
Heini_net Problem: endlosformular -> zelle im Währungsformat anzeig
Keine neuen Beiträge Access Tabellen & Abfragen: Aus einem Endlosformular Datensatz durch klicken anzeigen 2 frontera66 292 02. Jul 2009, 07:19
frontera66 Aus einem Endlosformular Datensatz durch klicken anzeigen
Keine neuen Beiträge Access Tabellen & Abfragen: Liste mit Aktivitäten --> Errechnen der benötigten Zeit 7 loggers 496 12. Apr 2009, 15:56
Marmeladenglas Liste mit Aktivitäten --> Errechnen der benötigten Zeit
Keine neuen Beiträge Access Tabellen & Abfragen: Kombinationsfeld in Textfeld umwandeln zeigt nur noch IDs 1 Carazza 3027 15. Feb 2009, 18:59
blicki Kombinationsfeld in Textfeld umwandeln zeigt nur noch IDs
Keine neuen Beiträge Access Tabellen & Abfragen: kleines Wirrwarr mit Abfragen und IDs 5 merke-dir 299 11. Jan 2009, 22:27
KlausMz kleines Wirrwarr mit Abfragen und IDs
Keine neuen Beiträge Access Tabellen & Abfragen: Liste in einer Spalte zurückgeben??? 2 RBX32 286 15. Nov 2008, 22:00
Willi Wipp Liste in einer Spalte zurückgeben???
Keine neuen Beiträge Access Tabellen & Abfragen: Abfrage: Eintrag 8 von 10 Tage in Liste ausgeben lassen 0 eXplicit 396 04. Nov 2008, 08:52
eXplicit Abfrage: Eintrag 8 von 10 Tage in Liste ausgeben lassen
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: PHP Forum