So können Sie Bilder speichersparend verwalten

Transcrição

So können Sie Bilder speichersparend verwalten
So können Sie Bilder speichersparend verwalten
Wer schon einmal versucht hat, Grafik-Dateien mit einer Access-Datenbank über ein OLE-Feld zu
verwalten, kennt das Problem: Die Datenbank hat nach der Aufnahme weniger Bilder/Grafiken eine
unverhältnismäßige Größe erreicht. Nicht selten belegt die Datenbank-Datei früher oder später 100,
200 oder mehr MB auf der Festplatte. Außerdem ist die Anzeige der Bilder/Grafiken in einem Formular
extrem träge - teilweise vergehen Sekunden, bis man sich das Ergebnis ansehen kann. Schließlich ist
die Verwaltung von Grafiken über OLE-Felder auch immer ein wenig doppelte Datenhalten: Die
Grafiken liegen in der Regel bereits als Dateien auf der Festplatte vor, werden von Access aber
zuzüglich einer Vorschaugrafik noch einmal in die Datenbank aufgenommen, so dass sich doppeltund dreifacher Platzbedarf ergibt.
Das lässt sich mit einem kleinen Trick vermeiden: Verwalten Sie in der Datenbank lediglich die Pfade
und Dateinamen der Grafiken verwaltet und zeigen Sie sie sozusagen "on the fly" in Ihren Formularen
an. Das hält die Größe der Datenbank in akzeptablen Grenzen und beschleunigt je nach GrafikFormat sogar die Anzeige. Der Einbau einer solchen Verwaltung ist relativ einfach:
Erweitern Sie zunächst die betreffende Tabelle um ein Feld "Foto" vom Datentyp "Text" und stellen
Sie dessen Eigenschaft "Länge" auf 250 Zeichen ein. So ist sichergestellt, dass auch längere Pfade
problemlos gespeichert werden können.
Für die Anzeige im Formular kommt ein Steuerelement vom Typ "Bild" mit dem Namen "bldFoto" zum
Einsatz, das in der Lage ist, verschiedene Bitmap-Formate (BMP, GIF, JPG etc.) darzustellen. Es
verfügt über die Eigenschaft "Bild" (Picture), die den Pfad/Dateinamen des anzuzeigenden Bildes
aufnimmt. Über die Eigenschaft "Größenanpassung" lässt sich zusätzlich festlegen, wie die Anzeige
des Bildes innerhalb des Steuerelementes erfolgt. Die Einstellung "Abschneiden" zeigt das Bild in
Originalgröße, "Dehnen" passt das Bild sowohl in der Breite als auch in der Höhe ohne
Berücksichtigung des Seitenverhältnisses an, so dass es das gesamte Steuerelement füllt. "Zoomen"
passt das Bild unter Beibehaltung des Seitenverhältnisses so an, dass es komplett im Steuerelement
zu sehen ist.
Beim Wechsel der Datensätze ruft Access die Ereignis-Prozedur "Beim Anzeigen" (Form_Current) des
Formulars auf. Das ist genau die richtige Stelle, um eine Verbindung zwischen dem Pfad im Feld
"Foto" der Tabelle und der Anzeige über das Bild-Steuerelement "bldFoto" im Formular herzustellen.
Dafür sorgen die folgenden Anweisungen:
Private Sub Form_Current()
Dim strPicFName As String
On Error Resume Next
DoCmd.Hourglass True
If Not IsNull(Me.[Foto]) Then
strPicFName = Me.[Foto]
If Dir$(StrPicFName) <> "" Then
Me.[bldFoto].Picture = strPicFName
Else
Me.[bldFoto].Picture = ""
DoEvents
Beep
MsgBox "Bilddatei nicht gefunden!"
End If
Else
Me.[bldFoto].Picture = ""
End If
DoCmd.Hourglass False
End Sub
Als erstes wird hier eine Prüfung durchgeführt, ob überhaupt ein Bild zugeordnet ist (IsNull(Me.[Foto]))
- wenn ja, erfolgt eine Zuweisung an die Variable "strPicFName" für den einfacheren Zugriff in den
folgenden Anweisungen. Über die Konstruktion 'If Dir$(strPicFName)<> ""' prüfen wir, ob die Bild-Datei
vorhanden ist - Dir$() liefert als Ergebnis eine leere Zeichenkette, wenn die angegebene Datei nicht
existiert.
Ist die Datei vorhanden, erfolgt eine Zuweisung des Pfades/Dateinamens zur Eigenschaft "Picture"
des Bild-Steuerelementes und das Bild wird angezeigt. Wurde dem aktuellen Datensatz hingegen
noch kein Foto zugeordnet oder ist die ehemals zugeordnete Bild-Datei nicht mehr vorhanden
(umbenannt, verschoben), erfolgt die Zuweisung einer leeren Zeichenkette zur Eigenschaft "Picture".
Das Steuerelement ist dann leer. Andernfalls würde es noch das Bild des vorherigen Datensatzes
anzeigen und den Anwender somit in die Irre führen.
Bilder speichersparend verwalten, Ergänzung
FRAGE: Vor einiger Zeit haben Sie den Tipp "So können Sie Bilder speichersparend verwalten"
veröffentlicht. Ich habe diesen Tipp nun ausprobiert und zunächst funktioniert es auch ganz gut. Doch
klicke ich im Datensatznavigator einige Male schnell hintereinander auf "nächster Datensatz" stürzt
Access ohne Warnung ab. Kennen Sie dieses Problem? Gibt es dafür eine Lösung, denn ansonsten
finde ich die Routine sehr gut und würde Sie gerne einsetzen.
ANTWORT: Das Problem entsteht, weil dass Access bei einem Klick auf den Datensatznavigator die
Ereignisprozedur "Beim Anzeigen" sofort aufruft und dabei nicht prüft, ob die Ereignisprozedur bereits
ausgeführt wird. Läuft die Ereignisprozedur schon, hat sie gegebenenfalls über die Zuweisung
"Me.[bldFoto].Picture = strPicFName" einen Konvertierer aufgerufen, der die jeweilige Bilddatei (JPG,
GIF, BMP etc.) in eine im Formular/Bild-Steuerelement anzeigbare Bitmap umsetzt. Durch das
schnelle Klicken in den Datensatznavigator wird der Konvertierer eventuell mehrmals hintereinander
aufgerufen, was dann zum Absturz von Access führen kann. Mit den Bordmitteln von Access lässt sich
hier keine Abhilfe schaffen. Sie können jedoch eigene Navigationsbuttons einsetzen und den
Datensatznavigator von Access ausblenden. In der Ereignisprozedur "Beim Klicken" der eigenen
Navigationsbuttons lässt sich dann der mehrmalige Aufruf des Konverters verhindern, indem eine
globale Variable entsprechend gesetzt und abgefragt wird:
Dim bolBildLaden As Boolean
Private Sub btnNext()
Dim strPicFName As String
'Wenn Ereignisprozedur läuf, zurückspringen
If bolBildLaden Then
Beep
Exit Sub
End If
'Hier der Code zum Datensatzwechsel
'.....
'.....
On Error Resume Next
bolBildLaden = True
DoCmd.Hourglass True
If Not IsNull(Me.[Foto]) Then
strPicFName = Me.[Foto]
If Dir$(StrPicFName) <> "" Then
Me.[bldFoto].Picture = strPicFName
Else
Me.[bldFoto].Picture = ""
DoEvents
Beep
MsgBox "Bilddatei nicht gefunden!"
End If
Else
Me.[bldFoto].Picture = ""
End If
DoCmd.Hourglass False
bolBildLaden = False
End Sub
Die Variable "bolBildLaden" gibt hier jeweils Auskunft, ob das Laden eines Bildes bereits läuft oder
nicht. Wenn ja, wird die Prozedur verlassen, ein Datensatzwechsel verhindert und so der mehrmalige
Aufruf des Konverters mit eventuellem Absturz von Access vermieden.
Bilder in Access-Datenbanken (Nachtrag)
FRAGE: Vielen Dank für Ihren Beitrag zur Verwaltung von Grafiken in Access. Trotzdem ist mir die
ganze Sache unklar: In der Beispieldatenbank "Nordwind" sind doch in der Tabelle "Personal" auch
Fotos der Angestellten als OLE-Objekte enthalten, die Foto-Bitmaps liegen also direkt in der
Datenbank. Und träge ist die Anzeige keineswegs. Die MDB-Datei ist 1706 KB groß - ist das
unverhältnismäßig? Beim Laden der Datenbank mit Bilddaten liegen diese zunächst als Datei vor.
Wenn sie aber direkt in die Datenbank aufgenommen werden, kann man doch die Original-Bilddateien
wieder von der Festplatte löschen, oder? Doppelte Datenhaltung muss also nicht sein; vielmehr
interessiert mich, wie ich die Bilddaten in die Datenbank aufnehmen kann.
ANTWORT: Von der "Nordwind" können Sie leider nicht ausgehen: Dort sind vergleichsweise wenige
Bilder im Format "BMP" eingebunden, so dass sie direkt im Formular angezeigt werden können. Wenn
Sie jedoch Bilder in anderen Formaten - JPG, GIF, TIF - einbinden, muss zusätzlich zu den JPG-,
GIF-, oder TIF-Daten noch ein Abbild im BMP-Format gespeichert werden, das Access anstelle der
JPG-, GIF, oder TIF-Daten im Formular anzeigt. Dadurch ergibt sich ein enormer Mehrbedarf an
Speicherplatz, der sich bei einigen Dutzend oder gar Hunderten von Bildern schnell im dreistelligen
MB-Bereich bewegt und die Datenbank zusätzlich träge macht. Was das Löschen der Original-Dateien
nach der Einbindung als OLE-Objekt betrifft: Es ist nicht immer möglich, die Originale zu löschen, da
sie beispielsweise gleichzeitig in einem Access-Infosystem für die Sachbearbeiter und in einem WordDokument für die Erstellung eines hochwertigen Kataloges eingebunden sind. Bei der Druckausgabe
in Word zum Beispiel über einen PostScript-Treiber für die Belichtung auf Film müssen die OriginalDateien also vorliegen.
Wo das nicht der Fall ist, können Sie Bilder in Tabellen über Felder des Datentyps "OLE-Objekt"
speichern. In Formularen setzen Sie für die Anzeige ein Steuerelement des Typs "Gebundenes
Objektfeld" ein (Bildsymbol mit einem "XYZ"-Rahmen in der Toolbox). Um ein Bild in ein solches Feld
zu laden, gibt es zwei Möglichkeiten:
Markieren Sie das Steuerelement für das Bild im Formular per Klick und wählen Sie das Menü
Einfügen-Objekt an.
Klicken Sie mit der rechten Maustaste auf das Steuerelement und wählen Sie Objekt einfügen im
Kontextmenü an.
Access präsentiert einen Dialog "Objekt einfügen", in dem Sie nun zunächst die Option Aus Datei
erstellen aktivieren. Die Option Verknüpfen darf nicht aktiviert sein! Über die Schaltfläche
Durchsuchen lokalisieren Sie dann das gewünschte Bild und klicken abschließend im Dialog "Objekt
einfügen" auf Ok. Etwas vereinfachen lässt sich das wie folgt:
Legen Sie neben oder unter dem Steuerelement für das Bild eine Schaltfläche "btnWaehlen" an.
Setzen Sie die Eigenschaft "Beim Klicken auf "[Ereignisprozedur]", klicken Sie auf die Schaltfläche mit
den drei kleinen Punkten dahinter und geben Sie folgende Anweisungen im VBA-Editor ein:
Private Sub btnWaehlen_Click()
On Error Resume Next
Me.Foto.SetFocus
DoCmd.RunCommand acCmdInsertObject
End Sub
"On Error Resume Next" verhindert zunächst die Anzeige eines Laufzeitfehlers, wenn die Anweisung
"DoCmd..." abgebrochen wird. Dann setzen wir den Fokus auf das betreffende Steuerelement für das
Bild, hier "Foto" und rufen dann die Funktion "Objekt einfügen" über "DoCmd.RunCommand
acCmdInsertObject" auf. Wenn Sie hier auf Abbrechen klicken, würde Access einen Laufzeitfehler
anzeigen, den wir aber wie oben erläutert, über "On Error Resume Next" vermeiden.