![]() |
VB(A) - Kommunikation zwischen Formularen....
Gibts eine schnelle und einfach Möglichkeit um div. Parameter usw. zwischen Formularen zu übergeben?
Das einzige was mir bis jetzt eingefallen ist, ist ein globales Modul mit div. Funktionen, die in globale Variablen des Moduls schreiben. Und dann rufe ich vom anderen Formular wieder Funktionen des Moduls auf, die mir dann die Parameter wieder zurück geben. Ist total umständlich, und ich denk mir, da muss es doch was besseres und saubereres geben. ;) Ich dank euch schon mal für eure Ideen. :) |
Da ist deine Problemstellung leider ein wenig ungenau. Was genau willst du machen?
Wenn du auf Werte von beiden Formularen aus zugreifen willst, dann sind globale Variablen gar keine schlechte Lösung. Wenn's passt wäre vielleicht sogar eine Kapselung über eine Klasse was schönes. Wenn du aus einem Formular direkt im anderen Formular was machen willst, dann kannst du es ja auch direkt ansprechen (Funktionen, Felder, ...) |
z.B.
ich hab ein Übersichtsformular mit div. Datensätzen in einem Listefeld. Dann klickt man einen Datensatz an - ich möchte die ID an ein anderes Formular übergeben. Weil in dem Formular was sich dann öffnet möchte ich natürlich gleich den Datensatz anzeigen, der im "Hauptformular" angeklickt wurde. Ich hab mich mal mit Globalen Variablen gespielt (is schon länger her > 1 Jahr) nur damals hat das ganze net so hin gehaut. Globale Variablen def. man ja eigenltich in einem modul mit public dim - oder? Und die Idee mitn Klassenmodul is net sogar supa - das könnt ich mir überlegen. Weil dann mach ich mir eine Klasse, und setz dort meine Parameter die ich übergeben möchte, und im anderen Formular lese ich diese Standardmäßig aus. ;) |
Nur so 'ne blöde Idee:
Die Variablen müssten doch "Kinder" der Formulare sein. Vielleicht kann man sie also mit formularname.variable ansprechen?:confused: Ähnlich müsste es auch mit eingabefeldern funktionieren (formularname.eingabefeldname.value). Keine Ahnung ob das geht (siehe oben). Jak |
@ jak: Absolut korrekt.
@ LLR: Beim Öffnen eines Formulars kann man auch ein Argument übergeben. docmd.OpenForm "frmVourForm",,,,,,"YourArgument" |
Zitat:
und die Idee von Jak könnt ich auch aufgreifen. Jetzt denke ich, ich habe einige Ideen von euch bekommen, wie man das ganze recht schnell abwickeln kann. :) |
So jetzt steh ich vor dem "Problem" (ich hab schon ein wenig früher gepostet - damit ich dann nicht anstehe... ;))
Hmm, Problem is, wie moch i des jetzt. Die Einfachste Methode, die ich bei dem Fall jetzt gerne Verwendet hätte ist einer Globalen Variable eines Formulars einen Wert zu geben. Das Formular was geöffnet wird heißt Formular2 - die Variable Test (vom Typ String). Der Code dazu schaut folgendermaßen aus: Code:
DoCmd.OpenForm "Formular2", , , , , , "" Mir is das auch ein bißchen zu leicht vor gekommen. ;) Die andere Idee wäre ja ein Klassenmodul. Nur im Prinzip ists da ja dann so, wie wenn ich das mit einem "normalen" Modul und dortigen globalen Variablen gemacht hätte. Bzw. kann ich überhaupt einer Function/Procedure in einer Klasse Variablen übergeben - weil ich bekomm bei meinem kleinen Testprogramm sowohl bei der Prozedur "schreiben (strVar as string)" als auch bei der Function "Lesen() as string" die Fehlermeldung: "Objektvariable oder With-Blockvariable nicht fest gelegt" Hmm, ich bin noch ein ziemlicher DAU was Klassen betrifft. :rolleyes: BTW: wenn jemand ein paar nette Tutorials od. sonstige Webseiten zum Thema Klassen in VB kennt (damit meine ich was geht, was geht nicht und wie gehts), dann bitte einen Link posten. :) |
Zitat:
|
das is der ganze Code vom neuen Formular:
Code:
Option Compare Database Aufgerufen wirds von einem anderen "Pseudo-Formular", names Formular1, auch mit einem Button. ;) |
Zitat:
Code:
Public test as String |
Zitat:
Probier ich morgen, wenn ich wieder in der Arbeit bin. |
Es geht wirklich so einfach. Du hast nur verabsäumt dem Variant Formular2 zu sagen wer und was er ist :D
In deinem Code ist Formular2 nämlich wirklich nur ein nicht befüllter Variant (Zum Glück gibt's den Datentyp in .NET nimma). Dein Code: ------------------------------------------- DoCmd.OpenForm "Formular2", , , , , , "" Formular2.test = "hallo" ------------------------------------------- Versuch's mal so: ------------------------------------------- Dim Formular2 As Access.Form DoCmd.OpenForm "Formular2" set Formular2 = Application.Forms.Item("Formular2") Formular2.test = "hallo" ------------------------------------------- 0der als Kurzfassung: ------------------------------------------- DoCmd.OpenForm "Formular2" Application.Forms("Formular2").test = "hallo" ------------------------------------------- |
Wieder mal ein großes Merci an euch beide (flinx und Seidl) :hallo:
Public test as string und dann im 1. Form den Code vom Seidl, und es geht 1A. Aber eines noch: (@Seidl) falls du dazu kommst, könntest du ev. kurz "ausführen" wie du das mit der Klasse gemacht hättest? Brauchst mir jetzt keine Klasse bauen, nur kurz in Worte fassen, wie du das gemacht hättest (rein aus interesse) :rolleyes: :) Also nochmal danke, wünsch euch noch einen schönen (Arbeits-)Tag. |
Für eine Variable allein würde eine Klasse auch keinen Sinn machen. Sinnvoll würde sowas z.B. dann, wenn mehrere globale Variablen von mehreren Formularen aus gelesen und geschrieben werden sollen und sich dabei gegenseitig beeinflussen (kommt auch vor).
In so einem Fall wären die Variablen als private Members einer Klasse gut aufgehoben. Wenn z.B. Recordsets dabei sind, dann kannst du die im Initialize der Klasse setzen und im Terminate wieder vernichten. Die Änderungen an Variablen könnte man dann über Methoden oder Properties (property set) der Klasse definieren. Dadurch würde jede Änderung an den Variablen, egal von wo sie ausgeht, den richtigen Ablauf von nötigen Änderungen durchlaufen. Man kann dann nicht mal versehentlich eine der Variablen ändern ohne die von ihr abhängigen anderen zu berücksichtigen. Ausgelesen würden die Variablen dann natürlich über property get. |
hui - das wirft ja wieder viele Fragen auf... ;)
Zitat:
Zitat:
dim neueInstanz as Klasse set neueInstanz = new Klasse? terminate? set neueInstanz = nothing? Zitat:
hmm, ich glaub ich brauch doch eine Beispielklasse von dir... Mit Methoden versteh ichs ja noch. Man macht globale Variablen in der Klasse (mit Dim im "Kopf" des Klassenmoduls) Und in die schreib bzw. lese ich dann mit Prozeduren/Funktionen - right? Aber Property set/get? Von dem hab ich noch nicht wirklich was gehört. Naja, ich hoff ich geh dir nicht zu sehr am Geist, aber vielleicht findest ja mal Zeit. ;) Und ich dank dir auf alle Fälle schon einmal für deine Ausführungen. Denn wie du siehst, bin ich nicht sehr bewandert was Klassen betrifft und hab sie eigentlich bis auf eine Ausnahme noch nicht verwendet. (obwohl ma sicher sooo viel damit machen kann) |
Mit Klassen kannst du eigentlich auch nicht viel mehr machen als ohne. Es geht nur um das gedankliche Modell mit dem man übersichtlicher und weniger fehleranfällig programmieren kann. In der wirklichen Welt abstrahieren wir ja auch zu einfachen Denkmodellen. Wer kümmert sich schon darum was in einem Auto vorgeht wenn man auf's Gas tritt? Es gibt eben das Auto und die Möglichkeit auf's Gas zu treten, was zur Folge hat das man schneller wird. Man muss das Auto dazu nicht verstehen und es ist im Prinzip komplett austauschbar, solange jedes der Autos ein Gaspedal hat.
Ich hänge dir eine gezippte Access-Datenbank an in der ich eine Kreis-Klasse und ein kleines Modul in dem sie verwendet wird geschrieben habe. Natürlich ist die Klasse eigentlich komplett sinnlos aber wenn's nur darum geht mal sowas zu sehen, wird es schon reichen. Allerdings muss ich dich darauf hinweisen, dass meine Theorie auch schon ein wenig eingerostet ist. ;) Ich würde dir auf jeden Fall empfehlen ein wenig über das Prinzip der objektorientierten Programmierung zu lesen. Wenn man das richtig einsetzt kann es sehr viel Arbeit sparen. Der Code wird leichter wiederverwendbar und kann einfacher ausgetauscht werden. Wenn du mit anderen Programmierern zusammenarbeiten musst wirst du ohnehin nicht drum rum kommen. |
Danke!
Von der allg. Theorie kenn ich mich eh aus. (Klassen, Instanzen, Methoden, ....) Und das mit der Abstraktionsweise usw. - ist mir bekannt. (ein bissl lernt man ja in der Schule auch) Nur habe ich es eben noch nie IRL verwendet (verwenden müssen). Und der springende Punkt ist eben, den du angesprochen hast, es wird übersichtlicher. Nur die "rohe" Theorie bringt mir halt net viel, ohne sowas mal zu programmieren, bzw. genau zu wissen, wie ich die einzelnen Klassen entwerfen kann und was es dafür für "Eigenheiten" der Programmiersprache gibt. Ich werd mir dann dein quasi Lehrbuchbeispiel, zumindest der Name lässt darauf schließen, anschaun. Und da werd ich schon sehen, wie das in VB funktioniert. :) mfg, LLR |
Eine Klasse für einen Kreis habe ich wirklich schon öfter als Beispiel für Klassen gesehen. Ich fürchte, das wird aber so ziemlich alles sein, was mein Beispiel mit einem Lehrbuch verbindet :D
Sehr beliebt ist auch das Beispiel Bankkonto. Dazu ist mir aber nicht viel anschauliches eingefallen. Tja, ich werd' langsam vergesslich und doof. |
Zitat:
Es war auch kein Lehrbuch, sondern eine haufen Zettel, die von einem Univ. Prof. geschrieben wurde, der bei meiner (alten) Schule unterrichtet (hab ihn aber leider nicht gehabt) Dort warens Kreise, Dreiecke und Rechtecke/Quadrate... Und so viel wie du weißt, glaub ich nicht, dass du doof wirst. :) :hammer: |
So jetzt hab ich mir grad deine Beispielklasse angesehen - das war genau das was ich gebraucht habe. :D
Jetzt weiß ich endlich, was man wie wo in VB machen kann. ;) 2 kurze Fragen hab ich noch: die Procedure "Class_Initialize()" wird nehm ich an ausgeführt, sobald man eine Instanz der Klasse erstellt - richtig? und "Class_Terminate()" wird ausgeführt wenn man die Instanz = nothing setzt bzw. der Code zu Ende ist - right? Und ich denke, die werden immer so heißen, wurscht welchen Namen die Klasse erhält. Ups, jetzt warens doch 3 Fragen. Das nächste is eigentlich noch was, was nicht direkt zur Klasse gehört: was machst du mit dem Recordset und den 2 "Prozeduren": Code:
Property Set Data(Data As ADODB.Recordset) BTW: kann man eigentlich "Sub-Klassen" definieren, die dann Eigenschaften/Methoden etc. von der Parent-Klasse erben? Nochmals herzlichen Dank. :) |
Mit den ersten beiden Punkten bist du absolut richtig gelegen. Die beiden Event-Prozeduren "Class_Initialize()" und "Class_Terminate()" reagieren quasi auf die Geburt bzw. den Tod eines Objekts der Klasse. Sie heissen auch überall gleich. Allerdings muss ich hier eine kleine Einschränkung setzen. In VB sieht die Sache wieder ein wenig anders aus. Dort kann man dem Konstruktor "New" auch Werte übergeben und diese zum Initialisieren verwenden.
Das sinnlose Property mit dem Recordset habe ich eigentlich nur eingebaut, um ein Property mit einem Objekt zu haben. Damit wollte ich den Unterschied zwischen "Property Set" für Objekte und "Property Let" für Variablen veranschaulichen. Ist aber auch nicht so besonders wichtig. In .NET gibt's diese Unterscheidung meines Wissens ohnehin nicht mehr. ;) Ableitungen von Klassen sind zwar in VB, nicht aber in VBA möglich. Das selbe gilt auch für Schnittstellen (Stichwort "Implements"). Dazu gleich wieder ein kleiner .NET-Exkurs; In .NET kann man nicht nur Klassen von einer Basis-Klasse ableiten, sondern man kann das selbe auch für Formulare und Controls machen. Was zu den Klassen in VBA vielleicht sonst noch erwähnenswert wäre ist die Möglichkeit zu "Private / Friend / Public" Prozeduren. Friend Prozeduren sind in Standardmodulen nicht möglich. Solche Prozeduren sind nur innerhalb des Projekts aufrufbar; also nicht ganz Private aber auch nicht ganz public ;) Manchmal kann auch eine als Static definierte Variable ganz praktisch sein. Die behält ihren Wert solange der Code ausgeführt wird und bleibt damit in einer Prozedur auch zwischen Aufrufen erhalten. Das ist aber keine Besonderheit von Klassen und sei hier nur mal so erwähnt weil es auch in diesem Zusammenhang nützlich sein kann. Wenn wir jetzt in Java oder C++ wären, müsste nach Static auch Final angesprochen werden. Ein so definiertes Member wäre allen Objekten einer Klasse gemeinsam. Gibt's in VBA und VB leider nicht aber ich hoffe diesbezüglich auf .NET ;) Damit dürfte ich jetzt mein Wissen ziemlich komplett vor dir ausgebreitet haben. Viel mehr fällt mir nämlich zu dem Thema wirklich nicht mehr ein. Falls du noch Fragen hast, weisst du ja wie du mich erreichst ;) |
Danke. :laola: :D
Alles hab ich jetzt zwar auch net verstanden, aber das is jetzt auch net so wichtig. ;) Was ich jetzt aber auch gesehen hab (und nicht wusste), dass man einfach einen Recordset öffnen kann und darin Sachen abspeichern. Is ja quasi wie ein eigener Datentyp (der mit type und end type) definiert wird - nur dass man noch ein paar Zusatzoperationen hat. :) Ich denk mal so Gschichten wie rst.RecordCount usw. werden auch funktionieren. Und danke für dein "Angebot". Ich werde sicher wieder mal darauf zurück kommen - bzw. weiter kleine Schwierigkeiten/Fragen bei div. VB Programmen haben. ;) |
Alle Zeitangaben in WEZ +2. Es ist jetzt 02:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag