MS Access: Unicode-Zeichen per VBA erzeugen

Hinterlasse einen Kommentar

Unicode-Zeichen können in MS Access unter VBA mit der Funktion ChrW() erzeugt werden. Als Parameter übergibt man den Unicode-Wert.

Auf den erzeugten String können die üblichen String-Operationen angewendet werden, also z. B. sixSimaString=”6″  &  ChrW(963)  & “=”  &  sixSigmaWert .

Die Funktion zur Ermittlung des Unicode-Wertes eines Zeichens heißt  AscW().

Zumindest unter Access 2002 können Unicode-Zeichen, die keine ASCII-Zeichen sind, nicht im VB-Code-Editor angezeigt werden.

MS Access: sporadische #gelöscht-Anzeige in Unterformularen

Hinterlasse einen Kommentar

In einer MS Access-Anwendung, die ich geschrieben habe, werden in einem Formular in mehreren Registerkarten unter anderem zwei Unterformulare verwendet, welche die Ergebnisse von Datenbank-Abfragen erhalten. Beim Betätigen eines Buttons innerhalb des Formulars werden die Abfragen aufgefrischt und danach stets die erste Registerkarte, die keine Unterformulare enthält, selektiert.

Oftmals kommt es vor, dass nun in den Unterformularen einzelnen Spalten nach einer Auffrischung den Eintrag #gelöscht enthalten, während die anderen Spalten der Unterformulare korrekt aktualisiert werden. Da dieses Problem nicht immer auftritt, vermute ich hier eine Race Condition innerhalb von Access.

Da ich die wirkliche Ursache des Problems nicht lösen kann, behelfe ich mir mit folgendem Workaround:

Ich fange das Ereignis des Registerkartenwechsels ab und führe dann einen Refresh durch.

Private Sub Registerkarte_Change()
     Me.UF1_Abfrage.Requery
     Me.UF2_Abfrage.Requery
End Sub

Durch den erneuten, zeitversetzten Requery nach der ursprünglichen Aktualisierung tritt die Race Condition nicht mehr auf, und alle Spalten der beiden Unterformulare werden jetzt korrekt dargestellt.

 

 

MS Access: Standard-Menüleiste wieder herstellen

Hinterlasse einen Kommentar

Falls einmal die Standard-Menüleiste deaktiviert hat und sie über die GUI nicht mehr aktiviert bekommt, lässt sich sich in VBA mit den Befehl

Application.CommandBars("menu bar").Enabled=True

wieder einschalten.

MS Access: Fehlermeldung über mangelnden Speicherplatz

Hinterlasse einen Kommentar

In den letzten Tagen habe ich in einer selbsterstellten Access-Anwendung die Fehlermeldung “Nicht genügend Speicherplatz, um diese Operation durchzuführen. Schließen Sie Anwendungen, die Sie nicht benötigen, und versuchen Sie es noch einmal.” erhalten. Meine Versuche, die Fehlerursache einzugrenzen, blieben erfolglos.

Nachdem ich im Internet über die Probleme von Access mit der Speicherverwaltung gelesen habe, prüfte ich meinen Programmcode und gab allozierten Speicher, z. B. für ADODB.RecordSet-Objekte am Ende einer Sub/Function jeweils explizit frei (Set Variable = Nothing). Damit konnte ich mein Problem nicht lösen.

Geholfen hat schließlich, eine neue MDB-Datei anzulegen und alle Tabellen, Formulare, Abfragen, Berichte, Makros und Codemodule aus der alten MDB-Datei zu importieren. Danach erschien die Fehlermeldung nicht mehr.

Zu beachten ist, dass man gegebenenfalls für die neue MDB-Datei auch alle Verweise (im Code-Editor unter Extras/Verweise) neu setzt und auch unter dem Menüpunkt Extras die gewünschten Einstellungen vorzunehmen.

MS Access: Feldnamen für den Zugriff auf Felder in Formularen dynamisch erzeugen

Hinterlasse einen Kommentar

MS Access bietet die Möglichkeit, Feldnamen für den Zugriff auf Formulare dynamisch zu erzeugen, konkret einen String mit dem gewünschten Feldnamen zur Laufzeit zusammenzusetzen.

Dies ist beispielsweise hilfreich,  falls in einem Formular “durchnummerierte” Felder, z. B. Betreff1, Betreff2, Betreff3 verwendet werden. Mit folgendem Code lassen sich beispielsweise alle 30 Betreff-Felder im Formular AV_Lanes_Anzeigen leeren:

For i=1 to 30
Forms!AV_Lanes_anzeigen("Betreff"&i).Caption = ""
Next i

MS Access: “geklonte” Formulare in den Vordergrund holen

Hinterlasse einen Kommentar

Ich schrieb ja schon, wie man Formulare unter Access “klonen” kann.

Ich bin nun auf das Problem gestossen, im Hintergrund befindliche “Klon-Formulare” in den Vordergrund holen zu müssen.

An sich gibt es dafür den Befehl

DoCmd.SelectObject acForm, <Formularname>

Leider haben aber alle geklonten Formulare den gleichen Namen, von dem ich auch nicht weiß, wie ich ihn ändern könnte. Auch

DoCmd.SelectObject acForm, Formularkopie(i)

funktioniert nicht.

Die Lösung besteht darin, ein “Klon-Formular”, das man in den Vordergrund holen möchte, erst unsichtbar und dann wieder sichtbar zu machen:

Formularkopie(i).Visible = False
Formularkopie(i).Visible = True

Der Umgang mit Fehlern in MS Access

Hinterlasse einen Kommentar

Ein Programm sollte so konzipiert sein, dass es auf auftretende Fehler möglichst sinnvoll reagiert, diese am besten jedoch verhindert (Pokal Yoke).

Programmfehler

Um aufgetretene Fehler zu behandeln, bietet Access den On Error-Befehl an. Er bietet zum einen die Möglichkeit, im Fehlerfall zu einer Marke in der Sub/Function zu springen und den dortigen Code zur Fehlerbehandlung abzuarbeiten (On Error GoTo  Sprungmarke), als auch die Option, den Fehler zu ignorieren und mit dem nächsten Kommando weiter zu machen (On Error Resume Next). Im Fehlerfall wird ein Objekt Err erzeugt, über das man ein paar Informationen zum aufgetretenen Fehler erhält.

Für die Fehlerbehandlung in Formularen kann man die Sub Form_Error im jeweiligen Formular verwenden, die eine Fehlernummer bereit stellt.

Ich formuliere “gefahrengeneigten” Code meistens in Funktionen und melde als Rückgabewert den Fehlerstatus (0=kein Fehler, alle anderen Werte sind Fehler). In der aufrufenden Sub/Function kann dann gegebenenfalls auf den zurück gegebenen Fehlercode entsprechend reagiert werden, ohne dass der Programmlauf abgebrochen wird.

Ich verwende eine allgemeine Fehlerbehandlungsroutine, die im Fehlerfall jeweils aufgerufen wird und den Fehler in vereinheitlichter Form ausgibt, z. B. über eine Messagebox.

Zusätzlich werden die aufgetretenen Fehler noch in ein Fehlerprotokoll geschrieben, so dass ich ggfs. noch eine Post-Mortem-Analyse durchführen kann. Leider werden Fehler ja auch nicht immer von den Anwendern gemeldet, so dass die gefühlte und die reale Fehlerhäufigkeit voneinander abweichen können. Durch die Protokollierung der Fehler ist ggfs. auch eine statistische Auswertung der Fehler möglich, um die “Hot Spots” zu erkennen, in denen die meisten Fehler auftreten und wo die Entwickler-Zeit am sinnvollsten investiert werden sollte.

Ich habe drei Fehlerkategorien definiert. Die erste führt zum Programmabbruch nach Fehlermeldung und -protokollierung, die zweite zeigt den Fehler an und protokolliert ihn (ohne Programmabbruch) und die dritte protokolliert einen Fehler “still”.

Bei Anwendungen im betrieblichen Umfeld muss man hinsichtlich der Protokollierung den Aspekt der Leistungs- und Verhaltenskontrolle beachten.

Plausibilitätsprüfungen

Neben der Behandlung aufgetretener Fehler sollte  nach meinem Verständnis auch die Vorbeugung von Fehlern implementiert werden. Ich baue daher Plausibilitätsprüfungen in meine Programme ein, die bei Auftreten von nicht prozesskonformen Werten oder Wertekombinationen einen Hinweis ausgeben oder ggfs. selbsttätig korrigieren (Jidoka).

Ein Beispiel dafür ist, dass ich z. B. das Erledigt-Flag in einer Erfassungsmaske automatisch setzen lassen, wenn ein Erledigungsdatum von Anwender eingegeben wurde. Ein anderes Beispiel ist die Prüfung eines Datumswertes mit der IsDate-Funktion auf Gültigkeit.

Je besser die Plausibilitätsprüfungen sein sollen, desto besser muss man natürlich den abgebildeten Prozess kennen und verstehen. Bei Prozessänderungen müssen die Plausibilitätsprüfungen jeweils angepasst werden.

Gerade in Formularen bietet Access bereits eingebaute Möglichkeiten zur Gültigkeitsprüfung für einzelne Eingabefelder an.

Je nach Schwere der verletzten Plausibilitätskriterien kann man es bei einer Meldung über die Plausibilitätsverletzung (Messagebox vom Typ vbInformation) belassen, die Plausibilität per Programmlogik herstellen, oder man erzwingt die Eingabe von plausiblen Daten (z. B.  lässt sich vorher das Eingabeformular nicht schließen).

Hier muss die Balance zwischen der Datenkonsistenz und der “Freiheit des Anwenders” gefunden werden.

Weitere Massnahmen

Um Fehlbedienungen/Falscheingaben zu minimieren, bietet es sich an, möglichst nur die gerade relevanten Programmoptionen anzuzeigen. Ich blende beispielsweise je nach Programmsituation in Access-Formularen Optionen oder Buttons aus bzw. ein.

Neben der Behandlung von technischen und logischen Fehlern spielt auch die Benutzerfreundlichkeit eine wichtige Rolle, z. B. durch erwartungskonformes Verhalten des Programms.

Ein Programm sollte Idealerweise so gestaltet sein, dass der Anwender es gerne nutzt, auch wenn sich dies in der Praxis nicht immer umsetzen lässt.

Meine eigene Personal-Kanban-Anwendung

2 Kommentare

Da ich an meinem Arbeitsplatz in der Wahl meiner Software leider sehr eingeschränkt bin, aber dennoch Personal Kanban zur Bewältigung meiner täglichen Arbeit ausprobieren wollte, habe ich mir kurzerhand in MS Access eine eigene Anwendung programmiert. Ich bin dabei über einfache Personal Kanban-Karten hinaus gegangen und habe meine Story-”Karten” um weitere Informationen, wie z. B. Fälligkeit, Priorität, etc. erweitert. Ich hatte neben Personal Kanban noch GTD und die Eisenhower-Matrix im Hinterkopf und habe die Anwendung mehrbenutzerfähig ausgelegt.

Meine Erfassungsmaske für die Bearbeitung von Aufgaben sieht so aus:

Sie weist mehrere Registerkarten für allgemeine Aufgabendaten, eine ausführliche Beschreibung,  Teilaufgaben und eine Bearbeitungshistorie auf. Als Priorität kann man dabei einen der Quadranten der Eisenhower-Matrix auswählen. Der Status gibt an, ob die Aufgabe unbearbeitet ist, weiter bearbeitet werden kann oder blockiert ist (z. B. durch Warten auf etwas). Der Aufgabentyp legt grob fest, worum es bei der Aufgabe geht, z. B. Datenpflege oder Programmierung. Über den geschätzten Zeitbedarf soll man später einmal den spätesten Anfangszeitpunkt errechnen lassen können – ganz im Sinne von Just in time – und auch ein Gespür dafür erhalten, wie gut man den Zeitbedarf für eine Aufgabe abschätzen kann. Den Auftraggeber wählt man aus einer Liste aus, gepeichert wird die Personalnummer, so dass später eine leichte Suche nach Auftraggebern möglich ist (auch, wenn diese ihren Namen durch Heirat ändern). Daneben gibt es noch den Erfasser und den Bearbeiter der Aufgabe, beides ist bei Teamarbeit relevant. Wenn eine Aufgabe angelegt wird, erstellt das Programm auch automatisch ein Ablageverzeichnis für alle dieser Aufgabe zugehörigen Dateien, so ist immer alles schön beeinander.

Mein Kanban-Board habe ich relativ simpel gehalten mit den drei Lanes Bereit, In Bearbeitung und Erledigt. In die Lane Bereit packe ich die Aufgaben aus dem Backlog, die ich mir zur Ausführung ausgesucht habe:

Die Farben der Kanban-Karten spiegelt den Aufgabentyp wieder. Die Farbe für jeden Aufgabentyp ist vom Anwender frei vergebbar (mittels Color Picker aus Access heraus). Die Rahmenfarbe spiegelt die Priorität und Fälligkeit wieder. Der rote Rahmen im Beispiel signalisiert beispielsweise, dass es sich um eine Aufgabe des Eisenhower-Quadranten wichtig und dringend handelt, der gelbe Rahmen um die Karte darunter, dass diese Aufgabe die Priorität wichtig und dringend hat. Das kleine farbige Quadrant in den Kanban-Karten in den Lanes Bereit und In Bearbeitung signalisiert, ob die Aufgabe weiter bearbeitet werden kann (grün), ob ob sie blockiert ist (rot). Über die Details-Buttons lässt sich die betreffende Aufgabe in der Erfassungsmaske öffnen.

Über einen Suchdialog kann man nach verschiedenen Kriterien, inclusive der Volltextsuche, bestimmte Kanban-Karten suchen. Das Suchergebnis wird als ein 6×5-Board mit den Treffern dargestellt:

Das Backlog wird in der gleichen Weise dargestellt. Über die Buttons mit den Ausrufezeichen kann man eine Aufgabe als Bearbeiter übernehmen.

Mögliche Erweiterungen sehe ich im Bereich der Kapazitätsplanung (die geschätzte Bearbeitungsdauer einer Aufgabe sowie deren Priorität sind ja bekannt) und vor allem im Bereich der Statistik (z. B. Durchlaufzeiten). Die Anwendung muss sich jetzt erst einmal in der Praxis bewähren und eventuelle Fehler behoben werden.

MS Access: Nutzung eines Farbauswahl-Dialogs (Color Picker)

1 Kommentar

Um den Farbauswahl-Dialog des Betriebssystems zu nutzen, muß der entsprechende Windows-API-Aufruf deklariert werden, hier gleich ergänzt um ein paar Konstanten:

Private Declare Function ChooseColor_Dlg Lib "comdlg32.dll" _
Alias "ChooseColorA" ( _
lpcc As CHOOSECOLOR_TYPE) As Long
Private Type CHOOSECOLOR_TYPE
 lStructSize As Long
 hwndOwner As Long
 hInstance As Long
 rgbResult As Long
 lpCustColors As Long
 flags As Long
 lCustData As Long
 lpfnHook As Long
 lpTemplateName As String
End Type
' Ein paar gebräuchliche Konstanten für den Color Picker
Private Const CC_ANYCOLOR = &H100
Private Const CC_ENABLEHOOK = &H10
Private Const CC_ENABLETEMPLATE = &H20
Private Const CC_ENABLETEMPLATEHANDLE = &H40
Private Const CC_FULLOPEN = &H2
Private Const CC_PREVENTFULLOPEN = &H4
Private Const CC_RGBINIT = &H1
Private Const CC_SHOWHELP = &H8
Private Const CC_SOLIDCOLOR = &H80

Hier etwas Beispielcode, bei dem ein Anwender über einen Button FarbeAuswählen den Dialog aufruft und die ausgewählte Farbe dann als Vordergrundfarbe für das Dialogelement Beispiel gesetzt wird:

Private Sub FarbeAuswählen_Click()
 Dim CC_T As CHOOSECOLOR_TYPE, Retval As Long
 Static BDF(16) As Long
 ' Einige Farben vorgeben (Benutzerdefinierte Farben)
 BDF(0) = RGB(255, 0, 255)
 BDF(1) = RGB(125, 125, 125)
 BDF(2) = RGB(90, 90, 90)
 With CC_T
  .lStructSize = Len(CC_T)
  .hInstance = 0
  .hwndOwner = Me.hwnd
  .flags = CC_RGBINIT Or CC_ANYCOLOR Or CC_FULLOPEN Or _
  CC_PREVENTFULLOPEN
  .rgbResult = RGB(0, 255, 0)
  .lpCustColors = VarPtr(BDF(0))
 End With
 Retval = ChooseColor_Dlg(CC_T)
 If Retval <> 0 Then
  Beispiel.ForeColor = CC_T.rgbResult
 Else
  MsgBox "Sie haben keine Farbe ausgewählt!"
 End If
End Sub

MS Access: Einbindung eines Datum-Auswahldialoges (Date Picker)

Hinterlasse einen Kommentar

Um einen Date Picker in MS Access zu nutzen, muss dieser möglicherweise erst einmal über das Werkzeug “Weitere Steuerelemente” im Formulardesigner eingebunden werden. Die Bezeichnung des Elementes variiert möglicherweise je nach Windows-Version und installierter Software, bei mir unter Windows Vista nennt es sich “Kalender-Steuerelement 10.0″. Das Element wird dann wie üblich auf dem Formular platziert. Das Ansprechen des Elements im Code passiert dann folgendermaßen (das Element hat hier den Namen Calendar0):

In der Prozedur Form_Load() könnte man als Default-Datum das Tagesdatum setzen:

Me.Calendar0.Value=Format(Now(), "d/m/yy",vbMonday, vbUserSystem)

Der Parameter d/m/yy stellt klar, dass das Default-Datum im Format Tag/Monat/Jahr übergeben wird, der vbMonday legt den Montag als ersten Wochentag fest, vbUserSystem sagt, dass die erste Kalenderwoche des Jahres gemäß Systemeinstellungen ermittelt werden sollen.

Das vom Anwender ausgewählte Datum kann vom Steuerelement dann wie üblich abgefragt werden:

Datum=Me.Calendar0.Value

Ältere Artikel

Follow

Bekomme jeden neuen Artikel in deinen Posteingang.