{"id":55000495,"date":"2025-12-01T00:00:00","date_gmt":"2026-02-05T12:00:18","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=495"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/","title":{"rendered":"Per VBA von Early Binding zu Late Binding wechseln"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/f7d78bb3497f4d1f8860b4b1757ff0d3\" width=\"1\" height=\"1\" alt=\"\"><b>Im Artikel &#8220;VBA: Early Binding und Late Binding&#8221; (www.vbentwickler.de\/4) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L&ouml;sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun&auml;chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm&ouml;glicht, diese in Late Binding-Elemente umzuwandeln. <\/b><\/p>\n<p>Die L&ouml;sung aus diesem Artikel soll es erm&ouml;glichen, alle Module der aktuellen Datenbank aus einem Listenfeld auszuw&auml;hlen und alle dort in Deklarationszeilen vorhandenen Klassen, Typen und Enumerationen einzulesen.<\/p>\n<p>Wir ben&ouml;tigen zwar die Typen und Enumerationen nicht, da wir diese nicht nach Late Binding migrieren k&ouml;nnen, aber aus technischen Gr&uuml;nden k&ouml;nnen wir diese nicht ohne erheblichen Aufwand aus der Ermittlung ausschlie&szlig;en. <\/p>\n<p>Das Formular zur Steuerung dieses Vorgangs sehen wir in Bild 1. Hier haben wir das Modul <b>mdlTest <\/b>ausgew&auml;hlt und anschlie&szlig;end auf die Schaltfl&auml;che <b>Typen einlesen <\/b>geklickt, um alle dort enthaltenen Typen zu ermitteln und in einem weiteren Listenfeld anzuzeigen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_495_001.png\" alt=\"Formular zum Steuern der Migration nach Late Binding\" width=\"574,6265\" height=\"737,238\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Formular zum Steuern der Migration nach Late Binding<\/span><\/b><\/p>\n<p>Wenn wir nun einen oder mehrere dieser Eintr&auml;ge markieren und auf die Schaltfl&auml;che Early Binding ersetzen klicken, werden die als Early Binding deklarierten Elemente samt der zur Initialisierung verwendeten Anweisungen in Late Binding umgewandelt &#8211; und zwar in allen Modulen, die im oberen Listenfeld markiert sind.<\/p>\n<p>Zus&auml;tzlich finden wir dort noch ein Kontrollk&auml;stchen namens <b>Ersetzte Zeilen als Kommentar behalten<\/b>. Damit k&ouml;nnen wir festlegen, dass die Early Binding-Anweisungen nicht gel&ouml;scht, sondern lediglich auskommentiert werden.<\/p>\n<p>Im Beispielmodul <b>mdlTest <\/b>haben wir einige mit Early Binding versehene Anweisungen untergebracht &#8211; und zwar in den unterschiedlichsten Auspr&auml;gungen:<\/p>\n<ul>\n<li>als einfache Deklarationszeilen, <\/li>\n<li>als Parameter von Prozeduren, <\/li>\n<li>als Deklaration in Prozeduren, <\/li>\n<li>als R&uuml;ckgabewert von Prozeduren und <\/li>\n<li>mit und ohne Zeilenumbr&uuml;che (siehe Bild 2).<\/li>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_495_002.png\" alt=\"Beispielanweisungen mit Early Binding\" width=\"649,627\" height=\"404,9859\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Beispielanweisungen mit Early Binding<\/span><\/b><\/p>\n<\/ul>\n<p>Nachdem wir die beiden Typen <b>ADODB.Connection <\/b>und <b>ADODB.Recordset <\/b>mit unserem Formular umgestellt haben, sieht der abgebildete Ausschnitt des Moduls wie in Bild 3 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_495_003.png\" alt=\"Beispielanweisungen mit Late Binding und auskommentierter Early Binding-Version\" width=\"649,627\" height=\"500,0595\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Beispielanweisungen mit Late Binding und auskommentierter Early Binding-Version<\/span><\/b><\/p>\n<h2>Beschreibung des Formulars<\/h2>\n<p>Im Formular finden wir in der Entwurfsansicht die folgenden Steuerelemente (siehe Bild 4):<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_495_004.png\" alt=\"Das Formular frmEarlyBindingToLateBinding in der Entwurfsansicht\" width=\"649,627\" height=\"836,5625\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Das Formular frmEarlyBindingToLateBinding in der Entwurfsansicht<\/span><\/b><\/p>\n<ul>\n<li><b>txtSucheModule<\/b>: Erlaubt das schnelle Filtern der im Listenfeld <b>lstModule <\/b>angezeigten Module. <\/li>\n<li>Schaltfl&auml;che <b>cmdAlleAuswahlen<\/b>: Markiert alle Eintr&auml;ge im Listenfeld <b>lstModules<\/b>.<\/li>\n<li>Listenfeld <b>lstModules<\/b>: Zeigt die gefundenen Module an, die den jeweiligen Typ enthalten.<\/li>\n<li>Schaltfl&auml;che <b>cmdTypenEinlesen<\/b>: Liest alle Typen der markierten Module ein und zeigt diese im Listenfeld <b>lstTypes <\/b>an.<\/li>\n<li>Textfeld <b>txtSucheTypen<\/b>: Filtert das Listenfeld <b>lstTypes <\/b>nach dem eingegebenen Suchbegriff.<\/li>\n<li>Schaltfl&auml;che <b>cmdAlleTypenAuswaehlen<\/b>: Markiert alle Eintr&auml;ge des Listenfeldes <b>lstTypes<\/b>.<\/li>\n<li>Listenfeld <b>lstTypes<\/b>: Zeigt alle gefundenen Typen in den markierten Modulen an.<\/li>\n<li>Schaltfl&auml;che <b>cmdEarlyBindingErsetzen<\/b>: Ersetzt f&uuml;r alle markierten Typen in den markierten Modulen Early Binding durch Late Binding.<\/li>\n<li>Kontrollk&auml;stchen <b>chkErsetzeZeilenAlsKommentarBehalten<\/b>: Gibt an, ob die ersetzten Zeilen auskommentiert oder einfach ersetzt werden sollen.<\/li>\n<\/ul>\n<h2>Ereignis beim Laden des Formulars<\/h2>\n<p>Beim Laden des Formulars wird das Ereignis aus Listing 1 ausgel&ouml;st. Es referenziert die aktuelle Datenbank mit der <b>CodeDb<\/b>-Funktion (dies ist eine Vorbereitung, um die L&ouml;sung als Add-In zu nutzen). Dann l&ouml;scht es die beiden Tabellen <b>tblModules <\/b>und <b>tblTypes<\/b>, in denen wir die ermittelten Daten speichern, um sie in den Listenfeldern anzuzeigen. <b>tblModules <\/b>enth&auml;lt das Prim&auml;rschl&uuml;sselfeld <b>ModulID <\/b>und das Textfeld <b>Modul<\/b>. Die Tabelle <b>tblTypes <\/b>enth&auml;lt die beiden Felder <b>TypeID <\/b>und <b>Type <\/b>sowie <b>Line <\/b>und <b>LineNumber<\/b>, um jeweils eine Zeile zu speichern, in der dieser Typ auftritt (diese wurden eher zu Testzwecken w&auml;hrend der Programmierung der L&ouml;sung genutzt).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> db = CodeDb\r\n     db.Execute \"DELETE * FROM tblModules\", dbFailOnError\r\n     db.Execute \"DELETE * FROM tblTypes\", dbFailOnError\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = CurrentVBProject\r\n     For Each objVBComponent In objVBProject.VBComponents\r\n         db.Execute \"INSERT INTO tblModules(Modul) VALUES(''\" & objVBComponent.name & \"'')\", dbFailOnError\r\n     <span style=\"color:blue;\">Next<\/span> objVBComponent\r\n     \r\n     Me.lstModules.Requery\r\n     Me.lstTypes.Requery\r\n     \r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me.OpenArgs)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>strVBComponent<span style=\"color:blue;\"> As String<\/span>\r\n         strVBComponent = Me.OpenArgs\r\n         For i = 0 To Me.lstModules.ListCount - 1\r\n             <span style=\"color:blue;\">If <\/span>Me.lstModules.Column(1, i) = strVBComponent<span style=\"color:blue;\"> Then<\/span>\r\n                 Me.lstModules.Selected(i) = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">Call<\/span> cmdTypenEinlesen_Click\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 If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Ereignisprozedur, die beim Laden des Formulars ausgel&ouml;st wird<\/span><\/b><\/p>\n<p>Danach holen wir mit der Funktion <b>CurrentVBProject <\/b>einen Verweis auf das VBA-Projekt der aktuellen Datenbank. Dies ist notwendig, da beim Vorhandensein von Access-Add-Ins oder eingebundenen Bibliotheksdatenbanken sonst gegebenenfalls das falsche VBA-Projekt verwendet wird. Die Funktion <b>CurrentVBProject <\/b>sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>CurrentVBProject()<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     For Each objVBProject In VBE.VBProjects\r\n         <span style=\"color:blue;\">If <\/span>objVBProject.FileName = CurrentDb.Name<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> CurrentVBProject = objVBProject\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> objVBProject\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Sie durchl&auml;uft alle vorhandenen VB-Projekte und pr&uuml;ft, ob der Pfad dem Pfad der aktuell ge&ouml;ffneten Access-Datenbank entspricht. Ist das der Fall, wird der Verweis auf dieses VB-Projekt zur&uuml;ckgegeben.<\/p>\n<p>F&uuml;r die Verwendung dieser und anderer nachfolgend genutzter Elemente, die auf den VBA-Editor und seine Module zugreifen, f&uuml;gen wir dem VBA-Projekt einen Verweis auf die Bibliothek <b>Microsoft Visual Basic for Applications Extensibility 5.3 Object Library <\/b>hinzu.<\/p>\n<p>Die Prozedur <b>Form_Load <\/b>durchl&auml;uft nun alle Elemente der Auflistung <b>VBComponents<\/b>, was den Modulen entspricht. F&uuml;r jedes Modul wird ein Eintrag in der Tabelle <b>tblModules <\/b>angelegt. Danach werden die beiden Listenfelder <b>lstModules <\/b>und <b>lstTypes <\/b>aktualisiert, damit sie den aktuellen Inhalt der beiden Tabellen <b>tblModules <\/b>und <b>tblTypes <\/b>anzeigen.<\/p>\n<p>Schlie&szlig;lich haben wir noch den Fall vorbereitet, dass das Formular direkt f&uuml;r ein bestimmtes Modul aufgerufen wird. Dann w&uuml;rden wir das Argument OpenArgs mit dem Namen des gew&uuml;nschten Moduls f&uuml;llen. Dies wird dann direkt im Listenfeld lstModules markiert.<\/p>\n<p>Der Aufruf des Formulars f&uuml;r diesen Fall sieht wie folgt aus:<\/p>\n<pre>DoCmd.OpenForm \"frmEarlyBindingToLateBinding\", _    OpenArgs:=\"mdlTest\"<\/pre>\n<h2>Ausw&auml;hlen aller Module<\/h2>\n<p>Um alle Module auszuw&auml;hlen, klicken wir auf die Schaltfl&auml;che <b>cmdAlleTypenAuswaehlen<\/b>. Diese durchl&auml;uft alle Elemente des Listenfeldes und stellt die Eigenschaft <b>Selected <\/b>f&uuml;r den jeweiligen Index auf <b>True <\/b>ein:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdAlleTypenAuswaehlen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>lngItem<span style=\"color:blue;\"> As Long<\/span>\r\n     For lngItem = 0 To Me.lstTypes.ListCount - 1\r\n         Me.lstTypes.Selected(lngItem) = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> lngItem\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Einlesen der Typen der markierten Module<\/h2>\n<p>Ein Klick auf die Schaltfl&auml;che <b>cmdTypenEinlesen <\/b>soll alle Typen der markierten Module ermitteln und in die Tabelle <b>tblTypes <\/b>schreiben.<\/p>\n<p>Dazu referenziert sie wieder die Datenbank mit dem Formular und leert die Tabelle <b>tblTypes<\/b>. Dann pr&uuml;ft sie, ob &uuml;berhaupt Eintr&auml;ge im Listenfeld <b>lstModules <\/b>markiert sind, und weist darauf hin, falls das nicht der Fall ist.<\/p>\n<p>Danach durchl&auml;uft sie alle markierten Eintr&auml;ge des Listenfeldes <b>lstModules <\/b>&uuml;ber die <b>ItemsSelected<\/b>-Auflistung und ermittelt mit <b>Column(1, var) <\/b>den Namen des jeweiligen Moduls. Innerhalb der Schleife ruft sie f&uuml;r jedes dieser Elemente die Prozedur <b>TypesToTable<\/b> auf und &uuml;bergibt dieser den Namen des Moduls. Schlie&szlig;lich aktualisiert sie die Liste der Typen.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdTypenEinlesen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>var<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strModule<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> db = CodeDb\r\n     DoCmd.Hourglass <span style=\"color:blue;\">True<\/span>\r\n     db.Execute \"DELETE * FROM tblTypes\", dbFailOnError\r\n     \r\n     <span style=\"color:blue;\">If <\/span>Me.lstModules.ItemsSelected.Count = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Markiere die zu untersuchenden Module.\", _\r\n             vbOKOnly + vbExclamation, \"Kein Modul markiert\"\r\n         <span style=\"color:blue;\">Exit Sub<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     \r\n     For Each var In Me.lstModules.ItemsSelected\r\n         strModule = Me.lstModules.Column(1, var)\r\n         <span style=\"color:blue;\">Call<\/span> TypesToTable(strModule)\r\n     <span style=\"color:blue;\">Next<\/span> var\r\n     Me.lstTypes.Requery\r\n     DoCmd.Hourglass <span style=\"color:blue;\">False<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Auslesen der Typen eines Moduls<\/h2>\n<p>Die Prozedur <b>TypesToTable <\/b>referenziert wieder die Code-Datenbank und das aktuelle VBA-Projekt (siehe Listing 2).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TypesToTable(strModule<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBIDE.VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBIDE.VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodeModule<span style=\"color:blue;\"> As <\/span>VBIDE.CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>strLine<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strProc<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcType<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcBodyLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strLineOriginal<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcline<span style=\"color:blue;\"> As Long<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> db = CodeDb\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = CurrentVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n     For lngLine = 1 To objCodeModule.CountOfLines\r\n         strLineOriginal = objCodeModule.Lines(lngLine, 1)\r\n         strLine = <span style=\"color:blue;\">Trim<\/span>(strLineOriginal)\r\n         strLine = KommentarAbschneiden(strLine)\r\n         strLine = TextAusLiteralenEntfernen(strLine)\r\n         ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Einlesen der Typen (Teil 1)<\/span><\/b><\/p>\n<p>Danach f&uuml;llt sie die Variable <b>objVBComponent <\/b>mit einem Verweis auf das &uuml;bergebene Modul und holt einen weiteren Verweis auf das enthaltene <b>CodeModule<\/b>-Objekt, das in <b>objCodeModule <\/b>landet.<\/p>\n<p>Dann durchl&auml;uft sie in einer <b>For&#8230;Next<\/b>-Schleife alle Codezeilen, wobei die letzte Zeile mit der Eigenschaft <b>CountOfLines <\/b>ermittelt wird.<\/p>\n<p>Hier speichert sie die Originalzeile in <b>strLineOriginal <\/b>und in <b>strLine <\/b>die um f&uuml;hrende und folgende Leerzeichen bereinigte Version der Zeile.<\/p>\n<p>F&uuml;r diese ruft sie nun die Funktion <b>KommentarAbschneiden <\/b>auf, die wir ebenfalls im Modul finden und die alle am Ende der Zeile befindlichen Kommentare aus <b>strLine <\/b>entfernt.<\/p>\n<p>Eine weitere Funktion namens <b>TextAusLiteralenEntfernen <\/b>leert eventuell in Anf&uuml;hrungszeichen vorhandene Texte. Aus der Zeile <b>strText = &#8220;Beispieltext&#8221; <\/b>wird dann zum Beispiel <b>strText = &#8220;&#8221;<\/b>.<\/p>\n<p>Dies dient der Vereinfachung, damit eventuell in Literalen enthaltene Bezeichnungen der gesuchten Typen nicht ber&uuml;cksichtigt werden. Die Ersetzung schl&auml;gt sich nicht auf die sp&auml;teren &Auml;nderungen nieder.<\/p>\n<p>Danach steigen wir in eine <b>Select Case<\/b>-Bedingung ein, die verschiedene Aspekte &uuml;berpr&uuml;ft (siehe Listing 3). Der erste <b>Case<\/b>-Zweig pr&uuml;ft, ob die Anweisung der aktuellen Zeile mit <b>Const<\/b>, <b>Public Const <\/b>oder <b>Private Const <\/b>beginnt. Solche Zeilen sollen nicht ber&uuml;cksichtigt werden, da Konstanten keine der f&uuml;r uns interessanten Typen aufnehmen k&ouml;nnen.<\/p>\n<pre>         ...\r\n         Select Case <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">Left<\/span>(strLine, 5) = \"Const\", <span style=\"color:blue;\">Left<\/span>(strLine, 12) = \"Public Const\", <span style=\"color:blue;\">Left<\/span>(strLine, 13) = \"Private Const\"\r\n             <span style=\"color:blue;\">Case Else<\/span>\r\n                 lngProcline = lngLine\r\n                 <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Right<\/span>(strLine, 1) = \"_\"\r\n                     lngProcline = lngProcline + 1\r\n                     strLine = <span style=\"color:blue;\">Left<\/span>(strLine, <span style=\"color:blue;\">Len<\/span>(strLine) - 1)\r\n                     strLine = strLine & <span style=\"color:blue;\">Trim<\/span>(objCodeModule.Lines(lngProcline, 1))\r\n                 <span style=\"color:blue;\">Loop<\/span>\r\n                 <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">InStr<\/span>(1, strLine, \"<span style=\"color:blue;\"> As <\/span>\") = 0<span style=\"color:blue;\"> Then<\/span>\r\n                     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strLine) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                         strProc = \"\"\r\n                         strProc = objCodeModule.ProcOfLine(lngLine, lngProcType)\r\n                         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Len<\/span>(strProc) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                             lngProcBodyLine = objCodeModule.ProcBodyLine(strProc, lngProcType)\r\n                         <span style=\"color:blue;\">Else<\/span>\r\n                             If <span style=\"color:blue;\">Split<\/span>(strLine, \" \")(0) = \"Event\" Or <span style=\"color:blue;\">Split<\/span>(strLine, \" \")(1) = \"Event\" _\r\n                                     Or <span style=\"color:blue;\">Split<\/span>(strLine, \" \")(0) = \"Declare\" Or <span style=\"color:blue;\">Split<\/span>(strLine, \" \")(1) = \"Declare\" Then\r\n                                 lngProcBodyLine = lngLine\r\n                             <span style=\"color:blue;\">End If<\/span>\r\n                         <span style=\"color:blue;\">End If<\/span>\r\n                         <span style=\"color:blue;\">If <\/span>lngProcBodyLine = lngLine<span style=\"color:blue;\"> Then<\/span>\r\n                             <span style=\"color:blue;\">Call<\/span> ProzedurparameterVerarbeiten(db, strLine, strLineOriginal, lngLine)\r\n                             <span style=\"color:blue;\">Call<\/span> RueckgabewertVerarbeiten(db, strLine, strLineOriginal, lngLine)\r\n                         <span style=\"color:blue;\">Else<\/span>\r\n                             Select Case <span style=\"color:blue;\">True<\/span>\r\n                                 <span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">Left<\/span>(strLine, 3) = \"Dim\", <span style=\"color:blue;\">Left<\/span>(strLine, 6) = \"Public\", <span style=\"color:blue;\">Left<\/span>(strLine, 7) = \"Private\"\r\n                                     <span style=\"color:blue;\">Call<\/span> DeklarationenVerarbeiten(db, strLine, strLineOriginal, lngLine)\r\n                             <span style=\"color:blue;\">End Select<\/span>\r\n                         <span style=\"color:blue;\">End If<\/span>\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n                 lngLine = lngProcline\r\n         <span style=\"color:blue;\">End Select<\/span>\r\n         DoEvents\r\n     <span style=\"color:blue;\">Next<\/span> lngLine\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Einlesen der Typen (Teil 2)<\/span><\/b><\/p>\n<p>Der zweite Case-Zweig bearbeitet alle &uuml;brigen Zeilen, wo wir als Erstes eventuell auf mehrere Zeilen aufgeteilte Anweisungen in eine Zeile schreiben. Aus <\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestParameterCrLf( _\r\n     rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)<\/pre>\n<p>wird dann beispielsweise<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestParameterCrLf(rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)<\/pre>\n<p>Dazu holen wir uns als Erstes die Nummer der aktuellen Zeile und speichern diese in <b>lngProcLine<\/b>. Solange die Zeile mit dem Unterstrich endet und die Anweisung somit in der n&auml;chsten Zeile fortgesetzt wird, erh&ouml;hen wir <b>lngProcLine <\/b>um den Wert <b>1 <\/b>und lesen den Teil der Zeile vor dem Unterstrich in <b>strLine <\/b>ein. Aus <\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestParameterCrLf( _<\/pre>\n<p>wird somit die folgende Zeile:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestParameterCrLf(<\/pre>\n<p>Dann f&uuml;gen wir den Inhalt der folgenden Zeile zu <b>strLine <\/b>hinzu. Diesen Vorgang wiederholen wir, bis die letzte Zeile der Anweisung erreicht ist. Sp&auml;ter stellen wir lngLine auf <b>lngProcLine <\/b>ein, damit die Zeilenfortsetzungen nicht erneut eingelesen werden.<\/p>\n<p>Nun untersuchen wir weitere Aspekte. Zun&auml;chst pr&uuml;fen wir, ob die Zeile das Schl&uuml;sselwort <b>As <\/b>enth&auml;lt. Nur in diesem Fall kann &uuml;berhaupt eine Deklaration f&uuml;r einen Typ vorliegen.<\/p>\n<p>Als N&auml;chstes pr&uuml;fen wir, ob es sich bei der aktuellen Zeile um eine einfache Deklaration oder um einen Prozedurkopf handelt. Dazu ermitteln wir mit der Funktion <b>ProcOfLine<\/b>, ob sich die aktuelle Zeile innerhalb einer Prozedur befindet. In diesem Fall liefert die Funktion den Namen der Prozedur zur&uuml;ck, den wir in <b>strProc <\/b>speichern. Ist <b>strProc <\/b>nicht leer, befindet sich die Zeile innerhalb einer Prozedur. Um herauszufinden, ob es sich bei der Zeile um den Prozedurkopf handelt, ermitteln wir mit <b>ProcBodyLine <\/b>die Nummer der Zeile, in der sich der Prozedurkopf der aktuellen Prozedur befindet. Ist <b>strProc <\/b>leer, handelt es sich um eine Prozedurkopf-&auml;hnliche Anweisung, etwa ein Event oder eine API-Deklaration. Auch diese wollen wir wie einen Prozedurkopf behandeln und speichern auch hier die Zeilennummer in <b>lngProc<\/b>.<\/p>\n<p>Wenn die aktuelle Zeile aus <b>lngLine <\/b>nun dem Wert aus <b>lngProc <\/b>entspricht, handelt es sich um einen Prozedurkopf oder eine <b>Event<\/b>&#8211; oder <b>Declare<\/b>-Anweisung.<\/p>\n<p>In diesem Fall rufen wir eine weitere Prozedur namens <b>ProzedurparameterVerarbeiten <\/b>auf und &uuml;bergeben die relevanten Parameter. Diese Prozedur beschreiben wir im Anschluss. Au&szlig;erdem rufen wir noch die Prozedur <b>RueckgabewertVerarbeiten <\/b>auf, denn auch die R&uuml;ckgabewerte einer Prozedur k&ouml;nnen Typen enthalten, die wir umwandeln wollen.<\/p>\n<p>Ist es keine Prozedurkopfzeile, handelt es sich um eine Deklarationszeile. Dies pr&uuml;fen wir noch, indem wir untersuchen, ob die ersten Zeichen der Anweisung <b>Dim<\/b>, <b>Public <\/b>oder <b>Private <\/b>lauten. In diesem Fall rufen wir die Prozedur <b>DeklarationenVerarbeiten <\/b>auf.<\/p>\n<p>Auf diese Weise haben wir nun alle Anweisungen auf Typen untersucht. In den aufgerufenen Prozeduren werden die Typen in die Tabelle <b>tblTypes <\/b>eingetragen.<\/p>\n<h2>Deklarationszeilen analysieren<\/h2>\n<p>Wir schauen uns diese Verarbeitung beispielhaft an der Prozedur <b>DeklarationenVerarbeiten<\/b> an (siehe Listing 4).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>DeklarationenVerarbeiten(db<span style=\"color:blue;\"> As <\/span>DAO.Database, strLine<span style=\"color:blue;\"> As String<\/span>, strLineOriginal<span style=\"color:blue;\"> As String<\/span>, _\r\n         lngLine<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intDeclaration<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDeclarations()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDeclaration<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngStartAs<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strLineBehindAs<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strType<span style=\"color:blue;\"> As String<\/span>\r\n     \r\n     strDeclarations = <span style=\"color:blue;\">Split<\/span>(strLine, \",\")\r\n     For intDeclaration = <span style=\"color:blue;\">LBound<\/span>(strDeclarations) To <span style=\"color:blue;\">UBound<\/span>(strDeclarations)\r\n         strDeclaration = strDeclarations(intDeclaration)\r\n         \r\n         strDeclaration = <span style=\"color:blue;\">Replace<\/span>(strDeclaration, \" <span style=\"color:blue;\">New<\/span> \", \" \")\r\n         lngStartAs = <span style=\"color:blue;\">InStr<\/span>(strDeclaration, \"<span style=\"color:blue;\"> As <\/span>\")\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> lngStartAs = 0<span style=\"color:blue;\"> Then<\/span>\r\n             strLineBehindAs = <span style=\"color:blue;\">Mid<\/span>(strDeclaration, <span style=\"color:blue;\">InStr<\/span>(1, strDeclaration, \"<span style=\"color:blue;\"> As <\/span>\") + 4)\r\n             strType = <span style=\"color:blue;\">Split<\/span>(strLineBehindAs, \" \")(0)\r\n             <span style=\"color:blue;\">Call<\/span> SaveTypesToTable(db, strType, strLineOriginal, lngLine)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> intDeclaration\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Verarbeiten der Deklarationszeilen<\/span><\/b><\/p>\n<p>Diese splittet die Deklarationszeile zun&auml;chst am Komma auf und schreibt die einzelnen Elemente in ein Array. Dies ber&uuml;cksichtigt Deklarationen wie die folgende:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset, cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection<\/pre>\n<p>Das Array durchlaufen wir in einer <b>For&#8230;Next<\/b>-Schleife. Hier schreiben wir zun&auml;chst das aktuelle Element in die Variable <b>strDeclaration<\/b>, zum Beispiel <b>Dim rst As ADODB.Recordset<\/b>. Wir pr&uuml;fen, ob das Element das Schl&uuml;sselwort <b>New <\/b>enth&auml;lt und ersetzen dieses durch eine leere Zeichenkette.<\/p>\n<p>Dann ermitteln wir die Position des Schl&uuml;sselwortes <b>As<\/b>. Wenn diese nicht <b>0 <\/b>ist, lesen wir den Teil hinter dem Schl&uuml;sselwort As ein, zum Beispiel <b>ADODB.Recordset<\/b>, und tragen diesen Typ in <b>strLineBehindAs <\/b>ein. Dieser kann wiederum aus mehreren Elementen bestehen, wobei uns nur das erste Element interessiert. Dieses landet in der Variablen <b>strType<\/b>.<\/p>\n<p>Mit der Prozedur <b>SaveTypesToTable <\/b>tragen wir diesen Typ in die Tabelle <b>tblTypes <\/b>ein und bearbeiten anschlie&szlig;end eventuell weitere in dieser Zeile enthaltene Deklarationen.<\/p>\n<h2>Schreiben der Typen in die Tabelle tblTypes<\/h2>\n<p>Die Prozedur <b>SaveTypesToTable <\/b>untersucht, ob es sich bei dem Typ um einen der einfachen Datentypen wie <b>Boolean<\/b>, <b>String<\/b>, <b>Long <\/b>und so weiter handelt.<\/p>\n<p>Diese werden nicht in der Tabelle gespeichert. Nur die &uuml;brigen Typen landen in der Tabelle <b>tblTypes<\/b> (siehe Listing 5).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>SaveTypesToTable(db<span style=\"color:blue;\"> As <\/span>DAO.Database, strType<span style=\"color:blue;\"> As String<\/span>, strLine<span style=\"color:blue;\"> As String<\/span>, lngStartline<span style=\"color:blue;\"> As Long<\/span>)\r\n     Select Case strType\r\n         <span style=\"color:blue;\">Case <\/span>\"Boolean\", \"Byte\", \"Currency\", \"Date\", \"Decimal\", \"Object\", \"Variant\", \"String\", \"Long\", \"Double\", _\r\n             \"Single\", \"Integer\", \"LongPtr\", \"Byte()\", \"Any\", \"Collection\", \"LongLong\"\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n             db.Execute \"INSERT INTO tblTypes(Type, Line, LineNumber) VALUES(''\" & strType & \"'', ''\" & strLine & \"'', \" _\r\n                 & lngStartline & \")\", dbFailOnError\r\n             <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Speichern der Typen in der Tabelle tblTypes<\/span><\/b><\/p>\n<h2>Schreiben der Typen aus Prozedurparametern und R&uuml;ckgabewerten<\/h2>\n<p>Die beiden Prozeduren <b>ProzedurparameterVerarbeiten <\/b>und <b>RueckgabewertVerarbeiten <\/b>arbeiten &auml;hnlich wie DeklarationenVerarbeiten, sind aber etwas aufwendiger. Daher wollen wir diese hier nicht ausf&uuml;hrlich beschreiben, sondern nur zusammenfassen:<\/p>\n<p>Die Prozedur <b>ProzedurparameterVerarbeiten <\/b>untersucht die Liste der Parameter von Prozedurk&ouml;pfen und <b>Declare<\/b>&#8211; und <b>Event<\/b>-Anweisungen. Dabei durchl&auml;uft sie wiederum alle enthaltenen Elemente und schreibt die entsprechenden Typen in die Tabelle <b>tblTypes<\/b>. Die Prozedur <b>RueckgabewertVerarbeiten<\/b> erledigt dies f&uuml;r die R&uuml;ckgabewerte von Funktionen.<\/p>\n<h2>Typen von Early Binding in Late Binding umwandeln<\/h2>\n<p>Um den Umwandlungsprozess zu starten, klicken wir die Schaltfl&auml;che <b>cmdEarlyBindingErsetzen <\/b>an. Diese l&ouml;st die Prozedur aus Listing 6 aus.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdEarlyBindingErsetzen_Click()\r\n     <span style=\"color:blue;\">Dim <\/span>varModule<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>varType<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strModule<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strType<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolErsetzteZeilenAlsKommentarBehalten<span style=\"color:blue;\"> As Boolean<\/span>\r\n     \r\n     DoCmd.Hourglass <span style=\"color:blue;\">True<\/span>\r\n     \r\n     bolErsetzteZeilenAlsKommentarBehalten = Me.chkErsetzteZeilenAlsKommentarBehalten\r\n     \r\n     <span style=\"color:blue;\">If <\/span>Me.lstTypes.ItemsSelected.Count = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Markiere die zu ersetzenden Typen.\", vbOKOnly + vbExclamation, \"Keine Typen markiert\"\r\n         <span style=\"color:blue;\">Exit Sub<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     For Each varModule In Me.lstModules.ItemsSelected\r\n         strModule = Me.lstModules.Column(1, varModule)\r\n         For varType = Me.lstTypes.ListCount - 1 To 0 Step -1\r\n             <span style=\"color:blue;\">If <\/span>Me.lstTypes.Selected(varType) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n                 strType = Me.lstTypes.Column(1, varType)\r\n                 <span style=\"color:blue;\">Call<\/span> TypeErsetzen(strModule, strType, bolErsetzteZeilenAlsKommentarBehalten)\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> varType\r\n     <span style=\"color:blue;\">Next<\/span> varModule\r\n     \r\n     DoCmd.Hourglass <span style=\"color:blue;\">False<\/span>\r\n     \r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Start der Umwandlung<\/span><\/b><\/p>\n<p>Hier tragen wir den Wert des Kontrollk&auml;stchens <b>chkErsetzteZeilenAlsKommentarBehalten <\/b>in die Variable <b>bolErsetzteZeilenAlsKommentarBehalten <\/b>ein.<\/p>\n<p>Dann pr&uuml;fen wir, ob &uuml;berhaupt Typen f&uuml;r die Umwandlung markiert sind, und geben gegebenenfalls eine entsprechende Meldung aus.<\/p>\n<p>Danach durchlaufen wir alle markierten Module aus <b>lstModules <\/b>und schreiben deren Namen in <b>strModule<\/b>. In einer inneren Schleife durchlaufen wir nun alle markierten Eintr&auml;ge des Listenfeldes <b>lstTypes<\/b> in umgekehrter Reihenfolge und rufen f&uuml;r jede Kombination aus Modul und Typ die Prozedur <b>TypeErsetzen <\/b>auf.<\/p>\n<h2>Prozedur zum Ersetzen von Early Binding durch Late Binding<\/h2>\n<p>Die Hauptarbeit erledigt die Prozedur <b>TypeErsetzen<\/b>, der wir den Namen des Moduls, den Typ und den Wert aus <b>bolErsetzteZeilenAlsKommentarBehalten <\/b>&uuml;bergeben (siehe Listing 7).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TypeErsetzen(strModule<span style=\"color:blue;\"> As String<\/span>, strType<span style=\"color:blue;\"> As String<\/span>, bolErsetzteZeilenAlsKommentarBehalten<span style=\"color:blue;\"> As Boolean<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBComponent\r\n     <span style=\"color:blue;\">Dim <\/span>objCodeModule<span style=\"color:blue;\"> As <\/span>CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>lngLine<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngCountOfLines<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcline<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strLine<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strLineOld<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strWork<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolHasContinuation<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolReplaced<span style=\"color:blue;\"> As Boolean<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = CurrentVBProject\r\n     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strModule)\r\n     <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n     lngCountOfLines = objCodeModule.CountOfLines\r\n     <span style=\"color:blue;\">Do While<\/span> lngLine &lt; lngCountOfLines\r\n         lngLine = lngLine + 1\r\n         bolReplaced = <span style=\"color:blue;\">False<\/span>\r\n         bolHasContinuation = <span style=\"color:blue;\">False<\/span>\r\n         lngProcline = 0\r\n         strLine = objCodeModule.Lines(lngLine, 1)\r\n         <span style=\"color:blue;\">If <\/span>Left$(Trim$(strLine), 1) = \"''\"<span style=\"color:blue;\"> Then<\/span>\r\n             GoTo NextLine\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strLineOld = strLine\r\n         strWork = strLine\r\n         <span style=\"color:blue;\">If <\/span>Right$(Trim$(strWork), 1) = \"_\"<span style=\"color:blue;\"> Then<\/span>\r\n             bolHasContinuation = <span style=\"color:blue;\">True<\/span>\r\n             lngProcline = lngLine\r\n             <span style=\"color:blue;\">Do While<\/span> Right$(Trim$(strWork), 1) = \"_\"\r\n                 lngProcline = lngProcline + 1\r\n                 strWork = Left$(strWork, <span style=\"color:blue;\">Len<\/span>(strWork) - 1)\r\n                 strWork = strWork & Trim$(objCodeModule.Lines(lngProcline, 1))\r\n             <span style=\"color:blue;\">Loop<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Hauptprozedur zum Umwandeln (Teil 1)<\/span><\/b><\/p>\n<p>Hier referenzieren wir wieder das aktuelle VBA-Projekt und holen uns Verweise auf das zu bearbeitende <b>VBComponent<\/b>&#8211; und <b>CodeModule<\/b>-Objekt.<\/p>\n<p>Au&szlig;erdem ermitteln wir die Anzahl der zu untersuchenden Zeilen mit <b>CountOfLines <\/b>und speichern diesen Wert in <b>lngCountOfLines<\/b>.<\/p>\n<p>Anschlie&szlig;end durchlaufen wir eine Schleife, die so lange l&auml;uft, bis die aktuelle Zeile aus <b>lngLine <\/b>nicht mehr kleiner als <b>lngCountOfLines <\/b>ist. Warum keine <b>For&#8230;Next<\/b>-Schleife? Weil sich die Anzahl der Zeilen ver&auml;ndern kann, weil wir beispielsweise Zeilen f&uuml;r die auskommentierten Early Binding-Zeilen unterbringen m&uuml;ssen.<\/p>\n<p>Hier springen wir zur n&auml;chsten Zeile und setzen die Variablen <b>bolReplaced <\/b>und <b>bolHasContinuation <\/b>auf <b>False <\/b>sowie <b>lngProcLine <\/b>auf <b>0<\/b> ein.<\/p>\n<p>Dann lesen wir die aktuelle Zeile in <b>strLine <\/b>ein. Handelt es sich um eine Kommentarzeile, springen wir zur Marke <b>NextLine <\/b>und wenden uns in der Schleife gleich der n&auml;chsten Zeile zu. Anderenfalls speichern wir die aktuelle Zeile in <b>strOldLine <\/b>und in <b>strWork<\/b>.<\/p>\n<p>Nun ziehen wir Anweisungen, die durch den Unterstrich auf mehrere Zeilen aufgeteilt sind, in einer einzigen Zeile zusammen und speichern das Ergebnis in der Variablen <b>strWork<\/b>. Au&szlig;erdem erh&ouml;hen wir <b>lngProcline <\/b>f&uuml;r jede dieser Zeilen um den Wert <b>1<\/b>, damit wir die Fortsetzungszeilen sp&auml;ter &uuml;berspringen k&ouml;nnen.<\/p>\n<p>Damit kommen wir zu dem Teil, der in Listing 8 abgebildet ist. Hier pr&uuml;fen wir mit der Funktion <b>WouldReplaceType<\/b>, ob die Zeile &uuml;berhaupt den aktuell zu ersetzenden Typ enth&auml;lt. Falls ja, speichern wir <b>strWork <\/b>in <b>strLineOld <\/b>und ersetzen die umgebrochene Zeile im Modul tats&auml;chlich durch die zusammengezogene Zeile.<\/p>\n<pre>         ...\r\n         <span style=\"color:blue;\">If <\/span>WouldReplaceType(strWork, strType)<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">If <\/span>bolHasContinuation<span style=\"color:blue;\"> Then<\/span>\r\n                 strLineOld = strWork\r\n                 objCodeModule.ReplaceLine lngLine, strWork\r\n                 objCodeModule.DeleteLines lngLine + 1, lngProcline - lngLine\r\n                 lngCountOfLines = objCodeModule.CountOfLines\r\n                 strLine = strWork\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 strLine = strWork\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             strLine = ReplaceTypeInLine(strLine, strType, bolReplaced)\r\n             <span style=\"color:blue;\">If <\/span>bolReplaced<span style=\"color:blue;\"> Then<\/span>\r\n                 objCodeModule.ReplaceLine lngLine, strLine\r\n                 <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, <span style=\"color:blue;\">vbCrLf<\/span>) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                     lngLine = lngLine + 1\r\n                     lngCountOfLines = objCodeModule.CountOfLines\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">If <\/span>bolErsetzteZeilenAlsKommentarBehalten<span style=\"color:blue;\"> Then<\/span>\r\n                     objCodeModule.InsertLines lngLine, \"''\" & strLineOld\r\n                     lngLine = lngLine + 1\r\n                     lngCountOfLines = objCodeModule.CountOfLines\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\nNextLine:\r\n         lngCountOfLines = objCodeModule.CountOfLines\r\n         DoEvents\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 8: Hauptprozedur zum Umwandeln (Teil 2)<\/span><\/b><\/p>\n<p>Au&szlig;erdem l&ouml;schen wir die Zeilenfortsetzungen mit der <b>Delete<\/b>-Methode im Code, wobei wir die Startzeile und die Anzahl der zu l&ouml;schenden Zeilen &uuml;bergeben.<\/p>\n<p>Au&szlig;erdem aktualisieren wir nun die Anzahl der zu bearbeitenden Zeilen in <b>lngCountOfLines <\/b>mit der aktuellen Zeilenanzahl, da ja Zeilen gel&ouml;scht wurden. Der aktuelle Zwischenstand aus <b>strWork <\/b>landet in <b>strLine <\/b>&#8211; sowohl f&uuml;r eine zusammengezogene Anweisung als auch f&uuml;r eine einzeilige Anweisung.<\/p>\n<p>Schlie&szlig;lich folgt die eigentliche Ersetzung, die in der Funktion <b>ReplaceTypeInLine <\/b>durchgef&uuml;hrt wird.<\/p>\n<p>Dieser &uuml;bergeben wir die Zeilennummer, den Typ sowie den Wert der Variablen <b>bolReplaced<\/b>.<\/p>\n<p>Wenn <b>bolReplaced <\/b>anschlie&szlig;end den Wert <b>True <\/b>aufweist, wurden Ersetzungen vorgenommen und wir ersetzen die ersetzte Zeile mit der Nummer <b>lngLine <\/b>durch die in <b>strLine <\/b>geschriebene neue Version der Zeile. Hier kann es vorkommen, dass zus&auml;tzliche Zeilen entstanden sind. Die Anzahl der Zeilen ermitteln wir &uuml;ber die Anzahl der Zeilenumbr&uuml;che in der Zeile (<b>vbCrLf<\/b>) und springen in <b>lngLine <\/b>um die entsprechende Anzahl weiter. Au&szlig;erdem passen wir wieder <b>lngCountOfLines <\/b>an.<\/p>\n<p>Ist die Option <b>bolErsetzteZeilenAlsKommentarBehalten <\/b>gesetzt, f&uuml;gen wir die urspr&uuml;ngliche Anweisung noch als Kommentar &uuml;ber der neuen Version der Zeile hinzu und passen wieder <b>lngLine <\/b>und <b>lngCountOfLines <\/b>an.<\/p>\n<p>Auf diese Weise durchlaufen wir nun alle Zeilen und nehmen die erforderlichen &Auml;nderungen vor.<\/p>\n<h2>Pr&uuml;fen, ob eine Zeile ersetzt werden muss<\/h2>\n<p>In der Funktion <b>WouldReplaceType <\/b>pr&uuml;fen wir, ob eine Zeile &uuml;berhaupt einen zu ersetzenden Typen enth&auml;lt (siehe Listing 9).<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>WouldReplaceType(ByVal strLine<span style=\"color:blue;\"> As String<\/span>, ByVal strType<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \"<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> \" & strType, vbTextCompare) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         WouldReplaceType = <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;\">If <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \" = <span style=\"color:blue;\">New<\/span> \" & strType, vbTextCompare) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         WouldReplaceType = <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;\">If <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \"<span style=\"color:blue;\"> As <\/span>\" & strType, vbTextCompare) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         WouldReplaceType = <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;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 9: Pr&uuml;fen, ob in einer Zeile &Auml;nderungen vorgenommen werden m&uuml;ssen<\/span><\/b><\/p>\n<p>Die Funktion pr&uuml;ft, ob einer der Ausdr&uuml;cke <b>As New [Type]<\/b>, <b>= New [Type] <\/b>oder <b>As [Type] <\/b>enthalten ist und gibt in diesem Fall den Wert <b>True <\/b>als Funktionsergebnis zur&uuml;ck.<\/p>\n<p>Dazu nutzen wir jeweils die <b>Instr<\/b>-Funktion mit dem entsprechenden Ausdruck als Suchbegriff.<\/p>\n<h2>Funktion zum Ersetzen von Typen in Anweisungen<\/h2>\n<p>Die eigentliche Ersetzung wird in der Funktion <b>ReplaceTypeInLine <\/b>durchgef&uuml;hrt (siehe Listing 10). Die Prozedur nimmt die anzupassende Zeile, den Typ sowie den R&uuml;ckgabeparameter <b>bolReplaced <\/b>entgegen. Dieser wird zun&auml;chst auf <b>False <\/b>eingestellt.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>ReplaceTypeInLine(ByVal strLine<span style=\"color:blue;\"> As String<\/span>, ByVal strType<span style=\"color:blue;\"> As String<\/span>, _\r\n         ByRef bolReplaced<span style=\"color:blue;\"> As Boolean<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngStart<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngSpaces<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strVariable<span style=\"color:blue;\"> As String<\/span>\r\n     bolReplaced = <span style=\"color:blue;\">False<\/span>\r\n     Select Case <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \"<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> \" & strType, vbTextCompare) &gt; 0\r\n             <span style=\"color:blue;\">If <\/span>Right$(Trim$(strLine), <span style=\"color:blue;\">Len<\/span>(strType)) = strType<span style=\"color:blue;\"> Then<\/span>\r\n                 lngSpaces = <span style=\"color:blue;\">Len<\/span>(strLine) - <span style=\"color:blue;\">Len<\/span>(LTrim$(strLine))\r\n                 strVariable = Trim$(Replace$(strLine, strType, \"\", , , vbTextCompare))\r\n                 strVariable = Trim$(Replace$(strVariable, \"<span style=\"color:blue;\"> As <\/span>New\", \"\", , , vbTextCompare))\r\n                 strVariable = Trim$(Mid$(strVariable, <span style=\"color:blue;\">InStrRev<\/span>(strVariable, \" \")))\r\n                 strLine = Replace$(strLine, \"<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> \" & strType, \"<span style=\"color:blue;\"> As Object<\/span>\", , , vbTextCompare)\r\n                 strLine = strLine & <span style=\"color:blue;\">vbCrLf<\/span> & Space$(lngSpaces) & _\r\n                           \"<span style=\"color:blue;\">Set<\/span> \" & strVariable & \" = CreateObject(\"\"\" & strType & \"\"\")\"\r\n                 bolReplaced = <span style=\"color:blue;\">True<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \" = <span style=\"color:blue;\">New<\/span> \" & strType, vbTextCompare) &gt; 0\r\n             strLine = Replace$(strLine, \" = <span style=\"color:blue;\">New<\/span> \" & strType, _\r\n                                \" = CreateObject(\"\"\" & strType & \"\"\")\", , , vbTextCompare)\r\n             bolReplaced = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case <\/span><span style=\"color:blue;\">InStr<\/span>(1, strLine, \"<span style=\"color:blue;\"> As <\/span>\" & strType, vbTextCompare) &gt; 0\r\n             lngStart = <span style=\"color:blue;\">InStr<\/span>(1, strLine, strType, vbTextCompare)\r\n             <span style=\"color:blue;\">Do While<\/span> lngStart &gt; 0\r\n                 Select Case <span style=\"color:blue;\">True<\/span>\r\n                     <span style=\"color:blue;\">Case <\/span>Right$(Trim$(strLine), <span style=\"color:blue;\">Len<\/span>(strType)) = strType\r\n                         strLine = Left$(strLine, <span style=\"color:blue;\">Len<\/span>(strLine) - <span style=\"color:blue;\">Len<\/span>(strType)) & \"Object\"\r\n                         bolReplaced = <span style=\"color:blue;\">True<\/span>\r\n                     <span style=\"color:blue;\">Case <\/span>Mid$(strLine, lngStart + <span style=\"color:blue;\">Len<\/span>(strType), 1) = \",\" _\r\n                       Or Mid$(strLine, lngStart + <span style=\"color:blue;\">Len<\/span>(strType), 1) = \")\" _\r\n                       Or Mid$(strLine, lngStart + <span style=\"color:blue;\">Len<\/span>(strType) + 1, 1) = \"=\"\r\n                         strLine = Left$(strLine, lngStart - 1) & \"Object\" & Mid$(strLine, lngStart + <span style=\"color:blue;\">Len<\/span>(strType))\r\n                         bolReplaced = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">End Select<\/span>\r\n                 lngStart = <span style=\"color:blue;\">InStr<\/span>(lngStart + 1, strLine, strType, vbTextCompare)\r\n             <span style=\"color:blue;\">Loop<\/span>\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     ReplaceTypeInLine = strLine\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 10: Durchf&uuml;hrung der &Auml;nderungen am Code<\/span><\/b><\/p>\n<p>Die Funktion pr&uuml;ft in einer <b>Select Case<\/b>-Bedingung, ob eine der gesuchten Anwendungen des Typs vorhanden ist.<\/p>\n<p>Im ersten <b>Case<\/b>-Zweig untersucht sie, ob <b>As New [Type] <\/b>gefunden werden kann. Hier pr&uuml;ft sie, ob der Typ am Ende der Zeile enthalten ist. Falls ja, holt sie die Anzahl der einger&uuml;ckten Zeichen und schreibt diese in <b>lngSpaces<\/b>, damit die Einr&uuml;ckung anschlie&szlig;end wiederhergestellt werden kann.<\/p>\n<p>Anschlie&szlig;end liest sie den Namen der verwendeten Variablen f&uuml;r diesen Typ in die Variable <b>strVariable <\/b>ein. In der Zeile wird nun <b>As New [Type] <\/b>durch <b>As Object <\/b>ersetzt. Au&szlig;erdem wird in diesem Fall eine weitere Zeile hinzugef&uuml;gt, die das neue Objekt erstellt.<\/p>\n<p>Aus <\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span><span style=\"color:blue;\">New<\/span> ADODB.Recordset<\/pre>\n<p>wird nun:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As Object<\/span>\r\n<span style=\"color:blue;\">Set<\/span> rst = CreateObject(\"ADODB.Recordset\")<\/pre>\n<p><b>bolReplaced <\/b>wird auf <b>True <\/b>eingestellt, damit die aufrufende Prozedur die Zeile tats&auml;chlich im Code ersetzt.<\/p>\n<p>Im zweiten <b>Case<\/b>-Zweig suchen wir nach Vorkommen von <b>= New [Type]<\/b>.<\/p>\n<p>Hier ersetzen wir zum Beispiel<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset<\/pre>\n<p>durch die folgende Zeile:<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> rst = CreateObject(\"ADODB.Recordset\")<\/pre>\n<p>Der folgende <b>Case<\/b>-Zweig ist der aufwendigste, weil wir hier reine Deklarationen ersetzen. Das ist an sich nicht aufwendig, aber sie behandelt auch Prozedurk&ouml;pfe etc., die mehrere Zuweisungen des Typs enthalten k&ouml;nnen und die alle untersucht und gegebenenfalls ersetzt werden m&uuml;ssen.<\/p>\n<p>Sie sucht nach Vorkommen von <b>As [Type]<\/b>, erledigt dies aber in einer <b>Do While<\/b>-Schleife, bis alle Vorkommen ersetzt wurden.<\/p>\n<p>So wird beispielsweise aus<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestMixedParametersZweiVorkommen(rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset, rst2<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)<\/pre>\n<p>die folgende Zeile:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestMixedParametersZweiVorkommen(rst<span style=\"color:blue;\"> As Object<\/span>, rst2<span style=\"color:blue;\"> As Object<\/span>)<\/pre>\n<p>Schlie&szlig;lich gibt <b>ReplaceTypeInLine <\/b>den aktuellen Wert von <b>strLine <\/b>zur&uuml;ck.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Die hier vorgestellten Techniken wurden mit einer Reihe von Datenbanken getestet. Dennoch ist nicht auszuschlie&szlig;en, dass es Konstellationen gibt, wo sie nicht vollst&auml;ndig funktioniert. In diesem Fall schreib mir gern eine E-Mail an <b>support@andreminhorst.de<\/b>.<\/p>\n<p>Ein weiterer Schritt, der beispielsweise bei Verwendung der ADODB-Bibliothek n&ouml;tig ist, ist das Ersetzen der Konstanten durch Zahlenwerte oder durch entsprechende Deklaration der Konstanten.<\/p>\n<p>Wenn im Code zum Beispiel <b>adOpenDynamic <\/b>(Wert <b>2<\/b>) in einer <b>Open<\/b>-Methode verwendet wird, musst Du entweder in der <b>Open<\/b>-Methode die Konstante durch den Zahlenwert ersetzen oder diesen wie folgt &ouml;ffentlich in einem Standardmodul deklarieren:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Const adOpenDynamic<span style=\"color:blue;\"> As Long<\/span> = 2<\/pre>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>EarlyBindingInLateBindingUmwandeln.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/BEA1CCCF-A385-412F-B060-B2F239692286\/vbe_495.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Artikel &#8220;VBA: Early Binding und Late Binding&#8221; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L&ouml;sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun&auml;chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm&ouml;glicht, diese in Late Binding-Elemente umzuwandeln. <\/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":[662025,66062025,44000037],"tags":[],"yst_prominent_words":[],"class_list":["post-55000495","post","type-post","status-publish","format-standard","hentry","category-662025","category-66062025","category-VBAEditor_programmieren"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.8 - aioseo.com -->\n\t<meta name=\"description\" content=\"Im Artikel &quot;VBA: Early Binding und Late Binding&quot; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Andr\u00e9 Minhorst\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.8\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Visual Basic Entwickler - Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler\" \/>\n\t\t<meta property=\"og:description\" content=\"Im Artikel &quot;VBA: Early Binding und Late Binding&quot; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-02-05T12:00:18+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"-001-11-30T00:00:00+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Im Artikel &quot;VBA: Early Binding und Late Binding&quot; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#blogposting\",\"name\":\"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler\",\"headline\":\"Per VBA von Early Binding zu Late Binding wechseln\",\"author\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/f7d78bb3497f4d1f8860b4b1757ff0d3\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#articleImage\"},\"datePublished\":\"2025-12-01T00:00:00+00:00\",\"dateModified\":\"-0001-11-30T00:00:00+00:00\",\"inLanguage\":\"de-DE\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#webpage\"},\"articleSection\":\"2025, 6\\\/2025, VBA-Editor programmieren\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/vbentwickler.de\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"name\":\"2025\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"position\":2,\"name\":\"2025\",\"item\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#listItem\",\"name\":\"Per VBA von Early Binding zu Late Binding wechseln\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#listItem\",\"position\":3,\"name\":\"Per VBA von Early Binding zu Late Binding wechseln\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"name\":\"2025\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\",\"name\":\"Datenbankentwickler\",\"description\":\"Das Magazin f\\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/cropped-header_vbe-1.png\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#organizationLogo\",\"width\":664,\"height\":225},\"image\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#organizationLogo\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/\",\"name\":\"Andr\\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Andr\\u00e9 Minhorst\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#webpage\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/\",\"name\":\"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler\",\"description\":\"Im Artikel \\\"VBA: Early Binding und Late Binding\\\" (www.vbentwickler.de\\\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.\",\"inLanguage\":\"de-DE\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"datePublished\":\"2025-12-01T00:00:00+00:00\",\"dateModified\":\"-0001-11-30T00:00:00+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#website\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/\",\"name\":\"Datenbankentwickler\",\"description\":\"Das Magazin f\\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\",\"inLanguage\":\"de-DE\",\"publisher\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler","description":"Im Artikel \"VBA: Early Binding und Late Binding\" (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.","canonical_url":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#blogposting","name":"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler","headline":"Per VBA von Early Binding zu Late Binding wechseln","author":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"publisher":{"@id":"https:\/\/vbentwickler.de\/#organization"},"image":{"@type":"ImageObject","url":"http:\/\/vg08.met.vgwort.de\/na\/f7d78bb3497f4d1f8860b4b1757ff0d3","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#articleImage"},"datePublished":"2025-12-01T00:00:00+00:00","dateModified":"-0001-11-30T00:00:00+00:00","inLanguage":"de-DE","mainEntityOfPage":{"@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#webpage"},"isPartOf":{"@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#webpage"},"articleSection":"2025, 6\/2025, VBA-Editor programmieren"},{"@type":"BreadcrumbList","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/vbentwickler.de#listItem","position":1,"name":"Home","item":"https:\/\/vbentwickler.de","nextItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","name":"2025"}},{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","position":2,"name":"2025","item":"https:\/\/vbentwickler.de\/category\/2025\/","nextItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#listItem","name":"Per VBA von Early Binding zu Late Binding wechseln"},"previousItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#listItem","position":3,"name":"Per VBA von Early Binding zu Late Binding wechseln","previousItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","name":"2025"}}]},{"@type":"Organization","@id":"https:\/\/vbentwickler.de\/#organization","name":"Datenbankentwickler","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","url":"https:\/\/vbentwickler.de\/","logo":{"@type":"ImageObject","url":"https:\/\/vbentwickler.de\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#organizationLogo","width":664,"height":225},"image":{"@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#organizationLogo"}},{"@type":"Person","@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author","url":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","width":96,"height":96,"caption":"Andr\u00e9 Minhorst"}},{"@type":"WebPage","@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#webpage","url":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/","name":"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler","description":"Im Artikel \"VBA: Early Binding und Late Binding\" (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.","inLanguage":"de-DE","isPartOf":{"@id":"https:\/\/vbentwickler.de\/#website"},"breadcrumb":{"@id":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/#breadcrumblist"},"author":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"creator":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"datePublished":"2025-12-01T00:00:00+00:00","dateModified":"-0001-11-30T00:00:00+00:00"},{"@type":"WebSite","@id":"https:\/\/vbentwickler.de\/#website","url":"https:\/\/vbentwickler.de\/","name":"Datenbankentwickler","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","inLanguage":"de-DE","publisher":{"@id":"https:\/\/vbentwickler.de\/#organization"}}]},"og:locale":"de_DE","og:site_name":"Visual Basic Entwickler - Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","og:type":"article","og:title":"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler","og:description":"Im Artikel &quot;VBA: Early Binding und Late Binding&quot; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.","og:url":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/","og:image":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","og:image:secure_url":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","article:published_time":"2026-02-05T12:00:18+00:00","article:modified_time":"-001-11-30T00:00:00+00:00","twitter:card":"summary_large_image","twitter:title":"Per VBA von Early Binding zu Late Binding wechseln - Visual Basic Entwickler","twitter:description":"Im Artikel &quot;VBA: Early Binding und Late Binding&quot; (www.vbentwickler.de\/494) haben wir die beiden Methoden Early Binding und Late Binding vorgestellt und ihre Vor- und Nachteile beschrieben. Im vorliegenden Artikel zeigen wir nun eine automatische L\u00f6sung, um schnell einige oder alle per Early Binding definierten Elemente nach Late Binding zu migrieren. Dazu nutzen wir Code, der zun\u00e4chst alle Early Binding-Elemente ermittelt, diese in einem Formular anzeigt und es dann erm\u00f6glicht, diese in Late Binding-Elemente umzuwandeln.","twitter:image":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png"},"aioseo_meta_data":{"post_id":"55000495","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"created":"2026-02-01 21:07:02","updated":"2026-05-16 09:22:29","ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/vbentwickler.de\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/vbentwickler.de\/category\/2025\/\" title=\"2025\">2025<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tPer VBA von Early Binding zu Late Binding wechseln\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/vbentwickler.de"},{"label":"2025","link":"https:\/\/vbentwickler.de\/category\/2025\/"},{"label":"Per VBA von Early Binding zu Late Binding wechseln","link":"https:\/\/vbentwickler.de\/Per_VBA_von_Early_Binding_zu_Late_Binding_wechseln\/"}],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000495","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=55000495"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000495\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000495"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}