{"id":55001064,"date":"2016-12-01T00:00:00","date_gmt":"2020-05-22T13:34:58","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1064"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Zippen_mit_Access","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/","title":{"rendered":"Zippen mit Access"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Sie werden immer mal wieder auf die Aufgabe sto&szlig;en, automatisiert Zip-Dateien zu erstellen, Daten in Zip-Dateien zu speichern oder Daten aus Zip-Dateien zu extrahieren. Dazu ben&ouml;tigen Sie optimalerweise VBA-Code ohne viel Schnickschnack wie externe Bibliotheken et cetera. Windows liefert gl&uuml;cklicherweise in aktuelleren Versionen M&ouml;glichkeiten, Zip-Dateien auch per VBA zu erstellen, zu f&uuml;llen und zu lesen. Diese sind zwar nicht so einfach zu finden, aber wir haben Ihnen eine Auswahl wichtiger Funktionen zusammengestellt.<\/b><\/p>\n<h2>Grundlegende Technik<\/h2>\n<p>Wenn wir die Windows-Funktionen zum Verwenden von Zip-Dateien nutzen wollen, haben wir nur eine eingeschr&auml;nkte Menge an M&ouml;glichkeiten zur Verf&uuml;gung. Diese sollten jedoch f&uuml;r den Gro&szlig;teil der denkbaren Einsatzf&auml;lle ausreichend sein.<\/p>\n<p>Ben&ouml;tigen Sie spezielle Techniken etwa zum Hinzuf&uuml;gen eines Kennworts zum Schutz des Inhalts der Zip-Datei, m&uuml;ssen Sie auf fertige Bibliotheken zur&uuml;ckgreifen, die m&ouml;glicherweise kostenpflichtig sind und gegebenenfalls auch erst beim Nutzer installiert werden m&uuml;ssen.<\/p>\n<p>Die hier vorgestellten Techniken nutzen allein die vom Betriebssystem bereitgestellten Funktionen.<\/p>\n<p>In einem halbwegs frischen System, also ohne zus&auml;tzliche Eintr&auml;ge in den Kontextmen&uuml;s, sieht die eingebaute Funktion zum Erstellen von Zip-Dateien wie in Bild 1 aus. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_001.png\" alt=\"Erstellen einer Zip-Datei mit Windows-Bordmitteln\" width=\"649,559\" height=\"285,8809\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Erstellen einer Zip-Datei mit Windows-Bordmitteln<\/span><\/b><\/p>\n<h2>Zip-Datei erstellen<\/h2>\n<p>Es gibt keine eingebaute Funktion, um eine leere Zip-Datei zu erstellen. Wie k&ouml;nnen wir dieses Problem umgehen Dazu gibt es zumindest zwei M&ouml;glichkeiten:<\/p>\n<ul>\n<li>Wir legen eine neue, leere Zip-Datei mit einem geeigneten Programm wie WinZip oder WinRar an, speichern diese in einem Anlage-Feld der Datenbank und exportieren dieses bei Bedarf als leere Zip-Datei in das Zielverzeichnis.<\/li>\n<li>Wir schauen uns an, wie eine leere Zip-Datei aufgebaut ist, und bauen diese einfach nach.<\/li>\n<\/ul>\n<p>Ersteres w&uuml;rde zumindest noch eine weitere Tabelle mit dem Anlage-Feld erforderlich machen, was wir an dieser Stelle f&uuml;r &uuml;bertriebenen Aufwand halten. Also erstellen wir lieber mit WinZip oder WinRar eine leere Zip-Datei und betrachten diese in einem Texteditor.<\/p>\n<p>Das Ergebnis sieht dann etwa wie in Bild 2 aus. Was soll schon schieflaufen, wenn wir einfach eine leere Textdatei mit den eingebauten VBA-Befehlen erzeugen und die hier enthaltenen Zeichen einf&uuml;gen Also machen wir uns an die Arbeit. Die Prozedur aus Listing 1 erwartet den Namen der zu erstellenden Zip-Datei und legt diese dann an. Dazu erstellt sie eine <b>String<\/b>-Variable namens <b>strZipinhalt <\/b>und f&uuml;llt sie genau mit dem Inhalt der Datei, die wir oben probehalber erzeugt und im Texteditor angezeigt haben. Die Zeichen in der verwendeten Vorlage werden vom Texteditor im hexadezimalen Format angezeigt. Wir m&uuml;ssen diese, bevor wir die Zeichen mit der Funktion <b>Chr() <\/b>ermitteln, in das Dezimalformat umwandeln. Dies erledigen wir durch Voranstellen der Zeichenkette <b>&#038;H<\/b>. Die achtzehn Nullen f&uuml;gen wir mit der Funktion <b>String()<\/b> hinzu, der wir als ersten Parameter die Anzahl der zu liefernden Zeichen und als zweiten den Code f&uuml;r das gew&uuml;nschte Zeichen &uuml;bergeben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_002.png\" alt=\"Aussehen einer leeren Zip-Datei\" width=\"549,6265\" height=\"382,3491\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Aussehen einer leeren Zip-Datei<\/span><\/b><\/p>\n<p>Die Prozedur ermittelt dann mit der Funktion <b>FreeFile <\/b>eine Dateinummer f&uuml;r den Zugriff auf die neu zu erstellende Datei. Diese &ouml;ffnen wir mit der <b>Open<\/b>-Methode, der wir den Namen der zu erstellenden Datei folgen lassen (<b>strZipdatei<\/b>). Der &ouml;ffnungsmodus ist <b>For Binary Access Write<\/b>, die Dateinummer lautet schlie&szlig;lich <b>#intDateinummer<\/b>. Die <b>Put<\/b>-Methode schreibt den Inhalt der Variablen <b>strZipinhalt <\/b>in die mit <b>#intDateinummer <\/b>ge&ouml;ffnete Datei, die <b>Close<\/b>-Methode schlie&szlig;t diese wieder.<\/p>\n<p>Ein beispielhafter Aufruf f&uuml;r diese Prozedur sieht etwa wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_ZipErstellen()\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     Kill CurrentProject.Path & \"\\testvba.zip\"\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     ZipErstellen CurrentProject.Path & \"\\testvba.zip\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die so erzeugte Datei hat genau den gleichen Inhalt wie die oben mit WinZip erzeugte Datei im Texteditor und kann somit auch etwa mit WinZip oder WinRar ge&ouml;ffnet werden. Au&szlig;erdem, und das ist ja unser erkl&auml;rtes Ziel, k&ouml;nnen wir diese neu erstellte Zip-Datei nun mit den von uns gew&uuml;nschten Dateien f&uuml;llen.<\/p>\n<h2>Zip-Datei f&uuml;llen<\/h2>\n<p>Der zweite Schritt besteht nun darin, eine Datei zu einer Zip-Datei hinzuzuf&uuml;gen. Dazu verwenden wir die Funktion <b>Zippen <\/b>aus Listing 2. Die Datei erwartet zwei Parameter:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Zippen(strZipdatei<span style=\"color:blue;\"> As String<\/span>, strDatei<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objZip<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objShell<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intCount<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n     <span style=\"color:blue;\">Set<\/span> objZip = objShell.Namespace((strZipdatei))\r\n     <span style=\"color:blue;\">If <\/span>objZip Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         ZipErstellen strZipdatei\r\n         <span style=\"color:blue;\">Set<\/span> objZip = objShell.Namespace(CVar(strZipdatei))\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     intCount = objZip.items.Count\r\n     ''''objZip.CopyHere strDatei\r\n     objZip.CopyHere (strDatei) ''''Klammer Pflicht, da sonst kein zippen\r\n     Do\r\n         <span style=\"color:blue;\">Call<\/span> Sleep(100)\r\n     <span style=\"color:blue;\">Loop<\/span> While <span style=\"color:blue;\">Not<\/span> ZipdateiGeschlossen(strZipdatei)\r\n     <span style=\"color:blue;\">If <\/span>objZip.items.Count &gt; intCount<span style=\"color:blue;\"> Then<\/span>\r\n         Zippen = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Funktion zum Hinzuf&uuml;gen einer Datei zu einer Zip-Datei<\/span><\/b><\/p>\n<ul>\n<li><b>strZipdatei <\/b>ist der Pfad zur Zip-Datei,<\/li>\n<li><b>strDatei <\/b>ist der Pfad zu der hinzuzuf&uuml;genden Datei.<\/li>\n<\/ul>\n<p>Die Funktion deklariert zwei Objektvariablen namens <b>objZip <\/b>und <b>objShell <\/b>sowie eine <b>Integer<\/b>-Variable namens <b>intCount<\/b>. <b>objShell <\/b>f&uuml;llen wir mit einem neuen Objekt auf Basis der Klasse <b>Shell.Application <\/b>wie bereits in der Prozedur <b>ZipErstellen<\/b>. <b>objZip <\/b>erh&auml;lt einen Verweis auf das <b>Namespace<\/b>-Objekt auf Basis der Zip-Datei.<\/p>\n<p>Diesen holen wir &uuml;ber die <b>Namespace<\/b>-Eigenschaft des <b>Shell.Application<\/b>-Objekts. Danach pr&uuml;ft die Funktion, ob <b>objZip <\/b>einen Verweis enth&auml;lt. Dies ist nicht der Fall, wenn die mit <b>strZipdatei <\/b>&uuml;bergebene Datei keine Zip-Datei ist. In diesem Fall erstellt die Funktion die Zip-Datei mit der bereits vorgestellten Prozedur <b>ZipErstellen <\/b>neu und erneuert dann den in <b>objZip <\/b>gespeicherten Verweis auf diese Datei.<\/p>\n<p>Nun folgt ein Schritt, der f&uuml;r die &uuml;berpr&uuml;fung des Erfolgs wichtig ist. Mit der Eigenschaft <b>Count<\/b> der <b>items<\/b>-Auflistung des <b>Namespace<\/b>-Objekts mit der Zip-Datei ermitteln wir die Anzahl der in der Zip-Datei enthaltenen Dateien beziehungsweise Elemente (hier werden auch Ordner mitgez&auml;hlt). Bei einer frisch angelegten Zip-Datei sollte dies den Wert <b>0 <\/b>liefern.<\/p>\n<p>Anschlie&szlig;end w&uuml;rden wir normalerweise einfach die <b>CopyHere<\/b>-Methode des <b>Namespace<\/b>-Objekts mit der Zip-Datei aufrufen und als Parameter den Namen der hinzuzuf&uuml;genden Datei &uuml;bergeben:<\/p>\n<pre>objZip.CopyHere strDatei<\/pre>\n<p>Dies ist auf dem Testsystem jedoch zuverl&auml;ssig schiefgegangen. Nach einigen Recherchen stellte sich heraus, dass man den Dateinamen in Klammern einfassen muss, damit es gelingt:<\/p>\n<pre>objZip.CopyHere (strDatei)<\/pre>\n<p>Die Methode <b>CopyHere <\/b>ist eine asynchrone Methode, das hei&szlig;t, sie wird ausgef&uuml;hrt, w&auml;hrend der Code weiterl&auml;uft. Wenn wir also direkt danach mit der folgenden Anweisung pr&uuml;fen w&uuml;rden, ob die Datei hinzugef&uuml;gt wurde, kann es sein, dass das Hinzuf&uuml;gen noch nicht abgeschlossen wurde:<\/p>\n<pre><span style=\"color:blue;\">If <\/span>objZip.items.Count &gt; intCount<span style=\"color:blue;\"> Then<\/span><\/pre>\n<p>Also bauen wir eine <b>Do&#8230;Loop<\/b>-Schleife ein, die mit einer Hilfsfunktion pr&uuml;ft, ob die Datei bereits zur Zip-Datei hinzugef&uuml;gt wurde. Mit jedem Durchlauf dieser Schleife rufen wir zun&auml;chst die <b>Sleep<\/b>-Funktion mit dem Wert <b>100 <\/b>als Parameter auf, was eine Pause von einer Zehntelsekunde hervorruft. Die <b>Sleep<\/b>-Funktion deklarieren wir wie folgt in einem Standardmodul:<\/p>\n<pre>Declare Sub Sleep Lib \"kernel32\" (ByVal dwMilliseconds<span style=\"color:blue;\"> As Long<\/span>)<\/pre>\n<p>Die Abbruchbedingung lautet so:<\/p>\n<pre><span style=\"color:blue;\">Loop<\/span> While <span style=\"color:blue;\">Not<\/span> ZipdateiGeschlossen(strZipdatei)<\/pre>\n<p>Die hier angegebene Funktion <b>ZipdateiGeschlossen <\/b>erwartet den Namen der zu &uuml;berpr&uuml;fenden Datei als Parameter (s. Listing 3). Sie ermittelt eine Nummer f&uuml;r den schreibenden Zugriff auf die angegebene Datei und versucht dann, diese mit der <b>Open<\/b>-Anweisung zu &ouml;ffnen.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>ZipdateiGeschlossen(strZipdatei<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intDateinummer<span style=\"color:blue;\"> As Integer<\/span>\r\n     intDateinummer = FreeFile\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> Ende_ZipdateiGeschlossen\r\n     Open strZipdatei For Binary Access Read Lock Write<span style=\"color:blue;\"> As <\/span>intDateinummer\r\n     Close intDateinummer\r\n     ZipdateiGeschlossen = <span style=\"color:blue;\">True<\/span>\r\nEnde_ZipdateiGeschlossen:\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Funktion zur Pr&uuml;fung, ob eine bestimmte Datei aktuell geschlossen ist<\/span><\/b><\/p>\n<p>Ist die Datei noch ge&ouml;ffnet, l&ouml;st diese Anweisung einen Fehler aus und die Funktion springt zur Marke <b>Ende_ZipdateiGeschlossen<\/b>. Die Funktion liefert dann den Wert <b>False <\/b>zur&uuml;ck. Anderenfalls schlie&szlig;t die Funktion die Datei mit der <b>Close<\/b>-Anweisung wieder und stellt den R&uuml;ckgabewert auf <b>True <\/b>ein.<\/p>\n<p>Auf diese Weise wird die <b>Do&#8230;Loop<\/b>-Schleife so lange durchlaufen, bis die Zip-Datei nicht mehr durch die <b>CopyHere<\/b>-Anweisung in Beschlag genommen wird und die Datei hinzugef&uuml;gt wurde. Danach k&ouml;nnen wir dann in der <b>If&#8230;Then<\/b>-Bedingung pr&uuml;fen, ob sich die Anzahl der enthaltenen Dateien im Anschluss an das Hinzuf&uuml;gen ge&auml;ndert hat. Falls ja, wird der R&uuml;ckgabewert der Funktion <b>Zippen <\/b>auf den Wert <b>True <\/b>eingestellt.<\/p>\n<p>Die Funktion <b>Zippen <\/b>testen wir etwa mit folgender Routine:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_Zippen_Datei_klein()\r\n     <span style=\"color:blue;\">Dim <\/span>strDatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     strDatei = CurrentProject.Path & \"\\test.txt\"\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Zippen erfolgreich \" _\r\n         & Zippen(strZipdatei, strDatei)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dies stellt die Pfadangaben zur Zip-Datei und zur hinzuzuf&uuml;genden Datei zusammen und &uuml;bergibt diese an die Funktion <b>Zippen<\/b>. Das Ergebnis wird dann in einer Meldung ausgegeben.<\/p>\n<h2>Verzeichnisse zippen<\/h2>\n<p>Mit der Funktion <b>Zippen <\/b>k&ouml;nnen Sie auch komplette Verzeichnisse zippen. Dazu &uuml;bergeben Sie als zweiten Parameter einfach den Pfad zu dem zu zippenden Verzeichnis:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_Zippen_Folder()\r\n     <span style=\"color:blue;\">Dim <\/span>strDatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     strDatei = CurrentProject.Path & \"\\test\\\"\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Zippen erfolgreich \" _\r\n         & Zippen(strZipdatei, strDatei)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Nachdem Sie diese beiden Test-Routinen aufgerufen haben, erhalten Sie eine Zip-Datei, die mit WinRar ge&ouml;ffnet etwa wie in Bild 3 aussieht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_003.png\" alt=\"Zip-Datei mit einigen per VBA hinzugef&uuml;gten Elementen\" width=\"424,7115\" height=\"174,7617\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Zip-Datei mit einigen per VBA hinzugef&uuml;gten Elementen<\/span><\/b><\/p>\n<p>Die bisher beschriebene Version der Funktion <b>Zippen <\/b>haben wir unter dem Namen <b>Zippen_Version1 <\/b>im Modul <b>mdlZippen <\/b>abgelegt.<\/p>\n<h2>Dateien eines Verzeichnisses einzeln zippen<\/h2>\n<p>Nun m&ouml;chten Sie m&ouml;glicherweise nicht das komplette Verzeichnis zippen, sondern nur die in diesem Verzeichnis enthaltenen Dateien. Das k&ouml;nnen Sie erledigen, indem Sie die Funktion <b>Zippen <\/b>entsprechend anpassen.<\/p>\n<p>Die neue Version sieht nun wie in Listing 4 aus. Sie erwartet zwei Parameter mehr als die vorherige Version, n&auml;mlich <b>lngAnzahl <\/b>und <b>bolOhneVerzeichnis<\/b>. Beide sind nur in Zusammenhang mit der &uuml;bergabe eines Verzeichnisses mit dem Parameter <b>strDateiVerzeichnis <\/b>interessant, da nur dann mehrere Dateien verarbeitet werden.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Zippen(strZipdatei<span style=\"color:blue;\"> As String<\/span>, ByVal strDateiVerzeichnis<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> lngAnzahl<span style=\"color:blue;\"> As Long<\/span>, <span style=\"color:blue;\">Optional<\/span> bolOhneVerzeichnis<span style=\"color:blue;\"> As Boolean<\/span> = <span style=\"color:blue;\">False<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objZip<span style=\"color:blue;\"> As Object<\/span>, objShell<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intCount<span style=\"color:blue;\"> As Integer<\/span>, strDatei<span style=\"color:blue;\"> As String<\/span>, strVerzeichnis<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n     <span style=\"color:blue;\">Set<\/span> objZip = objShell.NameSpace((strZipdatei))\r\n     <span style=\"color:blue;\">If <\/span>objZip Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         ZipErstellen strZipdatei\r\n         <span style=\"color:blue;\">Set<\/span> objZip = objShell.NameSpace(CVar(strZipdatei))\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     intCount = objZip.items.Count\r\n     <span style=\"color:blue;\">If <\/span>IstVerzeichnis(strDateiVerzeichnis) And bolOhneVerzeichnis<span style=\"color:blue;\"> Then<\/span>\r\n         strVerzeichnis = <span style=\"color:blue;\">Trim<\/span>(strDateiVerzeichnis)\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> <span style=\"color:blue;\">Right<\/span>(strVerzeichnis, 1) = \"\\\"<span style=\"color:blue;\"> Then<\/span>\r\n             strVerzeichnis = strVerzeichnis & \"\\\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strDatei = Dir(strVerzeichnis)\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Len<\/span>(strDatei) &gt; 0\r\n             objZip.CopyHere (strVerzeichnis & strDatei)\r\n             Do\r\n                 <span style=\"color:blue;\">Call<\/span> Sleep(100)\r\n             <span style=\"color:blue;\">Loop<\/span> While <span style=\"color:blue;\">Not<\/span> ZipdateiGeschlossen(strZipdatei)\r\n             strDatei = Dir()\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         objZip.CopyHere (strDateiVerzeichnis)\r\n         Do\r\n             <span style=\"color:blue;\">Call<\/span> Sleep(100)\r\n         <span style=\"color:blue;\">Loop<\/span> While <span style=\"color:blue;\">Not<\/span> ZipdateiGeschlossen(strZipdatei)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     lngAnzahl = objZip.items.Count - intCount\r\n     <span style=\"color:blue;\">If <\/span>lngAnzahl<span style=\"color:blue;\"> Then<\/span>\r\n         Zippen = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Zippen-Funktion, die auch einzelne Elemente eines Verzeichnisses zippt &#8211; mit R&uuml;ckgabe der Anzahl<\/span><\/b><\/p>\n<p>Die Funktion verwendet au&szlig;erdem drei zus&auml;tzliche Variablen: <b>intCount <\/b>nimmt die Anzahl der hinzuf&uuml;gten Elemente auf. <b>strDatei <\/b>soll, wenn es sich beim Inhalt des Parameters <b>strDateiVerzeichnis <\/b>um ein Verzeichnis handelt, zum Durchlaufen der darin enthaltenen Dateien dienen. <b>strVerzeichnis <\/b>nimmt entsprechend das Verzeichnis aus <b>strDateiVerzeichnis <\/b>auf &#8211; dies nur, um Verwechslungen zu vermeiden. Die Zip-Datei wird wie gehabt referenziert beziehungsweise, sofern noch nicht vorhanden, erstellt. Die Variable <b>intCount <\/b>speichert nach wie vor die Anzahl der Elemente des Zip-Archivs vor dem Hinzuf&uuml;gen der Elemente.<\/p>\n<p>Dann pr&uuml;ft die Hilfsfunktion <b>IstVerzeichnis<\/b>, ob es sich bei dem mit <b>strDateiVerzeichnis <\/b>&uuml;bergebenen Pfad um ein Verzeichnis handelt. Ist dies der Fall und gleichzeitig der Parameter <b>bolOhneVerzeichnis <\/b>auf <b>True <\/b>eingestellt, wird der erste Teil der <b>If&#8230;Then<\/b>-Bedingung abgearbeitet.<\/p>\n<p>Innerhalb dieses Abschnitts tr&auml;gt die Funktion den Wert von <b>strDateiVerzeichnis <\/b>in die Variable <b>strVerzeichnis <\/b>ein. Dann pr&uuml;ft sie, ob <b>strVerzeichnis <\/b>ein abschlie&szlig;endes Backslash-Zeichen (<b>\\<\/b>) enth&auml;lt, und f&uuml;gt dieses gegebenenfalls noch hinzu. Schlie&szlig;lich liest die Prozedur mit der <b>Dir<\/b>-Funktion den Namen des ersten Elements des in <b>strVerzeichnis <\/b>angegebenen Verzeichnisses in die Variable <b>strDatei <\/b>ein.<\/p>\n<p>Damit steigt die Funktion in eine <b>Do While<\/b>-Schleife ein, die so lange l&auml;uft, wie die L&auml;nge der in <b>strDatei <\/b>gespeicherten Zeichenkette gr&ouml;&szlig;er als <b>0 <\/b>ist, die Variable also einen Wert enth&auml;lt. Innerhalb der Schleife f&uuml;gt die <b>CopyHere<\/b>-Methode nun die Datei mit dem aus <b>strVerzeichnis <\/b>und <b>strDatei <\/b>zusammengesetzten Pfad zu der mit <b>objZip <\/b>referenzierten Zip-Datei hinzu. Die <b>Do&#8230;Loop<\/b>-Schleife mit dem Ausdruck <b>Not ZipdateiGeschlossen(strZipdatei) <\/b>h&auml;lt die weitere Ausf&uuml;hrung der Funktion wieder so lange an, bis die Zip-Datei durch den asynchronen Befehl <b>CopyHere <\/b>fertig beschrieben wurde.<\/p>\n<p>Danach ermittelt die Funktion &uuml;ber den einfachen Aufruf der <b>Dir<\/b>-Funktion die n&auml;chste Datei in dem angegebenen Verzeichnis. Warum kein Parameter Weil die <b>Dir<\/b>-Funktion so strukturiert ist, dass sie mit Verzeichnisangabe das erste Element dieses Verzeichnisses zur&uuml;ckliefert und ohne Parameter immer das jeweils folgende Element. Die Schleife beginnt nun von vorn, wo sie wieder pr&uuml;ft, ob <b>strDatei <\/b>noch mit einem Dateinamen gef&uuml;llt ist. Falls ja, werden auch die folgenden Dateien zur Zip-Datei hinzugef&uuml;gt, anderenfalls ist die Schleife abgearbeitet.<\/p>\n<p>Der Else-Teil der <b>If&#8230;Then<\/b>-Bedingung f&uuml;gt wie bereits in der vorherigen Version der <b>Zippen<\/b>-Funktion die mit <b>strDateiVerzeichnis <\/b>angegebene Datei oder das Verzeichnis zur Zip-Datei hinzu.<\/p>\n<p>Ob w&auml;hrend des Aufrufs der <b>Zippen<\/b>-Funktion ein oder mehrere Dateien zur Zip-Datei hinzugef&uuml;gt wurden, ermitteln wir wieder mit der Differenz aus <b>objZip.items.Count <\/b>und dem Wert aus der Variablen <b>intCount<\/b>. Diesmal landet das Ergebnis allerdings gleich im R&uuml;ckgabeparameter <b>lngAnzahl<\/b>. Deren Inhalt &uuml;berpr&uuml;ft dann auch die <b>If&#8230;Then<\/b>-Bedingung, welche den R&uuml;ckgabewert der Funktion <b>Zippen <\/b>im Falle eines Wertes gr&ouml;&szlig;er <b>0 <\/b>auf <b>True <\/b>einstellt.<\/p>\n<p>Die Hilfsfunktion <b>IstVerzeichnis<\/b>, mit der wir pr&uuml;fen, ob es sich bei dem mit <b>strDateiVerzeichnis <\/b>&uuml;bergebenen Ausdruck um eine Datei oder ein Verzeichnis handelt, sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>IstVerzeichnis(ByVal strPfad<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     IstVerzeichnis = _\r\n         ((GetAttr(strPfad) And vbDirectory) = vbDirectory)\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Sie liest den Wert der Funktion <b>GetAttr<\/b> f&uuml;r den Parameter <b>strPfad <\/b>ein und pr&uuml;ft, ob das Ergebnis die Konstante <b>vbDirectory <\/b>enth&auml;lt. In diesem Fall handelt es sich um ein Verzeichnis und die Funktion liefert den Wert <b>True <\/b>zur&uuml;ck.<\/p>\n<p>Das Ergebnis f&uuml;r ein Verzeichnis, das beispielsweise drei Textdateien enth&auml;lt und mit folgender Routine aufgerufen wurde, sieht wie in Bild 4 aus:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_004.png\" alt=\"Zip-Datei mit dem Inhalt eines Verzeichnis als einzelne Dateien\" width=\"424,7115\" height=\"289,8605\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Zip-Datei mit dem Inhalt eines Verzeichnis als einzelne Dateien<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_Zippen_VerzeichnisDateienEinzeln_MitAnzahl()\r\n     <span style=\"color:blue;\">Dim <\/span>strDatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngAnzahl<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bolZippen<span style=\"color:blue;\"> As Boolean<\/span>\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     strDatei = CurrentProject.Path & \"\\test\"\r\n     bolZippen = Zippen(strZipdatei, strDatei, lngAnzahl, <span style=\"color:blue;\">True<\/span>)\r\n     <span style=\"color:blue;\">If <\/span>bolZippen<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Zippen erfolgreich, Anzahl: \" & lngAnzahl\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Zippen nicht erfolgreich\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Elemente der Zip-Datei ermitteln<\/h2>\n<p>Nun wollen wir herausfinden, welche Dateien &uuml;berhaupt in einer Zip-Datei enthalten sind. Im Hinblick auf eine sp&auml;tere Anwendung, in der wir diese Dateien in einem Unterformular anzeigen wollen, speichern wir diese Daten direkt in einer Tabelle namens <b>tblDateien<\/b>.<\/p>\n<p>Diese sieht im Entwurf wie in Bild 5 aus. Neben dem Prim&auml;rschl&uuml;sselfeld speichert die Tabelle den Dateinamen, das Datum der letzten &auml;nderung, die Gr&ouml;&szlig;e der gepackten und der ungepackten Dateien sowie das Verh&auml;ltnis dieser Zahlen. Das Feld <b>Dateiname<\/b> versehen wir mit einem eindeutigen Schl&uuml;ssel, da die enthaltenen Dateien nur jeweils einmal vorkommen d&uuml;rfen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_005.png\" alt=\"Tabelle zum Speichern der Informationen der in einer Zip-Datei gespeicherten Dateien\" width=\"499,6607\" height=\"193,8887\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Tabelle zum Speichern der Informationen der in einer Zip-Datei gespeicherten Dateien<\/span><\/b><\/p>\n<h2>Zur Vereinfachung: Early Binding<\/h2>\n<p>Damit wir uns die Arbeit beim Erstellen der folgenden Routinen vereinfachen, binden wir zwischenzeitlich die Bibliothek <b>Microsoft Shell Controls and Automation <\/b>wie in Bild 6 ein (VBA-Editor, Men&uuml;punkt <b>Extras|Verweise<\/b>). Damit k&ouml;nnen wir nun IntelliSense nutzen und etwas intuitiver mit den Elementen der verwendeten Klasse <b>Shell32 <\/b>umgehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_006.png\" alt=\"Verweis auf die Bibliothek Microsoft Shell Controls and Automation\" width=\"424,7115\" height=\"199,0538\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Verweis auf die Bibliothek Microsoft Shell Controls and Automation<\/span><\/b><\/p>\n<p>Sp&auml;ter sollten Sie, um Versionskonflikte bei Verwendung verschiedener Betriebssystemversionen zu vermeiden, allerdings wieder auf Late Binding umsteigen. In diesem Fall reduziert sich der Aufwand darauf, in den Deklarationen die Variablentypen wieder in den Typ <b>Objekt <\/b>umzuwandeln.<\/p>\n<h2>Prozedur zum Einlesen der gezippten Dateien<\/h2>\n<p>Die Prozedur zum Einlesen der Dateien einer Zip-Datei in die Tabelle <b>tblDateien <\/b>sieht wie in Listing 5 aus. Sie erwartet lediglich den Namen der zu untersuchenden Zip-Datei als Parameter. Wir haben hier in der Early Binding-Variante gleich drei Objektvariablen deklariert, die Klassen der <b>Shell32<\/b>-Bibliothek nutzen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>ZipdateiUntersuchen(strZipdatei<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objShell<span style=\"color:blue;\"> As <\/span>Shell ''''(As Object) - f&uuml;r Late Binding wieder einkommentieren\r\n     <span style=\"color:blue;\">Dim <\/span>objZip<span style=\"color:blue;\"> As <\/span>Shell32.Folder2 ''''(As Object) - f&uuml;r Late Binding wieder einkommentieren\r\n     <span style=\"color:blue;\">Dim <\/span>objDatei<span style=\"color:blue;\"> As <\/span>Shell32.FolderItem ''''(As Object) - f&uuml;r Late Binding wieder einkommentieren\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>strDateiname<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>datLetzteAenderung<span style=\"color:blue;\"> As Date<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>dblGroesseUngepackt<span style=\"color:blue;\"> As Double<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>dblGroesseGepackt<span style=\"color:blue;\"> As Double<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>intRatioGepacktUngepackt<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     db.Execute \"DELETE FROM tblDateien\", dbFailOnError\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(Dir(strZipdatei)) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n         <span style=\"color:blue;\">Set<\/span> objZip = objShell.NameSpace(CVar(strZipdatei))\r\n         For Each objDatei In objZip.Items\r\n             <span style=\"color:blue;\">With<\/span> objZip\r\n                 strDateiname = .GetDetailsOf(objDatei, 0)\r\n                 datLetzteAenderung = <span style=\"color:blue;\">Replace<\/span>(<span style=\"color:blue;\">Replace<\/span>(.GetDetailsOf(objDatei, 7), ChrW(8206), \"\"), ChrW(8207), \"\")\r\n                 dblGroesseUngepackt = Val(.GetDetailsOf(objDatei, 5))\r\n                 dblGroesseGepackt = Val(.GetDetailsOf(objDatei, 2))\r\n                 intRatioGepacktUngepackt = Val(<span style=\"color:blue;\">Replace<\/span>(.GetDetailsOf(objDatei, 6), ChrW(8206), \"\"))\r\n                 db.Execute \"INSERT INTO tblDateien(Dateiname, ZuletztGeaendert, GepackteGroesse, \" _\r\n                     \"UngepackteGroesse, Ratio) VALUES(''''\" & strDateiname & \"'''', \" & ISODatum(datLetzteAenderung) & \", \" _\r\n                     & dblGroesseGepackt & \", \" & dblGroesseUngepackt & \", \" & intRatioGepacktUngepackt & \")\", dbFailOnError\r\n             End <span style=\"color:blue;\">With<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> varDatei\r\n         <span style=\"color:blue;\">Set<\/span> objShell = Nothing\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Funktion zum Auslesen der in einer Zip-Datei enthaltenen Dateien<\/span><\/b><\/p>\n<ul>\n<li><b>objShell <\/b>hat den Datentyp <b>Shell<\/b>,<\/li>\n<li><b>objZip <\/b>verwendet den Datentyp <b>Folder2 <\/b>und <\/li>\n<li><b>objDatei <\/b>hat den Datentyp <b>FolderItem<\/b>.<\/li>\n<\/ul>\n<p>Die &uuml;brigen Variablen nehmen tempor&auml;r die Informationen zur jeweiligen Datei auf. Die Prozedur f&uuml;llt die Database-Variable <b>db <\/b>zun&auml;chst mit einem Verweis auf die aktuelle Datenbank und l&ouml;scht dann alle Datens&auml;tze der Tabelle <b>tblDateien<\/b>. Sie pr&uuml;ft dann, ob der Parameter <b>strZipdatei <\/b>&uuml;berhaupt eine vorhandene Datei liefert. Falls ja, arbeitet die Prozedur einige Anweisungen ab, die sich innerhalb der entsprechenden <b>If&#8230;Then<\/b>-Bedingung befinden.<\/p>\n<p>Die erste erstellt ein Objekt auf Basis der Klasse <b>Shell.Application <\/b>und speichert den Verweis darauf in der Variablen <b>objShell<\/b>. Dazu verwendet sie die <b>CreateObject<\/b>-Methode. Da wir aktuell Early Binding verwenden, h&auml;tten wir das Objekt auch mit der <b>New<\/b>-Methode erstellen k&ouml;nnen. Da wir dies beim &auml;ndern in eine Late Binding-Methode wieder r&uuml;ckg&auml;ngig machen m&uuml;ssten, haben wir es bei der <b>CreateObject<\/b>-Methode belassen. Die zweite Anweisung referenziert die &uuml;bergebene Zip-Datei mit der <b>NameSpace<\/b>-Methode, welches ein <b>Folder2<\/b>-Objekt basierend auf dem &uuml;bergebenen Pfad zur&uuml;ckliefert. Dieses Objekt referenzieren wir mit der Variablen <b>objZip<\/b>.<\/p>\n<p>Nun durchl&auml;uft die Routine in einer <b>For Each<\/b>-Schleife alle in der Auflistung Items des <b>Folder2<\/b>-Objekts <b>objZip <\/b>enthaltenen Elemente und speichert diese jeweils in der Variablen <b>objDatei<\/b>.<\/p>\n<p>Das <b>Folder2<\/b>-Objekt <b>objZip <\/b>stellt nun eine Methode namens <b>GetDetailsOf <\/b>zur Verf&uuml;gung, der wir einen Verweis auf das zu untersuchende Element sowie den Index der zu untersuchenden Spalte beziehungsweise Eigenschaft &uuml;bergeben m&uuml;ssen. Das zu untersuchende Element ist jeweils das in <b>objDatei <\/b>gespeicherte Datei-Element der Zip-Datei. Den Dateinamen erhalten wir beispielsweise &uuml;ber den Index <b>0<\/b> und speichern ihn in der Variablen <b>strDateiname<\/b>:<\/p>\n<pre>strDateiname = .GetDetailsOf(objDatei, 0)<\/pre>\n<p>Beim &auml;nderungsdatum wird es etwas schwieriger. Die <b>GetDetailsOf<\/b>-Methode liefert mit dem Wert <b>7 <\/b>f&uuml;r den zweiten Parameter n&auml;mlich etwa den folgenden Ausdruck zur&uuml;ck:<\/p>\n<pre>20.10.2016 11:51<\/pre>\n<p>Hier haben wir zun&auml;chst mit geeigneten Zeichenkettenfunktionen den Code f&uuml;r die jeweils als Fragezeichen dargestellten Zeichen ermittelt. F&uuml;r das erste Zeichen etwa so:<\/p>\n<pre>  AscW(<span style=\"color:blue;\">Mid<\/span>(GetDetailsOf(objDatei, 7),15,1))\r\n8206<\/pre>\n<p>Auf diese Weise haben wir herausgefunden, dass wir die beiden Zeichen mit dem Code <b>8206 <\/b>und <b>8207 <\/b>ersetzen m&uuml;ssen. Dies erledigt die folgende Anweisung und speichert das Resultat in der Variablen <b>datLetzteAenderung<\/b>:<\/p>\n<pre>datLetzteAenderung = <span style=\"color:blue;\">Replace<\/span>(<span style=\"color:blue;\">Replace<\/span>(.GetDetailsOf( objDatei, 7), ChrW(8206), \"\"), ChrW(8207), \"\")<\/pre>\n<p>&auml;hnlich kompliziert sieht es bei der Gr&ouml;&szlig;e der gepackten und der ungepackten Datei aus. Diese Werte liefern uns die beiden Aufrufe von <b>GetDetailsOf <\/b>f&uuml;r die Spalten <b>5 <\/b>(ungepackte Gr&ouml;&szlig;e) und <b>6 <\/b>(gepackte Gr&ouml;&szlig;e).<\/p>\n<p>Die Werte sehen jedoch etwa so aus:<\/p>\n<pre>  .GetDetailsOf(objDatei, 5)\r\n3 Bytes<\/pre>\n<p>Den hinteren Teil der Zeichenkette zu entfernen, ist jedoch recht einfach. Genau genommen gehen wir umgekehrt vor &#8211; wir ermitteln einfach nur den Zahlen-Teil des Ausdrucks, und zwar mit der <b>Val<\/b>-Funktion. Das Ergebnis landet in der Variablen <b>dblGroesseUngepackt<\/b>:<\/p>\n<pre>dblGroesseUngepackt = Val(.GetDetailsOf(varDatei, 5))<\/pre>\n<p>Auf die gleiche Weise erhalten wir den Wert f&uuml;r die gepackte Dateigr&ouml;&szlig;e:<\/p>\n<pre>dblGroesseGepackt = Val(.GetDetailsOf(varDatei, 2))<\/pre>\n<p>Schlie&szlig;lich wollen wir noch das Verh&auml;ltnis der gepackten zur ungepackten Gr&ouml;&szlig;e ermitteln. Das unbearbeitete Ergebnis sieht beispielsweise so aus:<\/p>\n<pre>  .GetDetailsOf(objDatei, 6)\r\n23%<\/pre>\n<p>Hier setzen wir nun eine Kombination der zuvor verwendeten <b>Replace<\/b>&#8211; und <b>Val<\/b>-Funktionen ein, die so aussieht:<\/p>\n<pre>intRatioGepacktUngepackt =  Val(<span style=\"color:blue;\">Replace<\/span>(.GetDetailsOf(varDatei, 6), ChrW(8206), \"\"))<\/pre>\n<p>Schlie&szlig;lich speichert eine <b>INSERT INTO<\/b>-Aktionsabfrage die Daten der Dateien der Zip-Datei in der Tabelle <b>tblDateien<\/b>. Die <b>Next<\/b>-Anweisung l&auml;sst die Schleife zur n&auml;chsten  Datei springen, bis alle Elemente der <b>Items<\/b>-Auflistung von <b>objZip <\/b>durchlaufen sind.<\/p>\n<p>Der Aufruf der Routine erfolgt beispielsweise mit der folgenden Anweisung:<\/p>\n<pre>ZipdateiUntersuchen CurrentProject.Path & \"\\testvba.zip\"<\/pre>\n<p>F&uuml;r eine Beispiel-Zip-Datei sieht das Ergebnis in der Tabelle <b>tblDateien <\/b>nun etwa wie in Bild 7 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_007.png\" alt=\"Die Tabelle tblDateien mit einigen Beispieldatens&auml;tzen\" width=\"549,6265\" height=\"308,3062\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Die Tabelle tblDateien mit einigen Beispieldatens&auml;tzen<\/span><\/b><\/p>\n<h2>Dateien entzippen<\/h2>\n<p>Nun wollen wir die gezippten Dateien wieder entzippen. Das erledigen wir mit einer weiteren Funktion, der wir den Namen der Zip-Datei und den Namen des Zielordners &uuml;bergeben. Im ersten Anlauf wollen wir alle Dateien der Zip-Datei entpacken.<\/p>\n<p>Die Funktion <b>Entzippen <\/b>aus Listing 6 erwartet die beiden Parameter <b>strZipdatei <\/b>und <b>strZielordner<\/b>. Sie deklariert wieder eine Variable, die ein Objekt des Typs <b>Shell.Application <\/b>aufnehmen soll (f&uuml;r Late Binding-Zwecke wieder als <b>Object <\/b>deklarieren). Au&szlig;erdem verwendet die Funktion zwei Objekte zum Referenzieren des <b>Folder2<\/b>-Objekts f&uuml;r die Zip-Datei sowie f&uuml;r den Zielordner. Nach der Pr&uuml;fung, ob sowohl das Zielverzeichnis als auch die Zip-Datei vorhanden sind, erstellt sie das <b>Shell.Application<\/b>-Objekt. Danach landet der Namespace des Zielordners in der Variablen <b>objZielordner <\/b>(wieder vorher in einen Variant umgewandelt). Gleiches geschieht mit der Zip-Datei wie schon in den vorherigen Beispielen geschehen. Schlie&szlig;lich verwendet die Funktion die gleiche <b>CopyHere<\/b>-Methode, die wir ebenfalls bereits mehrmals verwendet haben, um den Inhalt der Zip-Datei in das Zielverzeichnis zu kopieren:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Entzippen(strZipdatei<span style=\"color:blue;\"> As String<\/span>, strZielordner<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objShell<span style=\"color:blue;\"> As <\/span>Shell32.Shell\r\n     <span style=\"color:blue;\">Dim <\/span>objZielordner<span style=\"color:blue;\"> As <\/span>Shell32.Folder2\r\n     <span style=\"color:blue;\">Dim <\/span>objZipdatei<span style=\"color:blue;\"> As <\/span>Shell32.Folder2\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(Dir(strZielordner, vbDirectory)) &gt; 0 And <span style=\"color:blue;\">Len<\/span>(Dir(strZipdatei)) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n         <span style=\"color:blue;\">Set<\/span> objZielordner = objShell.NameSpace(CVar(strZielordner))\r\n         <span style=\"color:blue;\">Set<\/span> objZipdatei = objShell.NameSpace(CVar(strZipdatei))\r\n         objZielordner.CopyHere objZipdatei.Items\r\n         <span style=\"color:blue;\">Set<\/span> objShell = Nothing\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Funktion zum Entzippen aller Dateien einer Zip-Datei<\/span><\/b><\/p>\n<pre>objZielordner.CopyHere objZipdatei.Items<\/pre>\n<p>Dabei blendet die Funktion den Dialog wie in Bild 8 ein und veranschaulicht so den Fortschritt. Die Prozedur, mit der wir einen Beispielaufruf der Funktionen implementieren, sieht wie folgt aus:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_008.png\" alt=\"Entzippen einiger Dateien\" width=\"424,7115\" height=\"302,56\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Entzippen einiger Dateien<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_Entzippen()\r\n     <span style=\"color:blue;\">Dim <\/span>strZielordner<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     strZielordner = CurrentProject.Path & \"\\Zielordner\\\"\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     Kill strZielordner & \"*.*\"\r\n     RmDir strZielordner\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     MkDir strZielordner\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     Entzippen strZipdatei, strZielordner\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Hier tragen wir den Pfad zum Zielordner in die Variable <b>strZielordner <\/b>ein. Dazu nutzen wir in diesem Fall einfach den Ordner <b>Zielordner <\/b>unterhalb des aktuellen Datenbankverzeichnisses, das wir mit <b>CurrentProject.Path <\/b>ermitteln. Nun l&ouml;schen wir mit der <b>Kill<\/b>-Anweisung nach vorheriger Abschaltung der eingebauten Fehlerbehandlung zun&auml;chst alle Dateien innerhalb des angegebenen Verzeichnisses &#8211; f&uuml;r den Fall, dass dieses nicht bereits zuvor schon einmal erstellt wurde. Erst danach k&ouml;nnen wir mit der <b>RmDir<\/b>-Anweisung das Verzeichnis selbst l&ouml;schen.<\/p>\n<p>Nun erstellen wir das Verzeichnis neu und tragen den Pfad zur Zip-Datei in die Variable <b>strZipdatei <\/b>ein. Die Variablen <b>strZipdatei <\/b>und <b>strZielverzeichnis <\/b>&uuml;bergeben wir dann an die Funktion <b>Entzippen<\/b>.<\/p>\n<p>Mit dem hier gezeigten Aufruf gelingt das Entpacken immer, wenn das Zielverzeichnis tats&auml;chlich nur Dateien und keine weiteren Unterverzeichnisse enth&auml;lt. Au&szlig;erdem darf nur das Zielverzeichnis fehlen, die dar&uuml;ber befindlichen Verzeichnisse aus <b>strZielverzeichnis<\/b> m&uuml;ssen vorhanden sein.<\/p>\n<h2>Einzelne Dateien entzippen<\/h2>\n<p>Wenn Sie eine einzelne Datei entzippen wollen, k&ouml;nnen Sie die Funktion aus Listing 7 verwenden. Diese hei&szlig;t <b>EntzippenEinzeln <\/b>und erwartet drei Parameter: den Pfad zur Zip-Datei (<b>strZipdatei<\/b>), den Pfad zum Zielordner (<b>strZielordner<\/b>) sowie den Namen der zu entpackenden Datei (<b>strDatei<\/b>).<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>EntzippenEinzeln(strZipdatei<span style=\"color:blue;\"> As String<\/span>, strZielordner<span style=\"color:blue;\"> As String<\/span>, strDatei<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objShell<span style=\"color:blue;\"> As <\/span>Shell32.Shell\r\n     <span style=\"color:blue;\">Dim <\/span>objZielordner<span style=\"color:blue;\"> As <\/span>Shell32.Folder2\r\n     <span style=\"color:blue;\">Dim <\/span>objZipdatei<span style=\"color:blue;\"> As <\/span>Shell32.Folder2\r\n     <span style=\"color:blue;\">Dim <\/span>objDatei<span style=\"color:blue;\"> As <\/span>Shell32.FolderItem\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(Dir(strZielordner, vbDirectory)) &gt; 0 And <span style=\"color:blue;\">Len<\/span>(Dir(strZipdatei)) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n         <span style=\"color:blue;\">Set<\/span> objZielordner = objShell.NameSpace(CVar(strZielordner))\r\n         <span style=\"color:blue;\">Set<\/span> objZipdatei = objShell.NameSpace(CVar(strZipdatei))\r\n         For Each objDatei In objZipdatei.Items\r\n             <span style=\"color:blue;\">If <\/span>objDatei.Name = strDatei<span style=\"color:blue;\"> Then<\/span>\r\n                 objZielordner.CopyHere objDatei\r\n                 EntzippenEinzeln = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">Exit For<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> objDatei\r\n         <span style=\"color:blue;\">Set<\/span> objShell = Nothing\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Funktion zum Entzippen einer Datei einer Zip-Datei<\/span><\/b><\/p>\n<p>Sie verwendet neben den bereits aus der Funktion <b>Entzippen <\/b>bekannten Variablen zus&auml;tzlich noch die Variable <b>objDatei<\/b>. Diese erh&auml;lt den Datentyp <b>FolderItem <\/b>und soll am Ende die zu entzippende Datei referenzieren. Nach der Pr&uuml;fung, ob Zielverzeichnis und Zip-Datei vorhanden sind, weist die Funktion wieder den Variablen <b>objShell<\/b>, <b>objZielordner <\/b>und <b>objZipdatei <\/b>die entsprechenden Objekte zu. Schlie&szlig;lich durchl&auml;uft sie in einer <b>For Each<\/b>-Schleife alle Elemente der Auflistung <b>Items <\/b>des Objekts <b>objZipdatei<\/b> und speichert das jeweils aktuelle Element in der Variablen <b>objDatei<\/b>. Diese Variable nimmt also nicht unbedingt sofort einen Verweis auf die zu extrahierende Datei auf.<\/p>\n<p>Innerhalb der Schleife pr&uuml;ft die Funktion, ob der Wert der Eigenschaft <b>Name <\/b>des in <b>objDatei <\/b>enthaltenen Objekts mit dem Namen der zu extrahierenden Datei &uuml;bereinstimmt. Warum haben wir weiter oben in der Routine <b>ZipdateiUntersuchen<\/b> auf so umst&auml;ndliche Art und Weise mit der Methode <b>GetDetailsOf <\/b>auf den Dateinamen zugegriffen, wenn dies auch einfach &uuml;ber die <b>Name<\/b>-Eigenschaft geht Nun: Dort ben&ouml;tigten wir noch weitere Eigenschaften wie die komprimierte und unkomprimierte Dateigr&ouml;&szlig;e, und diese Eigenschaften stellt das <b>FolderItem<\/b>-Element nicht zur Verf&uuml;gung. Au&szlig;erdem ist es immer gut, alle Alternativen f&uuml;r die Erledigung einer Aufgabe zu kennen &#8211; es gibt immer Besonderheiten, die sich nur auf eine bestimmte Art und Weise erledigen lassen.<\/p>\n<p>Nun: Sobald ein passendes <b>objDatei <\/b>gefunden wurde, ist die Bedingung <b>objDatei.Name = strDateiname <\/b>erf&uuml;llt und die <b>CopyHere<\/b>-Methode des Zielordner-Objekts schreibt die mit <b>objDatei <\/b>referenzierte Datei in den Zielordner. Au&szlig;erdem stellt dies den R&uuml;ckgabewert der Funktion auf den Wert <b>True <\/b>ein und verl&auml;sst die Schleife mit der <b>Exit For<\/b>-Anweisung, da ja die noch verbleibenden Elemente der Zip-Datei nicht mehr durchlaufen werden m&uuml;ssen.<\/p>\n<p>Auch f&uuml;r diese Funktion haben wir wieder eine Prozedur zum Ausprobieren erstellt. Diese sieht wie folgt aus und stellt die Werte f&uuml;r die drei Parameter <b>strZipdatei<\/b>, <b>strZielordner <\/b>und <b>strDatei <\/b>f&uuml;r den Aufruf der Funktion <b>EntzippenEinzeln <\/b>zusammen, bevor sie diese aufruft. Vorher wird die zu extrahierende Datei gegebenenfalls noch gel&ouml;scht:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_EntzippenEinzeln()\r\n     <span style=\"color:blue;\">Dim <\/span>strZielordner<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDatei<span style=\"color:blue;\"> As String<\/span>\r\n     strZielordner = CurrentProject.Path & \"\\Zielordner\\\"\r\n     strDatei = \"pic001.png\"\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     Kill strZielordner & strDatei\r\n     MkDir strZielordner\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     EntzippenEinzeln strZipdatei, strZielordner, strDatei\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Datei aus Zip-Datei l&ouml;schen<\/h2>\n<p>Sie k&ouml;nnen auch einzelne Elemente aus Zip-Dateien l&ouml;schen. Das ist allerdings nicht ohne Zutun des Benutzers m&ouml;glich, denn es erscheint eine Meldung wie in Bild 9. <\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_1064_009.png\" alt=\"Best&auml;tigung beim L&ouml;schen einer Datei\" width=\"424,7115\" height=\"213,2369\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Best&auml;tigung beim L&ouml;schen einer Datei<\/span><\/b><\/p>\n<p>Die Funktion <b>AusZipLoeschen <\/b>erwartet zwei Parameter: den Pfad zur Zip-Datei sowie den Namen der zu l&ouml;schenden Datei (s. Listing 8). Sie pr&uuml;ft, ob die Zip-Datei vorhanden ist und erstellt dann ein <b>Shell.Application<\/b>-Objekt sowie ein <b>Folder2<\/b>-Objekt auf Basis der Zip-Datei. Dann durchl&auml;uft sie wieder alle Elemente der Zip-Datei und pr&uuml;ft in einer <b>If&#8230;Then<\/b>-Bedingung, ob der Name des aktuell durchlaufenen Objekts aus <b>objDatei.Name <\/b>dem Namen der zu l&ouml;schenden Datei entspricht. Falls ja, ruft sie die Methode <b>InvokeVerb <\/b>mit dem Wert <b>DELETE <\/b>f&uuml;r den einzigen Parameter auf. Dies l&ouml;st die L&ouml;schen-Aktion aus, welche noch durch den Benutzer best&auml;tigt werden muss. Der Aufruf kann so aussehen:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>AusZipLoeschen(strZipdatei<span style=\"color:blue;\"> As String<\/span>, strDatei<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objShell<span style=\"color:blue;\"> As <\/span>Shell32.Shell\r\n     <span style=\"color:blue;\">Dim <\/span>objZipdatei<span style=\"color:blue;\"> As <\/span>Shell32.Folder2\r\n     <span style=\"color:blue;\">Dim <\/span>objDatei<span style=\"color:blue;\"> As <\/span>Shell32.FolderItem\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(Dir(strZipdatei)) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objShell = CreateObject(\"Shell.Application\")\r\n         <span style=\"color:blue;\">Set<\/span> objZipdatei = objShell.NameSpace(CVar(strZipdatei))\r\n         For Each objDatei In objZipdatei.Items\r\n             <span style=\"color:blue;\">If <\/span>objDatei.Name = strDatei<span style=\"color:blue;\"> Then<\/span>\r\n                 objDatei.InvokeVerb (\"DELETE\")\r\n                 AusZipLoeschen = <span style=\"color:blue;\">True<\/span>\r\n                 <span style=\"color:blue;\">Exit For<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> objDatei\r\n         <span style=\"color:blue;\">Set<\/span> objShell = Nothing\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 8: Funktion zum L&ouml;schen einer Datei aus einem Zip-Archiv<\/span><\/b><\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>Test_AusZipLoeschen()\r\n     <span style=\"color:blue;\">Dim <\/span>strZipdatei<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDatei<span style=\"color:blue;\"> As String<\/span>\r\n     strDatei = \"pic001.png\"\r\n     strZipdatei = CurrentProject.Path & \"\\testvba.zip\"\r\n     AusZipLoeschen strZipdatei, strDatei\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Hier wird der Name der Datei <b>pic001.png <\/b>als zweiter Parameter an die Funktion <b>AusZipLoeschen <\/b>&uuml;bergeben, welche dann aus der Zip-Datei gel&ouml;scht wird.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Dieser Beitrag hat gezeigt, wie Sie mit Access-Bordmitteln  Dateien zu Zip-Archiven hinzuf&uuml;gen und aus diesen entfernen und entpacken k&ouml;nnen. In einem weiteren Beitrag namens <b>Zip-Formular <\/b>(<b>www.access-im-unternehmen.de\/1067<\/b>) zeigen wir, wie Sie diese Funktionen &uuml;ber die Benutzeroberfl&auml;che einsetzen k&ouml;nnen. <\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Zippen.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/89CAA21C-7F4D-4E08-A741-BE0CA84956E0\/aiu_1064.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sie werden immer mal wieder auf die Aufgabe sto&szlig;en, automatisiert Zip-Dateien zu erstellen, Daten in Zip-Dateien zu speichern oder Daten aus Zip-Dateien zu extrahieren. Dazu ben&ouml;tigen Sie optimalerweise VBA-Code ohne viel Schnickschnack wie externe Bibliotheken et cetera. Windows liefert gl&uuml;cklicherweise in aktuelleren Versionen M&ouml;glichkeiten, Zip-Dateien auch per VBA zu erstellen und zu f&uuml;llen und lesen. Diese sind zwar nicht son einfach zu finden, aber wir haben Ihnen eine Auswahl wichtiger Funktionen zusammengestellt.<\/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":[662016,66062016,44000026],"tags":[],"class_list":["post-55001064","post","type-post","status-publish","format-standard","hentry","category-662016","category-66062016","category-Interaktiv"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Zippen mit Access - 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\/Zippen_mit_Access\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Zippen mit Access\" \/>\n<meta property=\"og:description\" content=\"Sie werden immer mal wieder auf die Aufgabe sto&szlig;en, automatisiert Zip-Dateien zu erstellen, Daten in Zip-Dateien zu speichern oder Daten aus Zip-Dateien zu extrahieren. Dazu ben&ouml;tigen Sie optimalerweise VBA-Code ohne viel Schnickschnack wie externe Bibliotheken et cetera. Windows liefert gl&uuml;cklicherweise in aktuelleren Versionen M&ouml;glichkeiten, Zip-Dateien auch per VBA zu erstellen und zu f&uuml;llen und lesen. Diese sind zwar nicht son einfach zu finden, aber wir haben Ihnen eine Auswahl wichtiger Funktionen zusammengestellt.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T13:34:58+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c\" \/>\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=\"25\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Zippen mit Access\",\"datePublished\":\"2020-05-22T13:34:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/\"},\"wordCount\":4003,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/508c0a899c264c9ebeda0d067ff5584c\",\"articleSection\":[\"2016\",\"6\\\/2016\",\"Interaktiv\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/\",\"name\":\"Zippen mit Access - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/508c0a899c264c9ebeda0d067ff5584c\",\"datePublished\":\"2020-05-22T13:34:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/508c0a899c264c9ebeda0d067ff5584c\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/508c0a899c264c9ebeda0d067ff5584c\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Zippen_mit_Access\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Zippen mit Access\"}]},{\"@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":"Zippen mit Access - 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\/Zippen_mit_Access\/","og_locale":"de_DE","og_type":"article","og_title":"Zippen mit Access","og_description":"Sie werden immer mal wieder auf die Aufgabe sto&szlig;en, automatisiert Zip-Dateien zu erstellen, Daten in Zip-Dateien zu speichern oder Daten aus Zip-Dateien zu extrahieren. Dazu ben&ouml;tigen Sie optimalerweise VBA-Code ohne viel Schnickschnack wie externe Bibliotheken et cetera. Windows liefert gl&uuml;cklicherweise in aktuelleren Versionen M&ouml;glichkeiten, Zip-Dateien auch per VBA zu erstellen und zu f&uuml;llen und lesen. Diese sind zwar nicht son einfach zu finden, aber wir haben Ihnen eine Auswahl wichtiger Funktionen zusammengestellt.","og_url":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T13:34:58+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"25\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Zippen mit Access","datePublished":"2020-05-22T13:34:58+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/"},"wordCount":4003,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c","articleSection":["2016","6\/2016","Interaktiv"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/","url":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/","name":"Zippen mit Access - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c","datePublished":"2020-05-22T13:34:58+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/508c0a899c264c9ebeda0d067ff5584c"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Zippen_mit_Access\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Zippen mit Access"}]},{"@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\/55001064","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=55001064"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001064\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001064"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001064"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}