PDA

Vollständige Version anzeigen : Darstellung und Datenpflege von m:n Datensätze über Kontrollkästchen


JPA
11.12.2012, 12:06
Hallo Forum,
ich möchte hiermit ein Teil meiner Programmbibliothek mit euch teilen.
Es geht um Darstellung und Datenpflege von m:n Datensätze.
Dies wir üblicherweise in MS Access über Haupt- und Unterformular umgesetzt.
Geht es allerdings darum, nur Datensätze ohne weitere Angaben einen Hauptdatensatz zu zuordnen, dann sind Unterformulare nicht wirklich optimal.
Daher stelle ich hier meine Lösung mit dynamischen Kontrollkästchen vor.
Beispiel: Zu Kontaktdaten sind Gruppen wie Geschäftlich, Freunde, Familie usw… zu zuordnen.

Klassisch Lösung mit Unterformular:
- Nur die bereits zugeordneten Einträge werden in der Liste dargestellt
- VBA-Code wird nicht benötigt
- Bedienung umständlich und fehleranfällig
- Jede Zuordnungsliste benötigt ein Unterformular
- Fazit: Geeignet für Listen mit vielen Einträgen

Meine Lösung mit dynamischen Kontrollkästchen:
- Sämtliche Einträge werden in der Liste übersichtlicht dargestellt
- Bedienung einfach und eindeutig
- Standardisiertes Design
- Nur ein Unterformular
- VBA-Code wird benötigt (ohne zusätzlichen Verweis, kein externes ActiveX (OCX) wird benötigt)
- Fazit: Geeignet für Listen mit wenig Einträgen

Lerneffekt:
Arbeiten mit der Klasse Form, mit Property und ENUM.
Verwendung von Unterabfragen.

Voraussetzung:
MS Access 97, 2000, 2002, 2003 , 2007 und 2010
Es werden 2 Stammdaten Tabellen und eine Zuordnungstabelle benötigt.
Die Stammdaten Tabellen benötigen ein Feld mit eindeutigen Daten (z.B. Primarykey auf ein Feld).
Einer der zwei Stammdaten Tabellen wird in ein Formular in der Formularansicht dargestellt. Zusätzliche Verweise in VBA werden nicht benötigt.

Installation/Verwendung:
1. Das Formular frmACB im aktuellen Projekt importieren
2. Dieses Formular als Unterformular in das Hauptformular einfügen
3. Die 3 folgenden Prozeduren in das Hauptformular einfügen, und dabei die Tabellen- und Feldnamen anpassen

Private Sub Form_Current()
AktZuordnungen
End Sub

Private Sub Form_AfterInsert()
AktZuordnungen
End Sub

Private Sub AktZuordnungen()
Static frmGruppe As Form_frmACB

If Me.CurrentView = 1 Then
If frmGruppe Is Nothing Then
Set frmGruppe = Me.frmZuordnungGruppe.Form
frmGruppe.eZuordnungstabelle = "tblZuordnungKontaktGruppe"
frmGruppe.eZuordnungsFeld1 = "KontaktID"
frmGruppe.eZuordnungsFeld2 = "GruppeID"
frmGruppe.eStammtabelle = "tblGruppe"
frmGruppe.eStammFeldID = "ID"
frmGruppe.eStammFeldBezeichnung = "Bezeichnung"
frmGruppe.eSortierung = NachSchlüsselfeld
frmGruppe.eSortierrichtung = Absteigend
End If
frmGruppe.RequeryRecords Me.ID & ""
End If
End Sub

Hintergrund der Technik:
Das Formular frmACB ist ein Endlosformular und wird als Unterformular in einem Hauptformular eingefügt. Es kann beliebig oft in einem Hauptformular eingefügt werden. Denn welche Datensätze abgebildet werden soll ist nicht in dem Unterformular hinterlegt, sondern wird über das Hauptformular einmalig definiert. Dies geschieht aus dem Hauptformular (Siehe Prozedur AktZuordnungen)

Nach jedem Datensatzwechsel im Hauptformular, wird über den Aufruf der Prozedur RequeryRecords, die entsprechende Datenherkunft im Unterformular frmACB gesetzt.
Die Prozedur RequeryRecords erzeugt eine sql-Abfrage die alle Datensätze der Stammdatentabelle (tblGruppe) anzeigt.
Über einen LEFT JOIN wird festgestellt, ob der Datensatz einen zugeordneten Datensatz in der Zuordnungstabelle (tblZuordnungKontaktGruppe) hat. Dies muss allerdings nur für den Datensatz geschehen, der im Hauptformular gerade vorhanden ist. Dies wird über eine integrierte Unterabfrage realisiert. Das Feld SELECTED enthält also den Wert True, wenn eine Zuordnung vorhanden ist, ansonsten False ;).

Die Änderung der Zuordnung kann allerdings nicht über das Kontrollkästchen SELECTED erfolgen, da dies ja ein berechneter Ausdruck ist, also nur zur Anzeige dient. Hier wird ein kleiner optischer Trick verwendet, über das Kontrollkästchen wird ein ungebundenes Kontrollkästchen chkChanger gelegt, welches die Änderungen erfasst.
Die Prozedur SetAssignment führt die Änderung tatsächlich durch.
Da nicht nur ein Datensatz hinzugefügt oder gelöscht werden soll, ist dies mit einer Anfüge- und Löschabfrage realisiert worden. Hier könnte dies auch über Openrecordset/Addnew/Delete realisiert werden, wenn einen genauere Fehlermeldung (Datensatzweise) erwünscht ist.

Ich freue mich sehr über jede Rückmeldung, sei es Fehlermeldung, Verbesserungsvorschlag, Rückfragen und Lob :grins:

Grüße
Jean Pierre Allain

JPA
01.09.2014, 08:48
Hier die aktuelle Version 1.3 mit folgenden Änderungen:
Die Eigenschaften eZuordnungstabelle und eStammtabelle können jetzt auch mit einen SQL-Code befüllt werden.
Gruß
JPA

JPA
19.09.2014, 17:53
Servus Forum!

Ich habe eine weitere Optimierung umgesetzt.

Dank Ereignis-Übergabe ins Unterform, ist die Implementierung jetzt noch einfacher :mrcool:

Es reicht nun den Code in einer einzigen Prozedur zu hinterlegen, der Rest erledigt das Unterform:
Option Compare Database
Option Explicit

Dim frmAktion As Form_frmACB

Private Sub Form_Load()
Set frmAktion = Me.frmZuordnungAktion.Form
With frmAktion
.eLinkMasterFeld = Me.ID 'Erforderlich. Steuerelement welches auf das Masterfeld zeigt
.eZuordnungstabelle = "tblZuordnungKontaktAktion" 'Erforderlich. Tabelle/abfrage-Name welche die Zuordnungen speichert
.eZuordnungsFeld1 = "KontaktID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Bewegungstabelle (tblKontakt) speichert
.eZuordnungsFeld2 = "AktionID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Stammdatentabelle (tblAktion) speichert
.eStammtabelle = "tblAktion" 'Erforderlich. Tabelle/abfrage-Name der Stammdatentabelle (tblAktion)
.eStammFeldID = "ID" 'Erforderlich. Feldname aus der Angabe in eStammtabelle (tblAktion), der den Eindeutigen Wert enthält. Dieser Wert wird in das angegebene Feld eZuordnungsFeld2 (AktionID) gespeichert, bei Zuordnung
.eStammFeldBezeichnung = "Bezeichnung" 'Erforderlich. Feldname mit dem Wert, der als Eintrag in der Liste neben dem Kontrollkästchen angezeigt werden soll

.eSpaltenBeschriftung = "Aktionen" 'Optional. Die Spaltenüberschriften werden im Formularkopf eingeblendet
.eStammFormName = "frmAktion" 'Optional. Formularname welches geöffnet werden soll, wenn auf die Schlatfläche 'Einträge verwalten...' geklickt wird (Diese Schaltfläche ist nur sichtbar, wenn eine Angabe in dieser Eigenschaft gemacht wird
.eStammFormSchaltflächenbeschriftung = "Aktionen verwalten..." 'Optional. Text der Beschriftung der Schaltfläche 'Einträge verwalten...' (Erscheint nur, wenn eStammFormName gefüllt ist)
.eAuswahlAlleEinblenden = True 'Optional. Ein-/ausblenden des Kontrollkästchen 'Alle auswählen' im Formularfuß. Ohne Angabe ist es ausgeblendet
.eSortierung = NachBezeichnung 'Optional. Sortierung der Liste. Ohne Angabe wird NachBezeichnung sortiert
.eSortierrichtung = Aufsteigend 'Optional. Sortierrichtung. Ohne Angabe wird Aufsteigend sortiert
End With
End Sub
Beachte, die Eigenschaft eLinkMasterFeld ist neu!

Die aktuelle Version 1.4 ist jetzt hier (http://msofficeinside.blogspot.de/2012/12/ms-access-datenpflege-von-mn-datensatze.html) zu finden.
Gruß
JPA

PS: Knapp 100 Downloads und keine einzige Rückmeldung. Leute, das ist echt schade...

Klaus S. aus B.
18.08.2015, 15:40
Hi JPA,

ich habe das Tool jetzt auch downgeloaded und schreibe auch gleich einen Kommentar. ;)

Ich finde es toll und sehr übersichtlich und komfortabel, haben aber etwas Problemchen damit.

Habe jetzt rausgefunden, wie ich es einbaue, dass es mir in der Zuordnungstabelle die richtigen Datensätze anlegt. Klappt super.
Auch die Anzeige der zugeordneten Items zum DS klappt prima.
Aber wenn ich ein Häkchen entferne bekomme ich die Fehlermeldung "unzulässige Verwendung von Null" (siehe screenshot) und es wird aus der Zuordnungstabelle kein DS entfernt.

Was mache ich falsch?

Gruß
Klaus

JPA
18.08.2015, 20:36
Schwer zu sagen, ich sehen ja nicht dein Code.
Null-Meldung deutet darauf hin, dass was mit der Zuordnung nicht stimmt.
Nur was, kann ich blind nicht sagen.
Das Problem müsste sich in der Prozedur Private Function SetAssignment abspielen...

In deinem Screenshot fällt mir auf, dass duplikate in der Liste sind.
Hat nichts direkt mit dem Fehler zu tun, jedoch ein Hinweis, dass was mit der Liste nicht stimmt.

Mach doch ein Auszug aus deiner Datenbank und wir schauen mal...
Gruß
jpa

Klaus S. aus B.
19.08.2015, 09:38
Hallo Jean Pierre,

im Anhang haben ich einen Snapshot der Beziehungen eingefügt und hier ist der angepasste Code.

Option Explicit

Dim frmAktion As Form_frmACB

Private Sub Form_Load()
Set frmAktion = Me.frmACB.Form
With frmAktion
.eLinkMasterFeld = Me.ID_OC 'Erforderlich. Steuerelement welches auf das Masterfeld zeigt
.eZuordnungstabelle = "tbl_CCL" 'Erforderlich. Tabelle/abfrage-Name welche die Zuordnungen speichert
.eZuordnungsFeld1 = "OC_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Bewegungstabelle (tblKontakt) speichert
.eZuordnungsFeld2 = "Aufg_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Stammdatentabelle (tblAktion) speichert
.eStammtabelle = "tbl_Aufgabe" 'Erforderlich. Tabelle/abfrage-Name der Stammdatentabelle (tblAktion)
.eStammFeldID = "ID_aufgabe" 'Erforderlich. Feldname aus der Angabe in eStammtabelle (tblAktion), der den Eindeutigen Wert enthält. Dieser Wert wird in das angegebene Feld eZuordnungsFeld2 (AktionID) gespeichert, bei Zuordnung
.eStammFeldBezeichnung = "capt" 'Erforderlich. Feldname mit dem Wert, der als Eintrag in der Liste neben dem Kontrollkästchen angezeigt werden soll

.eSpaltenBeschriftung = "Aufgabe" 'Optional. Die Spaltenüberschriften werden im Formularkopf eingeblendet
.eStammFormName = "frm_aufgabe" 'Optional. Formularname welches geöffnet werden soll, wenn auf die Schlatfläche 'Einträge verwalten...' geklickt wird (Diese Schaltfläche ist nur sichtbar, wenn eine Angabe in dieser Eigenschaft gemacht wird
.eStammFormSchaltflächenbeschriftung = "Aufgaben verwalten..." 'Optional. Text der Beschriftung der Schaltfläche 'Einträge verwalten...' (Erscheint nur, wenn eStammFormName gefüllt ist)
.eAuswahlAlleEinblenden = True 'Optional. Ein-/ausblenden des Kontrollkästchen 'Alle auswählen' im Formularfuß. Ohne Angabe ist es ausgeblendet
.eSortierung = NachBezeichnung 'Optional. Sortierung der Liste. Ohne Angabe wird NachBezeichnung sortiert
.eSortierrichtung = Aufsteigend 'Optional. Sortierrichtung. Ohne Angabe wird Aufsteigend sortiert
End With
End Sub


Die Duplikate sind ok, es sind nicht wirklich Dupplikate, sondern Aufgaben, die mehrfach vorkommen in verschiedenen Phasen. Ich habe mich nur noch nicht darum kümmern können die zweite Spalte der Aufgabentabelle, welche die Phase beschreibt einzublenden. Ich habe es vorerst mit einem Workaround auf Tabellenebene erledigt (screenshot 2).

Falls Dich diese Infos nicht weiterbringen, vesuche ich die Db zu strippen und hochzuladen.

Schon mal vielen Dank vorab.
gruß
Klaus

JPA
19.08.2015, 16:36
Sieht "leider" alles gut aus. Es funz ja.
Tritt der Fehler nur bei Häckchen rausnehmen auf? Oder auch beim setzen?

Wenn du mir ne kleinen auszug der db zu kommen lässt, bekommen wir das sicher hin.
Interessiert mich auch was so schief laufen kann.
Ich habe das seit jahren in div. Porjekten stabil am laufen.

G
Jean Pierre

Klaus S. aus B.
19.08.2015, 19:23
Hallo Jean Pierre,

bin schon den ganzen Tag am Kämpfen.
Immer wenn ich denke "jetzt hab ich's" funktioniert etwas anderes nicht.

Bin aber schon weiter gekommen. Bei einer Anwendung der frmACB war es eine fehlerhafte Datenverknüpfung. Für das Form frm_ccl funktioniert jetzt alles, aber das frm_ccldet bekomme ich nicht zum Laufen.

Dort ist es so, dass anlegen (Häkchen setzen) nicht geht, ergibt Fehlermeldung, ein manuell eingetragene DS wird aber korrekt angezeigt und lässt sich auch löschen (Häkchen entfernen).

Anbei die gestrippte DB. Bin gespannt, was ich falsch gemacht habe. :rolleyes:

Gruß
Klaus

JPA
19.08.2015, 21:22
Hast nicht auf die Zuordnungstabelle verwiesen, sondern auf die Abfrage abf_ccldet
So geht es (In grün die Anpassungen):
With frm_CCLDet
.eLinkMasterFeld = Me.ID_CCL 'Erforderlich. Steuerelement welches auf das Masterfeld zeigt
.eZuordnungstabelle = "tbl_CclDet" 'Erforderlich. Tabelle/abfrage-Name welche die Zuordnungen speichert
.eZuordnungsFeld1 = "CCL_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Bewegungstabelle (tblKontakt) speichert
.eZuordnungsFeld2 = "AufgDet_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Stammdatentabelle (tblAktion) speichert
.eStammtabelle = "tbl_AufgDetail" 'Erforderlich. Tabelle/abfrage-Name der Stammdatentabelle (tblAktion)
.eStammFeldID = "ID_aufgdet" 'Erforderlich. Feldname aus der Angabe in eStammtabelle (tblAktion), der den Eindeutigen Wert enthält. Dieser Wert wird in das angegebene Feld eZuordnungsFeld2 (AktionID) gespeichert, bei Zuordnung
.eStammFeldBezeichnung = "AufgDetail" 'Erforderlich. Feldname mit dem Wert, der als Eintrag in der Liste neben dem Kontrollkästchen angezeigt werden soll

.eSpaltenBeschriftung = "Aufgabendetail" 'Optional. Die Spaltenüberschriften werden im Formularkopf eingeblendet
.eStammFormName = "frm_aufgdetail" 'Optional. Formularname welches geöffnet werden soll, wenn auf die Schlatfläche 'Einträge verwalten...' geklickt wird (Diese Schaltfläche ist nur sichtbar, wenn eine Angabe in dieser Eigenschaft gemacht wird
.eStammFormSchaltflächenbeschriftung = "Details verwalten..." 'Optional. Text der Beschriftung der Schaltfläche 'Einträge verwalten...' (Erscheint nur, wenn eStammFormName gefüllt ist)
.eAuswahlAlleEinblenden = True 'Optional. Ein-/ausblenden des Kontrollkästchen 'Alle auswählen' im Formularfuß. Ohne Angabe ist es ausgeblendet
.eSortierung = NachBezeichnung 'Optional. Sortierung der Liste. Ohne Angabe wird NachBezeichnung sortiert
.eSortierrichtung = Aufsteigend 'Optional. Sortierrichtung. Ohne Angabe wird Aufsteigend sortiert
End With

Hab gesehen, in der Abfrage abf_ccldet nimmst du den CR aus der Bezeichnung raus.
Die Lösung würde dann so aussehen das du dir die Abfrage qryAufgDetail machst:
SELECT ID_aufgdet, Replace([AufgDetail],Chr(13)," ") AS Bezeichner FROM tbl_AufgDetail

Und dann dich auf dieser beziehst:
With frm_CCLDet
.eLinkMasterFeld = Me.ID_CCL 'Erforderlich. Steuerelement welches auf das Masterfeld zeigt
.eZuordnungstabelle = "tbl_CclDet" 'Erforderlich. Tabelle/abfrage-Name welche die Zuordnungen speichert
.eZuordnungsFeld1 = "CCL_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Bewegungstabelle (tblKontakt) speichert
.eZuordnungsFeld2 = "AufgDet_ID" 'Erforderlich. Feldname der Zuordnungstabelle welcher den Wert der Stammdatentabelle (tblAktion) speichert
.eStammtabelle = "qryAufgDetail" 'Erforderlich. Tabelle/abfrage-Name der Stammdatentabelle (tblAktion)
.eStammFeldID = "ID_aufgdet" 'Erforderlich. Feldname aus der Angabe in eStammtabelle (tblAktion), der den Eindeutigen Wert enthält. Dieser Wert wird in das angegebene Feld eZuordnungsFeld2 (AktionID) gespeichert, bei Zuordnung
.eStammFeldBezeichnung = "Bezeichner" 'Erforderlich. Feldname mit dem Wert, der als Eintrag in der Liste neben dem Kontrollkästchen angezeigt werden soll

.eSpaltenBeschriftung = "Aufgabendetail" 'Optional. Die Spaltenüberschriften werden im Formularkopf eingeblendet
.eStammFormName = "frm_aufgdetail" 'Optional. Formularname welches geöffnet werden soll, wenn auf die Schlatfläche 'Einträge verwalten...' geklickt wird (Diese Schaltfläche ist nur sichtbar, wenn eine Angabe in dieser Eigenschaft gemacht wird
.eStammFormSchaltflächenbeschriftung = "Details verwalten..." 'Optional. Text der Beschriftung der Schaltfläche 'Einträge verwalten...' (Erscheint nur, wenn eStammFormName gefüllt ist)
.eAuswahlAlleEinblenden = True 'Optional. Ein-/ausblenden des Kontrollkästchen 'Alle auswählen' im Formularfuß. Ohne Angabe ist es ausgeblendet
.eSortierung = NachBezeichnung 'Optional. Sortierung der Liste. Ohne Angabe wird NachBezeichnung sortiert
.eSortierrichtung = Aufsteigend 'Optional. Sortierrichtung. Ohne Angabe wird Aufsteigend sortiert
End With


Aber ich muss schon sagen, klappt ja alles wie geplant, ich bin begeistert :-)

Gruß
Jean Pierre

Klaus S. aus B.
21.08.2015, 15:48
Hallo Jean Pierre,

vielen Dank erstmal!

Langsam blicke ich eher durch wie das funktioniert.
Aber an einem Punkt hänge ich noch.

1. Die Funktion nachbauen mit Verweis auf die Tabelle (wie von Dir beschrieben) funktioniert.
2. Die Abfrage nachbauen, funktioniert auch.

Ich habe jetzt aber versucht die Abfrage noch zu erweitern. Bei der m:n Zuordnung gibt es sinnvolle und nicht sinnvolle Zuordnungen.
Daher versuche ich die Liste aus der Stammtabelle entsprechend zu filtern/reduzieren. Das gelingt mir auch mit der Abfrage wie im screenshot.
Über das Feld Aufg_ID in meinem Formular (frm_ccldet) erscheinen genau die Auswahlmöglichkeiten, die ich haben will.
Aber wenn ich ein Detail auswähle kommt die Fehlermeldung "1 Parameter erwartet, aber es wurden zu wenige Parameter übergeben."
Warum kommt dieser Fehler? Wenn ich das Kriterium aus der Abfrage herausnehme (gleiche Abfrage, aber ohne Filter), funktioniert alles? Die Werte, die ich auswähle sind doch aber identisch, ob gefiltert oder nicht? Oder habe ich hier einen generellen Denkfehler?

Gruß
Klaus

Klaus S. aus B.
21.08.2015, 15:57
:upps: :upps:

...ich glaube ich habe meinen Fehler.
Jetzt fehlt mir nur die Lösung. ;)

Ganz offensichtlich stört ihn die "Beschreibung, wo er das Kriterium finden soll.
= [Formulare]![frm_CCLDet]![Aufg_ID]
Wenn ich den Wert (=429) eingebe, funktioniert es.

Wie muss denn der Verweis auf das Feld in meinem Formular richtigerweise heißen?

Gruß
Klaus

JPA
21.08.2015, 16:08
Wenn du dich auf das Unterform beziehen willst, dann:
=[Forms]![frm_CCLDet].form![frm_DetZuordnen]![Aufg_ID]

BTW: Verwende Forms und nicht Formulare, dann läuft deine Anwendung auch unter Access Englisch oder andere Sprachen ;-)

Gruß
JP

Klaus S. aus B.
21.08.2015, 16:17
Hallo Jean Pierre,

ich will mich auf das Hauptformular beziehen, dort taucht das Feld Aufg_ID auf.
Aber mit
=[Forms]![frm_CCLDet]![Aufg_ID]

bekomme ich den Fehler. ???

Gruß
Klaus

JPA
21.08.2015, 16:48
Also bei mir klappt's.
Habe dir meine Version angehängt.

Und wieder ein kluger Spruch ;)
"Packe nur die Tabellen in Abfrage die du wirklich brauchst"
In deinem Screenshot sieht man, dass du die tabelle tbl_Aufgabe gar nicht verwendest, bzw. nicht verwenden musst, da du auf das Feld Aufg_ID der Tabelle tbl_VerbAufgAufgdet selektieren kannst (s. mein Anhang).

jp

Klaus S. aus B.
24.08.2015, 07:38
Hallo Jean Pierre,

beim klappt's mit Deiner Version auch nicht!
Gleicher Fehler wie bei mir: "1 Parameter wurde erwartet,..."

Gruß
Klaus

JPA
24.08.2015, 08:12
Ja, stimmt.
Schon erstaunlich, die Openrecordset-Methode kann mit dem Verweis auf's Form nicht umgehen.
Da brauchen wir eine andere Lösung.
Ich überlege mir was...
G
JP

JPA
25.08.2015, 07:53
Habe den Code dahingehend optimiert (ist sogar einfacher geworden :-)

Private Function SetAssignment(Selection As Boolean, IDz1 As String, Optional IDzN As String) As Boolean
Dim db As Object 'DAO.Database
Dim rs As Object 'DAO.Recordset
Dim rs2 As Object 'DAO.Recordset
Dim sql As String, t As String, i As Long, IDsAffected() As String

On Error GoTo Err_Handle
If Len(IDz1) > 0 Then
Set db = CurrentDb()
If Selection Then
'Zuordnung hinzufügen
Set rs = Me.RecordsetClone
If Len(IDzN) > 0 Then
rs.FindFirst "IDzN=" & IDzN
Else
rs.MoveFirst
End If
Set rs2 = db.OpenRecordset("SELECT Z.* FROM " & cZTable & " AS Z", , 8) 'dbAppendOnly)
Do Until rs.EOF
If rs(3) = False Then
rs2.AddNew
rs2(cZField1) = rs(2)
rs2(cZFieldN) = rs(1)
t = rs(1)
rs2.Update
ReDim Preserve IDsAffected(i)
IDsAffected(i) = t
i = i + 1
RaiseEvent AddAssignment(t)
If Len(IDzN) > 0 Then Exit Do
End If
rs.MoveNext
Loop
Else
'Zuordnung entfernen
If Len(IDzN) > 0 Then sql = " AND [" & cZFieldN & "]=" & IDzN
Set rs = db.OpenRecordset("SELECT * FROM " & cZTable & " WHERE [" & cZField1 & "]=" & IDz1 & sql)
Debug.Print cZTable
Debug.Print cZField1
Debug.Print IDz1
Debug.Print sql

Do Until rs.EOF
t = rs(2)
rs.Delete
ReDim Preserve IDsAffected(i)
IDsAffected(i) = t
i = i + 1
RaiseEvent RemoveAssignment(t)
rs.MoveNext
Loop
End If
SetAssignment = True
If i > 0 Then
sql = GetCriteria() 'Merke aktuellen Datensatz
Me.Requery 'Aktualisiere das Formular
GotoRecordInForm sql 'Gehe zu gemerkten Datensatz
RaiseEvent ChangeAssignment(Selection, IDsAffected)
End If
Else
MsgBox "Zuordnung kann nicht angelegt werden, solange kein Hauptdatensatz besteht.", vbExclamation, "Änderung der Zuordnung"
End If

Exit_Proc:
On Error Resume Next
rs.Close
Set rs = Nothing
rs2.Close
Set rs2 = Nothing
Set db = Nothing
Exit Function

Err_Handle:
Beep
MsgBox Err.Description, vbCritical, Err.Number
Resume Exit_Proc
End Function


Und im Anhang noch malmeine Lösung als Download.
G
Jean Pierre

Klaus S. aus B.
25.08.2015, 08:30
Hallo Jean Pierre,

Super! Vielen Dank!

Funktioniert einwandfrei.

Gruß
Klaus

GTRDRIVER
07.09.2015, 19:10
Hallo JPA

ich habe diesen Post mit großem Interesse gelesen (danke für den Link in dem ursprungs Post) - ich finde das Thema sehr spannend da ich sowas in mehreren Projekten gut gebrauchen kann.

Was mich aktuell daran hindert es einzusetzen ist, dass ich im Uform eine bedingte Formatierung mit Farbiger Markierung benötige.

Bei den klassischen Uforms mit Listdarstellung hab ich das bisher immer so gemacht dass ich ein zusätzliches Feld aus der Tabelle einlese aber unsichtbar schalte - dieses trägt dann die SchlüsselID für die bedingte Formatierung.

Nun hab ich schon ein wenig im Code deines Uforms rumgesucht - aber die Lernkurve ist offenbar zu steil - hier blick ich nicht durch ...

ich hoffe, dass ich mich einigermaßen ausdrücken konnte was ich meine :-)

CU
GTR

JPA
07.09.2015, 20:26
Allesklar, aber wo ist deine Fragen, was kann ich für dich tun?
G
JPA

GTRDRIVER
07.09.2015, 20:49
Hallo JPA

wenn du so direkt fragst :-)

Toll wäre es ein zusätzliches Feld (nicht aktualisierbar) aus der Tabelle anzeigen zu lassen (sichtbar oder nicht sichtbar konfigurierbar) aus welchem sich dann die bedingte Formatierung die Info holt

Ich weiss jetzt nicht wie aufwändig das ist da ich wie schon gesagt bei deiem (sehr genialem Uform) im VBA nicht so wirlich bei allem durchsteige...

CU
GTR

JPA
07.10.2015, 22:09
Hallo GT3-Fahrer,

leider habe ich mich entchieden den Steuerelementnamen CAPTION zu vergeben, was mit der Eigenschaft CAPTION in Konflikt gerät (Hätte ich mir ja denken können :rolleyes: )
Habe das Steuerelement jetzt CAPTIONTEXT umbennant (auch im Code).

So kann ich per VBA jetzt eine Bedingte Formatierung setzen
frm_ccl.[Captiontext].BackStyle = 1 'Nicht Transparent
frm_ccl.[Captiontext].BackColor = frm_ccl.Section(acDetail).BackColor
With frm_ccl.[Captiontext].FormatConditions.Add(acExpression, acEqual, "left([Captiontext],1)=""B""")
.FontBold = True
.BackColor = RGB(255, 255, 102)
End With


Also, alle Bezeichnungen die mit einem B anfangen werden Fett und mit Gelb im Hintergrund formatiert. Ist ja nur ein Beispiel, kannst es nach deinen Wünschen jetzt anpassen.

Im Anhang die fertige Lösung.
A propos fertig, das bin ich jetzt auch, gute Nacht.

4c-Driver :mrcool:
(Schön wär's :weinen: )

GTRDRIVER
09.10.2015, 11:07
Hallo

super - danke für die Anpassung.

Kannst du es bitte noch im "MDB" Format bereitstellen da ich es unter 2003 einsetzten möchte.

Danke !

CU
GTR

JPA
09.10.2015, 12:14
Ok, sorry, ich habe deine Anforderung mit der von User Klaus verwechselt.

Im Anhang das aktualisiert "offiziellle" Beispiel.
G
JPA

GTRDRIVER
09.10.2015, 15:43
Hallo Jpa

das klappt ja ganz Prima. - Danke auch für die MDB Variante.

Was mir aufgefallen ist (evtl auch nur unter A2003 so stark zu sehen) bei jedem "klick" (also wenn man eine Check anhackt oder abhackt) dann baut der Code offenbar die Liste neu auf.

Das hat jetzt "ohne die Farbige" Markierung von einzelnen Einträgen nicht gestört - ich hab jetzt mal nen Test mit 20 Einträgen gemacht und da "flackert" alles relativ massiv.

Das bitte jetzt keineswegs als Kritik verstehen - ich möchte nur "Berichten" - Wenn es keinen anderen Weg gibt - kein problem - aber Ich frage halt mal...

CU
GTR

JPA
16.10.2015, 10:28
Sorry, das flackern kommt von der bed.Formatierung von MS.
Weiss nicht wie dies zu beinflussen ist.
G
JPA

Klaus S. aus B.
31.03.2016, 10:57
Hallo Jean-Pierre,

habe mittlerweile meinen Fehler gefunden, jetzt klappt es sehr gut.

Ich hätte aber noch ein Spezialforderung und weiß nicht ob und wie man das umsetzen könnte.

Ich würde gerne dem in der Koppeltabelle erstellten DS noch zwei Werte (Datum) "mitgeben", die man auf dem Hauptformular eingibt.

Geht das?

Gruß
Klaus

JPA
31.03.2016, 11:48
Servus Klaus,

ich meine zu wissen was du meinst, jedoch eine kleine Beispiel DB würde helfen.

Ich habe mein Tool erweitert, es löst mittlerweile ereignisse aus bei auswahl oder abwahl. Diese könntest du dir für deine anforderung nutzen. :cool:

Gruß
Jean Pierre

Klaus S. aus B.
31.03.2016, 13:29
Hallo Jean-Pierre,

im Anhang meine Demo DB.

Die Idee ist einem Mitarbeiter Zertifizierungen (nach Schulung) für bestimmte Werkzeuge zuzuordnen.
Das klappt mit Deinem Tool hervorragend.

Jetzt würde ich gerne in die Koppeltabelle aber noch das Schulungsdatum und den Termin für die nächste Prüfung für alle zugewählten Werkzeuge übernehmen.

Gruß
Klaus

JPA
31.03.2016, 14:32
Wie geil, ich hatte ja bereits schon in dieser Version Ereignisse zur Verfügung gestellt.
Must nur noch diesen Teil ändern/ergänzen:
Private WithEvents frm_sikozert As Form_frmACB

Private Sub frm_sikozert_AddAssignment(IDAffected As String)
Dim rs As DAO.Recordset

On Error GoTo ErrHandler
Set rs = CurrentDb().OpenRecordset("SELECT * FROM tbl_SiKoZert WHERE MA_ID=" & Me.ID_MA & " AND SiKo_ID=" & IDAffected)
If Not rs.EOF Then
rs.Edit
rs("Schulungsdatum") = Me.txtSchulungsdatum
rs("AblaufZert") = Me.txtAblaufZert
rs.Update
End If

ExitProc:
On Error Resume Next
rs.Close
Set rs = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Description, vbCritical, Err.Number
Resume ExitProc
End Sub


Die fertige Demo habe ich dir auch angehängt ;)

Grüße
Jean Pierre

Klaus S. aus B.
31.03.2016, 15:48
Super!!!

Vielen Dank!:grins:

Klaus S. aus B.
08.04.2016, 16:34
Hallo Jean-Pierre,

ich habe schon wieder einen Sonderwunsch. ;)

Wäre es möglich zusätzlich die Sortierung nach einem (beliebigen) Feld, also nicht nur ID und Beschreibung, einzubauen?

Ich dacht, ich hätte es schon geschafft, habe dann aber festgestellt, dass er zwar die Bezeichnung richtig sortiert hatte, aber die Kästchen noch in der alten (und damit falschen) Reihenfolge waren. :(

Gruß
Klaus

JPA
09.04.2016, 09:58
Da müsste tatsächlich was im Code erweitert werden.

Wobei ich deine Anmerkung dass er zwar die Bezeichnung richtig sortiert hatte, aber die Kästchen noch in der alten (und damit falschen) Reihenfolge waren nicht ganz verstehe?

G
JP

Klaus S. aus B.
11.04.2016, 07:54
Hallo Jean-Pierre,

ich habe im Code umgestellt auf "Sortierung nach Schlüsselfeld" und habe im Code

Public Property Let eStammFeldID(t As String)
cSFieldID = t 'Speicherung des PK-Feldnamens der Stammtabelle (z.B. ID)
End Property

das t durch "RF" (mein Feld für die Reihenfolge) ersetzt.
Dann bekommt man eine korrekt sortierte Liste mit den falschen Häkchen.
:p

Kommt davon, wenn man keine Ahnung von VBA hat und rumprobiert. ;)

Gruß
Klaus

JPA
13.04.2016, 13:07
Folgendes muss ergänzt werden:
Private Sub Form_Load()
Set frm_sikozert = Me.Ufrm_sikozuord.Form
With frm_sikozert
.eLinkMasterFeld = Me.ID_MA 'Erforderlich.
.eZuordnungstabelle = "tbl_sikozert" 'Erforderlich.
.eZuordnungsFeld1 = "MA_ID" 'Erforderlich.
.eZuordnungsFeld2 = "Siko_ID" 'Erforderlich.
.eStammtabelle = "tbl_siko" 'Erforderlich.
.eStammFeldID = "ID_siko" 'Erforderlich.
.eStammFeldBezeichnung = "Komponente" 'Erforderlich.

.eSpaltenBeschriftung = "Aktionen" 'Optional.
.eStammFormName = "frmAktion" 'Optional.
.eStammFormSchaltflächenbeschriftung = "Aktionen verwalten..." 'Optional.
.eAuswahlAlleEinblenden = True 'Optional.

.eSortierFelder = "[R]" '[R] ist dein Feldname nach dem aufsteigend sortiert werden soll
' .eSortierFelder = "[R] DESC" '[R] ist dein Feldname nach dem absteigend sortiert werden soll

' .eSortierung = NachBezeichnung 'Optional.
' .eSortierrichtung = Aufsteigend 'Optional.
End With
End Sub

Und Code im Form frmACB wurde geändert!
Daher am besten neu importieren.

Jetzt kannst du nach einem beliebigen Feld aus der Stammdatentabelle sortieren.

Gruß
Jean Pierre

Klaus S. aus B.
19.04.2016, 10:40
Hallo Jean-Pierre,

eine möglicherweise doofe Frage: Funktioniert die Version mit den Ereignissen auch wenn man das frmACB in mehreren Formularen verwenden will?

Ich habe das Formular in eine DB kopiert, in dem das UF schon mal verwendet wird und jetzt "beschwert" er sich beim Öffnen des neuen Formulars immer, dass ihm ein Wert aus dem anderen Formular fehlt und das UF bleibt leer.

Aufruf in Formular 1
Option Explicit
Private WithEvents frm_sikozert As Form_frmACB

Private Sub Form_Load()

Set frm_sikozert = Me.Ufrm_sikozuord.Form
With frm_sikozert
.eLinkMasterFeld = Me.ID_MA 'Erforderlich. "..."

Aufruf in Formular 2
Option Explicit
Private WithEvents frm_PNOC As Form_frmACB


Private Sub Form_Load()

Set frm_PNOC = Me.ufrm_PNzuord.Form
With frm_PNOC
.eLinkMasterFeld = Me.ID_OC 'Erforderlic "..."

Gruß
Klaus

JPA
19.04.2016, 12:18
Ja, es funz auch bei mehrfachbenutzung, weil eine eigene instanz erstellt wird.

Dein beschriebener Fehler müsste eine andere Ursache haben.
Mit einer kleiner demo-Datei im Anhang könnte ich mehr sagen...
Gruß
Jean Pierre

Klaus S. aus B.
19.04.2016, 14:01
Hallo Jean-Pierre,

Demo Datei ist immer etwas schwierig, weil es eine riesige Datei ist.

Habe mal was zusammengebastelt. Da sieht man , dass das Formular frm_SikoZert prima funktioniert, beim frm_PNOC erschient aber leider der gleiche Inhalt beim frmACB.

:entsetzt:
Ich bekomme die Dateien nicht klein genug. Ist Faktor 80 zu groß, trotz komprimieren und zippen.

Gruß
KLaus

Klaus S. aus B.
28.06.2017, 09:22
Hallo Jean Pierre,

ich muss mal wieder eine ganz blöde Frage stellen, aber ich bekomme es nicht hin.

Kann ich, bzw. wie kann ich in der Prozedur ein SQL Abfrage als Datenquelle für ".eStammtabelle = " definieren?


Gruß
Klaus

klimbo123
22.01.2019, 10:10
Hallo Jean-Pierre,

eine möglicherweise doofe Frage: Funktioniert die Version mit den Ereignissen auch wenn man das frmACB in mehreren Formularen verwenden will?

Ich habe das Formular in eine DB kopiert, in dem das UF schon mal verwendet wird und jetzt "beschwert" er sich beim Öffnen des neuen Formulars immer, dass ihm ein Wert aus dem anderen Formular fehlt und das UF bleibt leer.

Aufruf in Formular 1
Option Explicit Tutuapp (https://dltutuapp.com/) 9apps (https://9apps.ooo/) Showbox (https://showbox.run/)
Private WithEvents frm_sikozert As Form_frmACB

Private Sub Form_Load()

Set frm_sikozert = Me.Ufrm_sikozuord.Form
With frm_sikozert
.eLinkMasterFeld = Me.ID_MA 'Erforderlich. "..."

Aufruf in Formular 2
Option Explicit
Private WithEvents frm_PNOC As Form_frmACB


Private Sub Form_Load()

Set frm_PNOC = Me.ufrm_PNzuord.Form
With frm_PNOC
.eLinkMasterFeld = Me.ID_OC 'Erforderlic "..."

Gruß
Klaus

Hallo
Ich habe das gleiche Problem, obwohl ich das Notwendige gemacht habe
Lösungen, um mich vorzuschlagen?

Klaus S. aus B.
26.03.2019, 14:59
Hallo Klimbo,

ich kann nicht sagen, ob es in Deinem Fall zutrifft.
Wenn ich Probleme hatte, dass es zu Fehlern bei mehrfacher Verwendung des Formulars kam, lag es daran, dass die Datensatzquelle des Formulars frmACB nicht leer war.

Ich konnte den Fehler beheben durch Formular im Entwurf öffnen, Datensatzquelle löschen und speichern.

Gruß
Klaus