{"id":55000335,"date":"2022-08-01T00:00:00","date_gmt":"2023-03-02T17:03:14","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=335"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"VBA_Basics_Makros_Prozeduren_Funktionen_und_Co","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/VBA_Basics_Makros_Prozeduren_Funktionen_und_Co\/","title":{"rendered":"VBA Basics: Makros, Prozeduren, Funktionen und Co."},"content":{"rendered":"<p><b>VBA-Code in VBA-Projekten von Office-Anwendungen landet zuerst einmal in Modulen. Darunter gibt es einige weitere Strukturen, auf welche die Anweisungen aufgeteilt werden. W&auml;hrend Deklarationen von Variablen auch direkt in einem Modul angelegt werden k&ouml;nnen, m&uuml;ssen ausf&uuml;hrbare Codezeilen zwingend in Konstrukten untergebracht werden, die je nach Anwendung Makros oder Prozeduren genannt werden. Au&szlig;erdem gibt es noch Funktionen. Was es mit all diesen Begriffen auf sich hat und wieso diese nicht einheitlich definiert sind, erl&auml;utern wir in diesem Artikel.<\/b><\/p>\n<h2>Makros vs. Prozeduren<\/h2>\n<p>Wer erstmal mit VBA unter Excel, Word oder PowerPoint in Kontakt kommt, erledigt dies in der Regel &uuml;ber das Aufzeichnen von Makros &#8211; mehr dazu im Artikel <b>VBA: Makros aufzeichnen <\/b>(<b>www.access-im-unternehmen.de\/324<\/b>). Bei der Aufzeichnung kommt ein sogenanntes Makro heraus. Schaut man sich das im VBA-Editor an, findet man jedoch eine Sub-Prozedur vor. Wir k&ouml;nnten nun einfach die Begriffe Makro und Sub-Prozedur synonym verwenden, wenn da nicht noch Access w&auml;re: Hier gibt es n&auml;mlich neben VBA noch einen eigenen Objekttyp zum Erstellen von Automatisierungen, der wiederum Makro hei&szlig;t.<\/p>\n<p>Allerdings hat das Makro unter Access nichts mit VBA zu tun, sondern es handelt sich dabei eher um eine M&ouml;glichkeit zum &#8220;Zusammenklicken&#8221; von Automatisierungen. Microsoft hat also den Begriff Makro in verschiedenen Office-Anwendungen f&uuml;r unterschiedliche Techniken verwendet, was bei Benutzern und Programmierern f&uuml;r Verwirrung sorgt.<\/p>\n<p>Allerdings ist das nicht nur dort problematisch, sondern auch f&uuml;r unser Magazin <b>Visual Basic Entwickler<\/b>.Wir wollen hier ja &uuml;ber den Einsatz von <b>Visual Basic for Applications <\/b>(<b>VBA<\/b>) und verwandten Sprachen wie <b>Visual Basic.NET <\/b>oder <b>twinBASIC <\/b>berichten, und zwar f&uuml;r alle Office-Anwendungen. <\/p>\n<p>Um Verwechslungen auszuschlie&szlig;en, werden wir also den Begriff &#8220;Makro&#8221; nur noch dort verwenden, wo wir tats&auml;chlich die Funktion zum Aufzeichnen von Makros nutzen. An allen anderen Stellen bezeichnen wir alle Code-Konstrukte, die in der ersten Zeile das Schl&uuml;sselwort <b>Sub <\/b>tragen, als Prozedur.<\/p>\n<h2>Prozeduren und Funktionen<\/h2>\n<p>Neben den Prozeduren gibt es noch zwei weitere Konstrukte, die zur Ausf&uuml;hrung bestimmte Codezeilen aufnehmen k&ouml;nnen. Das erste ist die sogenannte Funktion, das zweite sind die <b>Property&#8230;<\/b>-Methoden. Diese treten allerdings erst in Zusammenhang mit der objektorientierten Programmierung von Klassenmodulen auf, sodass wir in diesem Artikel nicht darauf eingehen wollen.<\/p>\n<p>Eigentlich sind die Bezeichnungen &#8220;Prozedur&#8221; und &#8220;Funktion&#8221; auch wieder nicht ganz konsequent, denn eigentlich sind beide Prozeduren &#8211; eine mit dem Schl&uuml;sselwort <b>Sub <\/b>und eine mit dem Schl&uuml;sselwort <b>Function<\/b>. Die korrekteren Bezeichnungen sind wohl <b>Sub<\/b>-Prozedur und <b>Function<\/b>-Prozedur. Allerdings denke ich, dass auch die Bezeichnungen <b>Prozedur <\/b>und <b>Funktion <\/b>verst&auml;ndlich sind, solange sie konsequent verwendet werden.<\/p>\n<p>Prozeduren und Funktionen f&uuml;hren beide eine oder mehrere Anweisungen aus. Der wichtigste Unterschied zwischen beiden ist, dass die Funktionen ein Funktionsergebnis direkt zur&uuml;ckgeben k&ouml;nnen. Dazu zwei Beispiele. Eine Prozedur sieht im einfachsten Fall wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>Meldung()\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Meldung per Prozedur\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Eine sehr einfache Funktion sieht so aus:<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>Eingabe()\r\n     Eingabe = InputBox(\"Funktionswert eingeben:\")\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Wir sehen schon, dass die Prozedur lediglich eine Meldung anzeigt. Die Funktion hingegen ruft eine InputBox auf und weist das Ergebnis einer Variablen namens <b>Eingabe <\/b>zu.<\/p>\n<p>Aber was soll das denn nun? Wir haben doch im Artikel <b>VBA-Basics: Variablen <\/b>(<b>www.access-im-unternehmen.de\/319<\/b>) geschrieben, dass Variablen ein Pr&auml;fix wie zum Beispiel <b>str <\/b>f&uuml;r eine <b>String<\/b>-Variable enthalten sollen? Und &uuml;berhaupt &#8211; es ist nirgends eine Variable namens <b>Eingabe <\/b>deklariert?<\/p>\n<p>Und das ist der Punkt: Der Name einer Funktion ist gleichzeitig der Name der Variablen, der wir den R&uuml;ckgabewert der Funktion zuweisen. Es ist also erstens kein Pr&auml;fix erforderlich, au&szlig;er Du m&ouml;chtest diesen bei Funktionen verwenden. Zweitens ist aber auch kein Datentyp angegeben, obwohl wir das im oben genannten Artikel ebenfalls empfohlen haben, weil sonst der Datentyp <b>Variant <\/b>verwendet wird, der mehr Speicherplatz als ein explizit angegebener Datentyp ben&ouml;tigt.<\/p>\n<p>Und wir haben geschrieben, dass die obigen Beispiele sehr einfache Beispiele sind. Dementsprechend haben wir auch nicht explizit einen G&uuml;ltigkeitsbereich f&uuml;r die Prozedur und die Funktion angegeben.<\/p>\n<p>Genau wie bei Variablen gilt hier: Wenn kein Schl&uuml;sselwort wie <b>Public <\/b>oder <b>Private <\/b>angegeben wurde, ist das Element &ouml;ffentlich erreichbar. Explizit m&uuml;ssten wir die Prozedur also wie folgt definieren, wenn diese im kompletten VBA-Projekt erreichbar sein soll:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Meldung()\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Meldung per Prozedur\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>F&uuml;r die Funktion gilt das Gleiche &#8211; und hier geben wir nun auch noch den Datentyp f&uuml;r den R&uuml;ckgabewert <b>Eingabe <\/b>an, der nicht nur Funktionsname, sondern auch noch Variable ist:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Eingabe()<span style=\"color:blue;\"> As String<\/span>\r\n     Eingabe = InputBox(\"Funktionswert eingeben:\")\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Routine als Synonym f&uuml;r Prozeduren und Funktionen<\/h2>\n<p>Wir werden im folgenden und auch in weiteren Artikeln Grundlagen und Techniken vorstellen, die f&uuml;r Prozeduren und Funktionen identisch sind. An diesen Stellen erw&auml;hnen wir nicht immer &#8220;Prozeduren und Funktionen&#8221;, sondern nutzen gelegentlich den Begriff Routine als Synonym f&uuml;r beide.<\/p>\n<h2>Aufruf per Direktbereich<\/h2>\n<p>Die Prozedur und die Funktion k&ouml;nnen wir beide &uuml;ber den Direktbereich des VBA-Editors aufrufen. Dazu aktivieren wir diesen, sofern noch nicht eingeblendet, mit <b>Strg + G<\/b>. Wenn er schon eingeblendet ist, kannst Du ihn mit dieser Tastenkombination aktivieren.<\/p>\n<p>Dort gibst Du einfach den Namen der Prozedur ein und schlie&szlig;t den Aufruf mit der Eingabetaste ab. Das Ergebnis sieht wie in Bild 1 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_04\/pic_335_001.png\" alt=\"Aufruf einer Prozedur\" width=\"424,6267\" height=\"189,466\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Aufruf einer Prozedur<\/span><\/b><\/p>\n<p>Die Funktion k&ouml;nnen wir auf die gleiche Weise aufrufen. Das zeigt die <b>InputBox <\/b>an, aber die Eingabe wird nicht ausgewertet. Um den Inhalt der <b>InputBox <\/b>auszugeben, k&ouml;nnen wir beispielsweise die folgende Anweisung nutzen:<\/p>\n<pre><span style=\"color:blue;\">Debug.Print<\/span> Eingabe<\/pre>\n<p>Dies ruft die Anzeige der <b>InputBox <\/b>wie in Bild 2 hervor. Und nach der Eingabe wird der eingegebene Text unter der Anweisung im Direktbereich ausgegeben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_04\/pic_335_002.png\" alt=\"Aufruf einer Funktion\" width=\"424,6267\" height=\"199,1612\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Aufruf einer Funktion<\/span><\/b><\/p>\n<h2>Aufruf einer Funktion von einer anderen Prozedur oder Funktion aus<\/h2>\n<p>Normalerweise soll das Ergebnis einer Funktion jedoch nicht im Direktbereich ausgegeben werden, sondern wir speichern es in einer Variablen oder verwenden es anderweitig weiter.<\/p>\n<p>Au&szlig;erdem wollen wir in diesem Zusammenhang direkt einmal zeigen, wie wir die Funktion von einer anderen Funktion aus aufrufen k&ouml;nnen. Dazu deklarieren wir im folgenden Beispiel eine <b>String<\/b>-Variable namens <b>strEingabe <\/b>und weisen nun dieser das Ergebnis der Funktion <b>Eingabe <\/b>zu. Danach geben wir dieses wieder im Direktbereich aus, um zu pr&uuml;fen, ob das Ergebnis korrekt verarbeitet wurde:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EingabeSpeichern()\r\n     <span style=\"color:blue;\">Dim <\/span>strEingabe<span style=\"color:blue;\"> As String<\/span>\r\n     strEingabe = Eingabe\r\n     <span style=\"color:blue;\">Debug.Print<\/span> strEingabe\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur <b>EingabeSpeichern <\/b>rufen wir zun&auml;chst wieder vom Direktbereich aus auf, indem wir ihren Namen eingeben und die Eingabetaste bet&auml;tigen.<\/p>\n<h2>Aufruf einer anderen Routine unterbricht die aktuelle Routine<\/h2>\n<p>Wichtig f&uuml;r das Verst&auml;ndnis des Ablaufs ist, dass Routinen unter VBA immer synchron ablaufen, dass hei&szlig;t, dass immer nur eine gleichzeitig ausgef&uuml;hrt wird. Wenn Routine A also mit einer Anweisung Routine B aufruft, dann wird Routine A solange angehalten, bis Routine B beendet ist. Anderenfalls w&uuml;rde man von asynchroner Ausf&uuml;hrung reden, was aber in reinem VBA nicht m&ouml;glich ist.<\/p>\n<h2>Aufruf einer Prozedur von einer anderen Prozedur aus<\/h2>\n<p>Wenn wir eine Prozedur von einer anderen Prozedur aus aufrufen wollen, k&ouml;nnen wir dies genau wie im Direktbereich erledigen.<\/p>\n<p>Wir tragen also einfach den Namen der zu startenden Prozedur als eigene Zeile innerhalb einer anderen Prozedur ein &#8211; hier wieder mit der zuerst vorgestellten Prozedur namens <b>Meldung<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AndereProzedurAufrufen()\r\n     Meldung\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dies funktioniert, aber etwas sauberer wirkt die Variante, in der wir die <b>Call<\/b>-Anweisung f&uuml;r den Aufruf der Prozedur nutzen:<\/p>\n<pre><span style=\"color:blue;\">Call<\/span> Meldung<\/pre>\n<p>Dies k&ouml;nnen wir auch im Direktbereich verwenden. Die <b>Call<\/b>-Anweisung hat keine Nachteile, aber sie kann in bestimmten Situationen Vorteile liefern. Diese sind aber rar. Wenn Du zum Beispiel zwei Prozeduraufrufe in einer Zeile unterbringen m&ouml;chtest, was un&uuml;blich ist und bestenfalls ein oder zwei Codezeilen spart, kannst Du Call einsetzen:<\/p>\n<pre><span style=\"color:blue;\">Call<\/span> Meldung: <span style=\"color:blue;\">Call<\/span> Eingabe<\/pre>\n<p>Wenn Du hier nur <b>Meldung : Eingabe <\/b>schreibst, wird Meldung als Sprungmarke interpretiert und der Code sieht anschlie&szlig;end so aus:<\/p>\n<pre>Meldung:\r\n     Eingabe<\/pre>\n<h2>Prozeduren und Funktionen direkt aufrufen<\/h2>\n<p>Es gibt noch weitere Methoden f&uuml;r den Aufruf von Prozeduren und Funktionen. Diese funktionieren aber nur, solange diese keine Parameter verwenden. Ist das der Fall, kannst Du die auszuf&uuml;hrende Prozedur oder Funktion einfach im VBA-Editor markieren, indem Du die Einf&uuml;gemarke an einer beliebigen Stelle des Codes der Prozedur oder Funktion platzierst und dann eine der folgenden Aktionen ausf&uuml;hrst:<\/p>\n<ul>\n<li>Du bet&auml;tigst die Taste <b>F5<\/b> (schnellste Methode).<\/li>\n<li>Du klickst in der Symbolleiste auf die Schaltfl&auml;che <b>Starten <\/b>(das Symbol mit dem blauen Quadrat).<\/li>\n<li>Du w&auml;hlst aus dem Men&uuml; den Befehl <b>Ausf&uuml;hren|Sub\/Userform ausf&uuml;hren <\/b>aus (was entgegen der Beschriftung auch f&uuml;r Funktionen l&auml;uft).<\/li>\n<\/ul>\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\/55000335\/\">\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\/55000335?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\/55000335\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"cbd3f36316\"\/>\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>VBA-Code in VBA-Projekten von Office-Anwendungen landet zuerst einmal in Modulen. Darunter gibt es einige weitere Strukturen, auf welche die Anweisungen aufgeteilt werden. W&auml;hrend Deklarationen von Variablen auch direkt in einem Modul angelegt werden k&ouml;nnen, m&uuml;ssen ausf&uuml;hrbare Codezeilen zwingend in Konstrukten untergebracht werden, die je nach Anwendung Makros oder Prozeduren genannt werden. Au&szlig;erdem gibt es noch Funktionen. Was es mit all diesen Begriffen auf sich hat und wieso diese nicht einheitlich definiert sind, erl&auml;utern wir in diesem Artikel.<\/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":[662022,66042022,44000023,44000025,44000028],"tags":[],"yst_prominent_words":[],"class_list":["post-55000335","post","type-post","status-publish","format-standard","hentry","category-662022","category-66042022","category-PowerApps","category-VBAProgrammierung","category-Word_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000335","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=55000335"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000335\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000335"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}