Button Home/Top/Zurück


Bilder in Formularen und Berichten




Es gibt eine ganze Reihe von Anwendungsbeispielen die mit Bilddateien umgegangen müssen. Hierbei stellt sich dann die Frage, wie man eine Bilddatei in der Datenbank abgelegt bzw. eine Verknüpfung von einem Datensatz zu einer Bilddatei auf der Festplatte herstellt.

Lösungsansatz
Es gibt verschieden Möglichkeiten mit Bilddateien umzugehen.

Bei der ersten wird in der Datenbank in der entsprechenden Tabelle eine Spalte vom Typ OLE-Objekt definiert. In diesem Objekt wird dann die Bilddatei gespeichert. Der Vorteil bei diesem Vorgehen ist, daß nach dem Speichern der Bilddatei in der Tabelle, diese nicht mehr auf der Festplatte vorgehalten werden muß. Darüber hinaus benötigt man für die Darstellung der Bilddatei in Formularen und Berichten lediglich ein gebundenes Objektfeld welchem einfach die Tabellenspalte des Bildes (OLE-Objekt) als Steuerelementinhalt zugewiesen wird.

Bei der zweiten Möglichkeit wird in der Datenbank lediglich ein Verweis (Dateiname ggf. mit Pfadangabe) der Bilddatei gespeichert. Dieses Vorgehen hat - gegenüber der 1. Variante - den Vorteil, daß die Datenbank nicht überproportional wächst, was auf die Größe der Bilddateien zurückzuführen ist, welche bei der ersten Variante Bestandteil der Datenbank sind.
Der Nachteil bei diesem Vorgehen ist - mal abgesehen davon daß die Bilddateien immer auf der Festplatte verfügbar sein müssen - daß der Entwickler sich selber um die Anzeige des Bildes in Formularen und Berichten kümmern muß.

Eine weitere Möglichkeit ist es, das Bild im binären Format in der Tabelle zu speichern.
Diese Möglichkeit hat den Vorteil, daß die Bilddaten in der Datenbank gespeichert werden, die ursprünglichen Bilddateien also nicht vorgehalten werden müssen. Außerdem wird hier die Größe der Datenbank nicht in dem Maße beeinflußt, wie es bei der ersten Variante der Fall ist.
Der einzige Nachteil ist, daß man sich selber um die Anzeige der Bilder kümmern muß.

Ich möchte es an dieser Stelle nicht versäumen den Verfechter dieser Variante (Sascha Trowitzsch) für die Bereitstellung der entsprechenden Funktionen und Prozeduren zu danken.

Danke Sascha



Voraussetzungen
Es sind verschiedene Bilddateien vorhanden.

Implementierung
Als erstes wird eine Tabelle angelegt, in der auch die Bildinformationen abgelegt werden können.
Diese könnte z.B. so aussehen:
ID | Bildname | Bilddatei        | BildObjekt | BinaerBild
---+----------+------------------+------------+------------
 1 | Bild 1   | C:\pic\Bild1.gif |            |
 2 | Bild 2   | C:\pic\Bild2.gif |            |
 3 | Bild 3   | C:\pic\Bild3.gif |            |
In der Spalte BildObjekt wird etwas wie Microsoft Photo Editor 3.0 zu sehen sein, wenn dort eine Bilddatei, als OLE-Objekt, speichert ist.
In der Spalte BinaerBild wird Long binary-Daten zu sehen sein, wenn dort eine Bilddatei im Binärformat gespeichert ist.
Beide Tabellenfelder sind vom Typ OLE-Objekt

Um nun eine Bilddatei von der Festplatte auszuwählen, wird der Datei-Öffnen Dialog aus der WIN-Api benötigt. Diesen Dialog gibt es bei Reinhard Kraasch (vielen Dank ).
Der Datei-Öffnen Dialog liefert, wenn denn eine Bilddatei ausgewählt wurde, den Dateinamen mit Pfadangaben zurück. Dieser Dateiname wird (komplett) in der Spalte Bilddatei der Tabelle gespeichert.
Darüber hinaus wird die Bilddatei im BildObjekt und im BinaerBild der Tabelle abgelegt.

Nachfolgend ein Code Beispiel für einen Button zur Auswahl einer Bilddatei (hier im GIF Format).
Private Sub PbOpenFile_Click()
'
' Ereignisprozedur "Beim Klick" eines Button zur Auswahl einer Bild-Datei
'
Dim Tmp, Tmp1
Dim sStartPath As String
Dim PfadDerDatenbank As String
    '
    ' Für den Fall, daß bereits ein Bilddatei im
    ' aktuellen Datensatz gespeichert ist, wird
    ' der FileOpen-Dialog in dessen Verzeichnis gestartet
    '
    If Me.Bilddatei <> "" Then
        sStartPath = GetPfad(Me.Bilddatei)
    Else
        sStartPath = "C:\"
    End If
    '
    ' Aufruf des Open-File Dialoges aus der WIN-Api
    '
    Tmp = FileDialog(True, "Datei öffnen", _
        "GIF Dateien (*.gif)" & Chr(0) & "*.gif" & Chr(0) & _
        "Grafik Dateien (*.gif)" & Chr(0) & "*.gif" & Chr(0) & _
        "Alle Dateien (*.*)" & Chr(0) & "*.*", "*.tmp", sStartPath, gblFlags, Me.hWnd)
    '
    ' Wenn eine Datei ausgewählt wurde (Tmp ist nicht leer)
    ' dann...
    '
    If Trim$(Tmp) <> "" Then
        '
        ' Als Default-Wert für den Bildnamen wird der Dateiname verwendet
        '
        If IsNull(Me.Bildname) Then
            '
            ' Dir() liefert, wenn man einen Dateinamen mit Pfad als
            ' Parameter übergibt den Dateinamen zurück !
            '
            Me.Bildname = Dir(Tmp)
        End If
        '
        '
        ' ...Pfad und Name der Bilddatei speichern
        '
        Me.Bilddatei = Tmp
        '
        ' ...Bild im Bild-Steuerelement anzeigen
        '
        Me.PicBild.Picture = Tmp
        '
        ' ...Bilddatei als Source des Bildobjektes angeben
        '
        Me.ObjBild.SourceDoc = Tmp
        '
        ' ...Bildobjekt erzeugen
        '
        Me.ObjBild.Action = acOLECreateEmbed
        '
        ' ...Bild im Binärformat speichern
        '    dazu muß der DS aber erst mal gespeichert werden
        '
        DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
        '
        '    und das OLE-Feld mit dem Binären Daten aktualisiert werden
        '
        UpdatePixFile Tmp, Me.Bildname
        '
        ' Sonderbehandlung für das Bildobjekt, welches das Bild aus dem
        ' Unterverzeichnis des DB Verzeichnisses anzeigen soll.
        ' Die Eigenschaft Picture wird beim Form_Current Ereignis korrekt gesetzt,
        ' d.h. an dieser Stelle muß das noch mal gemacht werden.
        '
        PfadDerDatenbank = GetPfad(CurrentDb.Name)
        Me.PicAusUnterverz.Picture = PfadDerDatenbank & "Bilder\" & GetDateiname(Me.Bilddatei)
    End If
 
End Sub

In diesem Beispiel ist
  • Me.Bilddatei ein Textfeld des Formulars, welches den Dateinamen (mit Pfadangabe) aufnimmt.
  • Me.PicBild ein Bild-Steuerelement, welches zur Anzeige der Bilddatei verwendet wird.
  • Me.ObjBild ein gebundenes Objektfeld, welches die Bilddatei aufnimmt.
  • UpdatePixFile eine Prozedur, die das Bildobjekt im Binärformat speichert.
Für die Variante, in der die Bilddatei in der Datenbank gespeichert wird, ist an dieser Stelle alles getan.
Für die zweite Variante muß beim Aktualisieren des Formulars (wenn ein neuer/anderer Datensatz angezeigt wird) eine Aktualisierung des Bild-Steuerelementes erfolgen.
Für die Variante, in der das Bild im Binärformat gespeichert wurde, muß beim Aktualisieren des Formulars eine temporäre Bilddatei erzeugt werden, um diese in einem Bildobjekt auf dem Formular anzuzeigen.
Hierzu folgendes Code Beispiel:
Private Sub Form_Current()
'
' Ereignisprozedur "Beim Anzeigen" des Formulars
'
Dim PfadDerDatenbank As String
    '
    ' Prüfen, ob eine Bilddatei (Pfad und Name)
    ' für den aktuellen Datensatz angegeben ist.
    '
    If Not IsNull(Me.Bilddatei) Then
        '
        ' Wenn Bilddatei angegeben ist, dann
        ' diese im Bild-Steuerelement anzeigen
        '
        Me.PicBild.Picture = Me.Bilddatei
        '
        ' Speicher-Ort der Datenbank ermitteln
        ' Die Funktion GetPfad() ist im Modul MdlUitl enthalten
        '
        PfadDerDatenbank = GetPfad(CurrentDb.Name)
        '
        ' Aus dem Pfad der Datenbank und der "festen" Unterverzeichnis
        ' den Namen der Bilddatei bilden und diese im
        ' Bild-Steuerelement anzeigen.
        ' Die Funktion GetDateiname() ist im Modul MdlUitl enthalten.
        '
        Me.PicAusUnterverz.Picture = PfadDerDatenbank & "Bilder\" & GetDateiname(Me.Bilddatei)
        '
        ' Aus den gespeicherten Binärdaten des Bildes muß (zur Anzeige des selben) eine Bilddatei
        ' erzeugt werden.
        ' Die Bilddatei wird im Verzeichnis der Datenbank unter dem Namen 'tmp.gif' angelegt.
        '
        CreatePixFile PfadDerDatenbank & "/tmp.gif", Me.Bildname
        '
        ' Dem Bild-Steuerelement auf dem Formular die temp. Bilddatei als
        ' Quelle zuweisen, um das Bild anzuzeigen.
        '
        Me.PicBinaer.Picture = PfadDerDatenbank & "/tmp.gif"
    Else
        '
        ' Wenn keine Bilddatei angegeben ist, dann
        ' dafür sorgen, daß im Bild-Steuerelement
        ' nichts angezeigt wird.
        ' Anderenfalls wird das Bild aus dem vorhergehenden
        ' Datensatz angezeigt.
        '
        Me.PicBild.Picture = ""
        Me.PicAusUnterverz.Picture = ""
    End If
 
End Sub

Neben dem Bild-Steuerelement, welches schon im vorhergehenden Code Beispiel verwendet wurde, gibt es in diesem Beispiel ein zweites Bild-Steuerelement (Me.PicAusUnterverz).
Dieses dient zur Verdeutlichung, was zu tun ist wenn die Bilddateien an einem quasi variablen Ort abgelegt werden sollen/müssen. Im Beispiel liegen die Bilddateien im Unterverzeichnis Bilder des Verzeichnisses, in welchem die Datenbank abgelegt ist.

Wenn die Bilder in einem Bericht angezeigt werden sollen, ist die Ereignisprozedur Beim Formatieren des Detailbereiches des Berichtes zu implementieren.
Da sich diese ein wenig von der Ereignisprozedur Beim Anzeigen des Formulars unterscheidet, hier auch dieser Code:
Private Sub Detailbereich_Format(Cancel As Integer, FormatCount As Integer)
'
' Ereignisprozedur "Beim Formatieren" des Detail-Bereiches
'
Dim PfadDerDatenbank As String
Dim TmpBildDatei As String
 
    '
    ' Prüfen, ob eine Bilddatei angegeben ist
    '
    If Not IsNull(Me.Bilddatei) Then
        '
        ' Wenn Bilddatei angegeben ist, dann dieses
        ' Bild im Bild-Steuerelement anzeigen
        '
        Me.PicBild.Picture = Me.Bilddatei
        '
        ' Bildsteuerelement sichtbar machen.
        '
        Me.PicBild.Visible = True
        '
        ' Speicher-Ort der Datenbank ermitteln
        ' Die Funktion GetPfad() ist im Modul MdlUitl enthalten
        '
        PfadDerDatenbank = GetPfad(CurrentDb.Name)
        '
        ' Aus dem Pfad der Datenbank und der "festen" Unterverzeichnis
        ' den Namen der Bilddatei bilden und diese im
        ' Bild-Steuerelement anzeigen.
        ' Die Funktion GetDateiname() ist im Modul MdlUitl enthalten.
        '
        Me.PicAusUnterverz.Picture = PfadDerDatenbank & "Bilder\" & GetDateiname(Me.Bilddatei)
        Me.PicAusUnterverz.Visible = True
        '
        ' Aus der binären Bildinformation muß eine temp. Bilddatei erzeugt werden.
        ' Da ggf. mehrer Bilder angezeigt werden, muß der Name der Bilddatei eindeutig sein.
        ' Wir verwenden dafür einfach die ID aus der Bildtabelle.
        ' Diese steht in dem unsichtbaren Textfeld dfID
        '
        TmpBildDatei = PfadDerDatenbank & "/tmp" & Trim(Str(Me.dfID)) & ".gif"
        CreatePixFile TmpBildDatei, Me.Bildname
        '
        ' Dem Bild-Steuerelement auf dem Formular die temp. Bilddatei als
        ' Quelle zuweisen, um das Bild anzuzeigen.
        '
        Me.PicBinaer.Picture = TmpBildDatei
 
    Else
        '
        ' Wenn keine Bilddatei angegeben ist, dann
        ' dafür sorgen, daß im Bild-Steuerelement
        ' nichts angezeigt wird.
        '
        Me.PicBild.Picture = ""
        Me.PicAusUnterverz.Picture = ""
        Me.PicBinaer.Picture = ""
        '
        ' um ganz sicher zu gehen das Bild-Steuerelement
        ' unsichtbar machen.
        '
        Me.PicBild.Visible = False
        Me.PicAusUnterverz.Visible = False
        Me.PicBinaer.Visible = False
    End If
 
End Sub

Die Darstellung der Prozeduren von Sascha spare ich mir hier, diese sind in der Beispiel-Datenbank enthalten und ausreichend kommentiert.
WinZip Icon Beispiel als ZIP-File (87 KB) zum downloaden.

Die ZIP-Datei enthält neben der Datenbank auch einige Bilddateien.
Die Daten in der Beispiel-Datenbank enthalten Pfadangaben die mit an Sicherheit grenzender Wahrscheinlichkeit nur auf meinem Rechner passen. Deshalb werden, ohne Vorhergehende Korrektur der Daten (Tabelle Bilddaten, Spalte Bilddatei) im Formular/Bericht nicht alle Bilder angezeigt werden.

Button Home/Top/Zurück