Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Ein UFO über "Verknüpfen nach" an eine feste Zeile eines anderen UFO verknüpfen

Begonnen von KonradR, Februar 19, 2025, 17:43:50

⏪ vorheriges - nächstes ⏩

KonradR

Hallo liebe Accessfreunde,

ich möchte ein Unterformularsteuerelement von seinem Fremdschlüsselfeld an das Primärschlüsselfeld des UFO's mit den Daten aus der übergeordneten Tabelle verknüpfen. Mit dem mir bekannten Wissen über z.B [sfrmBlock].Form![BlockID] funktioniert das leider nicht. Gibt es da auch eine Möglichkeit, auf eine bestimmte Zeile, also die 1., 2. oder 3. zu verknüpfen? Schon im Voraus vielen Dank.

MzKlMu

Hallo,
warum nutzt Du nicht die Dateneigenschaften "Verknüpfen von/nach". Da braucht es doch keinen Code.
Gruß Klaus

KonradR

Hallo Klaus,

Zitat von: MzKlMu am Februar 19, 2025, 18:03:18warum nutzt Du nicht die Dateneigenschaften "Verknüpfen von/nach"
Die will ich ja nutzen. [sfrmBlock].Form![BlockID] ist ja der Teil mit "Verknüpfen nach". Allerdings will ich in eine bestimmte Zeile, verknüpfen.

MzKlMu

Hallo,
das geht nicht.
Zitat[sfrmBlock].Form![BlockID]
Was soll das sein ?
Zum Verknüpfen brauchst Du einen Wert. Wie stellst Du sicher, dass der gewünschte Wert in der 3.Zeile steht. Oder, anders gefragt, warum die 3.Zeile ?
Wenn dieser Wert einmalig ist, hast Du nur einen Datensatz im Ufo.
Kannst Du das Vorhaben mal näher erläutern?
Was wird der Sinn des Vorhabens ?
Gruß Klaus

Knobbi38

Hallo Konrad,

bei den Eigenschaften Verknüpfen kommen entweder direkt die Feldnamen oder beteiligten Steuerelementnamen hinein. Eine bestimme Zeile kannst du aber so nicht auswählen, daß ist "Excel-Denke", Datenbanken verarbeiten Datensätze, auf die man per Keys zugreift.

Gruß
Knobbi38

KonradR

Hallo Klaus,

Zitat von: MzKlMu am Februar 19, 2025, 19:00:16Was soll das sein ?
Das ist der Inhalt von "Verknüpfen nach". Dabei wird auf das Unterformularsteuerelement "sfrmBlock" mit der "BlockID" verknüpft.

Zitat von: MzKlMu am Februar 19, 2025, 19:00:16Wie stellst Du sicher, dass der gewünschte Wert in der 3.Zeile steht.
Weil es um Tage einer Woche geht und der erste Tag immer in der ersten und der zweite Tag immer in der zweiten Zeile usw. steht.

Zitat von: MzKlMu am Februar 19, 2025, 19:00:16Kannst Du das Vorhaben mal näher erläutern?
Sehr gerne. Ich habe ein Formular mit 10 Unterformularen und einem Kombinationsfeld erstellt. Das Kombinationsfeld bestimmt die in den darauffolgenden 3 UFOs angezeigten Daten. Das habe ich mit "Verknüpfen von" und "Verknüpfen nach" erledigt. Die darauffolgenden Ufos zeigen den BLOCK die darin enthaltenen WOCHEN und die wiederum darin enthaltenen TAGE an. Jetzt möchte ich in den weiteren 7 UFOS die Mahlzeiten für jeden Tag einer  übersichtlich nebeneinander darstellen. Daher sind die Mahlzeiten für den ersten Tag einer Woche immer im UFO ganz links und für den zweiten Tag rechts daneben usw. angezeigt. Hier noch ein Bild, von der Formularoberfläche:
Sie dürfen in diesem Board keine Dateianhänge sehen.



KonradR

Hallo Knobbi38,

Zitat von: knobbi38 am Februar 19, 2025, 19:21:58Datenbanken verarbeiten Datensätze, auf die man per Keys zugreift.
Danke für deine Antwort. Dann komme ich um VBA also nicht herum. Ich dachte, erst es geht ohne.

MzKlMu

Hallo,
Du kannst doch die 7 Ufos für die Tage direkt auf den gewünschten Tag filtern.
Gruß Klaus

KonradR

Hallo Klaus,

Zitat von: MzKlMu am Februar 19, 2025, 19:31:42Du kannst doch die 7 Ufos für die Tage direkt auf den gewünschten Tag filtern.
Vielen Dank dafür. Gleichzeitig will ich die Mahlzeiten für den Tag in dem betreffenden UFO nicht nur anzeigen, sondern auch eingeben. Dann darf ich bei der Eingabe sicher auslesen dürfen, in welchem Unterformularsteuerelement ich mich gerade bewege und anhand dessen den Fremdschlüssel für den entsprechenden Tag setzten. Anschließend kann ich filtern. Wahrscheinlich mit der Form.Filter-Eigenschaft?

Knobbi38

Hallo Konrad,

es gibt mehrere Möglichkeiten, daß umzusetzen. Sicherlich könnte man 7 UFs erstellen und die jeweils anders konfigurieren, sinnvoller wäre es aber, 1 UF x-mal zu verwenden. Beim Öffnen des HF werden dann alle UF entsprechend initialisiert. Die Verknüpfung ist ja für alle gleich, aber die Datenherkunft kann über den Wochentag als Kriterium angepaßt werden. Alternativ kann auch ein entsprechender Filterausdruck pro UF verwendet werden. Bei der Initialisierung kannst du dann auch gleich den Default-Wert für den Fremdschlüssel zuweisen, so dass neue DS auch gleich richtig zugeordnet werden.

Gruß
Knobbi38

KonradR

Hallo knobbi38,

Zitat von: knobbi38 am Februar 20, 2025, 12:40:111 UF x-mal zu verwenden. Beim Öffnen des HF werden dann alle UF entsprechend initialisiert.
Das hatte ich auch ursprünglich gemeint, aber leider missverständlich geschrieben.

Zitat von: knobbi38 am Februar 20, 2025, 12:40:11Alternativ kann auch ein entsprechender Filterausdruck pro UF verwendet werden. Bei der Initialisierung kannst du dann auch gleich den Default-Wert für den Fremdschlüssel zuweisen, so dass neue DS auch gleich richtig zugeordnet werden.
Das habe ich schon recherschiert. Das dürfte ich umgesetzt bekommen.

Nur ist mir noch unklar, wie ich die entsprechende, gefilterte Instanz des Unterformulars nun dem gewünschten Unterformularsteuerelement zuweise. Wenn ich es so probiere, gibt es bei mir die Fehlermeldung "Typen unverträglich":
Dim MahlzeitMontag As Form_frm01Wochenplanung_Unter_Mahlzeit

Private Sub Form_Load()
    Set MahlzeitMontag = New Form_frm01Wochenplanung_Unter_Mahlzeit
    MahlzeitMontag.Visible = True
    Me.sfrmMahlzeitTag1.SourceObject = MahlzeitMontag
End Sub

Hast du da noch eine Idee, wie ich das umgesetzt bekomme?

Knobbi38

Zitat... wie ich die entsprechende, gefilterte Instanz des Unterformulars nun dem gewünschten Unterformularsteuerelement zuweise.
Das wäre ja so auch nicht ganz i.O.

Die Vorgehensweise ist in etwa so, wenn ich mal von der Filtermethode ausgehe:
  • Vorbedingung: im HF hast du für jeden Wochentag ein SubForm-Steuerelement angelegt, z.B. mit den Bezeichnern subMontag, subDienstag usw.
  • Im HF Form_Load Event werden die SubForm-Steuerelemente der Reihe nach initialisiert. In meinem Fall habe ich mir dazu einfach eine Private Prozedur LoadSubForm erstellt, welche mit den Argumenten "Name des Steuerelements" und einem Indikator für die Filterfunktion übergeben wird, z.B. die Wochentagsnummer.

Hier der Air-Code aus dem HF:
---
' Im HF Form Load Event:
  ' Bind meals per Weekday subforms
  If HasRecords(Me.Recordset) then
    LoadSubform Me.subMonday, vbMonday
    LoadSubform Me.subTuesday, vbTuesday
    ...
  End If
---

' Im HF Codemodul:
Private Sub LoadSubform( _
    ByRef ctl As Access.subForm, _
    ByVal DayOfWeek As VbDayOfWeek)

  Const FLT_EXPR As String = "[Wochentag]={0}"
  Const SUB_FORM_NAME as String = "sfrmMahlzeitenProWochentag"

  Dim strFilter As String

  ' Build filter expression
  strFilter = Replace(FLT_EXPR, "{0}", CStr(DayOfWeek))

  ' Load subform and apply filter
  ctl.SourceObject = SUB_FORM_NAME
  ctl.Form.Filter = strFilter
  ctl.Form.FilterOn = CBool(Len(strFilter) > 0)
End Sub
Feldnamen und Formularnamen mußt du natürlich noch an deinen Gegebenheiten anpassen und die Funktion HasRecords() selber noch kurz ausprogrammieren.

Gruß
Knobbi38

KonradR

Hallo Knobbi38,

danke für deine Antwort. Ich habe deinen Codevorschlag so übernommen und für "Wochentag" meinen Feldnamen für den Fremdschlüssel zur Tabelle mit den Wochen mit "MahlztagIDRef" eingetragen.
Wenn ich es so drin stehen habe, dann kommt die Fehlermeldung bei "Sub oder Function nicht definiert" und "hasrecords" wird markiert. "Hasrecords" scheint der Compiler nicht zu kennen. Wenn ich alles ohne "If" und "hasrecords" durchlaufen lasse, dann gibt es auch keine Fehlermeldung, aber die Formular sind trotzdem leer. Das Kombinationsfeld am Anfang habe ich mal als Standardwert mit dem ersten Eintrag aus der Datensatzherkunft versehen
 
Private Sub Form_Load()
        Me.cboErnaehrungsplan.DefaultValue = 1
        LoadSubform Me.sfrmMahlzeitTag1, vbMonday
        LoadSubform Me.sfrmMahlzeitTag2, vbTuesday
        LoadSubform Me.sfrmMahlzeitTag3, vbWednesday
        LoadSubform Me.sfrmMahlzeitTag4, vbThursday
        LoadSubform Me.sfrmMahlzeitTag5, vbFriday
        LoadSubform Me.sfrmMahlzeitTag6, vbSaturday
        LoadSubform Me.sfrmMahlzeitTag7, vbSunday
End Sub

Private Sub LoadSubform(ByRef ctl As Access.SubForm, ByVal DayOfWeek As VbDayOfWeek)

  Const FLT_EXPR As String = "[MahlztagIDRef]={0}"
  Const SUB_FORM_NAME As String = "sfrmMahlzeitenProWochentag"

  Dim strFilter As String

  ' Build filter expression
  strFilter = Replace(FLT_EXPR, "{0}", CStr(DayOfWeek))

  ' Load subform and apply filter
  ctl.SourceObject = "frm01Wochenplanung_Unter_Mahlzeit"
  ctl.Form.Filter = strFilter
  ctl.Form.FilterOn = CBool(Len(strFilter) > 0)
End Sub

Hast du noch eine Idee, woran es liegen kann, dass alles leer bleibt?

KonradR

Hallo liebe Accessfreunde,

ich habe es jetzt mal mit meinem Wissen probiert. Wissentlich, dass der folgende Code mit einer Schleife abgearbeitet werden könnte, habe ich es erst mal ohne gemacht, um mich auf die Funktionalität zu konzentrieren.
Für den Code ist es wichtig, dass die Formulare "Form_frm101Wochenplanung_Haupt" und "frm104Wochenplanung_UnterTag" geladen sind, da ich auf das RecordsetClone-Element des Formulars "frm104Wochenplanung_UnterTag" zugreife. Im Form_Load Ereigniss von Formular "frm101Wochenplanung_Haupt" funktioniert der Code auch super. Der Code soll aber auch im Form_Current Ereigniss von Unterformular "frm103Wochenplanung_UnterWoche" funktionieren. Nun ist es leider so, dass das 3. Unterformular gar nicht geladen, also
SysCmd(acSysCmdGetObjectState, acForm, "frm104Wochenplanung_UnterTag") = 0 ist. Wie kann das sein? Ich kann das Formular doch sehen. Könnt ihr mir da eine Hilfestellung geben, wie ich das Formular im Current_Ereignis von Formular "frm103Wochenplanung_UnterWoche" geladen bekommeJ? Anbei mein Code:
Private Sub Form_Current()
'    Debug.Print "Form_Current: " & Me.Name
    [Form_frm101Wochenplanung_Haupt].Form![sfrmTag].Requery
   
    Dim rstRSC As DAO.Recordset
    Dim lngTagRef1 As Long
    Dim lngTagRef2 As Long
    Dim lngTagRef3 As Long
    Dim lngTagRef4 As Long
    Dim lngTagRef5 As Long
    Dim lngTagRef6 As Long
    Dim lngTagRef7 As Long

    If SysCmd(acSysCmdGetObjectState, acForm, "frm101Wochenplanung_Haupt") > 0 Then 'And SysCmd(acSysCmdGetObjectState, acForm, "frm104Wochenplanung_UnterTag") > 0 Then
        Debug.Print Form_frm101Wochenplanung_Haupt.Name & ": " & SysCmd(acSysCmdGetObjectState, acForm, "frm101Wochenplanung_Haupt")
        Debug.Print Form_frm104Wochenplanung_UnterTag.Name & ": " & SysCmd(acSysCmdGetObjectState, acForm, "frm104Wochenplanung_UnterTag")
        Set rstRSC = Form_frm101Wochenplanung_Haupt.sfrmTag.Form.RecordsetClone
            If Not rstRSC.RecordCount = 0 Then
               lngTagRef1 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
               lngTagRef2 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
                lngTagRef3 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
                lngTagRef4 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
                lngTagRef5 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
                lngTagRef6 = rstRSC.Fields("TagID").Value
            End If
            rstRSC.MoveNext
            If Not rstRSC.EOF Then
                lngTagRef7 = rstRSC.Fields("TagID").Value
            End If
        rstRSC.Close
    Else
        Debug.Print Form_frm101Wochenplanung_Haupt.Name & ": " & SysCmd(acSysCmdGetObjectState, acForm, "frm101Wochenplanung_Haupt")
        Debug.Print Form_frm104Wochenplanung_UnterTag.Name & ": " & SysCmd(acSysCmdGetObjectState, acForm, "frm104Wochenplanung_UnterTag")
    End If
   
    With Form_frm101Wochenplanung_Haupt
        .sfrmMahlzeitTag1.SourceObject = "frm105Wochenplanung_UnterMahlzeit01"
        .sfrmMahlzeitTag2.SourceObject = "frm106Wochenplanung_UnterMahlzeit02"
        .sfrmMahlzeitTag3.SourceObject = "frm107Wochenplanung_UnterMahlzeit03"
        .sfrmMahlzeitTag4.SourceObject = "frm108Wochenplanung_UnterMahlzeit04"
        .sfrmMahlzeitTag5.SourceObject = "frm109Wochenplanung_UnterMahlzeit05"
        .sfrmMahlzeitTag6.SourceObject = "frm110Wochenplanung_UnterMahlzeit06"
        .sfrmMahlzeitTag7.SourceObject = "frm111Wochenplanung_UnterMahlzeit07"
    End With

    Form_frm105Wochenplanung_UnterMahlzeit01.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef1
    Form_frm106Wochenplanung_UnterMahlzeit02.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef2
    Form_frm107Wochenplanung_UnterMahlzeit03.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef3
    Form_frm108Wochenplanung_UnterMahlzeit04.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef4
    Form_frm109Wochenplanung_UnterMahlzeit05.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef5
    Form_frm110Wochenplanung_UnterMahlzeit06.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef6
    Form_frm111Wochenplanung_UnterMahlzeit07.RecordSource = "SELECT * FROM qryMahlzeitTagRezept01 WHERE MahlztagIDRef = " & lngTagRef7
   
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag1].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag2].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag3].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag4].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag5].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag6].Requery
    [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag7].Requery

End Sub

Knobbi38

Hallo Konrad,

du warst schon auf dem richtige Weg, bist dann aber nochmal abgebogen.  ;)

Wenn du auf meine Hilfestellung nicht eingehen möchtest, solltest du das klar kommunizieren und dann kannst du dein eigenes Ding weiter machen. Ich habe nicht vor, alles für die Mülltone zu schreiben. Mein Vorschlag beinhaltet die Wiederverwendung von einem UF und nicht von 7 verschiedenen UFs. Das ist eine ganz andere Baustelle.

Hier nochmal ein paar Anmerkungen bei einem UF:

Dein Trugschluss war, daß man ein geladenes UF so nicht erkennen kann, weder mit SysCmd() noch in der Forms-Auflistung oder per AllForms() Auflistung. Ob ein Formular als UF geladen ist, kann man nur erfahren, indem man bei allen SubForm-Controls die SourceObject Eigenschaft ausliest.

Zurück zum ursprünglichen Code von mir. Der setzt voraus, daß in dem UF bereits eine Datenherkunft (Recordsource) eingetragen ist:
.Recordsource = "SELECT * FROM qryMahlzeitTagRezept01"Sie ist für alle gleich und muß deshalb nicht separat zugewiesen werden, sondern kann fest im Entwurf eingestellt werden. Die Selektion mit der "Where-Bedingung" wird in diesem Beispiel über Zuweisung des Filters erreicht! Das ist auch der Grund, warum bei dir nichts angezeigt worden ist - ohne Datenherkunft?  ::)

Das die Funktion HasRecords() nicht existiert, hatte ich übrigens geschrieben. Das war als deine Hausaufgabe gedacht, ich kann ja nicht alles machen.  ;)

Noch ein paar Hinweise:
  • Solche Ausdrücke wie "Form_frm105Wochenplanung_UnterMahlzeit01.RecordSource" kannst du übrigens gleich vergessen, ein UF kann so nicht angesprochen werden!
  • Mit "Form_frm105Wochenplanung_UnterMahlzeit01" wird übrigens die Default-Instanz eines Formulars aufgerufen, was in Access normalerweise nicht notwendig ist - so etwas macht man einfach nicht, außer man weiß genau, warum und wann man es ausdrücklich braucht!
  • SysCmd() kann man zwar verwenden (stammt aus Urzeiten von Access), läßt sich aber ebenso gut durch Allforms.isloaded und .CurrentView ersetzen
  • [Form_frm101Wochenplanung_Haupt].Form![sfrmMahlzeitTag7].RequerySo ein Ausdruck ist natürlich quatsch. Was möchtest du damit eigentlich erreichen?
    Übrigens: wenn man einem Formular eine neue Recordsource zuweist, kann man sich ein Requery schenken, das ist doppelt gemoppelt.

Gruß
Knobbi38

Nachtrag:
Das HF Current Ereignis kannst du für eine Initialisierung dieser Art nicht verwenden, das gehört ins Load Ereignis! Das hatte ich aber auch schon geschrieben.