{"id":55000696,"date":"2009-12-01T00:00:00","date_gmt":"2020-05-22T22:40:31","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=696"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"ExcelImportAssistent_im_Eigenbau","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/","title":{"rendered":"Excel-Import-Assistent im Eigenbau"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Der Import-Assistent f&uuml;r Excel-Dateien hat einen entscheidenden Nachteil: Er erlaubt nicht, den zu importierenden Bereich des ausgew&auml;hlten Tabellenblatts manuell auszuw&auml;hlen. Diese Aufgabe m&uuml;ssen Sie vorher direkt in Excel erledigen, indem Sie einen sogenannten &#8222;benannten Bereich&#8220; definieren. Dieser ist dann im Import-Assistenten namentlich verf&uuml;gbar. Unser Assistent enth&auml;lt eine solche Funktion, und generell lernt man eine Menge, wenn man sich die Funktionsweise eines Excel-Imports einmal in Ruhe ansieht.<\/b><\/p>\n<p>Der eingebaute Import-Assistent unterscheidet prinzipiell zwischen dem Importieren von Daten aus Excel in eine neue und in eine bestehende Tabelle. In technischer Hinsicht ist der Unterschied schnell beschrieben: Beim Erstellen einer neuen Tabelle muss zuvor eine entsprechende SQL-Aktionsabfrage ausgef&uuml;hrt werden, die mit den DDL-Befehlen von SQL eine passende, leere Tabelle erzeugt.<\/p>\n<p><b>Importieren in eine bestehende Tabelle<\/b><\/p>\n<p>Der Import-Assistent von Access 2007, der sich nur in Details von denen vorheriger Access-Versionen unterscheidet, gibt dem Benutzer gleich auf der ersten Dialogseite die Gelegenheit, die gew&uuml;nschte Quelldatei auszuw&auml;hlen und anzugeben, ob die Daten in einer bestehenden oder in einer neuen Tabelle landen sollen.<\/p>\n<p>Bei einer bestehenden Tabelle reduzieren sich die folgenden Schritte darauf, die Zieltabelle auszuw&auml;hlen und das als Quelle zu verwendende Tabellenblatt oder den entsprechenden benannten Bereich auszuw&auml;hlen &#8211; der Rest l&auml;uft automatisch ab, und das auch nur, wenn dabei kein Fehler auftritt. Hier gibt es Nachbesserungsbedarf, den unser Assistent liefern soll: Wir m&ouml;chten zumindest die M&ouml;glichkeit bieten, dass der Benutzer f&uuml;r jede Spalte des betroffenen Bereichs der Excel-Tabelle das entsprechende Feld der Zieltabelle zuordnen kann.<\/p>\n<p><b>Importieren in eine neue Tabelle<\/b><\/p>\n<p>Hier bietet der eingebaute Import-Assistent von Access schon deutlich mehr M&ouml;glichkeiten:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Auswahl des Tabellenblatts oder des benannten Bereichs der Excel-Datei als Datenherkunft<\/li>\n<li class=\"aufz-hlung\">Festlegen, ob die erste Zeile der Tabelle Spalten&uuml;berschriften enth&auml;lt<\/li>\n<li class=\"aufz-hlung\">Angeben der Feldnamen der Zielfelder je Spalte der Datenherkunft<\/li>\n<li class=\"aufz-hlung\">Festlegen, ob ein Feld indiziert werden soll<\/li>\n<li class=\"aufz-hlung\">Zuweisen von Datentypen zu Spalten der Quelltabelle<\/li>\n<li class=\"aufz-hlung\">Abw&auml;hlen von Spalten, die nicht importiert werden sollen<\/li>\n<li class=\"aufz-hlung\">Festlegen, ob ein Feld der zu erzeugenden Tabelle als Prim&auml;rschl&uuml;sselfeld definiert werden soll, und falls ja, welches verwendet werden soll<\/li>\n<\/ul>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">ExcelImport.mda<\/p>\n<p>Der im Rahmen dieses Beitrags erstellte Assistent soll den Import in bestehende und neu erstellte Tabellen erm&ouml;glichen. Dabei soll er den Import in bestehende Tabellen insofern erweitern, dass der Benutzer zun&auml;chst den Bereich festlegt, aus dem die Daten importiert werden sollen.<\/p>\n<p>Dies soll innerhalb des Formulars des Import-Assistenten geschehen, das (sichtbare) &Ouml;ffnen einer Excel-Instanz soll unbedingt vermieden werden.<\/p>\n<p>Diese Funktion soll auch in dem Bereich des Assistenten zur Verf&uuml;gung stehen, der Excel-Daten in neue Tabellen importiert.<\/p>\n<p>F&uuml;r den Import in bestehende Tabellen soll der neue Assistent es au&szlig;erdem erlauben, den Spalten der Quelldatei Felder der Zieltabelle zuzuweisen, damit die Daten auch dort landen, wo sie hingeh&ouml;ren. Der Aufbau der Zieltabelle muss somit nicht identisch mit dem des Excel-Tabellenblatts sein, aus dem die Daten stammen.<\/p>\n<p><b>Grunds&auml;tzliche Vorgehensweise<\/b><\/p>\n<p>Beim neuen Import-Assistenten f&uuml;r Excel-Daten soll der Import in neue und bestehende Tabellen &auml;hnlich aufgebaut sein. Der Benutzer w&auml;hlt die Excel-Datei und das Tabellenblatt aus, aus dem die Daten importiert werden sollen. Der Assistent zeigt dann das komplette Tabellenblatt an und bietet dem Benutzer die M&ouml;glichkeit, den zu importierenden Bereich gleich im Assistenten auszuw&auml;hlen.<\/p>\n<p>Genau wie im eingebauten Assistenten kann er dabei festlegen, ob die Daten mit oder ohne Spalten&uuml;berschriften importiert werden sollen. Im Anschluss legt der Benutzer f&uuml;r die einzelnen Spalten fest, wie der Feldname in der Zieltabelle hei&szlig;t.<\/p>\n<p>Beim Import in eine bestehende Tabelle kann er zwischen den vorhandenen Feldern w&auml;hlen. Soll der Assistent die Daten hingegen in eine neue Tabelle schreiben, gibt der Benutzer die Namen der Felder an, wobei gegebenenfalls die Spalten&uuml;berschriften als Standardwert dienen.<\/p>\n<p>Beim Import in eine neue Tabelle muss der Benutzer au&szlig;erdem den Datentyp f&uuml;r jedes Zielfeld festlegen und angeben, ob das Feld indiziert werden soll. Zuletzt legt der Benutzer beim Import in eine neue Tabelle noch fest, welches der Felder als Prim&auml;rschl&uuml;sselfeld dienen soll.<\/p>\n<p>Alternativ kann er angeben, dass er gar kein Prim&auml;rschl&uuml;sselfeld w&uuml;nscht oder dass der Assistent ein von den zu importierenden Daten unabh&auml;ngiges Prim&auml;rschl&uuml;sselfeld zur Tabelle hinzuf&uuml;gen soll.<\/p>\n<p><b>Resultat des Assistenten<\/b><\/p>\n<p>Ein Ergebnis des Assistenten soll nat&uuml;rlich der erfolgreiche Import der gew&uuml;nschten Daten in die Zieltabelle sein. Technisch betrachtet steckt die Hauptarbeit auf diesem Wege aber darin, dem Benutzer folgende Arbeiten abzunehmen, die wiederum von der Importart abh&auml;ngen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Beim Import in eine bestehende Tabelle braucht der Assistent nur die Parameter f&uuml;r den Aufruf einer <b>DoCmd.TransferSpreadsheet<\/b>-Anweisung zu ermitteln.<\/li>\n<li class=\"aufz-hlung\">Beim Import in eine neue Tabelle muss der Assistent zus&auml;tzlich zu der <b>DoCmd.TransferSpreadsheet<\/b>-Anweisung noch eine <b>CREATE TABLE<\/b>-Abfrage zusammenstellen, welche die neue Tabelle erstellt.<\/li>\n<\/ul>\n<p><b>Aufbau des Assistenten-Formulars<\/b><\/p>\n<p>Wir wollen den Excel-Import-Assistenten so wie klassische Assistenten aufbauen. Der Benutzer soll damit also mehrere Schritte durchlaufen k&ouml;nnen und dabei die ben&ouml;tigten Daten zusammenstellen. Um dem Benutzer das Gef&uuml;hl zu geben, dass er die ganze Zeit mit einem einzigen Formular arbeitet, verwenden wir einfach ein einziges Formular &#8211; zumindest als Hauptformular.<\/p>\n<p>Die einzelnen Schritte des Assistenten laufen nat&uuml;rlich in verschiedenen Unterformularen ab, die je nach dem Fortschritt ein- und ausgeblendet werden. Das Hauptformular sieht etwa wie in Bild 1 aus. Es enth&auml;lt vier Schaltfl&auml;chen namens <b>cmdAbbrechen<\/b>, <b>cmdZurueck<\/b>, <b>cmdWeiter <\/b>und <b>cmdFertigstellen <\/b>sowie ein Unterformularsteuerelement namens <b>sfmExcelImportWizard<\/b>. Die Beschriftungen beginnen jeweils mit einem Kaufmanns-Und (&amp;), damit der erste Buchstabe unterstrichen dargestellt wird und die Schaltfl&auml;che durch die Kombination aus <b>Alt<\/b>-Schaltfl&auml;che und unterstrichenem Buchstaben &uuml;ber die Tastatur angesteuert werden kann.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic001_opt.jpeg\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Das Grundger&uuml;st des Excel-Import-Assistenten<\/span><\/b><\/p>\n<p>Desweiteren enth&auml;lt das Formular ein Unterformular-Steuerelement namens <b>sfmExcelImportWizard<\/b>, das die eigentlichen Elemente der Benutzeroberfl&auml;che des Assistenten liefert.<\/p>\n<p>Die Gr&ouml;&szlig;e des Hauptformulars und vor allem des Unterformularsteuerelements werden wir sicher in den folgenden Schritten noch anpassen m&uuml;ssen, weil etwa das Formular zur Auswahl des Bereichs der zu importierenden Excel-Datei etwas mehr Platz in Anspruch nehmen wird.<\/p>\n<p>Stellen Sie f&uuml;r alle Formulare und Unterformulare die Eigenschaften <b>Datensatzmarkierer<\/b>, <b>Navigationsschaltfl&auml;chen<\/b>, <b>Trennlinien <\/b>und <b>Bildlaufleisten <\/b>grunds&auml;tzlich auf <b>Nein <\/b>ein. Au&szlig;erdem soll die Eigenschaft <b>Rahmenart <\/b>des Unterformulars den Wert <b>Transparent <\/b>erhalten.<\/p>\n<p><b>Schritt 1: Ausw&auml;hlen der Quelldatei<\/b><\/p>\n<p>Egal, ob der Import in eine vorhandene oder eine neue Tabelle erfolgen soll, muss der Benutzer zun&auml;chst die Excel-Datei und dort das Tabellenblatt ausw&auml;hlen, aus dem die Daten f&uuml;r den Import stammen. Dateipfad und -name sollen in einem Textfeld namens <b>txtExcelDatei <\/b>landen, allerdings nicht durch eine manuelle Eingabe des Benutzers. Vielmehr soll dieser auf eine Schaltfl&auml;che rechts neben dem Textfeld mit dem Dateinamen klicken, um einen <b>Datei &ouml;ffnen<\/b>-Dialog anzuzeigen und damit die Quelldatei auszuw&auml;hlen.<\/p>\n<p>Nach Auswahl der Datei zeigt das darunter befindliche Kombinationsfeld <b>cboTabellenblaetter <\/b>alle in der ausgew&auml;hlten Excel-Datei enthaltenen Tabellenbl&auml;tter an. Das Unterformular f&uuml;r diesen ersten Schritt des Assistenten hei&szlig;t <b>sfmDateiUndBlatt <\/b>und sieht bislang wie in Bild 2 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic002_opt.jpeg\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Ausw&auml;hlen der Quelldatei und des Tabellenblatts<\/span><\/b><\/p>\n<p>Die Schaltfl&auml;che zum Ausw&auml;hlen der Excel-Datei hei&szlig;t <b>cmdDateiAuswaehlen <\/b>und ihre Ereigniseigenschaft <b>Beim Klicken <\/b>l&ouml;st die Ereignisprozedur aus Listing 1 aus. Diese ruft die bereits oft in Beitr&auml;gen von <b>Access im Unternehmen <\/b>verwendete Funktion zum Anzeigen eines <b>Datei &ouml;ffnen<\/b>-Dialogs auf (s. Beispieldatenbank, Modul <b>mdlTools<\/b>, Funktion <b>OpenFileName<\/b>) und schreibt das Ergebnis in das Textfeld <b>txtExcelDatei<\/b>.<\/p>\n<p class=\"kastentabelleheader\">Listing 1: Ausw&auml;hlen der Quelldatei und F&uuml;llen und &Ouml;ffnen des Kombinationsfelds zur Auswahl des Tabellenblatts<\/p>\n<pre>Private Sub cmdDateiAuswaehlen_Click()\r\n    Me!txtExcel-Datei = OpenFileName(CurrentProject.Path,\r\n    \"Excel-Datei ausw&auml;hlen&euro;, \"Excel 2002-2003 (*.xls)|\r\n    Excel 2007 (*.xlsx)|Alle Dateien (*.*)&euro;)\r\n    If Len(Me!txtExcel-Date) &gt; 0 Then\r\n        If Len(Dir(Me!txtExcel-Date)) &gt; 0 Then\r\n            With Me!cboTabellenblaetter\r\n            .RowSourceType = \"Value List&euro;\r\n            .RowSource = _\r\n            TabellennamenEinlesen(Me!txtExcel-Date)\r\n            .SetFocus\r\n            .Dropdown\r\n            End With\r\n        End If\r\n    End If\r\n    End Sub<\/pre>\n<p>Anschlie&szlig;end geschehen noch weitere Aktionen: Zun&auml;chst ruft die Prozedur eine Funktion namens <b>TabellennamenEinlesen <\/b>auf und schreibt das Ergebnis, das etwa in der Form <b>Tabelle1;Tabelle2;Tabelle3; <\/b>kommt, in die Eigenschaft <b>RowSource <\/b>des Kombinationsfelds, dessen Herkunftstyp zuvor &uuml;ber die Eigenschaft <b>RowSourceType <\/b>auf <b>Wertliste <\/b>eingestellt wurde. <\/p>\n<p>Die vorletzte Anweisung setzt den Fokus auf das Kombinationsfeld, was lediglich eine Voraussetzung f&uuml;r den letzten Befehl ist &#8211; und dieser klappt das Kombinationsfeld mit der <b>DropDown<\/b>-Methode auf. So kann der Benutzer gleich mit einem Mausklick das Quelltabellenblatt festlegen.<\/p>\n<p>Die Funktion <b>TabellennamenEinlesen <\/b>erwartet den Dateinamen der Excel-Datei als Parameter und liefert die oben beschriebene, durch Semikola getrennte Auflistung zur&uuml;ck. Den Quelltext dieser Funktion finden Sie in Listing 2. Die Funktion greift ohne Umschweife auf ein Objekt namens <b>objWorkbook<\/b> zu, obwohl dieses zuvor noch gar nicht deklariert oder instanziert und auch nicht per Parameter &uuml;bergeben wurde.<\/p>\n<p class=\"kastentabelleheader\">Listing 2: Diese Funktion liefert eine Liste der in der angegebenen Excel-Datei enthaltenen Tabellenbl&auml;tter zur&uuml;ck.<\/p>\n<pre>        Public Function TabellennamenEinlesen(strExcel-Datei As\r\n            String) As String\r\n            Dim objWorksheet As Excel.Worksheet\r\n            Dim strTabellen As String\r\n            For Each objWorksheet In objWorkbook(strExcel-Date).\r\n                Worksheets\r\n                strTabellen = strTabellen &amp; objWorksheet.Name &amp; \";&euro;\r\n            Next objWorksheet\r\n            TabellennamenEinlesen = strTabellen\r\n        End Function<\/pre>\n<p>Da wir im Rahmen des Assistenten m&ouml;glichst nur eine Excel-Instanz erstellen und auch die Quelldatei f&uuml;r den Import nur einmal &ouml;ffnen m&ouml;chten, verwenden wir einige globale Funktionen, welche die ben&ouml;tigten Objekte bei Bedarf erstmalig erzeugen und diese anschlie&szlig;end jederzeit bereitstellen.<\/p>\n<p>All diese finden Sie wie auch die Funktion <b>TabellennamenEinlesen<\/b> im Modul <b>mdlExcel<\/b>. Dort sind auch zwei Objektvariablen f&uuml;r die Excel-Instanz und f&uuml;r das Workbook deklariert:<\/p>\n<pre>Private m_Excel As Excel.Application\r\nPrivate m_Workbook As Excel.Workbook<\/pre>\n<p>F&uuml;r den einfachen Zugriff auf das Objektmodell von Excel ben&ouml;tigen wir zun&auml;chst einen Verweis auf die entsprechende Objektbibliothek (siehe Bild 3).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic010_opt.jpeg\" alt=\"pic010.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Festlegen eines Verweises auf die Excel-Objektbibliothek<\/span><\/b><\/p>\n<p>Die Deklaration der Variablen <b>m_Excel <\/b>und <b>m_Workbook<\/b> erfolgt privat, weil der Zugriff nur &uuml;ber entsprechende Funktionen m&ouml;glich sein soll, die gleichzeitig pr&uuml;fen, ob bereits Instanzen von Excel und der Importdatei bestehen. Die Excel-Instanz liefert die folgende Funktion:<\/p>\n<pre>Public Property Get objExcel() _\r\nAs Excel.Application\r\nIf m_Excel Is Nothing Then\r\n Set m_Excel = New Excel.Application\r\nEnd If\r\nSet objExcel = m_Excel\r\nEnd Property<\/pre>\n<p>Sie pr&uuml;ft zun&auml;chst, ob die private Variable <b>m_Excel <\/b>bereits einmal mit einer Excel-Instanz gef&uuml;llt wurde und holt dies gegebenenfalls nach. Die vorhandene oder neu erstellte Instanz wird dann als Funktionswert zur&uuml;ckgegeben.<\/p>\n<p>&auml;hnlich arbeitet die Funktion <b>objWorkbook<\/b>. Sie f&uuml;llt die zust&auml;ndige Variable <b>m_Workbook <\/b>jedoch in zwei F&auml;llen neu &#8211; erstens, wenn diese noch komplett leer ist, und zweitens, wenn diese eine andere Datei als die im Parameter angegebene enth&auml;lt (s. Listing 3).<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Die Funktion objWorkbook pr&uuml;ft, ob schon ein Workbook ge&ouml;ffnet ist. Falls nein oder falls dieses nicht das richtige ist, &ouml;ffnet sie die gew&uuml;nschte Datei und liefert einen Verweis darauf zur&uuml;ck.<\/p>\n<pre>Public Function objWorkbook(strExcel-Datei As String) As Excel.Workbook\r\n    If m_Workbook Is Nothing Then\r\n        Set m_Workbook = objExcel.Workbooks.Open(strExcel-Date)\r\n    Else\r\n        If Not m_Workbook.Path &amp; \"\\&euro; &amp; m_Workbook.Name = strExcel-Datei Then\r\n            Set m_Workbook = objExcel.Workbooks.Open(strExcel-Date)\r\n        End If\r\n    End If\r\n    Set objWorkbook = m_Workbook\r\nEnd Function<\/pre>\n<p>Auf diese Weise haben wir gleich mehrere Dinge erledigt: Wir haben eine Excel-Instanz erzeugt und den Verweis darauf gespeichert, und au&szlig;erdem das Gleiche mit einer potenziellen Importdatei erledigt. Wann immer wir sp&auml;ter auf diese beiden Objekte zugreifen wollen &#8211; sie sind stets parat.<\/p>\n<p>Nun geht es an die n&auml;chste Aufgabe: Das Anzeigen der Tabellenbl&auml;tter der ausgew&auml;hlten Excel-Datei.<\/p>\n<p>Hierzu m&uuml;ssen Sie wissen, dass es etwas unbequem ist, mit einer in ein Formular eingebundenen Excel-Instanz umzugehen.<\/p>\n<p>Beim Laden eines Dokuments flackert es ordentlich und auch danach wirkt das Excel-Dokument nicht wirklich integriert.<\/p>\n<p>Eine Alternative ist das Spreadsheet-Steuerelement der Office Web Components, die mit Office bis zur Version 2003 ausgeliefert wurden, f&uuml;r sp&auml;tere Versionen jedoch ebenfalls zus&auml;tzlich heruntergeladen werden k&ouml;nnen (schlagen Sie zu &#8211; wer wei&szlig;, wie lange noch!).<\/p>\n<p>Wir widmen diesem Steuerelement einen eigenen, kleinen Beitrag namens <b>Tabellen wie unter Excel <\/b>(Shortlink 694), in dem Sie weitere Informationen finden.<\/p>\n<p>Falls die Komponente nicht auf Ihrem Rechner installiert ist, k&ouml;nnen Sie diese unter <b>http:\/\/www.microsoft.com\/downloads\/details.aspxFamilyId=7287252C-402E-4F72-97A5-E0FD290D4B76&amp;displaylang=en<\/b> herunterladen (hier in der Version f&uuml;r Office 2003).<\/p>\n<p>Die Komponente f&uuml;gen Sie nun &uuml;ber den Dialog zum Einf&uuml;gen von ActiveX-Steuerelementen in das Formular <b>sfmDateiUndBlatt <\/b>ein, sodass dieses wie in Bild 4 aussieht. Weisen Sie der Komponente den Namen <b>ctlSpreadsheet <\/b>zu.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic003_opt.jpeg\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Das Spreadsheet-Steuerelement im Unterformular f&uuml;r den ersten Schritt des Assistenten<\/span><\/b><\/p>\n<p>F&uuml;gen Sie dann dem Formular <b>sfmDateiUndBlatt <\/b>eine Ereignisprozedur f&uuml;r das Ereignis <b>Beim Laden <\/b>hinzu, die wie folgt aussieht:<\/p>\n<pre>Private Sub Form_Load()\r\n    Set objSpreadsheet = _\r\n    Me!ctlSpreadsheet.Object\r\n    End Sub<\/pre>\n<p>Die hier verwendete Objektvariable <b>objSpreadsheet<\/b> deklarieren Sie im Kopf des gleichen Moduls:<\/p>\n<pre>Dim objSpreadsheet As OWC11.Spreadsheet<\/pre>\n<p>Und jetzt kommt&euro;\u00cb&#156;s: Das Unterformular soll nun nach der Auswahl einer Excel-Datei und des gew&uuml;nschten Tabellenblatts den Inhalt genau dieses Tabellenblatts im Spreadsheet-Steuerelement anzeigen.<\/p>\n<p>Dies geschieht genau nach der Auswahl eines Eintrags im Kombinationsfeld, wodurch das Ereignis <b>Nach Aktualisierung <\/b>dieses Steuerelements ausgel&ouml;st wird.<\/p>\n<p>Die passende Ereignisprozedur finden Sie in Listing 4. Sie pr&uuml;ft zun&auml;chst, ob das Kombinationsfeld &uuml;berhaupt einen Wert enth&auml;lt. Falls ja, f&uuml;llt sie das Objekt <b>objWorksheet <\/b>mit einem Verweis auf das angegebene Tabellenblatt der Importdatei. Dazu referenziert sie wiederum die weiter oben beschriebene Funktion <b>objWorkbook <\/b>mit dem angegebenen Dateinamen als Parameter und verwendet die Auflistung <b>Worksheets<\/b>, um an das gew&uuml;nschte Tabellenblatt heranzukommen. Sie sehen hier bereits einen der Vorteile der Funktion <b>objWorkbook<\/b>: Sie brauchen (und sollen) das Ergebnis nicht erst einer Variablen zuzuweisen, sondern greifen gleich &uuml;ber die Punkt-Syntax auf die Eigenschaften und Methoden des zur&uuml;ckgelieferten Objekts zu.<\/p>\n<p class=\"kastentabelleheader\">Listing 4: F&uuml;llen des Spreadsheet-Steuerelements mit dem ausgew&auml;hlten Tabellenblatt<\/p>\n<pre>Private Sub cboTabellenblaetter_AfterUpdate()\r\n    Dim objWorksheet As Excel.Worksheet\r\n    If Not IsNull(Me!cboTabellenblaetter) Then\r\n        Set objWorksheet = _\r\n        objWorkbook(Me!txtExcel-Date). _\r\n        Worksheets(CStr(Me!cboTabellenblaetter))\r\n        objWorksheet.Cells.Copy\r\n        objSpreadsheet.Cells.Paste\r\n    End If\r\n    End Sub<\/pre>\n<p>Ist das Tabellenblatt erst einmal in Form der Objektvariablen <b>objWorksheet <\/b>referenziert, geht der Rest ganz schnell: Wir kopieren den kompletten Inhalt, den wir mit der <b>Cells<\/b>-Eigenschaft erfassen, mit der <b>Copy<\/b>-Methode und schreiben alles mit der <b>Paste<\/b>-Methode in unser Spreadsheet-Steuerelement. Das Ergebnis kann sich sehen lassen: Die Kopie des Excel-Tabellenblatts wird im Formular des Assistenten angezeigt und Sie k&ouml;nnen mit der Maus Bereiche markieren, ohne dass es wie bei einer per OLE eingeblendeten Excel-Instanz flackert (siehe Bild 5).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic004_opt.jpeg\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Der erste Schritt des Assistenten ist vollendet.<\/span><\/b><\/p>\n<p><b>Schritt f&uuml;r Schritt<\/b><\/p>\n<p>Nach diesem Schritt widmen wir uns ein wenig dem Ablauf des Assistenten und seiner Steuerung. Im aktuellen Zustand sind beispielsweise alle Schaltfl&auml;chen beim Anzeigen des ersten Schritts aktiviert, was zumindest f&uuml;r die <b>Zur&uuml;ck<\/b>-Schaltfl&auml;che keinen Sinn macht, aber auch nicht f&uuml;r die <b>Fertigstellen<\/b>-Schaltfl&auml;che.<\/p>\n<p>Betrachten wir zun&auml;chst, wie viele und welche Schritte wir &uuml;berhaupt ben&ouml;tigen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Schritt 1: Ausw&auml;hlen der Datei und des Tabellenblatts (bereits erledigt)<\/li>\n<li class=\"aufz-hlung\">Schritt 2: Ausw&auml;hlen des zu importierenden Bereichs aus diesem Tabellenblatt<\/li>\n<li class=\"aufz-hlung\">Schritt 3: Festlegen, ob der Bereich in eine neue oder eine bestehende Tabelle importiert werden soll<\/li>\n<li class=\"aufz-hlung\">Schritt 4a: Falls in Schritt 3 der Import in eine neue Tabelle ausgew&auml;hlt wurde, werden hier die Felder der Tabelle definiert.<\/li>\n<li class=\"aufz-hlung\">Schritt 4b: Falls in Schritt 3 der Import in eine bestehende Tabelle ausgew&auml;hlt wurde, werden hier die zu importierenden Spalten den Feldern zugewiesen.<\/li>\n<li class=\"aufz-hlung\">Schritt 5: Festlegen, ob ein Prim&auml;rschl&uuml;sselfeld verwendet werden soll und welches dies ist beziehungsweise ob ein neues Prim&auml;rschl&uuml;sselfeld angelegt werden soll. Dies ist gleichzeitig der letzte Schritt.<\/li>\n<\/ul>\n<p><!--30percent--><\/p>\n<p>F&uuml;r die so definierten Schritte brauchen wir zun&auml;chst einige Unterformulare, die Sie gleich in Form von Kopien des ersten Unterformulars <b>sfmDateiUndBlatt <\/b>erstellen k&ouml;nnen &#8211; wir sparen uns so das wiederholte Hinzuf&uuml;gen des Spreadsheet-Steuerelements, das wir noch in weiteren Unterformularen ben&ouml;tigen. Die neuen Unterformulare sollen die folgenden Bezeichnungen erhalten:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>sfmBereichAuswaehlen<\/b><\/li>\n<li class=\"aufz-hlung\"><b>sfmZieltabelleFestlegen<\/b><\/li>\n<li class=\"aufz-hlung\"><b>sfmFelderDefinieren<\/b><\/li>\n<li class=\"aufz-hlung\"><b>sfmFelderZuweisen<\/b><\/li>\n<li class=\"aufz-hlung\"><b>sfmFertigstellen<\/b><\/li>\n<\/ul>\n<p>Danach wenden wir uns wieder dem Hauptformular zu, mit dessen Schaltfl&auml;chen der Benutzer schlie&szlig;lich die Anzeige der jeweiligen Unterformulare steuern soll. Zun&auml;chst deklarieren wir im Klassenformular des Formulars (<b>Form_frmExcelImportWizard<\/b>) eine Variable, welche die Nummer des aktuellen Schritts speichert:<\/p>\n<pre>Dim intStep As Integer<\/pre>\n<p>Danach f&uuml;llen wir die vier Schaltfl&auml;chen mit Leben. Am einfachsten ist dies bei der Schaltfl&auml;che <b>cmdAbbrechen<\/b>, die einfach nur das Formular schlie&szlig;t:<\/p>\n<pre>Private Sub cmdAbbrechen_Click()\r\n    Call Restarbeiten\r\n    DoCmd.Close acForm, Me.Name\r\n    End Sub<\/pre>\n<p>Die Prozedur <b>Restarbeiten<\/b> l&ouml;scht die Zwischenablage, leert Objektvariablen und beendet die verwendete Excel-Instanz, damit diese nicht unsichtbar in den Untiefen des Task Managers umherirrt und unn&ouml;tig Ressourcen belegt:<\/p>\n<pre>Public Function Restarbeiten()\r\n    ZwischenablageLeeren\r\n    Set m_Workbook = Nothing\r\n    If Not m_Excel Is Nothing Then\r\n        m_Excel.Quit\r\n        Set m_Excel = Nothing\r\n    End If\r\nEnd Function<\/pre>\n<p>Die beiden Schaltfl&auml;chen mit den Beschriftungen <b>Weiter <\/b>und <b>Zur&uuml;ck<\/b>, die Sie von jedem Assistenten kennen, enthalten nur minimal viel Code, n&auml;mlich jeweils zwei Anweisungen. Die <b>Weiter<\/b>-Schaltfl&auml;che erh&ouml;ht <b>intStep <\/b>um eins und ruft dann die Funktion <b>DoStep <\/b>auf:<\/p>\n<pre>Private Sub cmdWeiter_Click()\r\n    intStep = intStep + 1\r\n    DoStep\r\n        End Sub<\/pre>\n<p>Was die <b>Zur&uuml;ck<\/b>-Schaltfl&auml;che erledigt, k&ouml;nnen Sie sich vermutlich schon denken:<\/p>\n<pre>    Private Sub cmdZurueck_Click()\r\n        intStep = intStep - 1\r\n        DoStep\r\n            End Sub<\/pre>\n<p>Die Hauptfunktion bez&uuml;glich der Steuerung des Assistenten befindet sich in der Prozedur <b>DoStep<\/b> (s. Listing 5). Diese wird ja, wie oben gesehen, nach jedem Klick auf eine der beiden Schaltfl&auml;chen <b>cmdZurueck <\/b>und <b>cmdWeiter <\/b>je einmal aufgerufen, wobei sich jeweils der Wert von <b>intStep <\/b>&auml;ndert und somit ein anderer Zweig der in <b>DoStep <\/b>enthaltenen <b>Select Case<\/b>-Anweisung ausgef&uuml;hrt wird.<\/p>\n<p class=\"kastentabelleheader\">Listing 5: Diese Prozedur steuert den Ablauf des Assistenten und l&auml;dt die Unterformulare f&uuml;r die einzelnen Schritte.<\/p>\n<pre>Private Sub DoStep()\r\n    Select Case intStep\r\n    Case 1 &euro;\u00cb&#156;Datei und Tabelle festlegen\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmDateiUndBlatt&euro;\r\n    Me!cmdAbbrechen.Enabled = True\r\n    Me!cmdWeiter.SetFocus\r\n    Me!cmdZurueck.Enabled = False\r\n    Me!cmdWeiter.Enabled = True\r\n    Me!cmdFertigstellen.Enabled = False\r\n    Case 2 &euro;\u00cb&#156;Bereich ausw&auml;hlen\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmBereichAuswaehlen&euro;\r\n    Me!cmdAbbrechen.Enabled = True\r\n    Me!cmdZurueck.Enabled = True\r\n    Me!cmdWeiter.Enabled = True\r\n    Me!cmdFertigstellen.Enabled = False\r\n    Case 3 &euro;\u00cb&#156;Zieltabelle festlegen\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmZieltabelleFestlegen&euro;\r\n    Me!cmdAbbrechen.Enabled = True\r\n    Me!cmdZurueck.Enabled = True\r\n    Me!cmdWeiter.Enabled = True\r\n    Me!cmdFertigstellen.Enabled = False\r\n    Case 4 &euro;\u00cb&#156;Felder zuweisen (bei bestehender Tabelle) oder Felder definieren (bei neuer Tabelle)\r\n    Select Case bolNeueTabelle\r\n    Case True\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmFelderDefinieren&euro;\r\n    Case False\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmFelderZuweisen&euro;\r\n    End Select\r\n    Me!cmdAbbrechen.Enabled = True\r\n    Me!cmdZurueck.Enabled = True\r\n    Me!cmdWeiter.Enabled = True\r\n    Me!cmdFertigstellen.Enabled = False\r\n    Case 5 &euro;\u00cb&#156;Prim&auml;rschl&uuml;ssel festlegen, Importieren\/Fertigstellen\r\n    Me!sfmExcelImportWizard.SourceObject = \"sfmFertigstellen&euro;\r\n    Me!cmdAbbrechen.Enabled = True\r\n    Me!cmdZurueck.Enabled = True\r\n    Me!cmdFertigstellen.Enabled = True\r\n    Me!cmdFertigstellen.SetFocus\r\n    Me!cmdWeiter.Enabled = False\r\n    End Select\r\n    End Sub<\/pre>\n<p>Innerhalb der <b>Select Case<\/b>-Zweige legt die Prozedur jeweils das Unterformular f&uuml;r den aktuellen Schritt fest und l&auml;dt dieses in das Hauptformular. Au&szlig;erdem aktiviert beziehungsweise deaktiviert sie die vier Schaltfl&auml;chen des Hauptformulars in Abh&auml;ngigkeit von <b>intStep<\/b>.<\/p>\n<p>Eine Besonderheit gibt es bei Schritt 4: Hier wird noch der Wert der Variablen <b>bolNeueTabelle <\/b>gepr&uuml;ft, die im Unterformular von Schritt 3 gef&uuml;llt wird. Abh&auml;ngig vom Wert wird entweder das Unterformular zum Anlegen einer neuen Tabelle oder das zum F&uuml;llen einer bestehenden Tabelle angezeigt.<\/p>\n<p><b>Bereich ausw&auml;hlen<\/b><\/p>\n<p>Das Unterformular zum Ausw&auml;hlen eines Bereichs sieht wie in Bild 6 aus. Es enth&auml;lt ein Kontrollk&auml;stchen namens <b>chkSpaltenueberschriften<\/b>, mit dem der Benutzer angeben kann, ob der ausgew&auml;hlte Bereich Spalten&uuml;berschriften enth&auml;lt oder nicht.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic005_opt.jpeg\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Das Unterformular zum Definieren des zu importierenden Bereichs in der Entwurfsansicht<\/span><\/b><\/p>\n<p>Hier stellt sich eine erste Design-Frage: Wir haben ja bereits im ersten Unterformular des Assistenten ein Spreadsheet-Steuerelement eingebaut. Ein solches befindet sich nun auch im zweiten Unterformular. Im ersten Formular soll das Spreadsheet-Steuerelement nur die Daten im ausgew&auml;hlten Tabellenblatt anzeigen, damit der Benutzer sichergehen kann, dass er die richtigen Daten importiert. Im zweiten Schritt des Assistenten soll er im Spreadsheet-Steuerelement den Bereich des Tabellenblatts festlegen, der importiert werden soll. Nun m&uuml;ssen wir irgendwie daf&uuml;r sorgen, dass das <b>Spreadsheet<\/b>-Steuerelements des Unterformulars im zweiten Schritt mit dem Inhalt des Spreadsheet-Steuerelements des ersten Unterformulars gef&uuml;llt wird. Wir k&ouml;nnten dies erledigen, indem wir die Daten aus dem ersten Unterformular kopieren und im zweiten Unterformular einf&uuml;gen, aber das dauert fast genauso lange wie das F&uuml;llen des Spreadsheets im ersten Unterformular &#8211; bei gr&ouml;&szlig;eren Datenmengen also durchaus mehrere Sekunden.<\/p>\n<p>Die Alternative w&auml;re, doch nicht mit verschiedenen Unterformularen zu arbeiten, sondern die Steuerelemente je nach aktuellem Schritt ein- und auszublenden. Dazu ist jedoch anzumerken, dass bei vielen Steuerelementen ein ziemliches Durcheinander im Entwurfsmodus herrscht.<\/p>\n<p>Vielleicht funktioniert eine Mischl&ouml;sung &#8211; eine, bei der zwar alle &uuml;brigen Steuerelemente in separaten Unterformularen stecken, aber nicht das Spreadsheet-Steuerelement Wir m&uuml;ssen dann nur sicherstellen, dass das Spreadsheet-Steuerelement in der Z-Reihenfolge &uuml;ber dem Unterformular liegt und zu den richtigen Zeitpunkten ein- und ausgeblendet wird.<\/p>\n<p>Schneiden wir also das Steuerelement <b>ctlSpreadsheet <\/b>aus dem Unterformular <b>sfmDateiUndTabelle <\/b>aus und f&uuml;gen diese im Hauptformular <b>frmExcelImportWizard <\/b>ein. M&ouml;glicherweise verschwindet das Steuerelement gleich hinter dem Unterformularsteuerelement <b>sfmExcelImportWizard<\/b>, was Sie leicht beheben k&ouml;nnen: Dazu markieren Sie einfach das Unterformularsteuerelement und w&auml;hlen aus seinem Kontextmen&uuml; den Eintrag <b>Position|In den Vordergrund <\/b>aus (siehe Bild 7).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic006_opt.jpeg\" alt=\"pic006.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Anpassen der Z-Reihenfolge der Steuerelemente<\/span><\/b><\/p>\n<p>Dies macht sich interessanterweise nicht bemerkbar: In der Entwurfsansicht wird das Unterformular nach wie vor &uuml;ber dem Spreadsheet-Steuerelement angezeigt. Dies &auml;ndert sich jedoch, wenn Sie zur Formularansicht wechseln: Dort schiebt sich das ActiveX-Steuerelement nach vorn und &uuml;berdeckt das Unterformular-Steuerelement wie geplant.<\/p>\n<p>Gehen wir also zu dieser Strategie &uuml;ber: Das Spreadsheet-Steuerelement wird ins Hauptformular verschoben, aber &uuml;ber das von Schritt zu Schritt wechselnde Unterformular gelegt und gegebenenfalls ausgeblendet &#8211; so sparen wir das Kopieren beziehungsweise erneute Einlesen des Tabellenblatts zwischen den einzelnen Schritten. <\/p>\n<p>Kommen wir nun endlich zum Ausw&auml;hlen des Bereichs: Hier muss der Benutzer t&auml;tig werden und mit der Maus oder auch der Tastatur die Zellen markieren, deren Inhalt importiert werden soll. Au&szlig;erdem soll er angeben, ob dieser Bereich Spalten&uuml;berschriften enth&auml;lt oder nicht. Mit einem Klick auf die Schaltfl&auml;che <b>Weiter<\/b> ist dieser Schritt f&uuml;r den Benutzer erledigt &#8211; f&uuml;r uns aber noch nicht. Wir m&uuml;ssen erst noch die Angaben des Benutzers speichern, was wir mithilfe entsprechender Variablen im Hauptformular erledigen. Dazu brauchen wir f&uuml;nf Variablen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>lngX1<\/b>: x-Koordinate des linken, oberen Feldes<\/li>\n<li class=\"aufz-hlung\"><b>lngX2<\/b>: x-Koordinate des rechten, unteren Feldes<\/li>\n<li class=\"aufz-hlung\"><b>lngY1<\/b>: y-Koordinate des linken, oberen Feldes<\/li>\n<li class=\"aufz-hlung\"><b>lngY2<\/b>: y-Koordinate des rechten, unteren Feldes<\/li>\n<li class=\"aufz-hlung\"><b>bolSpaltenueberschriften<\/b>: Inhalt des Kontrollk&auml;stchens zur Angabe, ob der ausgew&auml;hlte Bereich Spalten&uuml;berschriften enth&auml;lt<\/li>\n<\/ul>\n<p>Die Variablen werden im Klassenmodul <b>Form_frmExcelImportWizard <\/b>wie folgt deklariert:<\/p>\n<pre>        Dim lngX1 As Long\r\n        Dim lngY1 As Long\r\n        Dim lngX2 As Long\r\n        Dim lngY2 As Long\r\n        Dim bolSpaltenueberschriften As Boolean<\/pre>\n<p>Gef&uuml;llt werden diese erst, wenn der Benutzer die <b>Weiter<\/b>-Schaltfl&auml;che des zweiten Schritts verwendet, um zum dritten Schritt zu wechseln. Dies schl&auml;gt sich im <b>Case<\/b>-Zweig f&uuml;r diesen Schritt in der bereits weiter oben vorgestellten Prozedur <b>DoStep <\/b>nieder:<\/p>\n<pre>        Case 3 &euro;\u00cb&#156;Zieltabelle festlegen\r\n        If intPreviousStep = 2 Then\r\n            With Me!ctlSpreadsheet.Object.Selection\r\n            lngX1 = .Column\r\n            lngX2 = .Column + .Columns.Count - 1\r\n            lngY1 = .Row\r\n            lngY2 = .Row + .Rows.Count - 1\r\n            End With\r\n            bolSpaltenueberschriften = _\r\n            Me!sfmExcelImportWizard. _\r\n            Form!ctlSpaltenueberschriften\r\n        End If\r\n        &euro;\u00cb&#156;...<\/pre>\n<p>Wir wollen die Koordinaten des gew&auml;hlten Bereichs als absolute, numerische Werte speichern. Dabei helfen die Eigenschaften <b>Column <\/b>und <b>Row<\/b>, welche die Koordinaten des linken, oberen Feldes des Bereichs liefern. Die Koordinate des rechten Rands erhalten wir &uuml;ber die Koordinate des linken Rands plus der Anzahl der in der Auswahl enthaltenen Spalten (<b>Columns.Count<\/b>) minus eins, die Koordinate des unteren Rands ermitteln wir analog.<\/p>\n<p><b>Zieltabelle angeben<\/b><\/p>\n<p>Als Zieltabelle soll der Benutzer entweder eine vorhandene Tabelle angeben k&ouml;nnen oder die Daten werden in eine neue Tabelle importiert &#8211; dann erwartet der Assistent die Eingabe des gew&uuml;nschten Tabellennamens. Das hier anzuzeigende Unterformular namens <b>sfmZieltabelleFestlegen <\/b>aus und besitzt folgende Steuerelemente (siehe Bild 8):<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic007_opt.jpeg\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 8: Mit diesem Unterformular gibt der Benutzer die Zieltabelle f&uuml;r den Import an.<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ogrZieltabelle<\/b>: Optionsgruppe mit zwei Optionen, welche die Optionswerte <b>1 <\/b>und <b>2 <\/b>besitzen<\/li>\n<li class=\"aufz-hlung\"><b>cboZieltabelle<\/b>: Kombinationsfeld zur Auswahl einer der bestehenden Tabellen<\/li>\n<li class=\"aufz-hlung\"><b>txtZieltabelle<\/b>: Textfeld zur Angabe des Namens einer neuen Tabelle<\/li>\n<\/ul>\n<p>Das Kombinationsfeld <b>cboZieltabelle<\/b> bezieht seine Daten aus der Systemtabelle <b>MSysObjects<\/b>. Diese Tabelle enth&auml;lt beispielsweise f&uuml;r jede Tabelle einen Eintrag. Mit folgender Abfrage als Datensatzherkunft zeigt das Kombinationsfeld alle Tabellen an, die nicht das f&uuml;r Systemtabellen typische Pr&auml;fix enthalten:<\/p>\n<pre>        SELECT Name FROM MSysObjects\r\n        WHERE Name Not Like &euro;\u00cb&#156;MSYS*&euro;\"&#162; AND Type = 1;<\/pre>\n<p>Je nach der Auswahl des Benutzers soll entweder das Kombinationsfeld <b>cboZieltabelle <\/b>oder das Textfeld <b>txtZieltabelle <\/b>aktiviert werden. Dies erreichen wir durch eine Ereignisprozedur, die durch das Ereignis <b>Nach Aktualisierung <\/b>der Optionsgruppe ausgel&ouml;st wird:<\/p>\n<pre>        Private Sub ogrZieltabelle_AfterUpdate()\r\n            Select Case Me.ogrZieltabelle\r\n            Case 1\r\n            Me!cboZieltabelle.Enabled = True\r\n            Me!txtZieltabelle.Enabled = False\r\n            Case 2\r\n            Me!cboZieltabelle.Enabled = False\r\n            Me!txtZieltabelle.Enabled = True\r\n            End Select\r\n            End Sub<\/pre>\n<p>Nat&uuml;rlich m&uuml;ssen wir auch daf&uuml;r sorgen, dass die Steuerelemente beim Erreichen dieses Schritts richtig konfiguriert werden. Grob sieht das wie folgt aus und geschieht in der Ereignisprozedur, die durch das Ereignis <b>Beim Laden <\/b>des Unterformulars ausgel&ouml;st wird:<\/p>\n<pre>        Private Sub Form_Load()\r\n            Me!ogrZieltabelle = 1\r\n            Me!cboZieltabelle.Enabled = True\r\n            Me!txtZieltabelle.Enabled = False\r\n            End Sub<\/pre>\n<p><b>Import in neue\/bestehende Tabelle steuern<\/b><\/p>\n<p>Der vierte und n&auml;chste Schritt des Assistenten ist zweigeteilt: Er behandelt sowohl den Import in eine bestehende als auch in eine neue Tabelle. Beide Teilschritte laufen im Wesentlichen in eigenen Unterformularen ab. Den nachfolgend ausschnittsweise beschriebenen Abschnitt finden Sie im Klassenmodul des Formulars <b>frmExcelImportWizard <\/b>in der <b>Select Case<\/b>-Anweisung der Prozedur <b>DoStep <\/b>unter <b>Case 4<\/b>.<\/p>\n<p>Wie bei den anderen Schritten wird dieser Schritt noch vom Unterformular des vorherigen Schritts aufgerufen, hier also von den unter <b>Case 3 <\/b>zu findenden Anweisungen. Zu diesem Zeitpunkt ist noch das Unterformular <b>sfmZieltabelleFestlegen <\/b>zur Auswahl der Zieltabelle aktiviert. Daher kann zu Beginn des Abschnitts unter <b>Case 4 <\/b>noch gepr&uuml;ft werden, ob der Benutzer eine Zieltabelle angegeben hat und der Sprung zum n&auml;chsten Unterformular gegebenenfalls unterbunden werden muss:<\/p>\n<pre>        If intPreviousStep = 3 Then\r\n            With frmZieltabelleFestlegen\r\n            bolNeueTabelle = .ogrNeueTabelle\r\n            If bolNeueTabelle Then\r\n                strZieltabelle = Nz(!txtZieltabelle)\r\n            Else\r\n                strZieltabelle = Nz(!cboZieltabelle)\r\n            End If\r\n            End With\r\n            If Len(strZieltabelle) = 0 Then\r\n                MsgBox \"Geben Sie die Zieltabelle an.&euro;, _\r\n                vbOKOnly + vbExclamation, _\r\n                \"Keine Zieltabelle angegeben.&euro;\r\n                intStep = 3\r\n                Exit Sub\r\n            End If\r\n        End If<\/pre>\n<p>Anderenfalls k&ouml;nnen wir uns einem der beiden m&ouml;glichen F&auml;lle zuwenden: dem Import in eine bestehende oder in eine neue Tabelle. In beiden F&auml;llen soll das Spreadsheet-Steuerelement eingeblendet werden; anschlie&szlig;end wird das entsprechende Unterformular angezeigt:<\/p>\n<pre>        Me!ctlSpreadsheet.Visible = True\r\n        Select Case bolNeueTabelle\r\n        Case True\r\n        &euro;\u00cb&#156;Unterformular sfmFelderDefinieren laden\r\n        &euro;\u00cb&#156;und konfigurieren\r\n        &euro;\u00cb&#156;...\r\n        Case False\r\n        &euro;\u00cb&#156;Unterformular\r\n        &euro;\u00cb&#156;sfmFelderZuweisen laden\r\n        &euro;\u00cb&#156;und konfigurieren\r\n        &euro;\u00cb&#156;...\r\n        End Select<\/pre>\n<p>Die folgenden Abschnitte beschreiben diese beiden Varianten.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Import in eine neue Tabelle<\/p>\n<p>Beim Import in eine neue Tabelle m&uuml;ssen Sie nicht nur erfassen, wie die neue Tabelle hei&szlig;en soll, sondern auch noch die Zielfelder f&uuml;r die ausgew&auml;hlten Spalten definieren. Dies geschieht mit dem Unterformular <b>sfmFelderDefinieren<\/b>, das Abb. 9 in der Entwurfsansicht zeigt. Das Unterformular enth&auml;lt zwei Schaltfl&auml;chen, mit denen Sie zwischen den Spalten des Excel-Sheets wechseln k&ouml;nnen. Zur optischen Hervorhebung der aktuell bearbeiteten Spalte soll diese im Spreadsheet-Steuerelement markiert werden (siehe Bild 10).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic008_opt.jpeg\" alt=\"pic008.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 9: Das Unterformular sfmFelderDefinieren in der Entwurfsansicht<\/span><\/b><\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic009_opt.jpeg\" alt=\"pic009.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 10: Die aktuell bearbeitete Spalte wird markiert dargestellt.<\/span><\/b><\/p>\n<p>Damit dies gelingt, wird erstmal das passende Unterformular eingestellt:<\/p>\n<pre>        Me!sfmExcelImportWizard.SourceObject =\r\n        \"sfmFelderDefinieren&euro;<\/pre>\n<p>Dann wird gleich die erste Spalte des f&uuml;r den Import ausgew&auml;hlten Bereichs markiert:<\/p>\n<pre>        With objSpreadsheet\r\n        .Range(.Cells(lngY1, lngX1), .Cells(lngY2, lngX1)).Select<\/pre>\n<p>Gleich im Anschluss pr&uuml;ft die Prozedur, ob der zu importierende Bereich Spalten&uuml;berschriften enth&auml;lt. Falls ja, wird das Feld <b>txtFeldname <\/b>des Unterformulars mit dem im Spaltenkopf der ersten Spalte enthaltenen Text gef&uuml;llt:<\/p>\n<pre>        If bolSpaltenueberschriften Then\r\n            Me!sfmExcelImportWizard.Form!txtFeldname\r\n            = .Range(.Cells(lngY1, lngX1),\r\n            .Cells(lngY1, lngX1))\r\n        End If\r\n        End With<\/pre>\n<p>Danach wird eine <b>WithEvents<\/b>-Objektvariable mit einem Verweis auf das aktuelle Unterformular gef&uuml;llt und gleich danach die <b>Beim Entladen<\/b>-Ereigniseigenschaft mit dem Ausdruck <b>[Event Procedure] <\/b>gef&uuml;llt:<\/p>\n<pre>        Set frmFelderDefinieren =\r\n        Me!sfmExcelImportWizard.Form\r\n        With frmFelderDefinieren\r\n        .OnUnload = \"[Event Procedure]&euro;\r\n        End With<\/pre>\n<p>Das Gleiche geschieht mit den beiden Schaltfl&auml;chen <b>cmdNaechsteSpalte <\/b>und <b>cmdVorherigeSpalte <\/b>&#8211; hier ist allerdings die Ereigniseigenschaft <b>Beim Klicken <\/b>betroffen:<\/p>\n<pre>        Set cmdVorherigeSpalte = Nothing\r\n        Set cmdVorherigeSpalte = frmFelderDefinieren!cmdVorherigeSpalte\r\n        With cmdVorherigeSpalte\r\n        .OnClick = \"[Event Procedure]&euro;\r\n        End With\r\n        Set cmdNaechsteSpalte = frmFelderDefinieren.cmdNaechsteSpalte\r\n        With cmdNaechsteSpalte\r\n        .OnClick = \"[Event Procedure]&euro;\r\n        End With<\/pre>\n<p>Da wir uns aktuell in der ersten Spalte befinden, wird eine Variable entsprechend eingestellt:<\/p>\n<pre>        intSpalte = 1<\/pre>\n<p>Au&szlig;erdem setzen wir den Fokus auf die Schaltfl&auml;che <b>cmdNaechsteSpalte <\/b>und deaktivieren die Schaltfl&auml;che <b>cmdVorherigeSpalte<\/b>:<\/p>\n<pre>        cmdNaechsteSpalte.SetFocus\r\n        cmdVorherigeSpalte.Enabled = False<\/pre>\n<p>Es kann auch geschehen, dass der zu importierende Bereich nur eine Spalte umfasst. Dann muss nat&uuml;rlich auch die Schaltfl&auml;che <b>cmdNaechsteSpalte <\/b>deaktiviert werden. Vorher verschieben wir den Fokus auf <b>txtFeldname<\/b>, weil Steuerelemente mit Fokus nicht deaktiviert werden k&ouml;nnen:<\/p>\n<pre>        If lngY2 - lngY1 = 0 Then\r\n            frmFelderDefinieren!txtFeldname.SetFocus\r\n            cmdNaechsteSpalte.Enabled = False\r\n        End If<\/pre>\n<p>Das waren schon die Vorbereitungen. Die restlichen Aktionen dieses Formulars befinden sich in den Ereignisprozeduren, die durch das Anklicken von <b>cmdNaechsteSpalte <\/b>und <b>cmdVorherigeSpalte <\/b>sowie das Entladen des Unterformulars ausgel&ouml;st werden.<\/p>\n<p><b>Tabelle zum Speichern der Feldeigenschaften<\/b><\/p>\n<p>Die beiden Unterformulare <b>sfmFelderDefinieren <\/b>und <b>sfmFelderZuweisen <\/b>weisen gegeben&uuml;ber den &uuml;brigen Unterformularen die Besonderheit auf, dass sie an eine Tabelle als Datenherkunft gebunden sind. Der Hintergrund ist, dass diese Unterformulare zu jeder Spalte des zu importierenden Bereiche der Excel-Tabelle Informationen &uuml;ber die Zielfelder aufnehmen sollen &#8211; und die m&uuml;ssen schlie&szlig;lich irgendwo landen. Wo sollte dies unter Access sonst geschehen als in einer Tabelle Diese hei&szlig;t <b>tblZuordnungen<\/b> und sieht im Entwurf wie in Bild 11 aus. Das Feld <b>Indiziert<\/b> ist als Kombinationsfeld ausgelegt und enth&auml;lt eine Wertliste als Datensatzherkunft, welche die Werte <b>Nein<\/b>, <b>Ja (Duplikate m&ouml;glich) <\/b>und <b>Ja (Ohne Duplikate) <\/b>zur Auswahl bereitstellt.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic010_opt1.jpeg\" alt=\"pic010.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 11: Diese Tabelle speichert die Eigenschaften der Zielfelder des Imports.<\/span><\/b><\/p>\n<p>Auf diesem Hintergrund k&ouml;nnen wir uns eine der beiden Routinen ansehen, die durch die Schaltfl&auml;chen <b>cmdVorherigeSpalte <\/b>und <b>cmdNaechsteSpalte <\/b>ausgel&ouml;st werden. Diese f&uuml;hren n&auml;mlich lediglich diese Aktionen aus:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Aktivieren beziehungsweise Deaktivieren der Schaltfl&auml;chen, wenn die erste oder letzte Spalte erreicht wurde<\/li>\n<li class=\"aufz-hlung\">Markieren der jeweils aktuellen Spalte im Spreadsheet-Steuerelement<\/li>\n<li class=\"aufz-hlung\">Setzen des Filters der Datenherkunft beim Wechseln der aktuell bearbeiteten Spalte<\/li>\n<\/ul>\n<p>Stellt sich nur eine Frage: Wo wird die Tabelle <b>tblZuordnungen<\/b> &uuml;berhaupt gef&uuml;llt Wenn diese je nach Spalte gefiltert wird, muss sie ja bereits Daten enthalten.<\/p>\n<p>Das F&uuml;llen dieser Tabelle geschieht in der Ereignisprozedur <b>frmBereichFestlegen_Unload<\/b>, die beim Entladen des Unterformulars <b>frmBereichFestlegen <\/b>ausgel&ouml;st wird.<\/p>\n<p>In diesem Unterformular wird, Sie erinnern sich, der zu importierende Bereich festgelegt und auch angegeben, ob dieser Spalten&uuml;berschriften enth&auml;lt oder auch nicht. Hat der Benutzer die Auswahl getroffen, schreibt diese Routine die entsprechenden Datens&auml;tze in die Tabelle <b>tblZuordnungen<\/b>.<\/p>\n<p>Kehrt der Benutzer nach dem Zuweisen der Spalten zu den Feldern der Zieltabelle zur Auswahl des zu importierenden Bereichs zur&uuml;ck und &auml;ndert diesen, werden automatisch auch alle Datens&auml;tze der Tabelle <b>tblZuordnungen <\/b>gel&ouml;scht.<\/p>\n<p><b>Import in eine bestehende Tabelle<\/b><\/p>\n<p>Bei einer bestehenden Tabelle besteht die Aufgabe des vierten Schritts des Assistenten darin, den ausgew&auml;hlten Spalten die entsprechenden Felder der Zieltabelle zuzuweisen. Dies geschieht im Unterformular <b>sfmFelderZuweisen<\/b>, das mit folgender Anweisung in das Unterformularsteuerelement <b>sfmExcelImportWizard <\/b>geladen wird:<\/p>\n<pre>        Me!sfmExcelImportWizard.SourceObject = \"sfmFelderZuweisen&euro;<\/pre>\n<p>Die &uuml;brigen Anweisungen in diesem Teil der <b>If&#8230;Then<\/b>-Bedingung unterhalb von <b>Case 4 <\/b>stimmen prinzipiell mit denen &uuml;berein, die auch beim Aufnehmen der Daten f&uuml;r eine bestehende Tabelle verwendet werden &#8211; eine genauere Betrachtung ist daher an dieser Stelle nicht notwendig.<\/p>\n<p>Unterschiede finden sich beim Unterformular <b>sfmFelderZuweisen<\/b>, das neben den beiden Schaltfl&auml;chen zum Bl&auml;ttern zwischen den Spalten des zu importierenden Bereichs lediglich ein Kombinationsfeld zur Auswahl eines der Felder der im vorherigen Schritt ausgew&auml;hlten Datenherkunft anbietet (siehe Bild 12).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic011_opt.jpeg\" alt=\"pic011.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 12: Dieses Unterformular dient der Zuordnung der Felder der Zieltabelle zu den zu importierenden Spalten.<\/span><\/b><\/p>\n<p>Damit dies funktioniert, enth&auml;lt die Eigenschaft <b>Herkunftsart <\/b>den Eintrag <b>Feldliste <\/b>und die Eigenschaft <b>Datensatzherkunft <\/b>wird zur Laufzeit per VBA &uuml;ber die folgende Anweisung mit dem in der Variablen <b>strZieltabelle <\/b>enthaltenen Namen der Zieltabelle gef&uuml;llt:<\/p>\n<pre>        cboFeldname.RowSource = strZieltabelle<\/pre>\n<p>Hiermit sind die Vorbereitungen abgeschlossen: Wir k&ouml;nnen uns nun darum k&uuml;mmern, wie der Import-Assistent die neue Tabelle anlegt und diese oder eine bestehende auf Basis der durch den Benutzer angegebenen Parameter mit den Daten aus der Excel-Tabelle f&uuml;llt.<\/p>\n<p><b>Erzeugen einer neuen Tabelle<\/b><\/p>\n<p>Eine der gr&ouml;&szlig;eren Herausforderungen beim Erstellen dieses Assistenten ist das Formulieren der SQL-Abfrage, welche die Benutzerangaben in eine Erzeugung einer kompletten Tabelle umwandelt. Dies geschieht auf Basis der in der Tabelle <b>tblZuordnungen <\/b>gemachten Angaben.<\/p>\n<p>Zum Verst&auml;ndnis der folgenden Abschnitte ist der Beitrag <b>Datenbanken und Tabellen per SQL anpassen <\/b>(Shortlink 609) hilfreich.<\/p>\n<p>Das letzte Unterformular hei&szlig;t <b>sfmFertigstellen <\/b>und enth&auml;lt ein Steuerelement namens <b>txtPrimaerschluessel<\/b>, in das der Benutzer den Namen eines Prim&auml;rschl&uuml;sselfelds mit <b>Autowert<\/b>-Funktion eingeben soll &#8211; wenn er denn eines m&ouml;chte.<\/p>\n<p>Das Textfeld wird auch &uuml;berhaupt nur aktiviert, wenn der Benutzer noch keines der bisherigen Felder als Prim&auml;rschl&uuml;sselfeld festgelegt hat (siehe Bild 13).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_06\/ExcelImport-web-images\/pic012_opt.jpeg\" alt=\"pic012.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 13: Der letzte Schritt im Excel-Import-Assistenten<\/span><\/b><\/p>\n<p>Die eigentliche Arbeit &uuml;bernimmt die Prozedur <b>NeueTabelleErstellen <\/b>aus Listing 6. Sie liest alle vorhandenen Daten aus und erzeugt SQL-Anweisungen, welche die Tabelle und gegebenenfalls zus&auml;tzliche Indizes erstellen.<\/p>\n<p class=\"kastentabelleheader\">Listing 6: Diese Prozedur erstellt eine neue Tabelle auf Basis der durch den Benutzer eingestellten Parameter.<\/p>\n<pre>Public Sub NeueTabelleErstellen(strZieltabelle As String, strPrimaerschluessel As String)\r\n&euro;\u00cb&#156;Deklaration ...\r\nSet db = CurrentDb\r\nSet rst = db.OpenRecordset(\"SELECT * FROM tblZuordnungen&euro;, dbOpenDynaset)\r\nSet cnn = CurrentProject.Connection\r\nstrSQL = \"DROP TABLE \" &amp; strZieltabelle\r\nOn Error Resume Next\r\ncnn.Execute strSQL\r\nOn Error GoTo 0\r\nstrSQL = \"CREATE TABLE \" &amp; strZieltabelle &amp; \"(\"\r\nIf Len(strPrimaerschluessel) &gt; 0 Then\r\n strFelder = strFelder &amp; \"[\" &amp; strPrimaerschluessel &amp; \"] COUNTER CONSTRAINT [\" &amp; CreateGUID _\r\n    &amp; \"] PRIMARY KEY, \"\r\nEnd If\r\nDo While Not rst.EOF\r\n With rst\r\n    If Not rst!Auslassen Then\r\n        If rst!Primaerschluessel Then\r\n            strFelder = strFelder &amp; \"[\" &amp; !Feldname &amp; \"] \" &amp; DLookup(\"SQLText&euro;, \"tblDatentypen&euro;, _\r\n            \"DatentypID = \" &amp; !Datentyp) &amp; \"CONSTRAINT [\" &amp; CreateGUID &amp; \"] PRIMARY KEY, \"\r\n        Else\r\n            strFelder = strFelder &amp; \"[\" &amp; !Feldname &amp; \"] \" &amp; DLookup(\"SQLText&euro;, \"tblDatentypen&euro;, _\r\n            \"DatentypID = \" &amp; !Datentyp) &amp; \", \"\r\n        End If\r\n    End If\r\n    Select Case !Indiziert\r\n    Case 1, 2\r\n    intConstraints = intConstraints + 1\r\n    ReDim Preserve strIndizes(intConstraints)\r\n    If !Indiziert = 2 Then\r\n        strConstraint = \"UNIQUE \"\r\n    Else\r\n        strConstraint = \"\"\r\n    End If\r\n    strIndizes(intConstraints) = \"CREATE \" &amp; strConstraint &amp; \"INDEX [\" &amp; CreateGUID &amp; \"] ON [\" _\r\n    &amp; strZieltabelle &amp; \"]([\" &amp; !Feldname &amp; \"])&euro;\r\n    End Select\r\n    End With\r\n    rst.MoveNext\r\nLoop\r\nstrFelder = Left(strFelder, Len(strFelder) - 2)\r\nstrSQL = strSQL &amp; strFelder &amp; \")&euro;\r\ncnn.Execute strSQL\r\nOn Error Resume Next\r\nFor i = LBound(strIndizes) To UBound(strIndizes)\r\n cnn.Execute strIndizes(i)\r\nNext i\r\nApplication.RefreshDatabaseWindow\r\nOn Error GoTo 0\r\nrst.Close\r\nSet rst = Nothing\r\nSet db = Nothing\r\nEnd Sub<\/pre>\n<p>Dabei durchl&auml;uft die Routine alle Datens&auml;tze der Tabelle <b>tblZuordnungen <\/b>und stellt so die SQL-Ausdr&uuml;cke f&uuml;r die einzelnen Felder zusammen. Gleichzeitig pr&uuml;ft sie, ob eindeutige oder einfache Indizes f&uuml;r die Felder angelegt werden sollen, und f&uuml;gt gegebenenfalls je eine DDL-Anweisung pro Index zum <b>String<\/b>-Array <b>strIndizes <\/b>hinzu.<\/p>\n<p>Dabei kommen dann beispielsweise solche DDL-Anweisungen heraus, die nur noch per <b>Execute<\/b>-Methode des <b>Connection<\/b>-Objekts der aktuellen Datenbank ausgef&uuml;hrt werden:<\/p>\n<pre>        CREATE TABLE tblTaetigkeiten([TaetigkeitID] COUNTER CONSTRAINT [{5F719D56-1E79-4A46-99DF-EC3A47657085}] PRIMARY KEY, [Startzeit:] DATETIME, [Endzeit] DATETIME, [Beschreibung] TEXT(255))\r\n        CREATE INDEX [{A843FEE7-E830-47D9-A205-43C99D3119C1}] ON [tblTaetigkeiten]([Startzeit:])<\/pre>\n<p>Als Namen f&uuml;r die Indizes werden jeweils frisch erzeugte GUID-Werte verwendet, um deren Eindeutigkeit zu gew&auml;hrleisten.<\/p>\n<p><b>Daten importieren<\/b><\/p>\n<p>Mit der obigen Prozedur zum Erstellen einer neuen Tabelle entsprechend den Vorgaben des Benutzers haben wir die Voraussetzung geschaffen, dass beide Import-Varianten, sowohl der Import in eine bestehende als auch in eine neue Tabelle, gleich behandelt werden k&ouml;nnen.<\/p>\n<p>Nun brauchen wir also nur noch eine kleine Prozedur, welche die Daten aus der Excel-Tabelle importiert. Technisch betrachtet gibt es verschiedene M&ouml;glichkeiten, um den Inhalt einer Excel-Tabelle in eine Access-Tabelle zu &uuml;bertragen.<\/p>\n<ul>\n<li class=\"aufz-hlung\">Die bekannteste d&uuml;rfte die <b>DoCmd.TransferSpreadsheet<\/b>-Methode sein. Sie ist verh&auml;ltnism&auml;&szlig;ig einfach zu bedienen, weil Sie ihr alle n&ouml;tigen Informationen schlicht per Parameter &uuml;bergeben k&ouml;nnen. Alles zu dieser Methode erfahren Sie im Beitrag <b>Exceldaten importieren mit TransferSpreadsheet <\/b>(Shortlink 692).<\/li>\n<li class=\"aufz-hlung\">VBA-Spezialisten scheuen sich nat&uuml;rlich nicht, den Import per direktem Zugriff per Code zu steuern und so Zeile f&uuml;r Zeile und Spalte f&uuml;r Spalte einzulesen und in die Access-Tabelle zu schreiben. Das n&ouml;tige Handwerkzeug liefert beispielsweise der Beitrag <b>Excel automatisieren <\/b>(Shortlink 693).<\/li>\n<\/ul>\n<p>Beide Varianten fallen f&uuml;r unsere Zwecke jedoch flach. Die <b>DoCmd.TransferSpreadsheet<\/b>-Methode ist zwar die schnellere Methode, taugt aber nur f&uuml;r den Einsatz in bestimmten Konstellationen &#8211; n&auml;mlich dort, wo ein zusammenh&auml;ngender Block aus einem Excel-Tabellenblatt importiert werden soll. Wenn wir von einer Auswahl von drei Spalten die mittlere vom Import ausschlie&szlig;en m&ouml;chten, scheitert diese Variante.<\/p>\n<p>Die Methode per VBA &uuml;ber das Excel-Objektmodell kann flexibler gestaltet werden und erm&ouml;glicht auch den Import nicht zusammenh&auml;ngender Bereiche. Allerdings f&auml;llt diese Vorgehensweise geschwindigkeitsm&auml;&szlig;ig weit hinter <b>DoCmd.TransferSpreadsheet <\/b>zur&uuml;ck.<\/p>\n<p>Zum Gl&uuml;ck gibt es eine dritte, weitgehend unbekannte, aber ungleich flexiblere Methode. Mit dieser greifen Sie &uuml;ber eine <b>SELECT<\/b>-Anweisung auf die Excel-Tabelle zu &#8211; fast genau so, wie Sie es auch bei einer Access-Tabelle tun w&uuml;rden. An dieser Stelle kommt implizit der ISAM-Treiber von JET zum Einsatz. Die Methode bietet einige speziell f&uuml;r den Zugriff auf Excel-Tabellen zugeschnittene M&ouml;glichkeiten. So kann man in dieser <b>SELECT<\/b>-Anweisung den Namen der Excel-Datei und des Tabellenblatts und sogar den gew&uuml;nschten Bereich angeben. Ein Beispiel f&uuml;r eine solche Anweisung sieht so aus:<\/p>\n<pre>        INSERT INTO tblTaetigkeiten(Startzeit,\r\n        Beschreibung)\r\n        SELECT F1, F3 FROM [Tabelle1$A6:C8]\r\n        IN &euro;\u00cb&#156;C:\\beispieldatei.xls&euro;\"&#162;\r\n        [Excel 8.0;HDR=No;IMEX=1]<\/pre>\n<p>Diese Anweisung enth&auml;lt die Zieltabelle und die zu f&uuml;llenden Felder wie in einer handels&uuml;blichen <b>INSERT INTO<\/b>-Abfrage. Danach folgt unbekanntes Terrain: Die <b>SELECT<\/b>-Anweisung liest die erste und dritte Spalte (<b>F1 <\/b>und <b>F3<\/b>) des Bereichs <b>A6:C8 <\/b>des Tabellenblatts <b>Tabelle1 <\/b>aus der Datei <b>c:\\beispieldatei.xls <\/b>ein.<\/p>\n<p>Dabei werden die zum Schluss in eckigen Klammern eingefassten Optionsparameter beachtet. Der erste gibt die Excel-Version an, der zweite, ob Spalten&uuml;berschriften zu beachten sind, der dritte, dass ein Import aus dieser Datei stattfinden soll.<\/p>\n<p>Die Prozedur <b>InBestehendeTabelleImportieren <\/b>aus Listing 7 erwartet genau diese Informationen von der aufrufenden Instanz. Einzig der zu importierende Bereich wird nicht in Form einer Zeichenkette wie <b>A1:B2<\/b>, sondern durch vier absolute Zahlenwerte repr&auml;sentiert.<\/p>\n<p class=\"kastentabelleheader\">Listing 7: F&uuml;llen einer vorhandenen oder neu erstellten Tabelle aus einem Excel-Bereich<\/p>\n<pre>        Public Sub InBestehendeTabelleImportieren(strZieltabelle As String, _\r\n        bolSpaltenueberschriften As Boolean, _\r\n        strExcelsheet As String, strDateiname As String, _\r\n        lngX1 As Long, lngY1 As Long, lngX2 As Long, lngY2 As Long)\r\n        &euro;\u00cb&#156;Deklarationen ...\r\n        If bolSpaltenueberschriften Then\r\n            lngY1 = lngY1 + 1\r\n        End If\r\n        strBereich = GetExcelRangeFromLong(lngX1, lngX2, lngY1, lngY2)\r\n        Set db = CurrentDb\r\n        Set cnn = CurrentProject.Connection\r\n        Set rst = db.OpenRecordset(\"SELECT * FROM tblZuordnungen&euro;, _\r\n        dbOpenDynaset)\r\n        strSQL = \"INSERT INTO [\" &amp; strZieltabelle &amp; \"](\"\r\n        strSelect = \"SELECT \"\r\n        Do While Not rst.EOF\r\n            i = i + 1\r\n            If Not rst!Auslassen Then\r\n                strFelder = strFelder &amp; \"[\" &amp; rst!Feldname &amp; \"], \"\r\n                strSelectFelder = strSelectFelder &amp; \"F&euro; &amp; i &amp; \", \"\r\n            End If\r\n            rst.MoveNext\r\n        Loop\r\n        strFelder = Left(strFelder, Len(strFelder) - 2)\r\n        strSelectFelder = Left(strSelectFelder, Len(strSelectFelder) - 2)\r\n        strSQL = strSQL &amp; strFelder\r\n        strSQL = strSQL &amp; \")&euro;\r\n        strSelect = strSelect &amp; strSelectFelder &amp; \" FROM [\" _\r\n        &amp; strExcelsheet &amp; \"$&euro; &amp; strBereich &amp; \"] IN &euro;\u00cb&#156;\" _\r\n        &amp; strDateiname &amp; \"&euro;\u00cb&#156; [Excel 8.0;HDR=No;IMEX=1]&euro;\r\n        cnn.Execute strSQL &amp; \" \" &amp; strSelect\r\n        rst.Close\r\n        Set rst = Nothing\r\n        Set db = Nothing\r\n        End Sub<\/pre>\n<p>Die zu erstellende SQL-Anweisung enth&auml;lt an zwei Stellen Auflistungen: erstens die Liste der in der Zieltabelle zu f&uuml;llenden Felder und zweitens die entsprechenden Quellfelder der Excel-Tabelle.<\/p>\n<p>Die Option <b>HDR<\/b>, die angibt, ob der angegebene Bereich der Excel-Tabelle Spalten&uuml;berschriften enth&auml;lt, setzt die Prozedur immer auf <b>No<\/b>. Der Hintergrund ist, dass die zu importierenden Spalten dann &uuml;ber die generischen Spalten&uuml;berschriften <b>F1<\/b>, <b>F2<\/b>, &#8230; anzusprechen sind statt &uuml;ber tats&auml;chlich vorhandene Spalten&uuml;berschriften.<\/p>\n<p>Wenn der Benutzer im Assistenten festlegt, dass Spalten&uuml;berschriften verwendet werden sollen, registriert die Prozedur dies nur insofern, als dass sie den Bereich, der ja die Spalten&uuml;berschriften enth&auml;lt, um die obere Zeile k&uuml;rzt.<\/p>\n<p>Durch die generischen Spalten&uuml;berschriften k&ouml;nnen wir in der <b>Do While<\/b>-Schleife, welche alle Datens&auml;tze der Tabelle <b>tblZuordnungen <\/b>durchl&auml;uft und die Liste der zu importierenden Spalten zusammenstellt, genau die Spalten ber&uuml;cksichtigen, f&uuml;r die der Benutzer den Parameter <b>Auslassen <\/b>nicht aktiviert hat und die Spalten&uuml;berschriften gleich aus dem Buchstaben <b>F <\/b>und der Laufvariablen <b>i <\/b>zusammenstellen.<\/p>\n<p>Der Import &uuml;ber die <b>SELECT<\/b>-Methode ist im Regelfall genauso schnell wie bei der <b>TransferSpreadsheet<\/b>-Methode (bei 5.000 Zeilen mit drei Spalten etwa ein bis zwei Sekunden), aber wesentlich flexibler. Es ist gut m&ouml;glich, dass <b>TransferSpreadsheet <\/b>intern auch auf die <b>SELECT<\/b>-Methode zugreift.<\/p>\n<p>Die Methode aus Listing 7 verwendet zwei Hilfsfunktionen. Die erste hei&szlig;t <b>GetExcelRangeFromLong <\/b>und wandelt vier absolute Zahlenwerte in einen Excel-Bereich wie <b>A10:C100 <\/b>um.<\/p>\n<p>Dabei kommt auch die Funktion <b>GetExcelChar <\/b>zum Einsatz, die Spaltennummern in die entsprechenden Excel-Buchstaben umwandelt (<b>1 <\/b>entspricht <b>A<\/b>, <b>27 <\/b>entspricht <b>AA <\/b>und so weiter).<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Zusammenfassung und Ausblick<\/p>\n<p>Mit dem <b>ExcelImportWizard <\/b>haben Sie ein Werkzeug, mit dem Sie Excel-Daten komplett von Access gesteuert in eine Access-Tabelle importieren k&ouml;nnen. Dies ist auch mit dem eingebauten Assistenten m&ouml;glich, jedoch kann man mit diesem selbst nicht den zu importierenden Bereich ausw&auml;hlen, wenn dieser nicht bereits als benannter Bereich definiert wurde.<\/p>\n<p>Die hier vorgestellte L&ouml;sung nutzt das <b>Spreadsheet<\/b>-Steuerelement, um die zu importierende Excel-Tabelle komplett anzuzeigen und dem Benutzer die M&ouml;glichkeit zu geben, den gew&uuml;nschten Bereich direkt aus dem Assistenten heraus zu importieren.<\/p>\n<p>Es bleibt noch ein wenig Arbeit offen, die wir im Rahmen dieses Beitrags nicht mehr beschreiben k&ouml;nnen. Dazu geh&ouml;ren einige Validierungen, die etwa abfragen, ob eine zu erstellende Tabelle bereits existiert.<\/p>\n<p>Au&szlig;erdem muss die Datenbank noch in eine Add-In-Datenbank konvertiert werden, damit Sie den Assistenten von jeder beliebigen Datenbank aus aufrufen k&ouml;nnen. Die dazu notwendigen Schritte werden im Beitrag <b>Access-Add-Ins <\/b>(Shortlink 643) erl&auml;utert.<\/p>\n<p>Es gibt noch weitere Funktionen, die wir dem Assistenten hinzuf&uuml;gen k&ouml;nnten: Beispielsweise w&uuml;rde eine Funktion zum Speichern eines Importvorgangs wiederkehrende Importe erleichtern.<\/p>\n<p>Hierbei k&ouml;nnte auch die Ausgabe der verwendeten SQL-Ausdr&uuml;cke zum Erstellen neuer Tabellen und zum Hinzuf&uuml;gen der zu importierenden Daten Sinn machen: Diese k&ouml;nnte man dann gleich in eigenen Code integrieren, ohne dass man auf den Wizard zugreifen muss.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>ExcelImportieren.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{10D600BF-4B35-4A5C-AC62-081C1C4ED75C}\/aiu_696.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der Import-Assistent f&uuml;r Excel-Dateien hat einen entscheidenden Nachteil: Er erlaubt nicht, den zu importierenden Bereich des ausgew&auml;hlten Tabellenblatts manuell auszuw&auml;hlen. Diese Aufgabe m&uuml;ssen Sie vorher direkt in Excel erledigen, indem Sie einen sogenannten &#8222;benannten Bereich&#8220; definieren. Dieser ist dann im Import-Assistenten namentlich verf&uuml;gbar. Unser Assistent enth&auml;lt eine solche Funktion, und generell lernt man eine Menge, wenn man sich die Funktionsweise eines Excel-Imports einmal in Ruhe ansieht.<\/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":[662009,66062009,44000026,44000027],"tags":[],"class_list":["post-55000696","post","type-post","status-publish","format-standard","hentry","category-662009","category-66062009","category-Interaktiv","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Excel-Import-Assistent im Eigenbau - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Excel-Import-Assistent im Eigenbau\" \/>\n<meta property=\"og:description\" content=\"Der Import-Assistent f&uuml;r Excel-Dateien hat einen entscheidenden Nachteil: Er erlaubt nicht, den zu importierenden Bereich des ausgew&auml;hlten Tabellenblatts manuell auszuw&auml;hlen. Diese Aufgabe m&uuml;ssen Sie vorher direkt in Excel erledigen, indem Sie einen sogenannten &quot;benannten Bereich&quot; definieren. Dieser ist dann im Import-Assistenten namentlich verf&uuml;gbar. Unser Assistent enth&auml;lt eine solche Funktion, und generell lernt man eine Menge, wenn man sich die Funktionsweise eines Excel-Imports einmal in Ruhe ansieht.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:40:31+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"37\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Excel-Import-Assistent im Eigenbau\",\"datePublished\":\"2020-05-22T22:40:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/\"},\"wordCount\":6250,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/cc87fa2ea1f546688badf5aa48371a4c\",\"articleSection\":[\"2009\",\"6\\\/2009\",\"Interaktiv\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/\",\"name\":\"Excel-Import-Assistent im Eigenbau - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/cc87fa2ea1f546688badf5aa48371a4c\",\"datePublished\":\"2020-05-22T22:40:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/cc87fa2ea1f546688badf5aa48371a4c\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/cc87fa2ea1f546688badf5aa48371a4c\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/ExcelImportAssistent_im_Eigenbau\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Excel-Import-Assistent im Eigenbau\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Excel-Import-Assistent im Eigenbau - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/","og_locale":"de_DE","og_type":"article","og_title":"Excel-Import-Assistent im Eigenbau","og_description":"Der Import-Assistent f&uuml;r Excel-Dateien hat einen entscheidenden Nachteil: Er erlaubt nicht, den zu importierenden Bereich des ausgew&auml;hlten Tabellenblatts manuell auszuw&auml;hlen. Diese Aufgabe m&uuml;ssen Sie vorher direkt in Excel erledigen, indem Sie einen sogenannten \"benannten Bereich\" definieren. Dieser ist dann im Import-Assistenten namentlich verf&uuml;gbar. Unser Assistent enth&auml;lt eine solche Funktion, und generell lernt man eine Menge, wenn man sich die Funktionsweise eines Excel-Imports einmal in Ruhe ansieht.","og_url":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:40:31+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"37\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Excel-Import-Assistent im Eigenbau","datePublished":"2020-05-22T22:40:31+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/"},"wordCount":6250,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c","articleSection":["2009","6\/2009","Interaktiv","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/","url":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/","name":"Excel-Import-Assistent im Eigenbau - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c","datePublished":"2020-05-22T22:40:31+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/cc87fa2ea1f546688badf5aa48371a4c"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/ExcelImportAssistent_im_Eigenbau\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Excel-Import-Assistent im Eigenbau"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000696"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000696\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}