4.1 Verschiedene Farben im Endlosformular |
https://www.donkarl.com?FAQ4.1 | aktualisiert 2007-05-18 |
Problem
Du möchtest in einem Endlosformular bestimmte Datensätze (bzw. Felder) durch spezielle Formatierungen kennzeichnen. Wenn du eine solche Zuweisung (z.B. per Code oder Ausdruck mit irgendeiner Bedingung) versuchst, wird die Formatierung in allen Datensätzen geändert.
Ursache
Format-Einstellungen für Formulare werden in Access gemeinsam gespeichert und gelten daher für alle Datensätze.
Lösung
Ab A00 lässt sich das mit der Bedingten Formatierung einstellen. Dazu in der Entwurfsansicht des Formulares ein Steuerelement markieren und Menü Format/Bedingte Formatierung wählen. Die Einstellungen sind auch per VBA möglich, s. <F1> zur FormatConditions-Eigenschaft.
Möglichkeiten in älteren Access-Versionen:
Bei der Textfarbe können mit der Format-Einstellung 4 Zustände unterschieden und entsprechend eingefärbt werden. s. Online-Hilfe unter "Format-Eigenschaft - Datentypen Zahl und Währung"
Für die Hintergrundfarbe gibt es versch. Trixereien (hinterlegte Steuerelemente, formatfüllende Textzeichen, BMPs etc.) Ein kleines Beispiel könnt ihr hier downloaden colorend.zip (11 KB)
Bei Stephen Lebans gibt's Lösungen unter Verwendung von APIs:
http://www.lebans.com/formatbycriteria.htm
Bei Dev Ashish gibt's ein Beispiel für den aktuellen Datensatz: http://www.mvps.org/access/forms/frm0047.htm
4.2 Bezug auf Unterformular/bericht |
https://www.donkarl.com?FAQ4.2 | aktualisiert 2012-12-14 |
Problem
Der Bezug auf ein Feld oder eine Eigenschaft im Unterformular/-bericht funktioniert nicht.
Lösung
Die Syntax für den Bezug auf ein Steuerelement im Ufo lautet:
Forms![Hauptformular]![UFoSteuerelement_im_Hauptformular].Form![Steuerelement_im_Ufo]
"UFoSteuerelement_im_Hauptformular" ist dabei der Name des Steuerelementes, in dem sich das Unterformular befindet. Diese Bezeichnung steht in der Eigenschaft Name des Steuerelementes und muss nicht ident sein mit dem Namen des Formulares, das als Unterformular dient, also der Eigenschaft Herkunftsobjekt. Diese Verwechslung ist die häufigste Fehlerquelle bei Bezügen.
Vom Hauptformular aus reicht:
Me![UFoSteuerelement_im_Hauptformular].Form![Steuerelement_im_Ufo]
Um den Fokus auf ein Element im Ufo setzen zu können, oder z.B. die Methode GoToRecord im Ufo anwenden zu können, ist es notwendig, vorher den Fokus auf das Ufo-Steuerelement im Hauptformular zu setzen:
Me![UFoSteuerelement_im_Hauptformular].SetFocus
Me![UFoSteuerelement_im_Hauptformular].Form![Steuerelement_im_Ufo].SetFocus
bzw.
Me![UFoSteuerelement_im_Hauptformular].SetFocus
DoCmd.GoToRecord , , acNext
Analog funktioniert es mit Berichten. Lediglich "Forms" ist durch "Reports" zu ersetzen und "Form" durch "Report".
Syntaxbeispiele für alle mögl. Varianten bei Dev Ashish:
http://www.mvps.org/access/forms/frm0031.htm
4.3 Formulare synchronisieren |
https://www.donkarl.com?FAQ4.3 | aktualisiert 2021-10-25 |
Problem
Du möchtest, wenn ein Datensatz in einem Formular ausgewählt wird, dass in einem anderen Formular der selbe Datensatz angezeigt wird.
Lösung
Angenommen, das eindeutige und zu vergleichende Feld in beiden Formularen heißt "Id". Dann bei einem passenden Ereignis z. B. Beim Anzeigen des 1. Formulares:
Forms!frmFormular2.Recordset.FindFirst "Id = " & Me!Id
Die Verwendung des Formular-Recordsets ist ab Access 2000 möglich. In älteren Versionen kann man mit dem RecordsetClone arbeiten. Ein Beispiel dafür zeige ich hier: mein deutscher KB-Artikel dazu im Webarchiv
4.4 Datensatz suchen |
https://www.donkarl.com?FAQ4.4 | aktualisiert 2021-10-25 |
Problem
Du hast ein ungebundenes Text- oder Kombifeld z.B. "txtSuch". Nach Eingabe oder Auswahl eines Wertes z.B. einer RechnungsNr, möchtest du, dass der Datensatz mit dieser RechnungsNr gefunden und angezeigt wird.
Lösung
Wenn dein Feld "RechnungsNr" im Formular sichtbar ist und den Fokus haben kann, dann kannst du beim Ereignis Nach Aktualisierung von "txtSuch" die FindRecord-Methode verwenden:
Me!RechnungsNr.SetFocus
DoCmd.FindRecord Me!txtSuch
Ansonsten kannst du ebenfalls bei Nach Aktualisierung von "txtSuch" folgendes veranstalten:
Me.Recordset.FindFirst "RechnungsNr = " & Me!txtSuch
'oder falls RechnungsNr kein Zahlenfeld ist sondern vom Typ Text:
'Me.Recordset.FindFirst "RechnungsNr = '" & Me!txtSuch & "'"
Die Verwendung des Formular-Recordsets ist ab Access 2000 möglich. In älteren Versionen kann man mit dem RecordsetClone arbeiten. Ein Beispiel dafür zeige ich hier:
mein deutscher KB-Artikel dazu im Webarchiv
4.5 Gleicher Datensatz nach Requery |
https://www.donkarl.com?FAQ4.5 | aktualisiert 2012-12-14 |
Problem
Du musst zur Aktualisierung der Daten ein Requery durchführen. Der Fokus geht dabei auf den 1. Datensatz des Formulares zurück. Du möchtest aber beim vorher aktuellen Datensatz bleiben.
Lösung
Speichere die Id (ein eindeutiges Feld) des aktuellen Datensatzes. Dann kannst du nach dem Requery zurückkehren.
Dim lngStore As Long
lngStore = Me!Id
'Bildschirmflackern reduzieren
Me.Painting = False
Me.Requery
Me.Recordset.FindFirst "Id = " & lngStore
Me.Painting = True
4.6 Formular mehrfach anzeigen |
https://www.donkarl.com?FAQ4.6 | aktualisiert 2021-10-25 |
Problem
Du möchtest ein Formular mehrfach aufrufen d.h mehrmals am Bildschirm haben um z.B. mehrere Datensätze neben- und übereinander darstellen zu können.
Lösung
Du kannst (ab A95) mehrere Instanzen eines Formulares öffnen. Bissel Info dazu gibt's in der Online-Hilfe unter "Instanzen von Formularen".
z.B. schreibst du im Deklarationsbereich des Formularmoduls:
Dim FormNochmal As New Form_DeinFormular
Bei einem passenden Ereignis machst du dann die 2. Instanz sichtbar und setzt sie an eine andere Stelle am Bildschirm, sonst liegt sie genau über der 1. Instanz:
With FormNochmal
.Visible = True
DoCmd.MoveSize 2000, 2000
End With
s.a. KB-Artikel im Webarchiv
mein deutscher KB-Artikel dazu im Webarchiv
4.7 Sortierung im Formular ändern |
https://www.donkarl.com?FAQ4.7 | aktualisiert 2021-10-25 |
Problem
Du möchtest die Sortierreihenfolge im Formular ändern, ohne die Menü- oder Symbolleistenpunkte Aufsteigend/Absteigend Sortieren zu verwenden, sondern z.B. beim Klicken einer selbst erstellten Schaltfläche.
Lösung
Entweder du bastelst dir einen SQL-String mit einer entsprechenden Order By-Klausel als Datenherkunft des Formulares oder du setzt die Formular-Eigenschaften OrderBy und OrderByOn mit VBA:
Beispiel mit SQL-String:
Dim strSQL As String
strSQL = "SELECT tbl_Kunden.* FROM tbl_Kunden ORDER BY tbl_Kunden.Vorname;"
Me.RecordSource = strSQL
Wenn man nicht besonders SQL-erfahren ist oder bei komplizierteren Statements, ist es am einfachsten, eine Abfrage im Abfrageeditor von Access zu erzeugen und sich den SQL-Text dann aus der SQL-Ansicht des Abfrageentwurfs zu kopieren.
Das Sortieren durch Änderung der Datenherkunft ist i.d.R. die bessere Variante. Nicht nur, weil's professioneller wirkt, sondern auch weil Access bei Sortierung über die Formular-Eigenschaften (egal ob über die Benutzeroberfläche oder per Code) die letzte Sortierung in der Sortiert nach-Eigenschaft fix speichert. Dennoch auch dafür Beispiele:
'aufsteigend nach dem Feld Vorname sortieren
Me.OrderBy = "Vorname"
Me.OrderByOn = True
'absteigend
Me.OrderBy = "Vorname desc"
Me.OrderByOn = True
Access speichert die letzte Sortierung. Um sie beim nächsten Öffnen des Formulares nicht anzuwenden, kann man im Ereigniscode beim Öffnen schreiben:
Me.OrderBy = ""
s.a. KB-Artikel im Webarchiv
mein deutscher KB-Artikel dazu im Webarchiv
4.8 Unterformular wechseln |
https://www.donkarl.com?FAQ4.8 | aktualisiert 2021-10-25 |
Problem
Du möchtest während der Laufzeit in einem Formular verschiedene Unterformulare im selben Unterformular-Steuerelement verwenden.
Lösung
Du kannst mit VBA die Eigenschaft Herkunftsobjekt des Ufo-Steuerelementes im Hauptformular (hier: "UFoElement") ändern:
Me!UFoElement.SourceObject = "NächstesUFo"
Wenn dadurch auch die Felder für die Verknüpfung zwischen Haupt- und Unterformular anders heißen, musst du die Eigenschaften Verknüpfen von und Verknüpfen nach des UFoElements ändern:
Me!UFoElement.LinkChildFields = "FeldimUFo"
Me!UFoElement.LinkMasterFields = "FeldimHauptFormular"
Access verknüpft automatisch über das Primärschlüsselfeld, sofern vorhanden. Wenn du bei einem Ufo-Wechsel nicht über ein vorhandenes Primärschlüsselfeld verknüpfen willst, musst du vor dem Neuzuweisen der Verknüpfungsfelder die Eigenschaften auf einen Leerstring setzen:
Me!UFoElement.SourceObject = "NächstesUFo"
Me!UFoElement.LinkChildFields = ""
Me!UFoElement.LinkMasterFields = ""
Me!UFoElement.LinkChildFields = "FeldimUFo"
Me!UFoElement.LinkMasterFields = "FeldimHauptFormular"
mein deutscher KB-Artikel dazu im Webarchiv
4.9 Speichern/Löschen funktioniert nicht im A97-PopUp |
https://www.donkarl.com?FAQ4.9 |
Problem
Du verwendest in A97 in einem PopUp-Formular Code, den der Assistent erstellt hat. Im Code befinden sich Befehle, die DoMenuItem verwenden z.B. Speichern, Löschen. Diese Befehle funktionieren nicht.
Ursache
In A97 funktioniert DoMenuItem nicht im PopUp, weil die Menübefehle auch per VBA in einem PopUp-Formular nicht zugänglich sind. (in anderen Versionen sollte es funktionieren)
Lösung
Ersetze die DoMenuItem-Befehle durch RunCommands z.B.
Speichern des aktuellen Datensatzes: RunCommand acCmdSaveRecord
Löschen des aktuellen Datensatzes: RunCommand acCmdDeleteRecord
Das Ersetzen der veralteten DoMenuItem-Befehle ist in jedem Fall ratsam. Sie werden nur noch aus Kompatibilitätsgründen mitgeschleppt bzw. weil MS die Assistenten nie aktualisiert hat, und die RunCommand-Befehle sind wesentlich aussagekräftiger.
4.10 Zeilenwechsel mit Pfeiltasten |
https://www.donkarl.com?FAQ4.10 | aktualisiert 2021-10-25 |
Problem
Du möchtest in der Formularansicht mit den Tasten PfeilAuf und PfeilAb den Datensatz wechseln, ähnlich wie das in der Datenblattansicht oder in Tabellen und Abfragen möglich ist.
Lösung
Stelle die Eigenschaft Tastenvorschau des Formulares auf Ja ein. In das Ereignis Bei Taste Ab des Formulares kopierst du folgendes:
On Error Resume Next 'falls erster oder letzter Datensatz erreicht
Select Case KeyCode
Case vbKeyDown
KeyCode = 0
DoCmd.GoToRecord , , acNext
Case vbKeyUp
KeyCode = 0
DoCmd.GoToRecord , , acPrevious
End Select
mein deutscher KB-Artikel dazu im Webarchiv
4.11 Berechnetes Feld speichern |
https://www.donkarl.com?FAQ4.11 |
Problem
Du möchtest den Wert aus einem berechneten Steuerelement in der Tabelle speichern, auf der das Formular basiert.
Lösung
Prinzipiell ist es keine gute Angewohnheit, einen berechneten Wert zu speichern. Zuerst solltest du dir also überlegen, ob es wirklich nötig ist, weil der Wert i.d.R. jederzeit wieder berechnet werden kann. Sinnvoll ist eine Speicherung evtl., wenn sich einzelne Faktoren im Lauf der Zeit ändern können und du keine separate History-Tabelle führen willst, oder wenn die Formeln komplex sind und sich mit dem Speichern Performance gewinnen lässt.
Du brauchst natürlich in der Tabelle ein Feld, das den Wert aufnimmt.
Dann kannst du entweder Nach Aktualisierung jedes der Felder, die zur Berechnung beitragen, oder Vor Aktualisierung des Formulares folgenden Code verwenden:
Me!MeinTabellenFeld = Me!MeinBerechnetesSteuerelement
4.12 Kombi/Listenfeld - Eintrag auswählen |
https://www.donkarl.com?FAQ4.12 |
Problem
Du möchtest eine bestimmte Zeile in einem Kombinations- oder Listenfeld auswählen oder z.B. die erste Zeile als Standardwert definieren, damit sie beim Öffnen eines Formulares ausgewählt ist.
Lösung
Schreib in die Ereignisprozedur Beim Öffnen des Formulares:
Me!KombiName = Me!KombiName.ItemData(0)
oder
schreibe bei der Eigenschaft "Standardwert" des Kombis:
[KombiName].[ItemData](0)
Der Index von ItemData beginnt mit 0 = 1. Zeile, 1 = 2. Zeile etc.
4.13 Kombinationsfeld - Eintrag hinzufügen |
https://www.donkarl.com?FAQ4.13 | aktualisiert 2021-10-25 |
Problem
Du möchtest zu den Einträgen in einem Kombinationsfeld einen neuen hinzufügen.
Lösung
Variante 1
Wenn du ohne Nachfrage den eingegebenen Wert in die Datenherkunft des Kombis übernehmen willst, dann
- sortiere das Kombi nach dem Feld, dessen Wert eingegeben wird,
- setze die Eigenschaft Nur Listeneinträge auf Ja und
- verwende im Ereignis Bei nicht in Liste des Kombis Code wie diesen:
'************** CODE START **************
Response = acDataErrAdded
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Tabellenname", dbOpenDynaset)
rs.AddNew
rs!Feldname = NewData
rs.Update
rs.Close : Set rs = Nothing
Set db = Nothing
'************** CODE ENDE **************
Variante 2
Du möchtest z.B. im Formular "frm_Rechnung" bei neuem Eintrag im Kombi "cbo_SuchKunde" (gebundene Spalte ist "KundenID") zuerst nachfragen, dann das Eingabeformular ("frm_NeuKunde") öffnen, den im Kombi eingegebenen Kundennamen in das Eingabeformular übernehmen, dort weitere Details eingeben, und danach im Kombi den neuen Wert anzeigen. Im Ereignis Bei nicht in Liste des Kombis:
'************** CODE START **************
If MsgBox("Der Kunde ist neu. Möchten Sie ihn anlegen?", vbYesNo) = vbYes Then
Response = acDataErrContinue
DoCmd.OpenForm "frm_NeuKunde", , , , acFormAdd
Forms!frm_NeuKunde!Kundenname = NewData
Else 'z.B. bei Tippfehler
Response = acDataErrContinue
Me!cbo_SuchKunde.Undo
End If
'************** CODE ENDE **************
Beim Schließen des Eingabeformulars:
Forms!frm_Rechnung!cbo_SuchKunde = Me!KundenID
Forms!frm_Rechnung!cbo_SuchKunde.Requery
4.14 Kombinationsfeld per Code öffnen |
https://www.donkarl.com?FAQ4.14 |
Problem
Du möchtest die Auswahlliste eines Kombis öffnen, ohne, dass der User auf den Button des Kombis drücken muss.
Lösung
Dafür gibt es ab A95 eine eigene Methode namens Dropdown:
Me!Mein_Kombinationsfeld.SetFocus
Me!Mein_Kombinationsfeld.Dropdown
In A2 musst du das noch mit Sendkeys "%{down}"
oder Sendkeys "{F4}"
machen, was nicht zu empfehlen ist, weil Sendkeys buggy ist.
4.15 Kombi/Listenfeld - Zugriff auf Spalte n |
https://www.donkarl.com?FAQ4.15 |
Problem
Du möchtest aus einem Listen- oder Kombinationsfeld den Wert einer Spalte übernehmen, die nicht die gebundene Spalte ist.
Lösung
Verwende die Eigenschaft Column(Spalte).
Das Argument "Spalte" beginnt dabei mit 0 für die 1. Spalte zu zählen. Du kannst also z.B. den Wert aus der 2. Spalte eines Kombis in einem anderen Textfeld anzeigen, indem du als dessen Steuerelementinhalt schreibst:
=[Kombi].[Column](1)
Soll der Wert der Spalte in einem anderen Feld gespeichert werden, dann kann per VBA z.B. im Ereignis Nach Aktualisierung des Kombis die Zuweisung erfolgen:
DeinFeld = Me!Kombi.Column(1)
4.16 Listenfeld - Rechtsbündig ausrichten |
https://www.donkarl.com?FAQ4.16 |
Problem
Du möchtest eine Spalte (i.d.R. Zahlen) in einem Listenfeld rechtsbündig ausrichten.
Lösung
Es gibt keine eingebaute Eigenschaft oder dergl. mit der sich das einstellen lässt. Spalten in Listenfeldern werden immer linksbündig als Text ausgerichtet.
Ein altbekannter Workaround sieht so aus:
- Stelle für das Listenfeld eine nichtproportionale Schrift ein (z.B. eine der Courier-Schriften)
- Verwende eine Abfrage als Datensatzherkunft
- In der Abfrage schreibst du z.B. für ein Feld [Preis] folgenden Ausdruck
Leerzchn(12-Länge(Format([Preis];"#.##0,00"))) & Format([Preis];"#.##0,00")
Dadurch wird ein Text mit 12 Zeichen erzeugt und vorne mit Leerzeichen aufgefüllt. Das Beispiel hier reicht für eine Zahl bis zu einfachen Millionenbeträgen.
Eine weitere Möglichkeit ist die Verwendung von APIs. Die Sache funktioniert IMO ein bissel wackelig, aber du kannst dir den interessanten Versuch von Stephen Lebans dazu ansehen:
http://www.lebans.com/justicombo.htm
4.17 Register - Seitenwechsel-Ereignis |
https://www.donkarl.com?FAQ4.17 |
Problem
Du möchtest auf das Wechseln der Registerseite reagieren und findest kein passendes Ereignis.
Lösung
Beim Wechseln der Seite z.B. mit Klick auf die Registerzunge, wird das Ereignis Bei Änderung des Registersteuerelementes ausgelöst. Dabei lässt sich die Eigenschaft Seitenindex des Registers auslesen. Ist eh ident mit der Standardeigenschaft Value. Also einfach:
Select Case DeinRegisterSteuerelement
Case 0
'es wurde auf die 1. Seite gewechselt
Case 1
'die 2. Seite
'usw.
End Select
4.18 Register - Seitenwechsel mit Tastatur |
https://www.donkarl.com?FAQ4.18 | aktualisiert 2021-10-25 |
Problem
Du möchtest vom letzten Feld der 1. Registerseite durch Drücken der TAB-, RETURN- oder DOWN-Taste in das erste Feld der 2. Seite gelangen.
Lösung
Schreib im Code Bei Taste Ab deines letzten Feldes auf der 1. Seite:
Select Case KeyCode
Case vbKeyReturn, vbKeyDown, vbKeyTab And (Shift And acShiftMask) = 0
KeyCode = 0
Me!ErstesSteuerelementAufSeite2.SetFocus
End Select
mein deutscher KB-Artikel dazu im Webarchiv
4.19 Prüfen ob Formular geöffnet |
https://www.donkarl.com?FAQ4.19 |
Problem
Du möchtest für eine Bedingung in Code oder in einem Ausdruck wissen, ob ein bestimmtes Formular geöffnet ist.
Lösung
Ab A00 gibt es für Access-Objekte die Eigenschaft IsLoaded:
CurrentProject.AllForms("MeinFormular").IsLoaded
gibt True oder False zurück.
Alternativ und v.a. schon in A95 und A97 kann man SysCmd verwenden. Kopier dir dazu folgendes in ein Standardmodul:
Public Function fctIsFormOpen(StrName As String) As Boolean
fctIsFormOpen = (SysCmd(acSysCmdGetObjectState, acForm, StrName) > 0)
End Function
In VBA kannst du dann abfragen, ob das Formular geöffnet ist z.B.:
If fctIsFormOpen("MeinFormular") Then machwas…
In Ausdrücken an der Access-Oberfläche z.B. in der Bedingungsspalte eines Makros kannst du schreiben:
fctIsFormOpen("MeinFormular")
4.20 Bildschirmauflösung ermitteln |
https://www.donkarl.com?FAQ4.20 |
Problem
Du möchtest die aktuelle Auflösung des Bildschirmes ermitteln.
Lösung
Kopiere dir folgendes in den Deklarationsbereich eines Standardmoduls:
Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Const SM_CXSCREEN = 0
Const SM_CYSCREEN = 1
Aufruf dann z.B. über eine Funktion wie:
Public Function fctAufloesung()
fctAufloesung = "Pixel horizontal: " & GetSystemMetrics(SM_CXSCREEN) & _
" vertikal: " & GetSystemMetrics(SM_CYSCREEN)
End Function
4.21 Formulare an Auflösung anpassen |
https://www.donkarl.com?FAQ4.21 | aktualisiert 2021-06-29 |
Problem
Du möchtest die Größe der Formulare, Position und Größe der Steuerelemente usw. an die aktuelle Bildschirmauflösung anpassen.
Lösung
Eine technisch einfache, aber mit erhöhtem Pflegeaufwand verbundene Methode ist, mehrere Versionen eines Formulares zu erzeugen und je nach Auflösung das passende zu öffnen.
Für die dynamische Anpassung von Steuerelement-Größen gibt es ab Access 2007 die Anker-Eigenschaften.
Für weitergehende Anpassungen hingegen ist viel Code notwendig. Dabei kommt es oft zu Problemen im Detail mit Proportionen, Schriftgrößen etc. Das gilt manchmal auch für die diversen Beschreibungen und Tools im Internet wie z.B.
- Colin Riddingtons Tutorial http://www.mendipdatasystems.co.uk/automatic-form-resizing-1/4594554784
- Total Access Components http://www.fmsinc.com/microsoftaccess/controls.html
- ShrinkerStretcher http://www.peterssoftware.com/ss.htm
4.22 Standardwert aus vorherigem Datensatz |
https://www.donkarl.com?FAQ4.22 | aktualisiert 2021-10-25 |
Problem
Du möchtest einen gerade eingegebenen Wert in einem neuen Datensatz als Standardwert vorgeben, um ihn nur bei Bedarf ändern zu müssen.
Lösung
Schreibe in der Ereignisprozedur Nach Aktualisierung des jeweiligen Steuerelementes oder des Formulares:
bei Textfeldern
Me!MeinSteuerelement.DefaultValue = Chr$(34) & Me!MeinSteuerelement & Chr$(34)
bei Datumsfeldern
Me!MeinSteuerelement.DefaultValue = Str(CDbl(Me!MeinSteuerelement))
bei anderen Felddatentypen (Zahl, Ja/Nein etc.)
Me!MeinSteuerelement.DefaultValue = Me!MeinSteuerelement
4.23 Tasten BildAuf/BildAb deaktivieren |
https://www.donkarl.com?FAQ4.23 | aktualisiert 2005-08-24 |
Problem
Mit den Tasten <BildAuf> und <BildAb> kann standardmäßig der Datensatz gewechselt werden. Genau das möchtest du unterbinden.
Lösung
Setze die Eigenschaft Tastenvorschau des Formulares auf Ja.
Im Ereignis Bei Taste ab des Formulares:
If KeyCode = vbKeyPageUp Or KeyCode = vbKeyPageDown Then KeyCode = 0
Analog sind sämtliche Tasten auf Formularebene in VBA programmierbar.
Wenn du nur die normalen Access-Funktionstasten sperren willst, kannst du das auch im Menüpunkt Extras/Start machen. Ansonsten schau in die Online-Hilfe unter "Tastatur, Tastaturbelegung-Makrogruppen".
4.24 Cursor/Markierung positionieren |
https://www.donkarl.com?FAQ4.24 | aktualisiert 2021-10-25 |
Problem
Du möchtest den Cursor in einem Textfeld "automatisch" an die erste oder letzte Stelle setzen oder den ganzen Inhalt des Feldes markieren.
Lösung
Das Cursorverhalten bei Eintritt in ein Feld lässt sich (für die ganze Datenbank geltend) im Menü Extras/Optionen/Tastatur einstellen.
Für einzelne Steuerelemente lässt es sich programmieren. Entweder man verwendet die folgenden VBA-Anweisungen bei Ereignissen wie Beim Hingehen oder Beim Klicken des Steuerelementes oder man setzt zuvor den Cursor in das Steuerelement z.B. mit:
Me!MeinTextfeld.SetFocus
Cursor an den Anfang des Textes
Me!MeinTextfeld.SelStart = 0
Cursor an das Ende des Textes
Me!MeinTextfeld.SelStart = Len("" & Me!MeinTextfeld)
ganzen Text markieren
Me!MeinTextfeld.SelStart = 0
Me!MeinTextfeld.SelLength = Len("" & Me!MeinTextfeld)
Das Voransetzen des Leer-Strings verhindert eine Fehlermeldung der Len-Funktion bei leeren Feldern. Das gleiche erreicht man auch mit: Len(nz(Me!MeinTextfeld))
4.25 Doppelte Eingabe vermeiden |
https://www.donkarl.com?FAQ4.25 | aktualisiert 2005-12-07 |
Problem
Du möchtest vermeiden, dass in ein Feld ein Wert eingegeben wird, der schon einmal in der zugrunde liegenden Tabelle drin ist. Wenn das versucht wird, soll eine verständliche Fehlermeldung erscheinen.
Lösung
Variante 1
Setze in der Tabelle bei diesem Feld die Eigenschaft Indiziert auf Ja (Ohne Duplikate).
Im Ereigniscode Bei Fehler (On Error) des Formulares schreibst du:
If DataErr = 3022 Then
Response = acDataErrContinue
MsgBox Me!MeinSteuerelement & " gibt es bereits.", vbOKOnly, "Duplikat!"
Me!MeinSteuerelement.SetFocus
End If
Variante 2
Bei obigem Vorgehen erfolgt die Prüfung erst beim Versuch, den Datensatz zu speichern, also i.d.R. beim Wechseln des Datensatzes. Wenn die Prüfung gleich nach dem Eingeben des Wertes in ein Feld stattfinden soll, kannst du das Ereignis Vor Aktualisierung des Steuerelementes nutzen und Code wie diesen:
If Not IsNull(Dlookup("MeinFeld", "MeineTabelle", _
"MeinFeld = " & Chr$(34) & Me!MeinSteuerelement & Chr$(34))) _
And Me!MeinSteuerelement <> nz(Me!MeinSteuerelement.OldValue) Then
MsgBox Me!MeinSteuerelement & " gibt es bereits.", vbOKOnly, "Duplikat!"
Cancel = True
End If
In der 2. Zeile des Codes wird der Feldtyp Text vorausgesetzt. Wenn es sich hingegen um eine Zahl handelt, sollte die 2. Zeile lauten:
"MeinFeld = " & Str(Me!MeinSteuerelement))) _
4.26 Bezeichnungsfeld zuordnen |
https://www.donkarl.com?FAQ4.26 |
Problem
Du hast bei einem Steuerelement kein zugeordnetes Bezeichnungsfeld und möchtest ein solches nachträglich erstellen, z.B. damit man durch Klick darauf das übergeordnete Steuerelement aktivieren kann, die beiden im Entwurf gemeinsam verschoben werden etc.
Lösung
Erzeuge zunächst mithilfe der Toolbox ein ungebundenes Bezeichnungsfeld.
Schneide das Feld in die Zwischenablage aus.
Markiere das Steuerelement, dem es zugeordnet werden soll.
Füge das Bezeichnungsfeld aus der Zwischenablage wieder ein.
Es ist nun an das zuvor markierte Steuerelement gebunden.
4.27 Email mit Adresse aus Textfeld |
https://www.donkarl.com?FAQ4.27 |
Problem
Du hast im Formular ein Textfeld mit einer Emailadresse und möchtest das Standard-Emailprogramm mit einer neuen Email und der Adresse aus dem Feld öffnen.
Lösung
Schreib (ab A97) beim gewünschten Ereignis in der Ereignisprozedur:
DoCmd.SendObject , , , Me!MeinTextfeld , , , , , True
Wenn du den Text im Steuerelement gerade geändert hast und sich der Fokus beim Aufruf der Mail noch im Textfeld befindet, dann musst du die Eigenschaft Text des Steuerelementes verwenden:
DoCmd.SendObject , , , Me!MeinTextfeld.Text , , , , , True
Du kannst mit SendObject auch den Betreff und den Text der Email vorgeben. (s. <F1>)
Wenn du statt des Textfeldes unbedingt ein Hyperlink-Feld verwenden möchtest, besteht das Problem, dass der Anwender i.d.R. nicht weiß, dass er vor der Email-Adresse "mailto:" eingeben müsste. Tut er das nicht, geht Access auch bei einer Mail-Adresse von einer Webseite aus, setzt "http://" davor und öffnet den Webbrowser. Eine Möglichkeit, das zu verhindern, ist, die Eingabe im Ereignis Nach Aktualisierung des Feldes zu korrigieren:
If InStr(Me!MeinTextfeld, "@") > 0 Then
If InStr(Me!MeinTextfeld, "#http") > 0 Then
Me!MeinTextfeld = "#mailto:" & Mid(Me!MeinTextfeld, 1, InStr(Me!MeinTextfeld, "#http") - 1) & "#"
End If
End If
4.28 Tiptext funktioniert nicht |
https://www.donkarl.com?FAQ4.28 |
Problem
Du hast bei einem Steuerelement in der Eigenschaft Steuerelement Tip-Text einen Text eingegeben. Wenn du mit der Maus drauf gehst, erscheint der Tiptext aber nicht.
Lösung
Meistens liegt es daran, dass ein transparentes Rechteck oder dergl. über dem Steuerelement liegt und es daher nicht im Vordergrund ist. Auch wenn nichts darüber liegen sollte, markiere das betreffende Steuerelement und wähle den Menüpunkt Format/In den Vordergrund.
4.29 Mausrad wechselt den Datensatz |
https://www.donkarl.com?FAQ4.29 | aktualisiert 2009-10-19 |
Problem
Bei manchen Mäusen mit Rad (v.a. MS-Intellimouse) kann der Anwender durch Drehen des Rades den Datensatz wechseln, was du eigentlich verhindern möchtest. Es kann auch vorkommen, dass schon leichtes Drehen am Mausrad wildes Scrollen zwischen den Datensätzen zur Folge hat.
Lösung
Ab A07 besteht das Problem nicht mehr, da der Datensatzwechsel per Mausrad deaktiviert wurde.
Für Versionen bis inkl. A03 gibt es Code zum Abfangen der Mausbefehle von Wayne Phillips, der keine externe DLL oder dergl. braucht:
http://www.everythingaccess.com/tutorials.asp?ID=A-new-method-for-disabling-the-Mouse-Scroll-Wheel-in-Access-forms
Die klassischen Lösungen funktionieren mit DLLs:
http://www.lebans.com/mousewheelonoff.htm
http://support.microsoft.com/?kbid=278379
http://www.mvps.org/access/api/api0036.htm
Das wilde DS-Springen mit der Intellimouse wird lt. MS vom SR2 zu O97 bzw. durch neue Maustreiber gefixt:
http://support.microsoft.com/?kbid=192008
4.30 Spaltenüberschrift in Datenblattansicht |
https://www.donkarl.com?FAQ4.30 | aktualisiert 2007-01-03 |
Problem
Du öffnest ein Formular in der Datenblattansicht und möchtest die Spaltenüberschriften ändern, findest aber keine entsprechende Eigenschaft oder Einstellung.
Lösung
Es gibt zwei Möglichkeiten, woher die Spalten ihre Beschriftung beziehen.
1. Wenn zu einem Steuerelement kein Bezeichnungsfeld zugeordnet ist, dann wird die Eigenschaft Name des Steuerelementes als Überschrift verwendet, d.h. du kannst diese Eigenschaft ändern, um auch die Spaltenüberschrift zu ändern.
2. Existiert ein zugeordnetes Bezeichnungsfeld, dann wird dessen Eigenschaft Beschriftung (in VBA: Caption) als Spaltenüberschrift verwendet, auch wenn in der Datenblattansicht solche Bezeichnungsfelder gar nicht angezeigt werden. Du kannst also in der Entwurfsansicht oder per VBA diese Eigenschaft einstellen und damit die Spaltenüberschrift ändern. Wie man nachträglich Bezeichnungsfelder zuordnet steht in FAQ 4.26.
4.31 Animierte GIFs darstellen |
https://www.donkarl.com?FAQ4.31 | aktualisiert 2008-11-22 |
Problem
Du möchtest in einem Formular animierte GIFs darstellen.
Lösung
ohne ActiveX:
von Stephen Lebans http://www.lebans.com/animatedgifplayer.htm
ActiveX-Steuerelemente:
von MS gibt es das Microsoft Animation Control (kommt mit irgendwelchen MSComCtl-Klassen bzw. mit ODE/MOD)
s.a. http://support.microsoft.com/?kbid=209919
Shareware: Animation Gif Control http://www.jcomsoft.com/anigif.htm
Eine weitere Möglichkeit ist die Verwendung des Webbrowser- oder DHTML Edit-Steuerelements des MS Internet Explorers.
4.32 Rückfrage vor dem Speichern |
https://www.donkarl.com?FAQ4.32 |
Problem
Wenn ein Datensatz geändert wurde, soll er nicht automatisch gespeichert werden, sondern eine Sicherheitsabfrage erscheinen.
Lösung
Verwende in der Ereignisprozedur Vor Aktualisierung des Formulares Code wie diesen:
If MsgBox("Änderungen speichern?", vbYesNo, "Speichern?") = vbNo Then
Me.Undo 'rückgängig
Cancel = True 'Ereignisse verhindern
End If
4.33 Prüfen ob erster/letzter/neuer Datensatz |
https://www.donkarl.com?FAQ4.33 |
Problem
Du möchtest (programmatorisch) herausfinden, ob der aktuelle DS der erste oder letzte im Formular ist oder ein neuer.
Lösung
Verwende (ab A95) Code wie den folgenden bei einem passenden Ereignis z.B. Beim Anzeigen:
If Me.CurrentRecord = 1 Then MsgBox "Ich bin Erster!"
Me.RecordsetClone.MoveLast
If Me.CurrentRecord = Me.RecordsetClone.RecordCount Then MsgBox "Ich bin Letzter!"
If Me.NewRecord Then MsgBox "Ich bin neu hier."
Erläuterungen gibt's unter den Stichworten "CurrentRecord" und "NewRecord" in der Online-Hilfe.
4.34 Alle Steuerelemente sind verschwunden |
https://www.donkarl.com?FAQ4.34 | aktualisiert 2022-09-12 |
Problem
Ein Formular, das in Formularansicht geöffnet wird, ist völlig leer, d.h. enthält keine Steuerelemente mehr (weder Textfelder noch Befehlsschaltflächen etc.). In der Entwurfsansicht sind die Steuerelemente noch vorhanden.
Ursache
Fast immer ist dieses Verhalten "by Design". Die Ursache ist i.d.R., dass die zugrundeliegende Abfrage (eingetragen in der Eigenschaft Datensatzherkunft) keine Datensätze zurückliefert und in der Abfrage oder im Formular keine neuen Datensätze angelegt werden können (z.B. Formulareigenschaft Anfügen zulassen steht auf Nein).
Lösung
Entweder dafür sorgen, dass die Abfrage immer Datensätze liefert oder dass neue Datensätze angelegt werden können, also die Abfrage umbauen bzw. im Formular neue Datensätze zulassen.
Falls du bloß möchtest, dass zumindest deine Schaltflächen (z.B. zum Schließen des Formulares) sichtbar sind, reicht es, die Schaltflächen oder sonst. Steuerelemente in den Kopf- oder Fußbereich des Formulares zu verschieben. Komplett leer ist nämlich nur der Detailbereich.
Weitere Info: KB-Artikel im Webarchiv
4.35 Schließen-Schaltfläche vermeiden in A97-Formular |
https://www.donkarl.com?FAQ4.35 |
Problem
Du möchtest, dass ein Access-Formular keine eigene Schließen-Schaltfläche in seiner Titelleiste hat. Die entsprechende Eigenschaft für Formulare deaktiviert das Schließen-Symbol, wenn das Formular nicht maximiert ist. A97 hat aber den Bug, dass die Schließen-Schaltfläche des Formulars bei maximiertem Formularfenster wieder aktiviert ist. (in neueren Versionen ist das behoben)
Lösung
Wenn du nur das Schließen des Formulares verhindern möchtest, kannst du das Ereignis "Beim Entladen" des Formulares zum Abfangen verwenden (s. FAQ 1.12). Das hat den Vorteil, dass auch Windows-Tastenkombinationen wie <Strg>+<F4> und der Menübefehl zum Schließen des Fensters nicht mehr funktionieren.
Das Fehlverhalten von A97 ist hingegen nur per Windows-API zu verhindern. Das Code-Beispiel von Terry Kreft zeigt, wie man das Formular an die Größe des Access-MDI-Fensters anpassen kann, statt es maximiert zu öffnen:
http://www.mvps.org/access/api/api0022.htm
4.36 Abhängige Kombi/Listenfelder |
https://www.donkarl.com?FAQ4.36 |
Problem
Du hast in einem Formular 2 (oder mehr) Kombinations- oder Listenfelder und möchtest, dass der Inhalt des zweiten Kombis vom ersten abhängig ist, also nur mehr jene Datensätze anzeigt, für die im ersten die übergeordnete Kategorie gewählt wurde.
Lösung
Vorbemerkungen: Kombinationsfelder und Listenfelder sind diesbez. ident zu behandeln. Ich gehe auch nicht näher auf die Tabellenstruktur ein. Im Normalfall sollte es zwischen den involvierten Tabellen eine 1:n-Beziehung geben.
Angenommen du hast ein Formular "frm_Artikel" mit 2 Kombis. Eines "cbo_Gruppen" mit den Artikelgruppen, eines "cbo_Artikel" mit Artikeln. Nun möchtest du die Artikelgruppe auswählen und das zweite (abhängige) Kombi soll nur mehr jene Artikel zeigen, die dieser Gruppe angehören.
Enscheidend ist die Datensatzherkunft von cbo_Artikel.
Das kann eine gespeicherte Abfrage sein, in der beim GruppenID-Feld als Kriterium ein Bezug auf das übergeordnete Kombi steht:
Forms!frm_Artikel!cbo_Gruppen
Es kann aber auch ein SQL-Ausdruck sein, der in der Eigenschaft Datensatzherkunft des abhängigen Kombis steht oder der im Ereignis-Code Nach Aktualisierung des übergeordneten Kombis zugewiesen wird:
Me!cbo_Artikel.RowSource = "SELECT ArtikelBezeichnung FROM tbl_Artikel WHERE GruppenID= " & Me!cbo_Gruppen
Wenn die Datensatzherkunft des abhängigen Kombis nicht - wie im letzten Beispiel - dynamisch zugewiesen wird sondern z.B. eine gespeicherte Abfrage ist, dann muss noch die Anzeige aktualisiert werden. Dazu kannst du im Ereigniscode Nach Aktualisierung des übergeordneten Kombis die Requery-Methode verwenden:
Me!cbo_Artikel.Requery
Bei http://www.pc-creativ.de/ (unter "Tools) gibt es eine Beispiel-mdb "CreaKombi" von Anette Ratjen mit verschiedenen Varianten.
4.37 Rechnen in Textfeldern |
https://www.donkarl.com?FAQ4.37 | aktualisiert 2007-01-03 |
Problem
Du möchtest in einem Textfeld eine Rechenformel eingeben, deren Ergebnis in einem anderen Textfeld erscheinen soll.
Lösung
Dafür lässt sich die Funktion Eval() verwenden. Angenommen das Textfeld heißt "txt_Formel" und das Ergebnisfeld "txt_Ergebnis". Im Steuerelementinhalt von txt_Ergebnis könnte dann stehen:
=Eval([txt_Formel])
Störend ist dabei oft, dass man für Eval den Punkt als Dezimaltrennzeichen verwenden muss. Wenn im Textfeld mit dem Komma gearbeitet werden soll, kann man es mit Stringfunktionen oder ab A00 mit Replace (wesentlich einfacher) für Eval austauschen. Der Ausdruck im Ergebnisfeld könnte dann z.B. lauten:
=Eval(Replace([txt_Formel];",";"."))
Das Ergebnis wird so nur im Steuerelement angezeigt. Falls es gespeichert werden soll s. Berechnetes Feld speichern.
4.38 Datensatzwechsel per Tastatur verhindern |
https://www.donkarl.com?FAQ4.38 | aktualisiert 2007-01-03 |
Problem
Du möchtest verhindern, dass beim Drücken der Tabulator-, Enter- oder Pfeiltaste im ersten/letzten Steuerelement eines Datensatzes zum vorigen/nächsten Datensatz gewechselt wird.
Lösung
Stelle die Eigenschaft Zyklus des Formulares auf Aktueller Datensatz ein.
s.a. Tasten BildAuf/BildAb deaktivieren
4.39 Laufende Nummer/Summe in Formularen |
https://www.donkarl.com?FAQ4.39 | aktualisiert 2016-09-06 |
Problem
Du möchtest in einem Formular ein Textfeld mit einer fortlaufenden Nummer oder fortlaufenden Summe haben.
Lösung
Laufende Nummer
Du kannst dafür eine vorbereitende Abfrage verwenden, die bereits die laufende Nummer erzeugt.
Eine andere Variante ist die Verwendung der AbsolutePosition-Eigenschaft des DAO-Recordsets. Kopiere dir dazu den folgenden Code in das Formularmodul:
'************* CODE START ************
Function FctNr()
'gibt eine laufende Nummer im Formular zurück
'Anzeige im Formular durch ein Feld mit Steuerelementinhalt: =FctNr()
On Error GoTo FctNr_Error
Me.RecordsetClone.Bookmark = Me.Bookmark
FctNr = Me.RecordsetClone.AbsolutePosition + 1
FctNr_Exit:
Exit Function
FctNr_Error:
If Err.Number = 3021 Then FctNr = 0 'bei neuem DS
Resume FctNr_Exit
End Function
'************* CODE ENDE ************
Laufende Summe
Dafür gibt's ebenfalls mehrere Varianten, z.B. per DAO-Programmierung
Laufende Summe im Formular
Laufende Summe im Formular mit etwas mehr Code
oder mithilfe der DSum-Funktion:
Laufende Summe im Formular mit DSum
4.40 Mehrere markierte Datensätze ermitteln |
https://www.donkarl.com?FAQ4.40 | aktualisiert 2021-10-25 |
Problem
Du möchtest in einem Formular mehrere Datensätze markieren und dann per VBA ermitteln, welche markiert sind.
Lösung
Der Datensatzmarkierer von Access erlaubt nur eine zusammenhängende Markierung von Datensätzen. Die <Strg>-Taste hat hier nicht die sonst in Windows geltende Funktion einer getrennten Markierung. Wenn also mit dem Datensatzmarkierer mehrere DS markiert wurden, so kann man mithilfe der Seltop- und Selheight-Eigenschaften des Formulares eruieren, welche DS markiert sind. Ausführliche Beispiele dazu bieten folgende KB-Artikel:
KB-Artikel im Webarchiv
Wenn es um die Markierung von Datensätzen geht, die sich nicht unmittelbar untereinander befinden, ist der übliche Workaround die Verwendung eines gebundenen Kontrollkästchens, das dann in jedem DS gesetzt werden muss und z.B. mit einer Aktualisierungsabfrage wieder in einem Rutsch zurückgesetzt wird. Eine andere Variante ist die Verwendung eines Listenfeldes, bei dem die Eigenschaft Mehrfachauswahl auf Erweitert eingestellt ist.
4.41 Textfeld zur Passwort-Eingabe |
https://www.donkarl.com?FAQ4.41 | aktualisiert 2011-04-28 |
Problem
Du möchtest ein Textfeld für eine Passwort-Eingabe verwenden, d.h. man soll beim Tippen nur die üblichen Sternchen sehen.
Lösung
Setze die Eigenschaft Eingabeformat des Textfeldes auf: Kennwort
Zwei Anmerkungen zu diesem Themenbereich:
- Eine häufige Frage ist, ob das auch mit VBA-Inputboxen geht.
Antwort: Nein, man braucht ein Textfeld in einem Formular.
- Wenn sich der Cursor in dem Kennwort-Textfeld befindet und mit <F7> oder per Menüpunkt/Ribbon die Rechtschreibprüfung aktiviert wird, erscheint der eingegebene Text im Rechtschreibdialog in Klarschrift. Falls das ein Problem darstellt, sollte man die Funktionstaste deaktivieren (in den Starteigenschaften oder per Tastaturmakro) und den Menü- bzw. Ribboneintrag ausblenden.