Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 5/2007.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Zusammenfassung

Komprimieren und entpacken Sie Dateien mit einer kostenlosen Zip-DLL für VBA.

Techniken

VBA

Voraussetzungen

Access 2000 und höher

Beispieldateien

SawZipNG.mdb, DLL als Download unter Shortlink 496

Shortlink

496

Per VBA komprimieren mit SawZipNG

André Minhorst, Duisburg

Eine Schnittstelle für den Einsatz mit VBA liefern einige Produkte wie etwa WinZip direkt mit. Leider sind die meisten kostenpflichtig. Access im Unternehmen stellt eine frei verfügbare DLL vor, mit der Sie von Ihrer Datenbank aus die von den verbreiteten Komprimierungstools her bekannten Funktionen nachbilden können.

SawZipNG hat es merkwürdigerweise nie zu außergewöhnlichem Ruhm gebracht: Die Bibliothek war eine Zeit lang zum Download verfügbar, danach ist sie aber aus dem Blickfeld des Internets verschwunden. Zum Glück hat Access im Unternehmen eine Kopie dieser äußerst nützlichen DLL aufgetrieben; Sie finden diese auf der Heft-CD oder unter www.access-im-unternehmen.de zum Download.

Nach der Installation des Setups steht die passende Bibliothek bereit und wartet auf die Bereitstellung in der Zieldatenbank per passendem Verweis (siehe Abb. 1). Bei der Weitergabe brauchen Sie nicht das komplette Setup mitzuliefern, die Datei SawZipNG.dll reicht aus. Allerdings muss diese dann noch per RegSvr32.exe registriert werden.

pic001.tif

Abb. 1: Um die Zip-DLL in eine Anwendung einzubinden, muss man einen passenden Verweis anlegen.

Der Einsatz von Late Binding würde einen Verweis überflüssig machen; wie dies aussieht, können Sie der Beispieldatenbank entnehmen.

Archiv erstellen

Das Hauptobjekt der DLL ist das Archiv-Objekt. Es steht sowohl beim Erzeugen und Hinzufügen von Dateien als auch beim Entpacken eines Zip-Archivs im Mittelpunkt.

Bevor Sie das Tool einsetzen, müssen Sie sich überlegen, ob Sie gegebenenfalls auf die Ereignisse des Archive-Objekts reagieren möchten. Diese werden unter anderem ausgelöst, wenn eine Datei zum Archiv hinzugefügt, eine Datei gelöscht oder das Archiv entpackt wird. In dem Fall müssen Sie die Objektvariable mit dem Schlüsselwort WithEvents deklarieren, was nur in Formular-, Berichts- und Klassenmodulen, aber nicht in Standardmodulen möglich ist. Hier ist dann auch unbedingt der Verweis nötig, mit Late Binding gibt es keine unmittelbare Möglichkeit zum Einsatz von WithEvents und der passenden Ereignisse.

Für den Anfang lassen wir diese Option allerdings zunächst außen vor und konzentrieren uns auf die eigentlichen Funktionen.

Die Zeilen zum Erstellen und Erzeugen eines Archivs sehen beispielsweise wie folgt aus:

Dim objArchiv As SAWZipNG.Archive

Set objArchiv = New SAWZipNG.Archive

Das Archiv existiert bis dato nur im Speicher. Sie können nun Dateien hinzufügen und das Archiv auf die Festplatte bannen. Das funktioniert etwa so:

Dim objArchiv As SAWZipNG.Archive

Set objArchiv = New SAWZipNG.Archive

With objArchiv

   .Create "c:\SawZip.zip"

   .AddFile "c:\test.txt"

End With

Die Create-Methode legt zunächst die Zip-Datei an, die AddFile-Methode fügt die angegebene Datei hinzu - fertig, die erste Zip-Datei ist erstellt!

Beachten Sie, dass Access abstürzt, wenn Sie der Create-Methode eine leere Zeichenkette übergeben. Wenn der Benutzer den Dateinamen eingibt oder auswählt, prüfen Sie diesen zuvor auf seinen Inhalt.

Natürlich gibt es noch einige Einstellungen, die Sie in den folgenden Abschnitten kennen lernen.

Beispieldaten

Zum Testen der Zip-Bibliothek brauchen Sie ein paar Verzeichnisse und Dateien, an denen Sie nichts kaputt machen können. Mit der folgenden Routine legen Sie die passenden Elemente im Verzeichnis der aktuellen Datenbank an (s. Abb. 2):

pic002.tif

Abb. 2: Diese per VBA-Code schnell angelegte Verzeichnis- und Dateistruktur dient als Versuchsfeld für die Zip-Bibliothek.

Public Sub Beispieldateien()

   Dim i As Integer

   Dim j As Integer

   Dim strPfad As String

   On Error Resume Next

   strPfad = CurrentProject.Path

   MkDir strPfad & "\Zip"

   On Error GoTo 0

   For i = 1 To 10

     Open strPfad & "\Zip\Test" _
& Format(i, "00") _
& ".txt" For Output As #1

     Print #1, "Test"

     Close #1

     On Error Resume Next

     MkDir strPfad & "\Zip\Zap" _
& Format(i, "00")

     For j = 1 To 10

       Open strPfad & "\Zip\Zap" _
& Format(i, "00") & "\Test" _
& Format(j, "00") & ".txt" _
For Output As #2

       Write #2, "Test"

       Close #2

     Next j

     On Error GoTo 0

   Next i

End Sub

Zu Beispielzwecken könnte man nun ein Formular entwickeln, dass etwa die Funktionen von WinZip oder ähnlichen Produkten nachbildet. Das wäre anschaulich, macht aber wenig Sinn. Viel interessanter ist es, die Zip-Funktionen beispielsweise zum Zusammenpacken zu sichernder Daten zu verwenden - ein netter Anwendungszweck wäre eine Datenbank, die Berichte im Snapshot- oder PDF-Format speichert, diese packt und per Mail verschickt. Im Folgenden lernen Sie daher die nackten VBA-Anweisungen zur Steuerung der Zip-Bibliothek kennen.

Datei verschlüsselt packen

Um sicherzustellen, dass nur der Empfänger einer Datei Zugriff auf diese hat, können Sie diese nicht nur packen, sondern auch mit einem Passwort verschlüsseln.

Public Sub DateiVerschluesseln()

   ‘....

   With objArchiv

     .Create CurrentProject.Path _
& "\VerschluesseltesArchiv.zip"

     .Password = "test"

     .AddFile CurrentProject.Path _
& "\zip\test01.txt"

   End With

End Sub

Diese Routine erzeugt ein Zip-File mit einer verschlüsselten Datei, die WinZip wie in Abb. 3 darstellt. Wichtig ist hier die Reihenfolge: Nur diejenigen Dateien, die nach der Angabe des Schlüsselwortes mit der Password-Eigenschaft hinzugefügt wurden, sind auch verschlüsselt.

pic003.tif

Abb. 3: Verschlüsselt gezippte Dateien lassen sich nur mit dem entsprechenden Passwort wieder entschlüsseln.

Verzeichnisse packen

Wenn Sie die AddFile-Anweisung durch AddFolder ersetzen und ein Verzeichnis statt einer Datei angeben, können Sie ein komplettes Verzeichnis komprimieren. Ob Sie dabei nur das angegebene Verzeichnis und die darin enthaltenen Dateien oder auch die Unterverzeichnisse mit komplettem Inhalt zippen, hängt von der Einstellung für den Parameter includeSubDirs ab. Die folgende Routine demonstriert das Komprimieren des kompletten Astes ab dem Verzeichnis Zip:

Public Sub VerzeichnisMitUnterverzeichnissen()

   ‘...

   With objArchiv

     .Create CurrentProject.Path & "\File.zip"

     .AddFolder CurrentProject.Path _
& "\zip", includeSubDirs:=True

   End With

End Sub

Der rechte Pfad

Für den Empfänger eines Zip-Archivs ist es wichtig, wohin die enthaltenen Dateien entpackt werden. Das Ziel hängt entscheidend von dem in WinZip unter Pfad angezeigten Verzeichnis ab. Üblicherweise liefert man bei einzelnen Dateien gar keine Verzeichnisstruktur mit und beim Archivieren von kompletten Verzeichnissen den Teil des Verzeichnisbaums, der das zu archivierende Verzeichnis mit einschließt.

Standardmäßig fasst das Archivieren die komplette Verzeichnishierarchie mit Ausnahme des Laufwerkbuchstabens ein. Der Nachteil dabei ist, dass der Empfänger in dem Verzeichnis, in dem er die Zip-Datei entpackt, den kompletten Verzeichnisbaum abbildet, in dem sich auch die Originaldateien befanden. Wenn das Verzeichnis Zip also in c:\Ordner1\Ordner2\Ordner3 gespeichert war und mit Verzeichnisinformationen gezippt wurde, und der Benutzer es unter c:\Test\ entpackt, erhält er die Verzeichnisstruktur c:\Test\Ordner1\Ordner2\Ordner3\Zip, obwohl er eigentlich nur c:\Test\Zip erhalten wollte.

Wenn Sie den Parameter FullPath auf False einstellen, speichert das Archiv gar keine Pfad-Informationen:

With objArchiv

   .Create CurrentProject.Path _
& "\VerzeichnisOhneRoot.zip"

   .AddFolder CurrentProject.Path _
& "\zip", FullPath:=False

End With

Beim Entpacken gelangen dadurch alle Dateien in dasselbe Verzeichnis, wodurch die komplette Struktur verloren geht - auch das ist keine Optimallösung. Der beste Weg beim Zippen von Verzeichnissen ist der folgende: Es wird genau das Verzeichnis als Root-Verzeichnis in das Archiv geschrieben, das auch für die AddFolder-Methode angegeben wurde. Wenn Sie also einen Ordner namens Zip mit drei darin enthaltenen Dateien packen, soll genau dieser Ordner mit den drei Dateien an der Stelle entpackt werden, die der Benutzer angibt. Im Detail setzen Sie bei der AddFolder-Methode den Parameter FullPath auf den Wert False, geben aber in der Zeile vorher mit der RootPath-Eigenschaft an, welche Elemente vom ursprünglichen Pfad entnommen werden sollen:

Public Sub VerzeichnisOhneRoot()

   ‘...

   With objArchiv

     .Create CurrentProject.Path _
& "\VerzeichnisOhneRootMitPfad.zip"

     .RootPath = CurrentProject.Path

     .AddFolder CurrentProject.Path _
& "\zip\", includeSubDirs:=True, _
FullPath:=False

   End With

End Sub

Selbst wenn sich das betroffene Verzeichnis unter c:\Unterordner1\Unterordner2\zip befindet, enthält das Zip-File nur noch das Verzeichnis zip als Hauptordner (s. Abb. 3).

pic004.tif

Abb. 3: Mit der Eigenschaft RootPath kann man Teile des Zielverzeichnisses abschneiden, damit beim Entpacken nicht die kompletten übergeordneten Verzeichnisse des Originals nachgebildet werden.

Kompressionsrate

Für alle Archivierungsvorgänge gilt: Sie können die Kompressionsrate mit dem Parameter level für jedes mit einem einzelnen Add...-Befehl hinzugefügte Element (egal, ob Datei oder Ordner) einstellen. Die Werte reichen von 0 (keine Kompression) bis 9 (maximale Kompression).

Datei unter anderem Namen archivieren

Mit der Methode AddFileAs können Sie vorhandene Dateien unter einem anderen Namen im Zip-File archivieren, ohne dass Sie die Datei zuvor umbenennen müssen. Geben Sie einfach den neuen Namen zusätzlich zum Originalnamen an:

Public Sub DateiUnterAnderemNamen()

   ‘...

   With objArchiv

     .Create CurrentProject.Path & "\DateiUnterAnderemNamen.zip"

     .AddFileAs CurrentProject.Path & _
"\zip\test01.txt", "NeuerName.txt"

   End With

End Sub

Entpacken

Die SawZipNG-Bibliothek liefert auch Methoden zum automatisierten Entpacken von Zip-Dateien. Dies ist unter anderem sinnvoll, wenn Sie per Mail oder FTP zugestellte Zip-Dateien entpacken und die enthaltenen Daten in irgendeiner Weise weiterverarbeiten möchten (zum Beispiel könnten Anwendungen beim Kunden Fehlermeldungen in eine Textdatei schreiben, diese in einem Archiv speichern und zum Entwickler schicken). Üblicherweise extrahiert man direkt alle Dateien eines Archivs. Dies kann wie in folgendem Beispiel aussehen:

Public Sub AllesEntpacken()

   Dim objArchiv As SAWZipNG.Archive

   Dim i As Integer

   Set objArchiv = New SAWZipNG.Archive

   objArchiv.Open CurrentProject.Path & _
"\VerzeichnisseMitRoot.zip"

   With objArchiv

     For i = 0 To objArchiv.FileCount - 1

       .Extract i, CurrentProject.Path _
& "\Extrahiert"

     Next i

   End With

End Sub

Die Routine erzeugt zunächst auf die gleiche Weise wie auch beim Packen ein Archive-Objekt. Dem weist sie aber mit der Open-Methode ein existierendes Zip-File zu. Anhand der FileCount-Eigenschaft ermittelt sie die Anzahl der enthaltenen Dokumente und durchläuft dann eine Schleife, in der jedes einzelne Dokument unterhalb des angegebenen Verzeichnisses extrahiert wird. Dabei ist zu beachten, dass der Index bei 0 beginnt.

Verschlüsseltes Archiv entpacken

Beim Entpacken verschlüsselter Archive ist die Angabe des Passwortes mit derselben Eigenschaft wie beim Verschlüsseln selbst erforderlich. Wird vor der Extract-Methode kein oder ein falsches Passwort angegeben, löst dies einen Fehler aus:

Public Sub VerschluesseltesArchivEntpacken()

   ‘...

   With objArchiv

     For i = 0 To objArchiv.FileCount - 1

       .Password = "test"

       .Extract i, CurrentProject.Path _
& "\Extrahiert"

     Next i

   End With

End Sub

Bestimmte Datei entpacken

Gegebenenfalls möchten Sie auch einmal nur eine einzige Datei aus einem Archiv entpacken. Wenn Sie sich nur auf den Dateinamen beziehen möchten, verwenden Sie etwa die folgende Routine. Zu beachten sind die einzelnen Parameter der FindFile-Funktion. Diese Funktion liefert den Index der gefundenen Datei zurück, sonst den Wert -1.

Public Sub EineDateiEntpacken()

   ‘...

   With objArchiv

     i = .FindFile("Test01.txt", _
caseSensitive:=FF_NON_SENSITIVE, _
filenameOnly:=True)

     .Extract i, CurrentProject.Path, False

   End With

End Sub

Alternative Dateiendung

Da Zip-Dateien hier und da im Spam-Filter hängen bleiben, benötigen Sie gegebenenfalls eine alternative Dateiendung. Das ist kein Problem: Legen Sie das Archiv einfach unter der gewünschten Endung an; auch das Extrahieren mit SawZipNG bereitet mit alternativen Dateiendungen keine Probleme.

Zusammenfassung und Ausblick

Diese SawZipNG-Bibliothek liefert alles, was das Archivierer-Herz höher schlagen lässt. Neben den hier vorgestellten Möglichkeiten gibt es noch einige weitere Funktionen und Eigenschaften. Für weitere Informationen bietet sich das Studium der HTML-Datei archive.html aus dem auf der Heft-CD befindlichen Paket an.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Download

Download

Die .zip-Datei enthält folgende Dateien:

SawZipNG.mdb

SawZipNG.rar

Beispieldateien downloaden

© 2003-2015 André Minhorst Alle Rechte vorbehalten.