{"id":55000397,"date":"2023-10-01T00:00:00","date_gmt":"2023-10-19T13:10:49","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=397"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"twinBASIC_Daten_von_Form_zu_Form","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/twinBASIC_Daten_von_Form_zu_Form\/","title":{"rendered":"twinBASIC: Daten von Form zu Form"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/dfbea333971b4b94bb82b3886d9de46f\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Wenn man mit SDI-Forms arbeiten, also mit solchen Formularen, die als einzelne Fenster ge&ouml;ffnet werden, m&ouml;chte man manchmal eine der folgenden beiden Aufgaben erledigen &#8211; oder auch beide: Das aufrufende Formular soll Daten an das aufgerufene Formular &uuml;bergeben, beispielsweise um den Prim&auml;rschl&uuml;ssel eines im Detailformular anzuzeigenden Datensatzes zu &uuml;bergeben. Oder man m&ouml;chte ein Formular zum Abfragen von Daten &ouml;ffnen und diese dann vom aufrufenden Formular aus aufrufen. Wie beides gelingt und welche unterschiedlichen Wege es dazu gibt, schauen wir uns in diesem Artikel an. Au&szlig;erdem betrachten wir, welche Arten von Daten man grunds&auml;tzlich &uuml;bertragen k&ouml;nnen sollte.<\/b><\/p>\n<p>Es wird immer wieder Anl&auml;sse geben, bei denen wir einen Button auf einer Form verwenden, um eine andere Form damit zu &ouml;ffnen. In manchen F&auml;llen reicht dies aus &#8211; wir verwenden die andere Form dann f&uuml;r einen Zweck, der in sich abgeschlossen ist. In vielen F&auml;llen wird es jedoch so sein, dass wir Daten von einem zum anderen Fenster &uuml;bergeben wollen &#8211; und vielleicht auch wieder zur&uuml;ck. Ein Beispiel sind Forms, die an Daten gebunden sind. Wenn wir etwa ein Form-Objekt nutzen, um darauf eine Liste von Produkten anzuzeigen, wollen wir meist auch ein weiteres Form verwenden, um die Details eines einzelnen Produkts zu liefern &#8211; beispielsweise um diese bearbeiten zu k&ouml;nnen. Wenn wir dann einen der Eintr&auml;ge in der Liste markieren und auf eine Schaltfl&auml;che klicken, um die Form mit den Details anzuzeigen, m&uuml;ssen wir dieser Form auf irgendeine Weise die Information &uuml;bergeben, zu welchem Produkt es die Detaildaten anzeigen soll.<\/p>\n<p>Andersherum wollen wir nach dem Bearbeiten des Produkts oder auch nach dem Anlegen eines neuen Produkts und dem Schlie&szlig;en des Detailfensters Informationen an das aufrufende Fenster zur&uuml;ckgeben &#8211; zum Beispiel, weil wir den soeben bearbeiteten oder angelegten Datensatz in der Liste markieren wollen oder weil die &Auml;nderungen in den Daten direkt in den dort angezeigten Eintrag &uuml;bernommen werden sollen.<\/p>\n<p>Es gibt auch noch einfachere Beispiele, die es bereits gibt &#8211; zum Beispiel das mit der Funktion <b>MsgBox <\/b>angezeigte Meldungsfenster oder das mit <b>InputBox <\/b>angezeigte Eingabefenster f&uuml;r einen einfachen Text.<\/p>\n<p>Wenn wir einmal Daten vom Benutzer abfragen wollen, die zu umfangreich sind als jene, die wir mit <b>MsgBox <\/b>und <b>InputBox <\/b>ermitteln k&ouml;nnen, m&uuml;ssen wir eigene Forms daf&uuml;r entwickeln &#8211; und die dort ermittelten Daten wollen wir auf irgendeine Weise f&uuml;r die Weiterverarbeitung auslesen.<\/p>\n<h2>Weitere Beispiele f&uuml;r das &Uuml;bertragen von Daten<\/h2>\n<p>Beispiele f&uuml;r das &Uuml;bertragen von Daten zwischen zwei Form-Objekten sind die folgenden:<\/p>\n<ul>\n<li>Anmeldeformular<\/li>\n<li>Suchformular<\/li>\n<li>Einstellungen und Konfigurationen<\/li>\n<li>&Uuml;bertragung der ID eines ausgew&auml;hlten Datensatzes von einer Hauptform zur Bearbeitungsform.<\/li>\n<li>Workflows &uuml;ber mehrere Forms<\/li>\n<\/ul>\n<h2>M&ouml;glichkeiten zur &Uuml;bertragung von Daten an die zu &ouml;ffnende Form<\/h2>\n<p>Im Folgenden schauen wir uns verschiedene M&ouml;glichkeiten an, wie wir Daten vom aufrufenden <b>Form<\/b>-Objekt zum aufgerufenen <b>Form<\/b>-Objekt und zur&uuml;ck &uuml;bergeben k&ouml;nnen:<\/p>\n<ul>\n<li>Zwischenspeichern in einer globalen Variablen, die von der aufrufenden Form aus gef&uuml;llt und von der aufgerufenen Form aus ausgelesen wird und umgekehrt<\/li>\n<li>Wenn der zu &uuml;bergebende Wert in einem Steuerelement der aufrufenden Form enthalten ist, k&ouml;nnen wir dieses von der aufgerufenen Form aus auslesen.<\/li>\n<li>&Uuml;bergeben der Informationen von der aufrufenden Form an eine &ouml;ffentliche Eigenschaft der aufgerufenen Form. Diese kann von der aufgerufenen Form auch ge&auml;ndert werden, damit wir den Wert wieder in die aufrufende Form zur&uuml;ckholen k&ouml;nnen.<\/li>\n<\/ul>\n<h2>Von Form zu Form mit einer globalen Variablen<\/h2>\n<p>Die Verwendung einer globalen Variablen ist ein Weg, mit dem wir Daten zwar nicht direkt von einer Form zur n&auml;chsten &uuml;bertragen, aber wir k&ouml;nnen so einen Wert von der ersten Form aus so zur Verf&uuml;gung stellen, dass die aufgerufene Form diesen auch nutzen kann. Der Nachteil ist, dass dieser Wert nicht nur von den beiden Forms gelesen und geschrieben werden kann, die ihn nutzen, sondern auch noch von anderen Stellen aus. Hier ist also sicherzustellen, dass diese Variable nur f&uuml;r diesen speziellen Zweck verwendet wird &#8211; beispielsweise durch einen eindeutigen Namen.<\/p>\n<p>F&uuml;r das Beispiel ben&ouml;tigen wir als Erstes eine globale Variable, in der wir den zu &uuml;bergebenden Wert speichern k&ouml;nnen. Diese legen wir in einem neuen Modul namens <b>mdlGlobal <\/b>unter dem Namen <b>strGlobal <\/b>an (siehe Bild 1). Da wir nur Texte von einem Textfeld zum n&auml;chsten &uuml;bertragen wollen, reicht der Datentyp String aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_05\/pic_397_002.png\" alt=\"Globale Variable\" width=\"424,6267\" height=\"205,5885\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Globale Variable<\/span><\/b><\/p>\n<p>Im Formular <b>frmMain <\/b>haben wir ein Textfeld namens <b>txtValue <\/b>erstellt, in das wir den zu &uuml;bertragenden Wert eintragen. F&uuml;r die Schaltfl&auml;che <b>cmdSendViaGlobalVariable <\/b>haben wir den folgenden Code hinterlegt:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSendViaGlobalVariable_Click()\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(txtValue) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         strGlobal = txtValue\r\n         frmGlobalVariable.Show\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Textfeld ist leer.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dieser pr&uuml;ft, ob &uuml;berhaupt ein Text enthalten ist &#8211; falls nicht, erscheint eine entsprechende Meldung. Anderenfalls schreibt die Prozedur den Inhalt des Textfeldes in die Variable <b>strGlobal<\/b> und ruft die Form <b>frmGlobalVariable <\/b>auf. Diese Form enth&auml;lt ebenfalls ein Textfeld namens <b>txtValue <\/b>sowie eine Schaltfl&auml;che namens <b>cmdOK<\/b>. Das Textfeld <b>txtValue <\/b>soll mit dem Wert aus dem gleichnamigen Textfeld des aufrufenden Formulars gef&uuml;llt werden.<\/p>\n<p>Dazu legen wir in der aufgerufenen Form eine Ereignisprozedur f&uuml;r das Ereignis  <b>Load <\/b>an. Dieses sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     Me.txtValue = strGlobal\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit erhalten wir das Ergebnis aus Bild 2.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2023_05\/pic_397_001.png\" alt=\"Text per globaler Variable zum aufgerufenen Formular &uuml;bertragen\" width=\"549,6265\" height=\"295,3848\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Text per globaler Variable zum aufgerufenen Formular &uuml;bertragen<\/span><\/b><\/p>\n<h2>Auslesen des zu &uuml;bergebenden Wertes aus einem Steuerelement<\/h2>\n<p>Die n&auml;chste M&ouml;glichkeit setzt voraus, dass der zu &uuml;bergebende Wert in einem Steuerelement im aufrufenden <b>Form<\/b>-Element angezeigt wird &#8211; wie in unserem Beispiel im Textfeld <b>txtValue<\/b>. Wir rufen dann die zweite Form auf und k&ouml;nnen dann von dort aus dem Wert des Textfeldes auslesen und in das Textfeld der Zielform eintragen. Dazu f&uuml;gen wir <b>frmMain <\/b>eine zweite Schaltfl&auml;che namens <b>cmdReadValueFromControl <\/b>zu, die folgende Prozedur aufruft:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdReadValueFromControl_Click()\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(txtValue) = 0<span style=\"color:blue;\"> Then<\/span>\r\n         frmReadValueFromControl.Show\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Textfeld ist leer.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Sie soll also einfach die Form <b>frmReadValueFromControl <\/b>aufrufen. F&uuml;r die <b>Load<\/b>-Ereigniseigenschaft dieser Form k&ouml;nnten wir einfach die folgende Ereignisprozedur hinterlegen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     Me.txtValue.Text = frmMain.txtValue\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Das funktioniert, sofern die aufrufende Form <b>frmMain <\/b>aktuell ge&ouml;ffnet ist. Wenn die aufgerufene Form <b>frmReadValueFromControl <\/b>allerdings von einem anderen <b>Form<\/b>-Objekt ge&ouml;ffnet wird und <b>frmMain <\/b>nicht ge&ouml;ffnet ist, erhalten wir einen Fehler.<\/p>\n<p>Diesen k&ouml;nnen wir allerdings umgehen, indem wir pr&uuml;fen, ob die Form ge&ouml;ffnet ist. Dazu erweitern wir die Prozedur wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     <span style=\"color:blue;\">If <\/span>IsFormOpen(\"frmMain\")<span style=\"color:blue;\"> Then<\/span>\r\n         Me.txtValue.Text = frmMain.txtValue\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Funktion <b>IsFormOpen <\/b>ist allerdings keine eingebaute Funktion, wir m&uuml;ssen diese selbst programmieren. Die Funktion erwartet den Namen des zu untersuchenden Formulars und gibt den Wert <b>True <\/b>zur&uuml;ck, wenn es ge&ouml;ffnet ist. Sie durchl&auml;uft in einer <b>For&#8230;Next<\/b>-Schleife alle Zahlen von <b>0 <\/b>bis zur Anzahl der ge&ouml;ffneten Formulare minus <b>1<\/b>. In dieser Schleife vergleicht sie den Namen des aktuell durchlaufenen Formulars mit dem zu untersuchenden. Sind beide gleich, ist das Formular ge&ouml;ffnet und die Funktion kann den Wert <b>True <\/b>zur&uuml;ckgeben, bevor sie beendet wird.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>IsFormOpen(strForm<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     For i = 0 To Forms.Count - 1\r\n         <span style=\"color:blue;\">If <\/span>Forms(i).Name = strForm<span style=\"color:blue;\"> Then<\/span>\r\n             Return <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">Exit Function<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000397\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000397?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000397\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"9445dca723\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wenn man mit SDI-Forms arbeiten, also mit solchen Formularen, die als einzelne Fenster ge&ouml;ffnet werden, m&ouml;chte man manchmal eine der folgenden beiden Aufgaben erledigen &#8211; oder auch beide: Das aufrufende Formular soll Daten an das aufgerufene Formular &uuml;bergeben, beispielsweise um den Prim&auml;rschl&uuml;ssel eines im Detailformular anzuzeigenden Datensatzes zu &uuml;bergeben. Oder man m&ouml;chte ein Formular zum Abfragen von Daten &ouml;ffnen und diese dann vom aufrufenden Formular aus aufrufen. Wie beides gelingt und welche unterschiedlichen Wege es dazu gibt, schauen wir uns in diesem Artikel an. Au&szlig;erdem betrachten wir, welche Arten von Daten man grunds&auml;tzlich &uuml;bertragen k&ouml;nnen sollte.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662023,66052023,44000023,44000031],"tags":[],"yst_prominent_words":[],"class_list":["post-55000397","post","type-post","status-publish","format-standard","hentry","category-662023","category-66052023","category-PowerApps","category-twinBASICProgrammierung"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000397"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000397\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000397"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}