2. Allgemein

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 in A03
   
2.1 Runden
http://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

nach oben

2.2 Bilder speichern
http://www.donkarl.com?FAQ2.2 aktualisiert 2011-12-16

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. http://support.microsoft.com/?kbid=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: http://support.microsoft.com/?kbid=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

nach oben

2.3 Klang abspielen
http://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

nach oben

2.4 Warnmeldungen unterdrücken
http://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

nach oben

2.5 Pfad und Name der aktuellen Datenbank
http://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)

nach oben

2.6 Access-Verzeichnis ermitteln
http://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)

nach oben

2.7 Alter ermitteln
http://www.donkarl.com?FAQ2.7

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.

Falls du auch die vergangenen Monate und Tage brauchst:
http://support.microsoft.com/default.aspx?scid=kb;de;D37560

s.a. Geburtstagsliste erstellen

nach oben

2.8 Erster/Letzter Tag des Monats
http://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)

nach oben

2.9 Montag einer Kalenderwoche
http://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.

nach oben

2.10 Stundensumme über 24
http://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)))

nach oben

2.11 Zahl in Worten
http://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 *************

nach oben

2.12 Leerzeichen in kombiniertem Feld vermeiden
http://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.

nach oben

2.13 Leeres Feld verhindert Formelergebnis
http://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.

nach oben

2.14 Zeilenumbruch einfügen
http://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.

nach oben

2.15 Text wird automatisch geändert
http://www.donkarl.com?FAQ2.15

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 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.

nach oben

2.16 #Fehler bei Bezug auf leeres Objekt
http://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.

nach oben

2.17 Memo variabel formatieren
http://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

nach oben

2.18 Euro - Schriften, Währungssymbole
http://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.

nach oben

2.19 PLZ, BLZ, Länderdaten, Vorwahlen
http://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

nach oben

2.20 Feldinhalte nachträglich trennen
http://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.

nach oben

2.21 Makro "Tastaturbelegung" ab A00
http://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.

nach oben

2.22 Summe eines berechneten Steuerelementes
http://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)

nach oben

2.23 Datenänderungen protokollieren
http://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

nach oben

2.24 Netzwerk User/Computername auslesen
http://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

nach oben

2.25 Kalenderwoche ermitteln
http://www.donkarl.com?FAQ2.25

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!
Bei der Berechnung des letzten Montags eines Jahres gibt es einen bekannten Bug, der dafür sorgt, dass für manche Jahre eine falsche Kalenderwoche für den letzen Montag zurückgegeben wird. Beschreibung:
http://support.microsoft.com/?kbid=200299
Wenn das in deiner Anwendung eine Rolle spielen kann, dann sollte der im KB-Artikel angeführte Workaraound verwendet werden.

nach oben

2.26 Formularbasierte Filter in der Runtime
http://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

nach oben

2.27 Drag and Drop mit Access
http://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

nach oben

2.28 Sicherheitsmeldungen in A03
http://www.donkarl.com?FAQ2.28 aktualisiert 2004-12-17

Problem

Beim Öffnen einer Datenbank mit A03 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).

nach oben