PDA

Vollständige Version anzeigen : Eigene Befehlsschaltfläche erstellen (getestet für Access 97 und 2000)


Bourbon
24.10.2008, 15:47
Mein erster Beitrag, habt Nachsicht und behaltet diverse Rechtschreibfehler denn ich schenke sie euch ;)

Frage:
Wie kann ich in Access eine Befehlsschaltfläche (Button) mit eigenem Hintergrundbild (nicht *.bmp) erstellen?

Problem:
Access bietet von Haus aus nur Befehlsschaltflächen (Buttons) mit Hintergrundbilder als Bitmap (*.bmp) an.
Für Optische Gründe (Transparenz o.ä.) bedarf es oft einen Button mit Hintergrundbildern als *.png, oder *.gif .
Um dieses Problem zu lösen bedienen wir uns der von Access mitgelieferten Möglichkeiten.

Lösungsansatz:
Benutzung von hauseigenen Mittel von Access und der Option dies für mehrere Formulare mit Unterformularen, ohne tausend Zeilen Quellcode, zur Verfügung zu stellen.
Als Button wird lediglich ein Bildobjekt benötigt mit den Einstellungen:
- SpezialEffekt: Erhöht
- Name: btn_pic_ende (Hier im Beispiel)

Vorteile:
- schnell einsetzbar in allen Formulare
- beliebig erweiterbar
- einfacher und verständlicher Code
- keine undurchsichtigen API Tricks
- ungebundenheit an Hintergrundfarbe des Formulars
- optische Vorzüge

Nachteile:
- anstatt ein Click() Ereignis benötigt man Click(); MouseDown(); MouseUp()
- eintragen der Übergabevariablen für jeden Button
- evtl. umlenken des Focus (siehe Nachtrag)

Lösung:
In Modul einfügen:

Option Compare Database
Option Explicit

Public PicMerker As Boolean 'Verhindern des doppelklicks
Public x_btn_pic As String 'Bildposition der X-Achse
Public y_btn_pic As String 'Bildposition der Y-Achse

'=========================================================
'Erläuterung der Übergabevariablen:
'Picture = Name des Bildobjekts
'Value = True = Vertieft; False = Erhöht
'HFo = Name des Hauptformulars
'UFo = Name des Unterformulars (optionaler Parameter)
'=========================================================
Public Function MakeButton(Picture As String, _
Value As Boolean, _
HFo As String, _
Optional UFo As String = "")

If UFo = "" Then
If PicMerker = False Then
x_btn_pic = Forms(HFo)(Picture).Left
y_btn_pic = Forms(HFo)(Picture).Top
End If
If Value = True Then
Forms(HFo)(Picture).SpecialEffect = 2
Forms(HFo)(Picture).Left = x_btn_pic + 15
Forms(HFo)(Picture).Top = y_btn_pic + 15
PicMerker = True
ElseIf Value = False Then
Forms(HFo)(Picture).SpecialEffect = 1
Forms(HFo)(Picture).Left = x_btn_pic
Forms(HFo)(Picture).Top = y_btn_pic
PicMerker = False
End If
Else
If PicMerker = False Then
x_btn_pic = Forms(HFo)(UFo)(Picture).Left
y_btn_pic = Forms(HFo)(UFo)(Picture).Top
End If
If Value = True Then
Forms(HFo)(UFo)(Picture).SpecialEffect = 2
Forms(HFo)(UFo)(Picture).Left = x_btn_pic + 15
Forms(HFo)(UFo)(Picture).Top = y_btn_pic + 15
PicMerker = True
ElseIf Value = False Then
Forms(HFo)(UFo)(Picture).SpecialEffect = 1
Forms(HFo)(UFo)(Picture).Left = x_btn_pic
Forms(HFo)(UFo)(Picture).Top = y_btn_pic
PicMerker = False
End If
End If
End Function


Aufruf in Formularen:

Private Sub btn_pic_ende_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call MakeButton("btn_pic_ende", True, "FormularName", "UFoSteuerelementName")
End Sub
Private Sub btn_pic_ende_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call MakeButton("btn_pic_ende", False, "FormularName", "UFoSteuerelementName")
End Sub


Für Ereignis beim Klick:

Private Sub btn_pic_ende_Click()
...Anweisungen...
End Sub


Nachtrag:
Befehlsschaltflächen (Buttons) in Access haben die Eigenschft, dass sie den Focus auf sich lenken können, dies haben andere Elemente nicht. Um nun Berechnungen o.ä. mit einem Klick auf unserem eigenen Button durchführen zu können, muss man den Focus beim Ereignis Click() umlenken.

Für Ereignis beim Klick wenn Focus umgelenkt werden muss:

Private Sub btn_pic_ende_Click()
Me.SteuerelementName.SetFocus 'Focus muss abgegeben werden!
...Anweisungen...
End Sub


Ich hoffe dass mein Beitrag euch gefallen bzw. einen Nutzen gebracht hat.
Auf positive Rückmeldung würde ich mich freuen.

xStaer
05.11.2008, 10:57
Hallo,
schöner und nützlicher Beitrag. Ich verwende in meinen DB's auch schon eigene Bilder als Buttons, denn das grau möchte man in neuen Anwendungen nicht mehr so unbedingt haben.

Ich habe allerdings bei Endlosformularen das Problem, dass sich der Focus nicht in der aktuell angeklickten Zeile befindet, sondern immer da wo ich Ihn zuletzt hatte. Ich möchte aber nicht immer erst in die richtige Zeile klicken müssen, sondern gleich mit dem Button die aktion für die angeklickte Zeile ausführen.

Ich habe es auch schon mit dem Versetzen des Focus versucht, aber auch dort befinde ich mir immer wieder im zuletzt angewählten Datensatz.

Hast du da vielleicht eine Idee, wie man das ändern könnte.

Vielen Dank

Bourbon
05.11.2008, 15:27
Kurz gesagt: Leider nein.
In Endlosformularen funktioniert das mit focus-Verhalten via "Access Intern". Microsoft hat dafür extra die Kontrollkästchen, Radiobuttons und Schaltflächen, die über eine interne Funktion die aktuelle Datensätze (Deine sogenannten Zeilen, wenn ich das recht verstanden habe) markiert bzw. abfragt.

Eine Patent-Lösung habe ich da nicht, kannst es denke mal mittels If / Else, Switch / Case Anweisung den aktuellen Datensatz abfragen und den Focus auf das Ergebnis setzen.

Mehr als ein Denkanstoß kann ich Dir im mom leider nicht geben.

Grüße

xStaer
05.11.2008, 16:07
Ok danke auf jedenfall für deine Antwort. Ja, mit Zeile meinte ich Datensatz, war schneller getippt als gedacht. Sorry

Dann werd ich mich mal mit dem Abfragen des aktuellen Datensatzes versuche. Wenn dir noch was einfällt bitte melden.

WeinGeist
06.11.2008, 09:19
Habe mich vor einiger zeit auch damit beschäftigt. Ging aber da vor allem um HooverButtons, nochmal nen Stück komplexer. Im Endlosform macht dies kein Spass, ist aber auch möglich.

Da du gar keinen Hoover möchtest, ists easy. Da würde ich einfach einen durchsichtigen Button über das Image legen. Brauch halt drei Steuerelemente. Durch die Verwendung einer Function lassen sich diese auch mit einem Einzeiler exakt übereinander legen, ohne das du das in der Entwurfsansicht tun musst. So hast du ein richtiges Schaltflächenverhalten und dennoch ein hübsches aussehen. --> Evtl. hilft dir dazu meine Beispieldatei für MsgBox/InputBox, da müsste eigentlich das Verfahren erkennbar sein, auch wenn es da über klassen gelöst ist.

EDIT: Eine Erweiterung deines Codes wäre die Verweisung auf die Objekte selbst, dann würdest du dir es sparen immer auf die gleichen Objekte verweisen zu müssen. Also der Function einfach die Steuerelement-Referenz mit übergeben, dann brauchst die HF + UF usw. nicht mehr.
Durch die Verwendung einer Klasse könntest du die ganzen Click-Events auch darin behandeln, dann brauchst im aufrufenden Formular so gut wie keinen Code mehr. Allerdings lauern hier wieder gefahren mit der Verwendung von Access vor XP. --> Löst einer der Buttons, bei welchen die Click-Events verwendet werden ein Close des Formulars aus, stürtzt Access ab.

xStaer
06.11.2008, 10:02
Danke für den Hinweis. Ich muss ja ehrlich gestehen, dass mir die Eigenschaft "Transparent" bei Befehlsschaltflächen noch nie aufgefallen ist. Ich werde es erstmal damit lösen.

Die Geschichte mit den Hooverbuttons sehe ich mir nochmal genauer an, wenn am Projektende noch etwas Puffer ist. Ich finde es ist aber auch eine gelungene Sache, habe es gerade mal kurz debugged.

Vielen Dank nochmal