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 Knobbi38,

author=knobbi38 link=msg=166440 date=1740224771]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.[/quote]
Danke für deine Antwort. Ich bin dir sehr dankbar für deine Hilfestellung. Allerdings hatte ich in meinen Recherschen nur Lösungen gefunden, wo für jedes UF-Steuerelement ein separates Formular verwendet wird. Also Lösungen, welche die Formulare per VBA erzeugen und wieder löschen, wenn das Hauptformular geschlossen wird. Das erschien mir zu kompliziert, aber ich wollte den Weg mit mehreren Formularen auch ausprobieren, auch, weil ich den Veracht hatte, dass es mit einem Formular und mehreren Instanzen möglicherweise nicht geht.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Deine 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.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Sie 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 hatte ich tatsächlich nicht bedacht. Jetzt habe ich dem Formular im Eigenschaftsfenster im Feld "Datensatzquelle", diesen Ausdruck hinterlegt:
SELECT * FROM qryMahlzeitTagRezept01; Allerdings wird weiterhin in den Formularen nichts angezeigt.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Das die Funktion HasRecords() nicht existiert, hatte ich übrigens geschrieben. Das war als deine Hausaufgabe gedacht, ich kann ja nicht alles machen.
Das hatte ich überlesen. Danke dir noch mal für den Hinweis.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Solche Ausdrücke wie "Form_frm105Wochenplanung_UnterMahlzeit01.RecordSource" kannst du übrigens gleich vergessen, ein UF kann so nicht angesprochen werden!
Kann sein, aber die Datensatzquelle konnte ich mit dieser Variante tatsächlich dem Formular zuweisen. Es hat wirklich funktioniert.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11wenn man einem Formular eine neue Recordsource zuweist, kann man sich ein Requery schenken, das ist doppelt gemoppelt.
Danke, das macht dann absolut keinen Sinn. Das hatte ich vorher so nicht gesehen.

Anbei noch mal mein korrigierter Code:
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 = "frm105Wochenplanung_UnterMahlzeit01"

  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

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Das 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.
Was ist aber, wenn sich im vorgeschalteten Formular durch das Current-Ereigniss die angezeigten Daten ändern, dann bleiben die Daten in den 7 Unterformularen gleich. Ich hatte beabsichtig, dass sich das mitändert.

Zitat von: knobbi38 am Februar 22, 2025, 12:46:11Ob ein Formular als UF geladen ist, kann man nur erfahren, indem man bei allen SubForm-Controls die SourceObject Eigenschaft ausliest.
Und wenn da der Formularname ausgelesen wird, ist es geladen und wenn ein Leerstring herauskommt ist es nicht geladen?

Knobbi38

Nachtrag:
Zitat.sfrmMahlzeitTag1.SourceObject = "frm105Wochenplanung_UnterMahlzeit01"

Du solltes als Präfix für dein SubForm-Steuerelement nicht den Präfix für ein Unterformular verwenden - das erschwert die Lesbarkeit enorm.

Knobbi38

Hallo Konrad,

Zitat... also Lösungen, welche die Formulare per VBA erzeugen und wieder löschen, wenn das Hauptformular geschlossen wird. Das erschien mir zu kompliziert,
"Formulare per VBA erzeugen und wieder löschen"? Wo steht denn so ein Blödsinn? Selbstmodifizierende Programme sollte man erst gar nicht in Erwägung ziehen und sind immer äußerst verdächtig. 

Es ist deutlich einfacher, ein einzelnes Unterformular zu verwenden, als immer sieben Unterformulare ändern zu müssen, insbesondere dann, wenn sowieso das Gleiche dargestellt werden soll, nur mit anderen Parametern.

Wenn du ohne Filter bei dieser Query "SELECT * FROM qryMahlzeitTagRezept01; " nichts angezeigt bekommst, stimmen die Verknüpfungen (LinkMasterField, LinkChildField) nicht oder deine Query ist schlichtweg falsch. Die Query sollte ohne Filter alle Mahlzeiten einer ID für die ganze Woche anzeigen.

ZitatLoadSubform Me.sfrmMahlzeitTag1, vbMonday
siehe #16

ZitatMe.cboErnaehrungsplan.DefaultValue = 1
Ich dachte, die Kombobox gehört auf das UF und dann gehört die Initialisierung dafür in die Prozedur LoadSubForm. Der Wert kann auch nicht "1" sein, sondern müßte DayOfWeek sein, oder?

Gruß
Knobbi38
 

KonradR

Hallo Knobbi38,

Zitat von: knobbi38 am Februar 22, 2025, 15:46:05Du solltes als Präfix für dein SubForm-Steuerelement nicht den Präfix für ein Unterformular verwenden - das erschwert die Lesbarkeit enorm.
Präfix sfrm ist für mich immer das Unterformularsteuerelement und frm ist für mich immer das Formular. Für sich alleine ist ja jedes Formular ein Formular. Zum Unterformular wird es für mich durch das Suffix "_Unter".

Knobbi38

Zitat von: KonradR am Februar 22, 2025, 15:42:38Was ist aber, wenn sich im vorgeschalteten Formular durch das Current-Ereigniss die angezeigten Daten ändern, dann bleiben die Daten in den 7 Unterformularen gleich. Ich hatte beabsichtig, dass sich das mitändert.
Natürlich muß sich das mit ändern. Da wird aber mit Hilfe der Verknüpfungsfelder des SubForm-Steuerelements umgesetzt.
ZitatUnd wenn da der Formularname ausgelesen wird, ist es geladen und wenn ein Leerstring herauskommt ist es nicht geladen?
Jein, denn das ist ja nur die Information für ein SubForm-Steuerelement. Es müssen schon alle SubForm-Steuerelemente durchlaufen und geprüft werden, bis das Formular gefunden wird.

Gruß
Knobbi38

Knobbi38

Zitat von: KonradR am Februar 22, 2025, 16:09:08Präfix sfrm ist für mich immer das Unterformularsteuerelement
Das kann man natürlich so machen, aber es entspricht dann keiner gängigen Namenskonvention mehr und ist verwirrend, wenn andere das gleiche oder ein ähnliches Präfix für etwas anderes verwenden.  Präfixe sind im Allgemeinen nicht notwendig, aber wenn sie verwendet werden, sollten sie die Lesbarkeit verbessern.

Siehe mal hier unter "Tags for Control Objects":
http://access.mvps.org/access/general/gen0012.htm

Gruß
Knobbi38

KonradR

Hallo Knobbi,

Zitat von: knobbi38 am Februar 22, 2025, 16:04:10"Formulare per VBA erzeugen und wieder löschen"? Wo steht denn so ein Blödsinn?
Hier: https://access-im-unternehmen.de/Mehrere_Datensaetze_pro_Spalte_in_Formularen/

Zitat von: knobbi38 am Februar 22, 2025, 16:04:10Wenn du ohne Filter bei dieser Query "SELECT * FROM qryMahlzeitTagRezept01; " nichts angezeigt bekommst, stimmen die Verknüpfungen (LinkMasterField, LinkChildField) nicht oder deine Query ist schlichtweg falsch. Die Query sollte ohne Filter alle Mahlzeiten einer ID für die ganze Woche anzeigen.
Ich habe alle Filter rausgenommen, die Verknüpfungen ergänzt und die Abfrage geprüft. Parallel habe ich das selbe Unterformular in einem gleichen Unterformular verwendet und auf die herkömmliche Weise mit Datensatzquellenangabe der Abfrage und der Verknüpfungsfelder eingebunden. Das funktioniert tadellos

Zitat von: knobbi38 am Februar 22, 2025, 16:04:10Ich dachte, die Kombobox gehört auf das UF und dann gehört die Initialisierung dafür in die Prozedur LoadSubForm. Der Wert kann auch nicht "1" sein, sondern müßte DayOfWeek sein, oder?
Nein, hier geht es um etwas komplett anderes. Der Inhalt vom Kombinationsfeld ist der Ernährungsplan, der dann festlegt, was in den folgenden Wochen genau passiert. Jeder Ernährungsplan hat ein anderes Ziel. Den wähle ich am Anfang aus. Wenn ich nichts auswähle, ist das Feld leer und ich muss es doch auswählen. Dann setze ich lieber einen Standardwert und erspare mir so immer wieder das neue Auswählen des entsprechenden Eintrags.




KonradR

Zitat von: knobbi38 am Februar 22, 2025, 16:18:25Es müssen schon alle SubForm-Steuerelemente durchlaufen und geprüft werden, bis das Formular gefunden wird.
Also wenn die ControlSource Eigenschaft aller Unterformulare geprüft und der Name des Unterformulars nicht gefunden wurde, ist das Unterformular nicht geöffnet. Ok, Danke.

Zitat von: knobbi38 am Februar 22, 2025, 16:28:38Siehe mal hier unter "Tags for Control Objects":
http://access.mvps.org/access/general/gen0012.htm
Danke auch hier. Allerdings ist das Unterformularsteuerelement nicht extra benannt und hier gibt es nur "ctl" als mögliche Auswahl für Control als Representant für ein Steuerelement. Das ist sehr allgemein, wie ich finde. "sfrmctl" wäre da treffender, aber das ist leider nicht definiert.

Knobbi38

Hallo Konrad,

bezügl. deines Links: dort werden mitnichten SubForm-Controls und Formulare dynamisch zur Laufzeit angelegt, sondern es wird eine Hilfsprozedur verwendet, die Entwicklung etwas zu vereinfachen. Das sind quasi selbst geschriebene Tools und ist somit auch vollkommen legitim. Hätte mich auch gewundert, wenn André Minhorst so etwas machen würde. Die Formulare werden übrigens dort auch mit dem Präfix "sfm" angelegt. Leider werden zur Vereinfachung die SubForm-Steuerelemte mit den gleichen Präfixen versehen, um diese dann besser in einer Schleife ansprechen zu können - hätte man auch anders machen können, aber das ist eben die "künstlerische" Freiheit des Autors.

Knobbi38


Knobbi38

Zitat von: KonradR am Februar 22, 2025, 16:42:44Danke auch hier. Allerdings ist das Unterformularsteuerelement nicht extra benannt und hier gibt es nur "ctl" als mögliche Auswahl für Control als Representant für ein Steuerelement.
Das steht doch ganz eindeutig:

  "Subform/report    sub    subContact"

in der Tabelle.

Knobbi38

Hallo Konrad,

ich kenne dein Datenmodell nicht, deshalb kann ich leider dir bezüglich deiner Abfragen oder den Verknüpfungen der UFs nicht helfen, aber dass bekommst du sicherlich hin. Wenn du jedoch in den Unterformularen Datensätze anlegen möchtest und dafür Default-Werte benötigt werden, würde so etwas in die Sub LoadSubForm() gehören.

Gruß
Knobbi38
 

KonradR


KonradR

Zitat von: knobbi38 am Februar 22, 2025, 17:02:57Wenn du jedoch in den Unterformularen Datensätze anlegen möchtest und dafür Default-Werte benötigt werden, würde so etwas in die Sub LoadSubForm() gehören.
Danke für den Tip. Das kommt als nächste Herausforderung.

KonradR

Hallo Knobbi38,

ich habe mir deinen Code noch mal angeschaut und ein paar Fragen, vielleicht kannst du mir da noch mal weiterhelfen?

Warum deklarierst du die Variable ctl für ein Unterformularsteuerelement mit ByRef bzw. was passiert, wenn ich es einfach weglasse oder mit ByVal ersetzte?

Mit "DayOfWeek" hast du eine Variable vom Typ VbDayOfWeek erzeugt, der über eine Zahl von 0 bis 7 einen Wochentag angibt. Mir ist nicht klar, warum in der Replace()-Funktion die Zeichenkette (String) des vorher gesetzten Filterstrings mit "{0}" ersetzt und der zu ersetzende Typ anhand des vorher in einen String umgewandelten Wochentags gesucht wurde. Was ist "{0}" eigentlich? Diesen Ausdruck kenne ich nicht.
                                                                                       
Mit dem Ausdruck "[MahlztagIDRef]={0}" kann ich leider auch nichts anfangen, weil ich mit geschweiften Klammern in VBA noch nicht gearbeitet habe. Was machen die geschweiften Klammern und warum steht darin 0?
                                                                                       
Außerdem stellt sich mir bei deinem Code die Frage nach der Formularinstanz. Wenn ich deine "Private Sub LoadSubform" 7x, also für jeden Wochentag durchlaufe, bezieht sich der Code 7x auf das selbe Formular. Das heißt, ich zeige, Stand deinem Code, in jedem Unterformularsteuerelement hintereinander eine Filterung, der Inhalte beginnend mit Montag und endend mit Sonntag. Dann habe ich am Ende, wenn alles funktioniert, den Filter für das Formular für Sonntag gesetzt und sehe in allen Unterformularsteuerlementen das Formular mit dem Filter für Sonntag, weil sich alle Unterformularsteuerelement, wie oben erwähnt auf das selbe Unterformular beziehen. Wie siehst du das?

Knobbi38

Hallo Konrad,

ZitatWarum deklarierst du die Variable ctl für ein Unterformularsteuerelement mit ByRef bzw. was passiert, wenn ich es einfach weglasse oder mit ByVal ersetzte?
"ByRef" und "ByVal" sind für Objekte fast identisch, beide übergeben eine Referenz auf das Objekt ctl. Der Unterschied bei Objekten ist, dass mit "ByRef" direkt die Referenz auf das Objekt übergeben wird, mit "ByVal" wird eine Kopie der Referenz erzeugt und dann als Argument übergeben. Mit ByRef könnte man also in der Funktion die Referenz selber ändern, mit Byval würde man nur die Kopie verändern, das Original bliebe erhalten. Dieses Verhalten ist wichtig, wenn man innerhalb der Funktion das übergebene Objekt durch ein anderes ersetzen möchte - spielt in diesem Fall also keine Rolle. Hier wird der Vorteil genutzt, daß die Übergabe mit ByRef beim Aufruf performanter ist. 

ZitatMit "DayOfWeek" hast du eine Variable vom Typ VbDayOfWeek erzeugt, der über eine Zahl von 0 bis 7 einen Wochentag angibt. Mir ist nicht klar, warum in der Replace()-Funktion die Zeichenkette (String) des vorher gesetzten Filterstrings mit "{0}" ersetzt und der zu ersetzende Typ anhand des vorher in einen String umgewandelten Wochentags gesucht wurde. Was ist "{0}" eigentlich?
"{0}" ist ein von mir definierter Platzhalter (welcher im String nicht vorkommen sollte) und dient dazu in einem String an einer bestimmten Stelle einen anderen String einzufügen. Das erspart mir mit dem &-Operator den String aus den Teilstrings zusammenzusetzen und ist deutlich übersichtlicher und einfacher. Für das Ersetzen wird die Funktion Replace() verwendet. Weil Replace() einen String durch einen anderen ersetzt, wird mit CStr(vbMonday) der numerische Wert explizit in einen String konvertiert. Das hätte ich auch weglassen können, aber dann würde VBA eine implizite Konvertierung vornehmen und das möchte ich damit vermeiden.
                                                                                     
ZitatMit dem Ausdruck "[MahlztagIDRef]={0}" kann ich leider auch nichts anfangen, weil ich mit geschweiften Klammern in VBA noch nicht gearbeitet habe. Was machen die geschweiften Klammern und warum steht darin 0?
Wofür der String "{0}" steht, habe ich oben beschrieben, die "0" bedeutet einfach nur der 1. Platzhalter. Wenn man mehrere Platzhalter braucht, werden diese einfach durchnummeriert. Der nächste wäre dann "{1}".
                                                                                       
ZitatAußerdem stellt sich mir bei deinem Code die Frage nach der Formularinstanz. Wenn ich deine "Private Sub LoadSubform" 7x, also für jeden Wochentag durchlaufe, bezieht sich der Code 7x auf das selbe Formular.
Nein. LoadSubForm() bezieht sich 7 mal auf das gleiche Formular, nicht dasselbe! Es werden also 7 verschiedene Instanzen des gleichen Formulars erzeugt.

ZitatDas heißt, ich zeige, Stand deinem Code, in jedem Unterformularsteuerelement hintereinander eine Filterung, der Inhalte beginnend mit Montag und endend mit Sonntag. Dann habe ich am Ende, wenn alles funktioniert, den Filter für das Formular für Sonntag gesetzt und sehe in allen Unterformularsteuerlementen das Formular mit dem Filter für Sonntag, weil sich alle Unterformularsteuerelement, wie oben erwähnt auf das selbe Unterformular beziehen. Wie siehst du das?
Erklärung siehe vorher. Es werden sieben unterschiedliche Formularinstanzen erzeugt, die voneinander gar nichts wissen. Das ist genauso wie mit allen Objekten auch. Wenn du zwei Collections anlegst, haben die auch nichts miteinander zu tun, obwohl es beide Collections-Objekte sind.

Gruß
Knobbi38