{"id":55000189,"date":"2019-08-01T00:00:00","date_gmt":"2020-03-27T19:38:57","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=189"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Von_Access_zum_EDM_per_Kontextmenue","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Von_Access_zum_EDM_per_Kontextmenue\/","title":{"rendered":"Von Access zum EDM per Kontextmen&uuml;"},"content":{"rendered":"<p><b>Nach den vorbereitenden Artikel zum Thema Erweitern von Visual Studio, Anlegen von Elementen im Projektmappen-Explorer und Hinzuf&uuml;gen von Elementen wie Klassen, Prozeduren et cetera per Code k&ouml;nnen wir uns an ein praktisches Beispiel begeben: Eine Anwendung, die Sie per Men&uuml;eintrag aus dem Kontextmen&uuml; eines Projekts aus aufrufen k&ouml;nnen und die nach der Auswahl der Access-Datenbank mit dem zu verwendenden Datenmodell ein Entity Data Model auf Basis dieser Datenbank erstellt. Damit k&ouml;nnen Sie dann mit wenigen Handgriffen auch direkt eine SQL Server-Datenbank generieren.<\/b><\/p>\n<h2>Grundlagen<\/h2>\n<p>Die Grundlagen zu den hier verwendeten Techniken finden Sie in den Artikeln <b>Visual Studio erweitern: Men&uuml;befehle<\/b>, <b>Visual Studio erweitern: Elemente hinzuf&uuml;gen<\/b>, <b>Visual Studio mit LINQPad: Project und ProjectItems <\/b>und <b>Klassen, Methoden und Co. per Code generieren<\/b>. Au&szlig;erdem haben wir den gr&ouml;&szlig;ten Teil des Codes, den wir hier in eine Extension stecken wollen, in den Artikeln <b>Von Access zu Entity Framework: Datenmodell<\/b>, <b>Von Access zu Entity Framework: Daten<\/b>, <b>Von Access zu EF: Step by Step<\/b> und <b>Von Access zu Entity Framework: Update 1<\/b> beschrieben.<\/p>\n<h2>Projekt erstellen<\/h2>\n<p>Die Erweiterung, die unsere Funktionalit&auml;t in Visual Studio zur Verf&uuml;gung stellen soll, basiert auf einem Projekt mit der Vorlage <b>Visual Basic|Extensibility|VSIX Projekt<\/b>, die wir <b>Access2EDM <\/b>nennen. Die beiden Elemente <b>index.html <\/b>und <b>stylesheet.css<\/b>, die im nun erstellen Projekt vorliegen, l&ouml;schen wir direkt.<\/p>\n<p>Daf&uuml;r f&uuml;gen wir &uuml;ber den Kontextmen&uuml;-Eintrag <b>Hinzuf&uuml;gen|Neues Element&#8230; <\/b>des Projekt-Elements im Projektmappen-Explorer ein neues Element des Typs <b>Extensibility|Custom Command <\/b>hinzu und nennen dieses <b>cmdAccess2EDM<\/b>.<\/p>\n<p>Damit der standardm&auml;&szlig;ig im <b>Extras<\/b>-Men&uuml; angezeigte Befehl nun im Kontextmen&uuml; des Projekt-Elements im Projektmappen-Explorer erscheint, &auml;ndern wir eine Zeile in der Datei <b>cmdAccess2EDMPackage.vsct<\/b>, wo wir <b>IDM_VS_MENU_TOOLS <\/b>durch <b>IDM_VS_CTXT_PROJNODE <\/b>ersetzen, was folgende Zeile ergibt:<\/p>\n<pre>&lt;Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PROJNODE\"\/&gt;<\/pre>\n<p>Au&szlig;erdem &auml;ndern wir in der Zeile zur Definition des Elements <b>ButtonText <\/b>die Beschriftung wie folgt:<\/p>\n<pre>&lt;ButtonText&gt;EDM aus Access-Datenbank&lt;\/ButtonText&gt;<\/pre>\n<h2>Icon hinzuf&uuml;gen<\/h2>\n<p>Als Icon wollen wir ein Access-Logo verwenden. Dieses finden wir in einer Ressourcen-Datei <b>accicons.exe<\/b>. Wir extrahieren die <b>.ico<\/b>-Datei und f&uuml;gen diese zum Ordner <b>Resources <\/b>des Projekts hinzu. Au&szlig;erdem &auml;ndern wir noch eine weitere Zeile in der bereits bearbeiteten Datei wie folgt ab, um die neu hinzugef&uuml;gte Bilddatei zu verwenden:<\/p>\n<pre>&lt;Bitmap guid=\"guidImages\" href=\"Resources\\Access.ico\"\/&gt;<\/pre>\n<p>Danach finden wir den Eintrag <b>EDM aus Access-Datenbank <\/b>wie Bild 1 in im Kontextmen&uuml; des Projekt-Elements im Projektmappen-Explorer der beim Debuggen gestarteten Instanz von Visual Studio vor.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_189_001.png\" alt=\"Erster Test des neuen Kontextmen&uuml;-Eintrags\" width=\"399,7285\" height=\"369,8023\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Erster Test des neuen Kontextmen&uuml;-Eintrags<\/span><\/b><\/p>\n<p>Damit sind die Arbeiten an der Datei <b>cmdAccess2EDMPackage.vsct <\/b>beendet und Sie k&ouml;nnen diese Datei speichern und schlie&szlig;en.<\/p>\n<h2>Wechsel zu LINQPad<\/h2>\n<p>Ab dieser Stelle sind wir f&uuml;r die Programmierung komplett auf LINQPad umgeschwenkt. Das st&auml;ndige Warten beim Debuggen der Anwendung zum Testen zerst&ouml;rt jeden Programmierfluss. Nur zwischendurch zum Testen und am Ende f&uuml;gen wir den produzierten Code in das VSIX-Projekt ein.<\/p>\n<h2>Die Basis: Entity Data Model<\/h2>\n<p>Basis f&uuml;r das Erstellen eines Entity Data Model auf Basis des Datenmodells einer Access-Datenbank ist das Hinzuf&uuml;gen eines neuen Elements des Typs <b>ADO.NET Entity Date Model<\/b>, was normalerweise &uuml;ber den Dialog <b>Neues Element hinzuf&uuml;gen <\/b>geschieht. Dort wird dann auch der Name des neuen Entity Data Models eingegeben (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_189_002.png\" alt=\"Hinzuf&uuml;gen des Entity Data Models auf herk&ouml;mmlichem Wege\" width=\"649,559\" height=\"332,6642\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Hinzuf&uuml;gen des Entity Data Models auf herk&ouml;mmlichem Wege<\/span><\/b><\/p>\n<p>Diesen Schritt wollen wir bereits per Code erledigen und dazu m&uuml;ssen wir den Pfad der Vorlage ermitteln. Diese finden wir mit einer kleinen Prozedur heraus, die wir im Tool <b>LINQPad <\/b>ausf&uuml;hren k&ouml;nnen und die wie folgt aussieht:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Main\r\n     <span style=\"color:blue;\">Dim <\/span>objDTE<span style=\"color:blue;\"> As <\/span>EnvDTE80.DTE2 = Nothing\r\n     <span style=\"color:blue;\">Dim <\/span>objSolution<span style=\"color:blue;\"> As <\/span>EnvDTE80.Solution2\r\n     <span style=\"color:blue;\">Dim <\/span>strTemplate<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>GetDTE(objDTE) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n         objSolution = Trycast(objDTE.Solution, EnvDTE80.Solution2)\r\n         strTemplate = objSolution.GetProjectItemTemplate(\"Daten\\ADO.NET Entity Data Model\", \"VisualBasic\")\r\n         <span style=\"color:blue;\">Debug.Print<\/span>(strTemplate)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die hier verwendete Hilfsfunktion <b>GetDTE <\/b>finden Sie in der Datei <b>Access2EDM.linq<\/b>. In dieser Datei entwickeln wir innerhalb der Benutzeroberfl&auml;che von LINQPad auch den Quellcode dieser L&ouml;sung. Der Hintergrund ist, dass das Debuggen von Extensions mit Visual Studio &auml;u&szlig;erst zeitaufwendig ist, da das Starten zum Debuggen wegen der dazu ben&ouml;tigten zus&auml;tzlichen Instanz von Visual Studio sehr lange dauert.<\/p>\n<p>Mit der oben genannten Prozedur finden wir den Pfad der Vorlage f&uuml;r das <b>ADO.NET Entity Data Model <\/b>schnell heraus:<\/p>\n<pre>C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\Common7\\IDE\\ItemTemplates\\VisualBasic\\Data\\1033\\EF_EDM\\ModelObjectItemVB.vstemplate<\/pre>\n<p>Sie k&ouml;nnen sich diese Datei auch einmal ansehen.<\/p>\n<h2>ADO.NET Entity Data Model-Vorlage hinzuf&uuml;gen<\/h2>\n<p>Wenn wir die oben begonnene Prozedur wie folgt erweitern, sollten eigentlich automatisch die entsprechenden Elemente f&uuml;r das Entity Data Model hinzugef&uuml;gt werden:<\/p>\n<pre><span style=\"color:blue;\">If <\/span>GetCurrentOrNewProject(objProject) = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n     objProject.ProjectItems.AddFromTemplate(strTemplate, \"BestellverwaltungContext\")\r\n<span style=\"color:blue;\">End If<\/span><\/pre>\n<p>Allerdings ruft dies noch den Dialog aus Bild 3 auf den Plan. Hier m&uuml;ssen wir noch die Option <b>Leeres Code First-Modell ausw&auml;hlen <\/b>und auf die Schaltfl&auml;che <b>Fertigstellen<\/b> klicken, damit die Elemente des leeren Entity Data Models zum Projekt hinzugef&uuml;gt werden. Leider ist und keine M&ouml;glichkeit bekannt, wir diesen Dialog umschiffen k&ouml;nnen. Daher f&uuml;gen wir vorher ein Meldungsfenster ein, das den Benutzer darauf hinweist, die Option <b>Leeres Code First-Modell <\/b>auszuw&auml;hlen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_189_003.png\" alt=\"Entity Data Model hinzuf&uuml;gen\" width=\"599,593\" height=\"543,229\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Entity Data Model hinzuf&uuml;gen<\/span><\/b><\/p>\n<p>In der Datei <b>ModelObjectItemVB.vstemplate <\/b>sehen wir dann auch, dass dort noch ein Assistent namens <b>ModelObjectItemWizard <\/b>ge&ouml;ffnet im Spiel ist, der vermutlich den soeben beschriebenen Dialog erscheinen l&auml;sst.<\/p>\n<p>Wenn wir uns nun allerdings ansehen, welche Elemente und &Auml;nderungen der Assistent in unser Projekt gebracht hat, stellt sich die Frage, ob wir nicht selbst eine passende Erweiterung aus dem &Auml;rmel sch&uuml;tteln k&ouml;nnen. Doch das w&uuml;rde aktuell den Rahmen sprengen, sodass wir uns dieses Thema in einer sp&auml;teren Ausgabe vornehmen werden.<\/p>\n<p>Wir haben nun jedenfalls die grundlegenden Elemente des Entity Data Models im Projekt:<\/p>\n<ul>\n<li>die Context-Klasse, die aus dem von uns eingegebenen Namen f&uuml;r die Anwendung und dem Zusatz <b>Context.vb <\/b>besteht, also etwa <b>BestellverwaltungContext.vb<\/b>,<\/li>\n<li>die Datei <b>App.Config<\/b>, in der im Bereich <b>connectionStrings <\/b>die Verbindungszeichenfolge f&uuml;r die zu erstellende SQL Server-Datenbank hinzugef&uuml;gt wurde sowie <\/li>\n<li>wie in der Datei <b>packages.config <\/b>zu erkennen, die hinzugef&uuml;gten Pakete mit den Funktionen des Entity Frameworks.<\/li>\n<\/ul>\n<p>Diese m&uuml;ssen wir nun erweitern, so wie wir es zuvor wie in den eingangs genannten Artikeln von Access aus erledigt haben. Dort haben wir auch per Code die Tabellendefinitionen durchlaufen und die passenden Entit&auml;tsklassen sowie Entit&auml;tsauflistungen definiert und die Anweisungen zum Einf&uuml;gen der in den Tabellen enthaltenen Daten zusammengestellt. Das wollen wir nun von unserer Erweiterung aus machen.<\/p>\n<h2>Access-Datenbank ermitteln<\/h2>\n<p>Dazu m&uuml;ssen wir als erstes herausfinden, welche Access-Datenbank als Grundlage f&uuml;r die Umsetzung des Datenmodells in ein Entity Data Model dienen soll. Dazu zeigen wir dem Benutzer einen <b>Datei ausw&auml;hlen<\/b>-Dialog an, was wir mit folgendem Code bewerkstelligen. Wir ben&ouml;tigen einen Verweis auf den Namespace <b>Microsoft.Win32<\/b>:<\/p>\n<pre>Imports Microsoft.Win32<\/pre>\n<p>Au&szlig;erdem verwenden wir die folgende Funktion, um den Pfad mit einem Dateiauswahl-Dialog zu ermitteln:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetDatabasePath()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objOpenFileDialog<span style=\"color:blue;\"> As <\/span>OpenFileDialog\r\n     <span style=\"color:blue;\">Dim <\/span>strDatabasePath<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     objOpenFileDialog = <span style=\"color:blue;\">New<\/span> OpenFileDialog\r\n     <span style=\"color:blue;\">With<\/span> objOpenFileDialog\r\n         .Filter = \"Access-Datenbanken (*.mdb,*.accdb)|*.mdb;*.accdb|Alle Dateien (*.*)|*.*\"\r\n         .FilterIndex = 1\r\n         <span style=\"color:blue;\">If <\/span>(.ShowDialog = DialogResult.OK)<span style=\"color:blue;\"> Then<\/span>\r\n             strDatabasepath = .FileName\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     Return strDatabasePath\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Wie wir diese aufrufen, zeigen wir gleich im Gesamtkontext der aufrufenden Methode.<\/p>\n<h2>Code zum Erzeugen des Datenmodells in das Visual Studio-Projekt kopieren<\/h2>\n<p>In den zu Beginn erw&auml;hnten Artikel haben wir bereits den Code beschrieben, der zum Erzeugen eines Entity Data Models aus einem Access-Datenmodell erforderlich ist. Diesen Code wollen wir nun zun&auml;chst aus dem Modul <b>mdlEDM <\/b>der Datenbank <b>Access2EDM.accdb <\/b>in ein neues Modul unseres Visual Basic-Projekts einf&uuml;gen.<\/p>\n<p>Das noch zu erstellende Modul soll <b>mdlAccess2EDM_Model <\/b>hei&szlig;en. Den Code aus dem Modul <b>mdlEDM <\/b>der Access-Datenbank f&uuml;gen wir einfach dort ein.<\/p>\n<p>Damit erhalten wir nat&uuml;rlich den einen oder anderen Fehler, wie auch der Ausschnitt aus Bild 4 zeigt. Das wir VBA-Code nicht problemlos in ein Visual Basic-Project &uuml;bernehmen k&ouml;nnen, war allerdings abzusehen. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_189_004.png\" alt=\"Fehler beim Einf&uuml;gen des VBA-Codes\" width=\"499,6607\" height=\"405,5579\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Fehler beim Einf&uuml;gen des VBA-Codes<\/span><\/b><\/p>\n<p>Die ersten Fehler durch das Fehlen der DAO-Objektbibliothek beheben wir, indem wir den fehlenden Objektverweis hinzuf&uuml;gen. Dazu &ouml;ffnen Sie den <b>Verweis-Manager <\/b>von Access, klicken auf Durchsuchen und navigieren zum Ordner <b>C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Visual Studio Tools for Office\\PIA\\Office15<\/b>. Hier f&uuml;gen Sie die beiden Bibliotheken aus Bild 5 hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_04\/pic_189_006.png\" alt=\"Hinzuf&uuml;gen der Access Database Engine-Bibliothek\" width=\"549,6265\" height=\"351,8639\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Hinzuf&uuml;gen der Access Database Engine-Bibliothek<\/span><\/b><\/p>\n<p>Danach f&uuml;gen Sie der Datei mit dem Modul <b>Access2EDM_Model <\/b>die folgenden Anweisungen hinzu:<\/p>\n<pre>Imports Microsoft.Office.Interop.Access\r\nImports Microsoft.Office.Interop.Access.Dao<\/pre>\n<p>Nun f&uuml;hren Sie folgende Schritte durch, um die VBA-Routine aus der Access-Datenbank Visual Basic-kompatibel zu machen:<\/p>\n<ul>\n<li>Entfernen der <b>Set<\/b>-Anweisungen vor Zuweisungen an Objekte<\/li>\n<li>Ersetzen der <b>MsgBox<\/b>-Anweisung durch <b>MessageBox.Show <\/b>und Anpassen der Parameter sowie gegebenenfalls Hinzuf&uuml;gen des Verweises auf <b>System.Windows.Forms <\/b>und dem entsprechenden Namespace:<\/li>\n<\/ul>\n<pre>         Imports System.Windows.Forms<\/pre>\n<ul>\n<li>Einfassen von Parametern von Funktionsaufrufen oder Methoden jeweils in Klammern<\/li>\n<li>Wo wir mit <b>CurrentDb <\/b>auf die aktuelle Datenbank zugreifen, m&uuml;ssen wir mit <b>DAO.DbEngine.OpenDatabase <\/b>erst die Datenbank &ouml;ffnen und geben diese dann per Parameter an aufgerufene Funktionen weiter, die auch auf diese Datenbank zugreifen:<\/li>\n<\/ul>\n<pre>         <span style=\"color:blue;\">Dim <\/span>objDBEngine<span style=\"color:blue;\"> As <\/span>Dao.DBEngine\r\n         objDBEngine = <span style=\"color:blue;\">New<\/span> Dao.DBEngine\r\n         db = objDBEngine.OpenDatabase(strDatabasePath)<\/pre>\n<ul>\n<li>R&uuml;ckgabewerte von Funktionen werden nicht mehr der Variablen mit dem Namen der Funktion zugewiesen, sondern mit <b>Return <Wert><\/b>.<\/li>\n<li>Ganz wichtig: Parameter, die Sie zum &Auml;ndern an eine Funktion &uuml;bergeben, die also von der aufrufenden Methode anschlie&szlig;end weiterverwendet werden sollen, m&uuml;ssen Sie mit dem Schl&uuml;sselwort <b>ByRef <\/b>deklarieren, in folgendem Beispiel den dritten Parameter:<\/li>\n<\/ul>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetPrimaryKeys(db<span style=\"color:blue;\"> As <\/span>Dao.database, strTable<span style=\"color:blue;\"> As String<\/span>, ByRef strPKs<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span><\/pre>\n<p>Gr&ouml;&szlig;ere Umbauarbeiten m&uuml;ssen wir an der Klasse <b>clsMappings<\/b> vornehmen, da die Gestaltung von Klassen mit Properties unter Visual Basic anders aussieht als unter VBA. Stellvertretend f&uuml;r die &uuml;brigen Member hier der neue Aufbau f&uuml;r die Eigenschaft <b>Tabelle<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Public Class<\/span> clsMapping\r\n     <span style=\"color:blue;\">Private <\/span>m_Tabelle<span style=\"color:blue;\"> As String<\/span>\r\n     ...\r\n     <span style=\"color:blue;\">Public <\/span>Property Tabelle<span style=\"color:blue;\"> As String<\/span>\r\n         Get\r\n             Return m_Tabelle\r\n         End Get\r\n         Set(value<span style=\"color:blue;\"> As String<\/span>)\r\n             m_Tabelle = value\r\n         End <span style=\"color:blue;\">Set<\/span>\r\n     End Property\r\n     ...\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<h2>DBSet-Anweisungen zur Context-Klasse hinzuf&uuml;gen<\/h2>\n<p>Die automatisch hinzugef&uuml;gte Context-Klasse enth&auml;lt einen auskommentierten Eintrag, der vorgibt, wie die Definitionen f&uuml;r die <b>DbSet<\/b>-Auflistungen der Entit&auml;ten aussehen sollen:<\/p>\n<pre>'' Public Overridable Property MyEntities()<span style=\"color:blue;\"> As <\/span>DbSet(Of MyEntity)<\/pre>\n<p>Diese wollen wir als Erstes hinzuf&uuml;gen. Dazu ben&ouml;tigen wir allerdings erst einmal die notwendigen Informationen, in diesem Fall eine Collection mit Elementen der Klasse <b>clsMapping<\/b>. Diese enthalten Infos &uuml;ber die urspr&uuml;nglichen Daten wie den Tabellennamen und das Prim&auml;rschl&uuml;sselfeld, aber auch den Namen der zu erstellenden Entit&auml;tsklasse und des <b>DbSet<\/b>-Elements. Die folgende Funktion ermittelt diese Daten aus dem Datenmodell.<\/p>\n<p>Dabei wird der Teil des Tabellennamens ohne <b>tbl <\/b>als Name der <b>DbSet<\/b>-Auflistung (bei <b>tblKunden <\/b>also <b>Kunden<\/b>) und der Name des Prim&auml;rschl&uuml;sselfeldes ohne abschlie&szlig;endes <b>ID <\/b>als Name der Entit&auml;t verwendet (bei <b>KundeID <\/b>also <b>Kunde<\/b>). Manchmal sind beide gleich, dann wird der Benutzer aufgefordert, unterschiedliche Bezeichnungen einzugeben &#8211; beispielsweise bei <b>tblArtikel <\/b>und <b>ArtikelID <\/b>kann man dann <b>Produkte <\/b>und <b>Produkt <\/b>angeben. Sind alle Tabellen durchlaufen, werden die Informationen in einer Collection zur&uuml;ckgegeben:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetMappings(strDatabasePath<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As <\/span>Collection\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database, tdf<span style=\"color:blue;\"> As <\/span>DAO.TableDef\r\n     <span style=\"color:blue;\">Dim <\/span>strDbSets<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     <span style=\"color:blue;\">Dim <\/span>strPK<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     <span style=\"color:blue;\">Dim <\/span>strDatatype<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     <span style=\"color:blue;\">Dim <\/span>strCode<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     <span style=\"color:blue;\">Dim <\/span>colMappings<span style=\"color:blue;\"> As <\/span>Collection\r\n     <span style=\"color:blue;\">Dim <\/span>objMapping<span style=\"color:blue;\"> As <\/span>clsMapping = Nothing\r\n     <span style=\"color:blue;\">Dim <\/span>strSeed<span style=\"color:blue;\"> As String<\/span> = \"\"\r\n     <span style=\"color:blue;\">Dim <\/span>objDBEngine<span style=\"color:blue;\"> As <\/span>Dao.DBEngine\r\n     objDBEngine = <span style=\"color:blue;\">New<\/span> Dao.DBEngine\r\n     db = objDBEngine.OpenDatabase(strDatabasePath)\r\n     colMappings = <span style=\"color:blue;\">New<\/span> Collection\r\n     For Each tdf In db.TableDefs\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Left<\/span>(tdf.Name, 4) = \"MSys\" And <span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Left<\/span>(tdf.Name, 1) = \"~\"<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> GetPrimaryKey(db, tdf.Name, strPK)<span style=\"color:blue;\"> Then<\/span>\r\n             MessageBox.Show($\"Mehrere Prim&auml;rsch&uuml;ssel in der Tabelle {tdf.Name}. Die Tabelle wird nicht ber&uuml;cksichtigt.\")\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 objMapping = <span style=\"color:blue;\">New<\/span> clsMapping\r\n                 <span style=\"color:blue;\">With<\/span> objMapping\r\n                     .Entity = <span style=\"color:blue;\">Replace<\/span>(strPK, \"ID\", \"\")\r\n                     .Entity_Original = .Entity\r\n                     .Entities = <span style=\"color:blue;\">Replace<\/span>(tdf.Name, \"tbl\", \"\")\r\n                     .Entities_Original = .Entities\r\n                     <span style=\"color:blue;\">If <\/span>.Entity = .Entities<span style=\"color:blue;\"> Then<\/span>\r\n                         <span style=\"color:blue;\">Do While<\/span> .Entity = .Entities\r\n                             MessageBox.Show(\"Plural und Singular der Bezeichnung der Entit&auml;ten (hier \"\"\" & .Entity _\r\n                                 & \"\"\") im Tabellennamen scheinen gleich zu sein.\" & <span style=\"color:blue;\">vbCrLf<\/span> & <span style=\"color:blue;\">vbCrLf<\/span> & \"Geben Sie \" _\r\n                                 & \"nachfolgend eine Bezeichnung f&uuml;r den Singular der Entit&auml;t ein und eine f&uuml;r den Plural.\")\r\n                             .Entity = InputBox(\"Bezeichnung f&uuml;r den Singular\/den Klassennamen der Entit&auml;t \"\"\" \r\n                                 & .Entity & \"\"\":\", \"Singular bestimmen\", .Entity)\r\n                             .Entities = InputBox(\"Bezeichnung f&uuml;r den Plural\/den Namen der Auflistung der Entit&auml;t \"\"\" _\r\n                                 & .Entities & \"\"\":\", \"Plural bestimmen\", .Entities)\r\n                         <span style=\"color:blue;\">Loop<\/span>\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                     .ID = \"ID\"\r\n                     .PK = strPK\r\n                     .Tabelle = tdf.Name\r\n                 End <span style=\"color:blue;\">With<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             colMappings.Add(objMapping)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> tdf\r\n     Return colMappings\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000189\/\">\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\/55000189?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\/55000189\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"dbce743e9d\"\/>\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>Nach den vorbereitenden Artikel zum Thema Erweitern von Visual Studio, Anlegen von Elementen im Projektmappen-Explorer und Hinzuf&uuml;gen von Elementen wie Klassen, Prozeduren et cetera per Code k&ouml;nnen wir uns an ein praktisches Beispiel begeben: Eine Anwendung, die Sie per Men&uuml;eintrag aus dem Kontextmen&uuml; eines Projekts aus aufrufen k&ouml;nnen und die nach der Auswahl der Access-Datenbank mit dem zu verwendenden Datenmodell ein Entity Data Model auf Basis dieser Datenbank erstellt. Damit k&ouml;nnen Sie dann mit wenigen Handgriffen auch direkt eine SQL Server-Datenbank generieren.<\/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":[662019,66042019,44000004],"tags":[],"yst_prominent_words":[],"class_list":["post-55000189","post","type-post","status-publish","format-standard","hentry","category-662019","category-66042019","category-Loesungen"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000189","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=55000189"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000189\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000189"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}