allgemeine Tipps, Trix, Workarounds | |
2.1 Runden | 2.15 Text wird automatisch geändert |
2.2 Bilder speichern | 2.16 #Fehler bei Bezug auf leeres Objekt |
2.3 Klang abspielen | 2.17 Memo variabel formatieren |
2.4 Warnmeldungen unterdrücken | 2.18 Euro - Schriften, Währungssymbole |
2.5 Pfad und Name der aktuellen Datenbank | 2.19 PLZ, BLZ, Länderdaten, Vorwahlen |
2.6 Access-Verzeichnis ermitteln | 2.20 Feldinhalte nachträglich trennen |
2.7 Alter ermitteln | 2.21 Makro "Tastaturbelegung" ab A00 |
2.8 Erster/Letzter Tag des Monats | 2.22 Summe eines berechneten Steuerelementes |
2.9 Montag einer Kalenderwoche | 2.23 Datenänderungen protokollieren |
2.10 Stundensumme über 24 | 2.24 Netzwerk User/Computername auslesen |
2.11 Zahl in Worten | 2.25 Kalenderwoche ermitteln |
2.12 Leerzeichen in kombiniertem Feld vermeiden | 2.26 Formularbasierte Filter in der Runtime |
2.13 Leeres Feld verhindert Formelergebnis | 2.27 Drag and Drop mit Access |
2.14 Zeilenumbruch einfügen | 2.28 Sicherheitsmeldungen |
2.1 Runden |
https://www.donkarl.com?FAQ2.1 |
Problem
Es ist keine Funktion zur kaufmännischen Rundung zu finden.
Bei Versuchen mit den Funktionen Int() und Fix() kommt es zu Ungenauigkeiten. CDbl() und CInt() runden nicht kaufmännisch sondern mathematisch d.h. bei 5 auf die nächste gerade Zahl (s. OH). Das gleiche gilt für die ab A00 eingebaute VBA-Funktion Round z.B. ergibt Round(1.085, 2) 1.08
s.a. http://support.microsoft.com/?kbid=225330 oder http://support.microsoft.com/?kbid=196652
Die - wie alle genannten Finger-weg-Varianten - öfter in NGs empfohlene Format-Funktion rundet (zumindest bis A97) ebenfalls nicht zuverlässig.
Ursache
Fließkommaberechnungen generell und Access-Datentypen sind ungenau.
Access besitzt seltsamerweise keine eingebaute Funktion zur kaufmännischen Rundung.
Lösung
Access-intern muss man sich einer selbstgebastelten Funktion bedienen.
Die kürzeste mir bekannte mit ausreichender Genauigkeit:
Function fctRound(varNr As Variant, Optional varPl As Integer = 2) As Double
'by Konrad Marfurt + ("" by) Luke Chung + Karl Donaubauer
'raus hier bei nicht-nummerischem Argument
If Not IsNumeric(varNr) Then Exit Function
fctRound = Fix("" & varNr * (10 ^ varPl) + Sgn(varNr) * 0.5) / (10 ^ varPl)
End Function
Anmerkungen:
Rundung auf 2 Dezimalstellen ist voreingestellt, falls das Argument dafür nicht übergeben wird. (s. Bsp1)
Bsp1: fctRound(1.025)
--> 1.03
Bsp2: fctRound(1.25,1)
--> 1.3
Bsp3: fctRound(1250,-2)
--> 1300
Der Leerstring "" ist kein Fehler in der Funktion sondern der Haupttrick zwecks Genauigkeit.
Eine andere Möglichkeit zur kaufmännischen Rundung:
Falls Excel vorhanden ist, kann man die Excel-Tabellenfunktion Round verwenden (entspricht nicht der gleichnamigen VBA-Funktion). Beschreibung von Günther Ritter:
Man nehme:
Ein Modul, und Häkchen unter Extras.Verweise auf die EXCEL8.0 Library.
Beispiel Funktion für Runden:
Function RundZahl(a,b)
RundZahl=Excel.Application.Round(a, b)
End Function
Noch ein Hinweis zur Fünfer-Rundung, z.B. bei der Schweizer 5-Rappen-Geschichte auf 0,00/0,05. Man kann dazu die o.a. Rundungsfunktion jedesmal oder in eine eigene Prozedur gekleidet wie folgt aufrufen:
fctRound((ZahloderFeldname * 20),0)/20
2.2 Bilder speichern |
https://www.donkarl.com?FAQ2.2 | aktualisiert 2020-08-03 |
Problem
Du möchtest Bilder in Access speichern und/oder anzeigen. Deine Datenbank bläht sich aber mit zunehmender Anzahl der Bilder unverhältnismäßig auf.
Ursache
Access speichert per OLE eingebundene Bilder in einem Bitmap-ähnlichen speicherfressenden Format.
Lösung
Ab der Version A07 hat MS sowohl die Anzeige als auch die Speicherung von Bildern erheblich verbessert.
Anzeige extern gespeicherter Bilder:
- in der Tabelle speichert man den Bildpfad in einem ganz normalen Textfeld
- in Formularen und Berichten fügt man ein Bild-Steuerelement ein und verwendet in der Eigenschaft Steuerelementinhalt den Namen des Textfeldes
Bild-Steuerelemente haben diese Eigenschaft und somit die Möglichkeit der Datenbindung ab A07. Daher ist auch die Anzeige im Endlosformular oder -bericht im Gegensatz zu früheren Access-Versionen kein Problem mehr.
Speicherung der Bilder in der Datenbank:
Wenn du Bilder in der Datenbank speichern musst, dann verwende ab A07 nicht mehr den Datentyp OLE-Objekt, sondern Anlage. Dieser mit A07 eingeführte Datentyp ist in der Speicherung wesentlich effizienter, d.h. er bläht die Datenbank nicht überdimensional auf, und man kann mehrere Bilder (oder andere Dateien) in einem Anlagefeld speichern.
Anleitung für ältere Access-Versionen bis inkl. A03
1. Variante
Speichere nur den Pfad zu den Bildern in Access - nicht die Bilder selbst.
s. KB-Artikel 148463
2. Variante
Wenn du die Bilder unbedingt in der DB speichern möchtest, gibt es die Möglichkeit, sie mit Hilfe der Open-Anweisung und der Methoden AppendChunk und GetChunk (s. Online-Hilfe) aus der Bild-Datei in Access einzulesen und binär zu speichern. Dann wächst ihre Größe nur unwesentlich. Um die Bilder in einem Formular anzuzeigen, kann man sie z.B. mit den gleichen Methoden wieder in eine temporäre Datei auslesen und diese dem Bild-Steuerelement als Quelle zuweisen. Code: KB-Artikel 103257
Beispiele und Dokus zum Thema:
Ein umfassendes Dokument, das alle Varianten und viele Probleme der Bildspeicherung behandelt, ist Harald Langers Vortragsmanuskript von der 4. AEK (s. AEK-Downloads).
Beispiel-MDBs für alle Varianten mit (englischer) Erklärung gibt es auch von Larry Linson:
http://members.tripod.com/accdevel
Beispiel von Klaus Oberdalhoff für die Variante mit dem Pfad-Verweis: "Bildanz.zip" bei http://www.freeaccess.de/
Beim externen Speichern führt der Bildladedialog manchmal zu Abstürzen oder stört. Er lässt sich mit einem Eintrag in der Registry ausschalten (Tipp von Harald Langer, aktualisiert von Phil Stiefel).
In Versionen <=A00:
HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\Graphics Filters\Import\betroffenes Grafikformat\Options Schlüssel ShowProgressDialog auf No.
In Versionen >=AX:
HKEY_CURRENT_USER\Software\Microsoft\Shared Tools\Graphics Filters\Import\betroffenes Grafikformat\Options Schlüssel ShowProgressDialog auf No
2.3 Klang abspielen |
https://www.donkarl.com?FAQ2.3 |
Problem
Du möchtest bei Ereignissen Klänge abspielen, die im wav-Format vorliegen (z.B. die Windows-Systemklänge).
Lösung
Geht mit API. Im Deklarationsteil eines allg.Moduls:
Declare Function sndPlaySound Lib "winmm.dll" _
Alias "sndPlaySoundA" (ByVal lpszSoundName As String, _
ByVal uFlags As Long) As Long
Aufruf im Code eines passenden Ereignisses:
sndPlaySound "Pfad_und_Name_der_WAV_Datei", 0
Falls das für deine Zwecke nicht ausreichend ist, gibt's eine komplexere Version zum Klang-Abspielen von Dev Ashish: http://www.mvps.org/access/api/api0011.htm
2.4 Warnmeldungen unterdrücken |
https://www.donkarl.com?FAQ2.4 | aktualisiert 2006-12-22 |
Problem
Bei Aktionsabfragen oder Datensatzänderungen erscheint eine Warnmeldung.
Lösung
Diese Meldungen können im Menü Extras/Optionen/Bearbeiten Suchen für die ganze mdb ausgeschaltet werden.
Per Code:
Application.SetOption "Confirm Record Changes", False
Application.SetOption "Confirm Document Deletions", False
Application.SetOption "Confirm Action Queries", False
Wenn die Meldungen nur für eine Aktion per VBA ausgeschaltet werden sollen:
DoCmd.SetWarnings False
'Aktion durchführen und danach wieder einschalten mit
DoCmd.SetWarnings True
Wenn es um Aktionsabfragen geht, gibt es noch eine weitere Möglichkeit, Nachfragen zu verhindern. Man kann (und sollte) statt DoCmd.RunSQL die Execute-Methode verwenden. z.B. in dieser Art:
CurrentDb.Execute "Name_der_Abfrage_oder_SQL_Statement", dbFailOnError
2.5 Pfad und Name der aktuellen Datenbank |
https://www.donkarl.com?FAQ2.5 |
Problem
Du möchtest Pfad und/oder Name der aktuellen mdb wiedergeben.
Lösung
Ab A00 gibt es dafür entspechende Eigenschaften des CurrentProject-Objektes:
CurrentProject.FullName
CurrentProject.Path
CurrentProject.Name
Sie funktionieren in VBA und in allen "deutschen" Ausdrücken z.B. als Steuerelementinhalt (dort Zeichen "=" davorsetzen).
Das gleiche gilt für folgende Varianten, die in allen Access-Versionen anwendbar sind (in dt. Ausdrücken "," durch ";" ersetzen):
Pfad und Name der Db:
CurrentDb.Name
nur Pfad:
Left(CurrentDb.Name,Len(CurrentDb.Name)-Len(Dir(CurrentDb.Name)))
nur Name:
Dir(CurrentDb.Name)
2.6 Access-Verzeichnis ermitteln |
https://www.donkarl.com?FAQ2.6 |
Problem
Du möchtest das Verzeichnis ermitteln, in dem sich Access d.h. die aktuell verwendete Datei msaccess.exe befindet.
Lösung
Verwende in VBA:
SysCmd(acSysCmdAccessDir)
2.7 Alter ermitteln |
https://www.donkarl.com?FAQ2.7 | aktualisiert 2021-10-25 |
Problem
Du möchtest das Alter einer Person anhand des Geburtsdatums feststellen.
Lösung
abgeleitet von Dev Ashish:
DatDiff("jjjj";[Geburtsdatum];Datum())+(Format(Datum();"mmtt")<Format([Geburtsdatum];"mmtt"))
Erläuterung:
Zuerst werden mit DatDiff die Jahre zwischen den beiden Daten ermittelt.
Dann wird geprüft, ob Tag und Monat des aktuellen Datums kleiner sind als jene des Geburtsdatums.
Wenn dem so ist, muss ein Jahr abgezogen werden.
Ergibt dieser Vergleich Wahr, stellt Access das intern als -1 dar. Bei Falsch als 0.
Deshalb kann man das Ergebnis gleich addieren.
s.a. Geburtstagsliste erstellen
2.8 Erster/Letzter Tag des Monats |
https://www.donkarl.com?FAQ2.8 |
Problem
Du möchtest in einem Feld den ersten oder letzten Tag des aktuellen Monats oder Jahres anzeigen.
Lösung
aktuelles Monat:
erster Tag = Datum()-Tag(Datum())+1
letzter Tag = DatSeriell(Jahr(Datum());Monat(Datum())+1;0)
aktuelles Jahr:
erster Tag = DatSeriell(Jahr(Datum());1;1)
letzter Tag = DatSeriell(Jahr(Datum());12;31)
2.9 Montag einer Kalenderwoche |
https://www.donkarl.com?FAQ2.9 |
Problem
Du möchtest ermitteln, welches Datum der Montag einer vorgegebenen Kalenderwoche hat.
Lösung
Du kannst folgenden Code verwenden:
'***************** CODE START ********************
Public Function fctKWMon(ArgKW As Byte, Optional ArgJahr)
'gibt den Montag der übergebenen Kalenderwoche zurück
'verwendet die in Europa übliche Einstellung: KW 1 = die erste mit 4 Tagen
'von Karl Donaubauer
Dim M As Date
If IsMissing(ArgJahr) Then ArgJahr = Year(Date)
M = DateSerial(ArgJahr, 1, 1) + (ArgKW - 1) * 7
M = M + 1 - WeekDay(M, vbMonday)
If Format(M, "ww", vbMonday, vbFirstFourDays) <> ArgKW Then M = M + 7
If (ArgKW = 1 Or ArgKW = 53) And Day(M) > 4 And Day(M) < 8 Then M = M - 7
fctKWMon = M
End Function
'***************** CODE ENDE ********************
Aufruf fctKWMon(1, 2000)
ergibt den Montag der 1. KW im Jahr 2000.
Ohne Jahresangabe fctKWMon(1)
wird das aktuelle Jahr angenommen.
2.10 Stundensumme über 24 |
https://www.donkarl.com?FAQ2.10 | aktualisiert 2007-01-03 |
Problem
Eine Zeitdifferenz oder eine Zeitsumme von mehr als 24 Stunden wird im Zeitformat nicht "richtig" angezeigt.
Ursache
Access kennt keine Zeitfelder, sondern rechnet alle Zeiten als Datum.
Lösung
für eine Zeitdifferenz
=Format$(Fix(FctRound([MeineZeit]*24));"0") & ":" & Format$([MeineZeit];"nn")
Anmerkung: Die Funktion fctRound() hilft, Rundungsfehler zu vermeiden. s. Runden.
für eine Zeitsumme (nach einer Idee von Uwe Weineck)
Setze folgende Funktion in ein VBA-Modul:
Function fctTimeSum(ByVal lngHour As Long, _
ByVal lngMin As Long, ByVal lngSec As Long) As String
fctTimeSum = Format$(lngHour + (lngMin + lngSec \ 60) \ 60, "00") _
& ":" & Format$((lngMin + lngSec \ 60) Mod 60, "00") _
& ":" & Format$(lngSec Mod 60, "00")
End Function
Aufruf z.B. im Steuerelement eines Textfeldes (alles in einer Zeile):
=fctTimeSum(Summe(Stunde(Gesamtzeit));Summe(Minute(Gesamtzeit));Summe(Sekunde(Gesamtzeit)))
2.11 Zahl in Worten |
https://www.donkarl.com?FAQ2.11 |
Problem
Du möchtest eine Zahl als geschriebenes Wort wiedergeben.
Beispiel: 4321 --> viertausenddreihunderteinundzwanzig
Lösung
Kopiere den folgenden Code in ein allg. Modul (A2, A95 oder A97).
(Der idente Code in der dt. MS-KB ist übrigens von mir, nicht umgekehrt. ;-)
Aufruf mit: FctZahl_In_Worten(4321)
'*********** CODE START *************
Public Function FctZahl_In_Worten(Zahl As Double)
'wandelt Zahlen im Bereich 0-999.999.999 in Worte um
'von Karl Donaubauer
Dim z As String, w As String
Dim r As Integer, i As Integer
z = Int(Zahl)
If z = 0 Then FctZahl_In_Worten = "null": Exit Function
For i = 6 To 0 Step -3
If Len(z) > i Then
r = Right(Int(z / (10 ^ i)), 3)
If r > 99 Then w = FctZif(1, Left(r, 1), w) & "hundert": r = Right(r, 2)
If r > 19 Then w = FctZif(3, Right(r, 1), w): w = FctZif(4, Left(r, 1), w)
If i = 0 And Right(z, 3) Like "00*" And r > 0 Then w = w & "und"
If r < 10 Then w = FctZif(1, r, w)
If r > 9 And r < 20 Then w = FctZif(2, Right(r, 1), w)
If i = 6 And Len(z) = 7 And r = 1 Then w = "einemillion"
If i = 6 And Right(Int(z / 10 ^ i), 3) > 1 Then w = w & "millionen"
If i = 3 And Right(Int(z / 10 ^ i), 3) > 0 Then w = w & "tausend"
If i = 0 And r = 1 Then w = w & "s"
End If
Next
FctZahl_In_Worten = w
End Function
'----------------------
Function FctZif(Par As Byte, r As Integer, w As String)
w = w & Choose(r, "ein", "zwei", "drei", "vier", "fünf", "sech", "sieb", "acht", "neun")
Select Case Par
Case 1, 3
If r = 6 Then w = w & "s"
If r = 7 Then w = w & "en"
If Par = 3 And r > 0 Then w = w & "und"
Case 2
w = w & "zehn"
If r = 1 Then w = Left(w, Len(w) - 7) & "elf"
If r = 2 Then w = Left(w, Len(w) - 8) & "zwölf"
Case 4
If r = 2 Then w = Left(w, Len(w) - 4) & "zwan"
w = w & "zig"
If r = 3 Then w = Left(w, Len(w) - 3) & "ßig"
End Select
FctZif = w
End Function
'*********** CODE ENDE *************
2.12 Leerzeichen in kombiniertem Feld vermeiden |
https://www.donkarl.com?FAQ2.12 |
Problem
Du setzt z.B. im Bericht ein Textfeld aus verschiedenen Feldern mit "&" zusammen und setzt Leerzeichen dazwischen. z.B.
[Titel] & " " & [Vorname] & " " & [Nachname]
Wenn nun eines der vorderen Felder leer ist, wird das Leerzeichen trotzdem eingefügt und stört.
Lösung
Verwende für das Anhängen der Leerzeichen "+" statt "&":
([Titel]+ " ") & ([Vorname]+ " ") & [Nachname]
Dem String-Operator & ist es egal, ob einer der Operanden fehlt. Der mathematische Operator + hingegen liefert nur ein Ergebnis, wenn beide vorhanden sind. Die Kombination der beiden führt daher zum gewünschten Ergebnis.
2.13 Leeres Feld verhindert Formelergebnis |
https://www.donkarl.com?FAQ2.13 |
Problem
Du verwendest irgendwo in Access einen Ausdruck. Wenn ein darin enthaltenes Feld leer ist, dann bringt der ganze Ausdruck kein Ergebnis. z.B. hast du als Steuerelementinhalt eines berechneten Feldes:
=[Feldx] + [Feldy] + [Feldz]
Wenn z.B. nur in [Feldy] nichts drin steht, dann kommt gar kein Ergebnis.
Lösung
Um das zu verhindern, gibt es ab A95 die Nz-Funktion (s. Online-Hilfe)
Für obiges Beispiel sollte der Ausdruck dann lauten:
=Nz([Feldx]) + Nz([Feldy]) + Nz([Feldz])
Damit liefert der Ausdruck immer ein Ergebnis. Sogar wenn alle drei Felder leer sind lautet das Ergebnis 0.
Man kann der Nz-Funktion auch einen Wert mitgeben, der erscheinen soll, falls das Feld leer ist. z.B. ergeben
Nz([DeinZahlFeld];1)
die Zahl 1 oder
Nz([DeinTextFeld];"Hugo")
den Text "Hugo" falls die Felder leer sind.
Die Nz-Funktion ist in allen Arten von Ausdrücken und in VBA anwendbar.
In A2 gibt es noch kein Nz, man kann aber die Wenn-Funktion verwenden:
=Wenn(IstNull([Feldx]);0;[Feldx]) + Wenn(IstNull([Feldy]);0;[Feldy])
usw.
2.14 Zeilenumbruch einfügen |
https://www.donkarl.com?FAQ2.14 | aktualisiert 2010-01-28 |
Problem
Du möchtest einen Zeilenumbruch in ein Steuerelement einfügen.
Lösung
Als Ausdruck z.B. in einem Steuerelementinhalt:
=ErsterTeilDesTextes & Zchn(13) + Zchn(10) & ZweiterTeilDesTextes
In VBA geht das mit Chr(13) + Chr(10)
oder mit den eingebauten Konstanten vbCrLf
und vbNewLine
.
Ab A07 gibt es für Memofelder und für den Steuerelementtyp Textfeld die Eigenschaft TextFormat. Wenn die Eigenschaft auf RichText eingestellt wurde, muss man darin für einen Zeilenumbruch den entsprechenden HTML-Befehl <br>
oder <br/>
verwenden.
2.15 Text wird automatisch geändert |
https://www.donkarl.com?FAQ2.15 | aktualisiert 2018-06-11 |
Problem
Du gibst in einem Feld in einer Tabelle, Abfrage oder einem Formular einen Text ein. Unmittelbar nach der Eingabe oder beim Verlassen des Feldes wird ein Wort in diesem Text geändert. z.B. wird aus einem Namen wie "Bernd Deise" automatisch ein "Bernd Diese".
Ursache
Die Autokorrektur hat zugeschlagen.
Lösung
Im Menü Extras/Autokorrektur bzw. Ribbon Datei - Optionen - Dokumentprüfung - Autokorrektur-Optionen den Eintrag für das Wort löschen oder während der Eingabe ersetzen und andere unerwünschte Korrekturen deaktivieren. Diese Einstellungen gelten dann für das ganze Access, also in allen Datenbanken.
Bei einem Formularfeld kannst du auch die Eigenschaft Autokorrektur zulassen auf Nein setzen. Dann bleibt nur dieses Feld von der Autokorrektur verschont. Diese Variante hilft auch, wenn man die Access-Einstellungen nicht kontrollieren kann z.B. bei Betrieb mit der Runtime. Diese Steuerelementeigenschaft lässt sich zudem per VBA einstellen:
Me!MeinTextFeld.AllowAutoCorrect = False
2.16 #Fehler bei Bezug auf leeres Objekt |
https://www.donkarl.com?FAQ2.16 |
Problem
Du hast in einem Steuerelementinhalt einen Bezug auf ein Feld eines anderen (Unter-)Formulares oder (Unter-)Berichtes. Wenn dort keine Datensätze vorhanden sind, wird der Detailbereich nicht angezeigt und das Feld mit dem Bezug hat als Inhalt: #Fehler
Lösung
Schreib statt einem einfachen Steuerelementinhalt wie:
=[UFo_Element]![Feldname]
eine Wenn-Bedingung inkl. Fehlerbehandlung:
=Wenn(IsError([UFo_Element]![Feldname]);Null;[UFo_Element]![Feldname])
Statt Null kannst du bei Textfeldern auch "" oder bei Zahlfeldern 0 schreiben.
2.17 Memo variabel formatieren |
https://www.donkarl.com?FAQ2.17 | aktualisiert 2010-01-28 |
Problem
Du möchtest innerhalb eines Text- oder Memofeldes Teile des Textes unterschiedlich formatieren. Die Formatierungen gelten aber in Access immer für das ganze Feld bzw. Steuerelement.
Lösung
Ab A07 gibt es für Memofelder und für Textfeld-Steuerelemente die Eigenschaft TextFormat, die man auf RichText einstellen kann. Damit hat man etliche Formatierungsmöglichkeiten, die über Ribbons und über eine Minisymbolleiste angeboten werden. Access verwendet dabei als Formatierungscode eine begrenzte Auswahl von HTML-Tags. Für Details s. http://office.microsoft.com/de-de/access/HA100140971031.aspx?pid=CH100645681031
Alternativen und Lösungen für ältere Access-Versionen:
Für Textfelder in Berichten und einfache Arten von unterschiedlichen Formatierungen gibt's relativ einfache Programmiertricks mit reinen Access-Mitteln. Stephen Lebans bietet Beispiele dafür: http://www.lebans.com/mixbold-plain.htm
Für Formulare oder komplexere Formatierungen kann man Zusatzsteuerelemente verwenden, die das Rich-Text-Format (RTF) unterstützen:
MS bietet in der Office Developer's Edition (ODE) (s. FAQ 1.3) ein solches RichText-Control an. Es funktioniert aber nicht in Berichten.
Ein empfehlenswertes, kostenloses RichText-ActiveX gibt es wiederum von Stephen Lebans: http://www.lebans.com/richtext.htm. Es bietet weniger Mängel und mehr Leistung (z.B. Blocksatz) als das Steuerelement von MS.
Außerdem gibt es das kommerzielle, aber komfortable "Total Access Memo" von http://www.fmsinc.com.
Falls der MS Internet Explorer vorhanden ist, bieten auch das DHTML-EDIT und das Webbrowser-Control des IE eine kostenlose Alternative.
Zur Problematik Blocksatz gibt es Folien und Infos über Tools von Josef Syrovatka: http://access.primary.at/downloads.htm
2.18 Euro - Schriften, Währungssymbole |
https://www.donkarl.com?FAQ2.18 |
Problem
Euro-Symbol € fehlt in den Schriften; in Währungsfeldern ändert sich bei Umstellung in der Win-Systemsteuerung das Symbol nicht.
Lösung
Eurofonts (Arial, Times, Courier) für Win95 und weitere Info
http://officeupdate.microsoft.com/downloadDetails/offeurofonts.htm
http://www.eu.microsoft.com/windows/euro.asp
http://www.microsoft.com/technet/topics/euro/default.htm
Währungsfelder mit Literalzeichen (von Christa Schwanke):
Bei an Währungsfelder gebundenen Formular- und Berichtsfeldern kannst Du im Formular bzw. Bericht einfach das Format Währung ganz rauslöschen. Dann wird das aktuelle Währungsformat aus der Ländereinstellung übernommen.
Bei errechneten bzw. ungebundenen Feldern kannst ebenfalls ohne Währungsformat arbeiten, musst aber dann beim Öffnen bzw. beim Anzeigen das Feld neu formatieren.
Beispiel:
Me.Controls("SummeDMVariabel").Format = "Currency"
Me.Controls("SummeEuroVariabel").Format = "Currency"
Auch dann wird die aktuelle Ländereinstellung übernommen.
2.19 PLZ, BLZ, Länderdaten, Vorwahlen |
https://www.donkarl.com?FAQ2.19 | aktualisiert 2010-04-23 |
Problem
Du suchst Bezugsquellen für Datenbestände wie Postleitzahlen, Vorwahlen, Ländercodes, Währungen, Feiertage etc.
Lösung
PLZ und BLZ für D, A, CH
http://www.access-paradies.de
PLZ mit Strassen und Gemeindeschlüsseln in D
http://www.muench-stahl.de/sascha
PLZ für A - die offiziellen, gratis von der .at-Post
http://app.post.at/plzverzeichnis/createplz.php
PLZ für CH - die offiziellen, gratis von der .ch-Post
http://www.post.ch/de/index/uk-privatkunden/pm-plz-verzeichnis.htm
Länderdaten wie Landeskürzel, Währungen, Hauptstädte, Feiertage etc.
(für D, A, CH, CZ, USA, tw. GB auch Bundesländer) enthält die
StateHoliday.zip von Stefan Wirrer (252 KB)
alle Bankleitzahlen und Banken in D
http://www.bundesbank.de unter Zahlungsverkehr/Bankleitzahlen
http://192.109.2.70/internet/bankleit.nsf/ludocs/Allgemein?OpenDocument
Ortsvorwahlenverzeichnis für D
http://www.dtag.de
2.20 Feldinhalte nachträglich trennen |
https://www.donkarl.com?FAQ2.20 |
Problem
Du hast ein Tabellenfeld in dem sich mehrteilige Inhalte befinden, z.B. Vor- und Nachname, Straße und Hausnummer etc. Zur weiteren Verarbeitung möchtest du diese Daten in jeweils eigene Felder auftrennen.
Lösung
Grundsätzlich solltest du darauf achten, in einem Tabellenfeld nur Werte zu speichern, die nicht weiter zerlegbar sind (--> 1. Normalform). Späteres Verketten ist stets einfacher als nächträgliches Trennen.
Wenn es brauchbare Trennungskriterien gibt z.B. trennende Leerzeichen oder Kommas, kannst du mit Aktualisierungsabfragen oder VBA-Funktionen einen Großteil der Arbeit automatisiert erledigen. Ein Beispiel:
Angenommen im Feld "Kunde" befinden sich Vor- und Nachname getrennt durch 1 Leerzeichen (z.B. "Bill Gates").
1. Lege in der Tabelle zwei neue Felder an und nenne sie "Vorname" und "Nachname".
2. Erzeuge auf Basis der Tabelle eine Aktualisierungsabfrage.
3. Schreibe im Abfrageentwurf in der Zeile "Aktualisieren" beim Feld "Vorname":
Left([Kunde];InStr([Kunde];" ")-1)
beim Feld "Nachname":
Mid([Kunde];InStr([Kunde];" ")+1)
Eine andere häufige Variante ist Nachname vor dem Vornamen durch Komma+Leerzeichen gertrennt ("Gates, Bill"). Hier lauten die Ausdrücke:
Left([Kunde];InStr([Kunde];",")-1)
Mid([Kunde];InStr([Kunde];",")+2)
Weitere Info gibt's im VBA-Editor mit <F1> zu den verwendeten String-Funktionen.
4. Führe die Abfrage aus und sei glücklich mit dem Ergebnis bzw...
Bei solchen Aktionen können Fehler passieren, weil z.B. jmd. mehrere/mehrteilige Vor- oder Nachnamen hat oder das Format nicht immer eingehalten wurde. Daher solltest du die Ergebnisse genau prüfen, z.B. die Ausdrücke zuerst in einer Auswahlabfrage als berechnete Felder testen und anpassen, oder die Daten händisch nachbearbeiten.
2.21 Makro "Tastaturbelegung" ab A00 |
https://www.donkarl.com?FAQ2.21 | aktualisiert 2006-05-24 |
Problem
Du hast eine DB aus einer älteren Version in eine Version >= Access 2000 konvertiert oder eine neue DB mit alten Gewohnheiten darin erstellt. Die Tastaturbelegungen, die du im Makro "Tastaturbelegung" festgelegt hast, funktionieren nicht mehr.
Lösung
In Versionen ab A00 muss der englische Name für das Tastatur-Makro verwendet werden. Benenne es daher um in "Autokeys".
Es kommt vor, dass das Tastaturbelegungsmakro auch bei richtiger Benennung von Access ignoriert wird. Dann kannst du versuchen, den Namen des Tastaturbelegungsmakros nochmal explizit zu setzen. Das geht mit:
Application.SetOption "Key Assignment Macro", "Tastaturbelegung"
oder
Application.SetOption "Key Assignment Macro", "Autokeys"
Du kannst damit auch einen beliebigen anderen Namen für das Tastaturbelegungsmakro vergeben. Manchmal ist es notwendig, nach dieser Zuweisung die Datenbank zu schließen und neu zu öffnen, damit das Makro verwendet wird.
2.22 Summe eines berechneten Steuerelementes |
https://www.donkarl.com?FAQ2.22 |
Problem
Du versuchst in einem Formular oder Bericht die Summe eines berechneten Steuerelementes zu bilden. Beim Öffnen fragt Access mit dem Namen des berechneten Steuerelementes nach einem Parameter bzw. zeigt in dem Summenfeld einen Fehler oder nichts an.
Lösung
Um die Summe eines berechneten Steuerelementes bilden zu können, musst du die Formel aus dem berechneten Steuerelement wiederholen. Beispiel:
Das berechnete Steuerelement "USt" hat als Steuerelementinhalt: =[Netto]*0,16
Ein Summenfeld mit folgendem Steuerelementinhalt funktioniert nicht: =Summe([USt])
Der richtige Steuerelementinhalt des Summenfeldes lautet: =Summe([Netto]*0,16)
2.23 Datenänderungen protokollieren |
https://www.donkarl.com?FAQ2.23 |
Problem
Du möchtest bei Neuanlage oder Änderung von Datensätzen festhalten, wann und wer das war.
Es gibt aber in Access, anders als in einigen anderen DBMS, keine eingebauten Funktionen, Zeitstempel, Trigger o.ä., die das erledigen.
Lösung
Wenn es nur darum geht, zu protokollieren, wann ein Datensatz angelegt wurde, dann funktioniert das recht einfach auf Tabellenebene. Lege dazu ein Feld vom Typ Datum/Uhrzeit an und schreibe in die Eigenschaft Standardwert: Jetzt()
Ähnlich kann man auch in einem Formular den Standardwert für Datum/Zeit der Neuanlage verwenden.
Was den aktuell angemeldeten Benutzer betrifft, so kann man ihn nicht auf Tabellenebene eintragen lassen (s. FAQ 3.3). In einem Formularfeld funktioniert hingegen als Standardwert: CurrentUser()
Für die Protokollierung von Änderungen an bestehenden Datensätzen muss ein Formular verwendet werden, weil das programmiert werden muss. Es gibt dabei zwei Denkschulen: Der übliche Weg ist, im Ereigniscode Vor Aktualisierung des Formulares Zeit und User in dieser Art einzutragen:
Me!MeinDatumsfeld = Now
Me!MeinBenutzerfeld = CurrentUser
Die andere Gruppe von Entwicklern möchte sicher gehen, dass die Protokollfelder nur gefüllt werden, wenn die Aktualisierung tatsächlich durchgeführt und nicht etwa durch irgendwelche Einschränkungen verhindert wurde. Deshalb wird beim Ereignis Nach Aktualisierung Code wie der folgende verwendet:
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.Bookmark = Me.Bookmark
rs.Edit
rs!MeinDatumsfeld = Now
rs!MeinBenutzerfeld = CurrentUser
rs.Update
Set rs = Nothing
2.24 Netzwerk User/Computername auslesen |
https://www.donkarl.com?FAQ2.24 |
Problem
Du möchtest in Access den aktuellen User-, Computer- oder Domain-Namen in einem Windows-Netzwerk auslesen.
Lösung
Geht per API. Hier ein paar Links mit verschiedenen Code-Beispielen.
User, Computer, Domain, Arbeitsgruppe
http://support.microsoft.com/?kbid=210088
Username
http://www.mvps.org/access/api/api0008.htm
http://support.microsoft.com/?kbid=161394
http://support.microsoft.com/?kbid=505875
vollständiger Name des Windows-Benutzers
http://www.mvps.org/access/api/api0066.htm
Computername
http://www.mvps.org/access/api/api0009.htm
NT-Domain
http://www.mvps.org/access/api/api0040.htm
UNC-Pfad eines Netzlaufwerks
http://support.microsoft.com/?kbid=160529
2.25 Kalenderwoche ermitteln |
https://www.donkarl.com?FAQ2.25 | aktualisiert 2019-11-07 |
Problem
Du möchtest aufgrund eines Datums (bzw. eines Datumsfeldes) die Kalenderwoche ermitteln.
Lösung
Du kannst (z.B. als Steuerelementinhalt eines berechneten Feldes) folgenden Audruck verwenden:
=DatTeil("ww";MeinDatumsFeld)
In VBA:
DatePart("ww", MeinDatumsFeld)
In der Onlinehilfe findest du bei der DatePart-Funktion die Beschreibung weiterer Parameter, mit denen du einstellen kannst, was für dich Wochenanfang und die erste Woche eines Jahres ist.
In Europa auf Basis von ISO 8601 üblich:
=DatTeil("ww";MeinDatumsFeld;2;2)
bzw. in VBA:
DatePart("ww", MeinDatumsFeld, vbMonday, vbFirstFourDays)
Ähnliche Möglichkeiten zur Ermittlung der Kalenderwoche bietet die Format-Funktion:
Format(MeinDatumsFeld, "ww")
Achtung!
Es gibt einen altbekannten Bug, der dafür sorgt, dass für manche Jahre eine falsche Kalenderwoche für den letzen Montag des Jahres zurückgegeben wird. Beschreibung:
https://docs.microsoft.com/office/troubleshoot/access/functions-return-wrong-week-number
Wenn das in deiner Anwendung eine Rolle spielen kann, dann sollte der im Artikel angeführte Workaraound verwendet werden.
2.26 Formularbasierte Filter in der Runtime |
https://www.donkarl.com?FAQ2.26 |
Problem
Du verwendest in deiner Anwendung Formularbasierte Filter. Wenn die Anwendung in der Runtime-Umgebung ausgeführt wird, funktionieren diese Filter nicht mehr.
Ursache
Es gibt keine Formularbasierten Filter in der Runtime:
http://support.microsoft.com/?kbid=172090
Lösung
Es gibt bei MS Beispiele für einen Workaraound als Download:
für A97: http://support.microsoft.com/?kbid=166634
für A00: http://support.microsoft.com/?kbid=262099
2.27 Drag and Drop mit Access |
https://www.donkarl.com?FAQ2.27 |
Problem
Du möchtest in eine Access-Anwendung Drag'n Drop einbauen, also Ziehen- und Fallenlassen mit der Maus, wie in vielen Windowsanwendungen und Entwicklungsumgebungen möglich.
Lösung
Access bietet dafür kein Ereignis an (wie etwa VB). Es gibt nur Workaraounds für die Verwendung in Formularen.
s. http://support.microsoft.com/?kbid=287642
Käufliches dazu gibt es von Peter De Baets:
http://www.peterssoftware.com/dd.htm
2.28 Sicherheitsmeldungen |
https://www.donkarl.com?FAQ2.28 | aktualisiert 2015-12-15 |
Problem
Beim Öffnen einer Datenbank erscheinen Warnmeldungen wie:
"Unsichere Ausdrücke sind nicht blockiert. Möchten Sie unsichere Ausdrücke blockieren?"
"...Diese Datei ist möglicherweise nicht sicher... möchten Sie das Öffnen abbrechen..."
"Microsoft Office Access kann PfadUndNameDerDatenbank aufgrund von Sicherheitsbeschränkungen nicht öffnen"
In weiteren Meldungen wird auf die Notwendigkeit des SP8 für Office hingewiesen usw.
Du möchtest diese Warnmeldungen loswerden.
Ursache
MS hat mit der Version 2003 in Access ähnliche Sicherheits-, Warn- und Zertifizierungsmechanismen eingebaut wie vorher schon in Excel und Word. Bei Access geht es v.a. darum, dass sog. "Unsichere Ausdrücke" bei nicht zertifizierten Datenbanken blockiert werden sollen (sog. Sandbox Mode). Das sind VBA-Befehle wie Shell, Kill, CurDir u.v.a., die Zugriff auf das Dateisystem erlauben. Eine Auflistung der Befehle und weitere Info gibt es beim Klick auf den Hilfe-Knopf in den div. Meldungsfenstern. Bei MS gibt's auch eine üppige Infoseite zum Thema Sicherheit mit Unterseiten zu den Warnmeldungen, Zertifikaten, Sandbox etc.
Lösung
1. Sicherheitsstufe auf "Niedrig" setzen.
Die einfachste Variante, um die Warnmeldungen loszuwerden, ist das Herabsetzen der Sicherheitsstufe im Menü Extras/Makro/Sicherheit. Wenn man die Einstellung dort auf "Niedrig" setzt, erscheinen keine Meldungen mehr. Das gilt für alle Datenbanken für diesen User auf diesem PC und entspricht der Einstellung in allen Access-Versionen vor A03, denn die hatten überhaupt keine Sicherheitsstufen.
Bei manchen Installationen fehlt der Menüpunkt Extras/Makro/Sicherheit, bes. bei konvertierten DBs.
s. http://support.microsoft.com/?kbid=833219
Das lässt sich folgendermaßen beheben:
- rechter Mausklick auf eine Menü- oder Symbolleiste und Anpassen wählen
- auf der Registerseite Befehle als Kategorie Extras wählen
- aus dem rechten Listenfeld den Eintrag Sicherheit... mit der Maus an die richtige Stelle im Extras-Menü ziehen
Der beschriebene Menüpunkt stellt zwei Registry-Werte um. Eine andere Variante, die Warnungen loszuwerden, ist daher, die Sicherheitsstufe und den Sandbox Mode direkt in der Registry umzustellen. Die Sicherheitsstufe ist Anwender-Sache. Der Schlüssel dafür ist:
\\HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Access\Security
Der Wert sollte auf 1 stehen, damit keine Meldungen erscheinen.
Der Sandbox-Modus hingegen gilt Maschinen-weit. Der Registry-Eintrag dafür ist:
\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\SandboxMode
Dieser Wert sollte entweder auf 2 oder auf 0 stehen, wenn man möchte, dass weiterhin alle Funktionen (auch die "unsicheren") laufen.
2 = Sandbox nur für Nicht-Access-Anwendungen, die auf JET zugreifen
0 = Sandbox generell deaktiviert
Weitere Info dazu: http://support.microsoft.com/?id=294698
Wenn nur die Runtime-Version von Access installiert ist, sind andere Registry-Einträge zuständig (Tipp von Albert Kallal). Es müssen 2 neue Schlüssel angelegt werden.
für die Sicherheitsstufe:
\\HKEY_LOCAL_MACHINE\Software\Microsoft\Office\11.0\Access\Security
neuer Schlüssel: level
Wert: #00000001
für den SandboxMode:
\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines
neuer Schlüssel: SandBoxMode
Wert: #00000002
2. Zertifikat erstellen
Sicherheitsstufe "Niedrig" wird von MS ausdrücklich "nicht empfohlen", denn es könnte jmd. böse Dinge tun mit den o.a. unsicheren Ausdrücken. Zudem hilft diese Einstellung nicht gegen Sicherheitswarnungen, wenn eine Datenbank auf einem Kundenrechner installiert wird, auf dem man die Stufe nicht niedriger setzen kann oder darf. Für diesen Fall sind sog. Digitale Zertifikate gedacht.
Die einfache Variante ist ein selbst erstelltes Zertifikat. Dafür gibt es in Office 2003 ein Tool, z.B. im Start-Menü Programme/Office/Tools/Digitale Signatur für VBA-Projekte oder das Programm SELFCERT.EXE im Office-Ordner direkt starten. Ein selbst erstelltes Zertifikat gilt aber wieder nur auf dem eigenen Rechner.
Andere Formen von Zertifikaten kann man von offiziellen Zertifizierungsfirmen kaufen. Es gibt sog. Class 3 Zertifikate für größere Firmen oder Organisationen und Class 2 Zertifikate für Einzelpersonen. Letztere sind allerdings noch kaum erhältlich und es gibt damit nur wenig Erfahrung (wie mit der ganzen Zertifiziererei).