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.