PDA

Vollständige Version anzeigen : Bla As Form vs. Bla As Form_frmMeinForm?


Beaker s.a.
07.06.2012, 16:32
Hallo,
Aufgrund dieses Zitats von Martin aus http://www.ms-office-forum.net/forum/showthread.php?t=290294&page=2
Im aufrufenden Formular, beim gewünschten Ereignis, wird der Docmd.Openform-Aufruf ersetzt durch:
Code:
If Len(Nz(Me!TextfeldMitDerTypeID)) > 0 Then
Set frmMakes = New Form_frmMakes 'Formularzugriff beginnen:
With frmMakes

stellt sich mir o.a. Frage.
Ich habe mehrere kleine Formulare, hauptsächlich zur Pflege von Vorratstabellen. Diese öffne ich z.Zt. per ButtonClick und .OpenForm. Die Synchronisierung (soweit erforderlich) passiert sowohl über .OpenArgs als auch über selbstdefinierte Properties.
Nun dachte ich mir, probiere obiges mal aus,

Private Sub btnEditKG_Click()
Dim frm As Form_frmKundenGruppen

Set frm = New Form_frmKundenGruppen
frm.Visible = True
End Sub

und es passiert Folgendes:
Das Form poppt kurz auf, und wird sofort wieder geschlossen weil der Code ja weiterläuft nach .Visible.
Wie halte ich denn in diesem Fall den Code an, um mit dem Formular arbeiten zu können bzw. wie simuliert man in diesem Fall den Parameter acDialog der OpenForm-Methode?
Ich habe es mit
Do While CurrentProject.AllForms(frm.Name).IsLoaded
DoEvents
Loop

probiert, aber da kommt beim Schliessen des Forms eine Fehlermeldung:
Fehlernummer: 5
Beschreibung: Ungültiger Prozeduraufruf oder ungültiges Argument
Prozedur: btnEditKG_Click
Wenn ich den abfange und mit Resume Next zur Tagesordnung übergehe funzt es, - hm.
Ist das der einzige Weg? Kommt mir etwas umständlich vor.
Dank im Voraus für Eure Unterstützung und
viele grüsse
ekkehard

Marsu65
07.06.2012, 16:48
Hallo Ekkehard,
verschiebe die die Deklaration
Dim frm As Form_frmKundenGruppen
in den Modulkopf.

Sauber ist in dem Fall beim Form_Close noch aufzuräumen:
Set frm = Nothing

Ursache für deine Beobachtung ist, dass wenn die Prozedur beendet wird, die Variablen in der Prozedur zurückgesetzt werden.

PS:
Eine andere (Josefs) Alternative ist eine Selbst-Referenzierung des Forms. Solange es eine Referenz auf das Objekt besteht, bleibt es bestehen.

hcscherzer
07.06.2012, 17:22
Hallo Ekkehard.

Ich würde jedenfalls dabei bleiben, die Formulare über docmd.openform zu öffnen.
In vb.net ist es möglich, Formulare über eine neue Instanz der Objektvariablen zu initialisieren aber da braucht es zusätzlich ein frm.show() oder ein frm.showdialog() um das Formular tatsächlich zu öffnen.

Beaker s.a.
07.06.2012, 17:27
Hallo Marsu,
Ursache für deine Beobachtung ist, dass wenn die Prozedur beendet wird, die Variablen in der Prozedur zurückgesetzt werden
Das war mir wohl klar; - hätte ich auch schreiben können :( . Ebenso das Aufräumen (das hab' ich inzwischen drauf).
Auf die Idee das im Modulkopf zu deklarieren hätte ich eigentlich auch selber kommen können (grrr), - danke für den Schubs.
Nun habe ich aber diverse von diesen kleinen Formularen. Da müsste ich für jedes eine eigene Deklaration einfügen. Kann man das nicht über ein öffentliches Modul variabel gestalten?
Kannst Du mir einen Link zu Josefs Alternative posten?
gruss ekkehard

Anne Berg
07.06.2012, 18:27
Hallo,Nun dachte ich mir, probiere obiges mal aus, was ist der Hintergrund für dieses "Experiment", was versprichst du dir davon?

Auch ich bin der Ansicht, dass du mit der herkömmlichen OpenForm-Methode bestens bedient bist.

Marsu65
07.06.2012, 18:33
Wenn ich das noch richtig im Kopf habe, funtioniert das so,
dass du im aufgerufenen Formular auch ein m_frm as Form_Sowiso deklarierst (oben im Deklarationsteil ;) SCNR)
und dann im Form_Load einfach
Set m_frm = Me
referenzierst.
Probier mal aus. Einen Link habe ich nicht, kann mich nur schwach erinnern, das mal irgendwo gesehen zu haben; ich benutze das auch nicht.

Allgemein:
Für Formulare, die eigenständig eine Funktion erfüllen und nicht vom aufrufenden Formular abhängig sind, bin ich H-Cs [und Annes] Meinung und öffne sie per DoCmd.

Anders sieht es aus, wenn ein Formular Teilaufgaben erfüllt, die für das aufrufende Formular wichtigt sind (z.B. Neuanlegen, Bearbeiten von einzelnen Datensätzen aus einem Übersichtsformular).
Oder aber das aufrufende Formular auf Events des aufgerufenen reagieren soll (Deklaration mit WithEvents). In den Fällen macht IMHO die Referenzierungsmethode Sinn.

Gibt es einen besonderen Grund, warum du auf Referenzierung umstellen möchtest?

Beaker s.a.
07.06.2012, 20:30
Hallo,
@all
Gibt es einen besonderen Grund, warum du auf Referenzierung umstellen möchtest?
Will ich ja gar nicht (unbedingt).
Meine Frage wurde ja durch die im OP zitierte Einlassung von Martin
wird der Docmd.Openform-Aufruf ersetzt
ausgelöst. Ich bin ja ein Lernender, und da dachte ich, dass es da Hintergründe gibt um den Code "eleganter/effektiver" zu gestalten. Scheint nicht so; - na gut, es funzt ja alles mit .OpenForm ganz gut.
Vielleicht doch noch zum Hintergrund. Ich habe neben Kombifeldern eine Schaltfläche welche das "zugehörige" Form öffnet. Per .OpenArgs bekommt dieses dann den Namen des aufrufenden Forms, den Namen des Kombis und den .Value des Kombis. So kann man sich schnell weitere Infos zu dem auszuwählenden Wert(en) im Kombi ansehen, ohne extra über ein Hauptmenu das Form suchen zu müssen um es zu öffnen; und auch, wenn nötig einen neuen DS für das Kombi anlegen. Per Checkbox im aufgerufenen Form lässt sich der dort aktuell anzeigte DS (ID) beim Schliessen auch direkt an das Kombi zurück geben.
Ich bedanke mich für Eure Erläuterungen, dass ich dann schon auf dem richtigen Weg bin.
gruss ekkehard

Stefan Dase
08.06.2012, 07:16
Moin Ekkehard,

wie die anderen schon geschrieben haben, wird in den meisten Fällen das DoCmd.OpenForm die bessere Lösung sein.

Die explizite Instanz mittels Set verwende ich nur in ganz seltenen Fällen. Hauptsächlich, wenn ich von einem Formular mehere Instanzen öffnen möchte; das geht mit dem DoCmd nämlich nicht.

Viele Grüße von der Domsheide,
Stefan