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

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 6/2006.

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

Berichte und Reporting

Flexible Briefköpfe in Berichten

Wie seinen Rechner, sein Auto oder das Design seiner Internetseite wird man gelegentlich auch mal das Aussehen seines Briefkopfes leid und tauscht diesen kurzerhand aus. Kurzerhand? Nicht wirklich: Wenn Sie etwa mehrere Access-Anwendungen anpassen müssen, die wiederum mehrere Berichte mit Ihrem Briefkopf enthalten, wartet eine Menge Handarbeit auf Sie.

Dabei geht es doch viel leichter: Erstellen Sie doch einfach einen Unterbericht mit dem Briefkopf und fügen Sie diesen in alle anderen Berichte, die einen Briefkopf benötigen, ein. Damit brauchen Sie Änderungen nur noch an einer Stelle vorzunehmen. Selbst wenn Sie mehrere Anwendungen haben, die Berichte mit einem Briefkopf enthalten, ist die Aufgabe schnell erledigt, denn Sie müssen ja nur den angepassten Bericht mit dem Briefkopf in alle relevanten Access-Datenbanken kopieren.

Und so funktioniert es: Legen Sie einen Bericht an und platzieren Sie darin die Elemente Ihres Briefkopfes. Entfernen Sie die Berichtskopfelemente aus einem vorhandenen Bericht. Fügen Sie dann den Bericht mit dem Briefkopf in den Zielbericht ein – das geht am einfachsten, wenn Sie den Zielbericht in der Entwurfsansicht öffnen und den einzufügenden Bericht aus dem Datenbankfenster an die gewünschte Stelle des Zielberichts ziehen.

VBA und Programmiertechnik

Doppelten Code loswerden

Wer keine Arbeit hat, der macht sich welche. Zum Beispiel, indem er funktionierende Codepassagen aus einer Routine in eine andere Routine kopiert. Funktioniert per Copy and Paste und liefert auch funktionell das gewünschte Ergebnis.

Manchmal programmiert man auch unbewusst an zwei Stellen innerhalb des gleichen Moduls oder zumindest innerhalb der gleichen Anwendung Codezeilen, die entweder völlig identisch sind oder zumindest genau die gleiche Funktion haben. Stehen dann einmal Änderungen innerhalb dieser Code-Dubletten an, hat man direkt die doppelte (oder x-fache) Arbeit: Jede Änderung müssen Sie an mehreren Stellen durchführen, damit alles wieder wie gewünscht funktioniert. Dabei lassen sich solche Probleme ganz einfach lösen: „Klammern“ Sie den doppelten Code einfach aus, indem Sie ihn in einer eigenen Routine anlegen und von den ursprünglichen Routinen darauf verweisen. Im einfachsten Fall funktioniert das nach dem folgenden Schema: Nehmen wir an, dass Sie bei bestimmten Aktionen eine Reihe von Steuerelementen in einem Formular aktivieren oder deaktivieren möchten und dass a im ganzen Modul bekannt ist:

Private Form_Load()

    If a Then

         Me!txt1.Enabled = True

         Me!txt2.Enabled = True

         Me!txt3.Enabled = True

     Else

         Me!txt1.Enabled = False

         Me!txt2.Enabled = False

         Me!txt3.Enabled = False

     End If

     ...

End Sub

Private cmdBeispiel_Click()

     If a Then

         Me!txt1.Enabled = True

         ...

End Sub

Wenn Sie dies nun bei verschiedenen Gelegenheiten tun – etwa beim Öffnen des Formulars, beim Anzeigen eines neuen Datensatzes oder beim Klick auf eine bestimmte Schaltfläche – haben Sie den gleichen Code an mehreren Stellen stehen. Kommt nun noch ein weiteres Steuerelement hinzu, müssen Sie den Code an mehreren Stellen anpassen. Stattdessen erstellen Sie eine neue Funktion mit einem sinnvollen Namen, etwa SteuerelementeAnpassen.

Private Sub SteuerelementeAnpassen

     If a Then

         Me!txt1.Enabled = True

         Me!txt2.Enabled = True

         Me!txt3.Enabled = True

     Else

         Me!txt1.Enabled = False

         Me!txt2.Enabled = False

         Me!txt3.Enabled = False

     End If

End Sub

Ersetzen Sie dann diese „extrahierten” Zeilen an allen betroffenen Stellen durch einen einfachen Aufruf der neuen Routine SteuerelementeAnpassen, etwa so:

Private Form_Load()

     SteuerelementeAnpassen

     ...

End Sub

Private cmdBeispiel_Click()

     SteuerelementeAnpassen

     ...

End Sub

Nun können Steuerelemente hinzukommen oder wegfallen, wie sie wollen, die Anpassung müssen Sie immer nur an einer Stelle vornehmen.

Etwas komplizierter wird die Angelegenheit, wenn Variablen ins Spiel kommen. Dazu können wir wiederum die Ausgangsposition des ersten Beispiels verwenden – mit dem kleinen Unterschied, dass wir davon ausgehen, dass a nur innerhalb der einzelnen Routinen bekannt ist.

Dann müsste man a mit einem Parameter übergeben, was bei der neuen extrahierten Routine wie folgt aussähe:

Private Sub SteuerelementeAnpassen(a As Boolean)

     If a Then

         Me!txt1.Enabled = True

         Me!txt2.Enabled = True

         Me!txt3.Enabled = True

     Else

         Me!txt1.Enabled = False

         Me!txt2.Enabled = False

         Me!txt3.Enabled = False

     End If

End Sub

Der Aufruf in den Ausgangsroutinen sieht dann wie folgt aus:

Private Form_Load()

     SteuerelementeAnpassen a

     ...

End Sub

Private cmdBeispiel_Click()

     SteuerelementeAnpassen a

     ...

End Sub

Noch komplizierter wird es, wenn die zu extrahierenden Zeilen ein Ergebnis liefern, das in den Folgezeilen weiter verwendet wird. Als Beispiel dient die folgende Routine, die nacheinander die Anführungszeichen und die Hochkommata aus einem String entfernt:

Private Sub Ausgangsroutine1

     Dim strAlt As String

     Dim strNeu As String

     ...

     strNeu = Replace(strAlt, Chr(34), Chr(34) & Chr(34))

     strNeu = Replace(strNeu, Chr(39), Chr(39) & Chr(39))

     ...

End Sub

Die neu zu erstellende Routine muss nicht nur eine Variable in Empfang nehmen, sondern auch noch einen Wert zurückliefern:

Private Function ZeichenErsetzen(strOriginal As String) As String

     Dim strTemp As String

     strTemp = Replace(strOriginal, Chr(34), Chr(34) & Chr(34))

     strTemp = Replace(strTemp, Chr(39), Chr(39) & Chr(39))

     ZeichenErsetzen = strTemp

End Function

Der Ersatz für die Zeilen in der Ursprungsroutine sieht dann so aus:

Private Sub Ausgangsroutine1

     Dim strAlt As String

     Dim strNeu As String

     ...

     strNeu = ZeichenErsetzen(strAlt)

     ...

End Sub

Es gibt noch eine weitere Ausbaustufe, bei der mehr als ein Wert zurückgegeben wird – diesen behandeln wir aber an anderer Stelle. Die Beispieleliefern neben der möglichen Zeitersparnis noch einen weiteren großen Vorteil: Die ursprünglichen Routinen wirken wesentlich aufgeräumter. Dadurch, dass mehrere Zeilen mit teilweise schwer lesbaren Anweisungen einfach in eine weitere Routine ausquartiert wurden und einen aussagekräftigen Namen erhielten, ist der Code in der Ausgangsroutine nun sehr viel lesbarer geworden.

Benutzeroberfläche und Formulare

Neue Eigenschaften für Formulare

Die Übergabe von Parametern von Formular zu Formular erfolgt meist auf eine der folgenden Arten:

  • beim Aufruf des Formulars über den OpenArgs-Parameter der DoCmd.OpenForm-Methode,
  • nach dem Aufruf des Formulars durch Zuweisen von Werten an Textfelder, die gegebenenfalls nicht sichtbar sind,
  • durch das Auslesen eines Wertes aus einer zuvor gefüllten globalen Variable oder
  • durch das Auslesen von Werten, die etwa in Steuerelementen des aufrufenden Formulars enthalten sind.

Eine weitere sinnvolle Alternative ist die Übergabe an eine neu definierte Variable des Formulars. Die Klassenmodule von Formularen können Sie genau wie übliche Klassenmodule mit privaten Eigenschaften versehen, die von außen über Property Let- und Property Set-Prozeduren gefüllt und ausgelesen werden können.

Im Detail legen Sie dazu im Formularmodul eines Formulars – etwa dem aus Abb. 1 – zunächst eine private Variable an:

Dim mPersonalID As Long

Damit Sie die Eigenschaft von außen füllen können, fügen Sie außerdem die folgende Property Set-Prozedur hinzu:

Public Property Let Personalnummer(lngPersonalID As Long)

     mPersonalID = lngPersonalID

     Me.Recordset.FindFirst „PersonalID = „ _
& mPersonalID

End Property

Diese Prozedur speichert nicht nur den Wert in der dafür vorgesehenen lokalen Variablen, sondern macht auch direkt etwas damit: Und zwar versucht sie, den Datensatz mit der angegebenen Personalnummer zu finden und anzuzeigen.

Um den Wert von außen zu ändern und damit zu einem anderen Datensatz zu wechseln, müssen Sie nur von einer anderen Routine oder über das Direktfenster den folgenden Befehl absetzen:

Forms!frmFormulareigenschaften.Personalnummer = 2

Achtung: Diese Vorgehensweise funktioniert nicht mit modal geöffneten Formularen.

pic001.tif

Abb. 1: Entwurfsansicht des Beispielformulars mit einer neuen Eigenschaft

Benutzeroberfläche und Formulare

Windows Explorer in Formular einbauen

Wer viel mit Access entwickelt, greift immer mal wieder auf den Windows Explorer zu. Wussten Sie, dass man diesen auch in ein Access-Formular integrieren kann? Und das geht so: Fügen Sie dem leeren Formular zunächst ein Webbrowser-ActiveX-Steuerelement hinzu und ändern Sie seinen Namen auf ctlWebbrowser. Erstellen Sie außerdem ein Textfeld sowie eine Optionsgruppe wie in Abb. 1 und vergeben Sie von links nach rechts die Optionswerte 1, 3, 4, 5 und 6 für die Optionen. Das Textfeld soll txtVerzeichnis, die Optionsgruppe (also der Rahmen) ogrAnsicht heißen.

Legen Sie für das Formular die Ereignisprozedur Beim Laden an und ergänzen Sie diese wie die Prozedur Form_Load aus Listing 1.

Fügen Sie auch die übrigen Prozeduren zum Modul hinzu und vergessen Sie nicht, den entsprechenden Ereigniseigenschaften den Wert [Ereignisprozedur] zuzuweisen.

Fertig! Jetzt müssen Sie nur noch in die Formularansicht wechseln und den Windows Explorer im Formular einsetzen.

Listing 2: Schnelles Filtern mit mehreren Parametern

Option Compare Database

Option Explicit

Dim WithEvents objWebbrowser As SHDocVw.WebBrowser

Private Sub Form_Load()

     Set objWebbrowser = Me.ctlWebbrowser.Object

     objWebbrowser.Navigate CurrentProject.Path

     objWebbrowser.Document.currentviewmode = Me!ogrAnsicht

End Sub

Private Sub objWebbrowser_DocumentComplete(ByVal pDisp As Object, _
URL As Variant)

     If objWebbrowser.ReadyState <> READYSTATE_COMPLETE Then

         DoEvents

     End If

     objWebbrowser.Document.currentviewmode = Me!ogrAnsicht

End Sub

Private Sub Form_Resize()

     If Me.Form.InsideHeight - Me.Formularkopf.Height > 150 Then

         objWebbrowser.Height = Me.Form.InsideHeight - _
Me.Formularkopf.Height - 150

     End If

     objWebbrowser.Width = Me.Form.InsideWidth

End Sub

Private Sub ogrAnsicht_AfterUpdate()

     objWebbrowser.Document.currentviewmode = Me!ogrAnsicht

End Sub

Private Sub txtVerzeichnis_AfterUpdate()

     objWebbrowser.Navigate Me!txtVerzeichnis

     objWebbrowser.Document.currentviewmode = Me!ogrAnsicht

End Sub

pic002.tif

Abb. 1: Der Windows Explorer im Access-Formular

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:

TippsUndTricks_2006_06.mdb

Beispieldateien downloaden

© 2003-2015 André Minhorst Alle Rechte vorbehalten.