6. VBA

6.1   Variablen statt Objektnamen 6.12 Info zu Runcommand-Konstanten
6.2   DB-Fenster ein/ausblenden 6.13 Mehrere Zeilen auskommentieren
6.3   Punkt und Rufzeichen 6.14 Warten bis Shell beendet ist
6.4   Ein Parameter wurde erwartet 6.15 Text in die Zwischenablage kopieren
6.5   Steuerelemente durchlaufen 6.16 Parameterabfrage per VBA öffnen
6.6   Aktuelle MDB komprimieren 6.17 Datensätze zählen
6.7   Andere MDB komprimieren 6.18 Info zu Treeview/Listview
6.8   Datum an SQL-String übergeben 6.19 Datenbank-Kennwort übergeben
6.9   Code anhalten für Dialog 6.20 MDE per Code erstellen
6.10 Seek bei eingebundenen Tabellen 6.21 Dezimalzahl an SQL-String übergeben
6.11 Formatierte Msg-Box nach A97 6.22 Diagramme programmieren
   
6.1 Variablen statt Objektnamen
http://www.donkarl.com?FAQ6.1 aktualisiert 2007-01-03

Problem

Du möchtest in VBA statt dem fixen Namen eines Objektes (z.B. Steuerelement im Formular oder Feld im Recordset) eine Variable einsetzen.

Lösung

Verwende die Schreibweise mit den runden Klammern:

Steuerelement im Formular: Forms("Formularname")(StringVariable)
oder
Feld im Recordset: rs(StringVariable)

s.a. Steuerelemente durchlaufen

nach oben

6.2 DB-Fenster ein/ausblenden
http://www.donkarl.com?FAQ6.2 aktualisiert 2014-04-25

Problem

Du möchtest per VBA das Datenbankfenster oder den Navigationsbereich ein- oder ausblenden, also das Fenster oder den Bereich, in dem die Objekte von Access angezeigt werden.

Lösung

Ausblenden des Datenbankfensters:
DoCmd.SelectObject acTable, , True
RunCommand acCmdWindowHide


Einblenden:
DoCmd.SelectObject acTable, , True

In Versionen >=A07 funktioniert das Ausblenden des Navigationsbereiches mit obigem Code nicht zuverlässig, wenn z.B. gerade sämtliche Tabellen mit der Suchleiste weggefiltert wurden. Sicherer ist:

DoCmd.NavigateTo "acNavigationCategoryObjectType"
RunCommand acCmdWindowHide

nach oben

6.3 Punkt und Rufzeichen
http://www.donkarl.com?FAQ6.3 aktualisiert 2006-05-13

Problem

Du bist unsicher, ob du bei Bezügen "." oder "!" als Trennzeichen verwenden sollst/musst.

Lösung

Eine Grundregel ist: Vor Objekten ein "!", vor Auflistungen und Eigenschaften ein "."

Falls du am Anfang unsicher bist, hilft evtl. auch folgende Regel:

Wenn nach dem Trennzeichen ein Element folgt, das fix in Access eingebaut ist, dann gehört der Punkt. Wenn das Element von dir d.h. benutzerdefiniert ist, dann gehört das Rufzeichen. z.B.

Application.Forms!frmKunden.Controls!Nachname.Visible

Die Forms-Auflistung ist von Access vorgegeben deshalb .Forms
"frmKunden" stammt von dir, deshalb ! davor.
Die Controls-Auflistung ist wieder von Access vorgegeben.
"Nachname" ist ein benutzerdefinierter Steuerelementname.
Die Eigenschaft Visible stammt wieder von Access.

Diese Regel gilt auch für die meist angewandte Kurzform:
Forms!frmKunden!Nachname.Visible

Wundere dich nicht, dass bei Steuerelementen auch die Punkt-Schreibweise funktioniert, also z.B.
Me.Nachname

Der Grund ist, dass Steuerelemente sowohl Objekte als auch Eigenschaften von Formularen sind. Hin und wieder treten mit dieser Schreibweise aber überraschende und bisher unerklärliche Fehler auf - manchmal erst ab einem bestimmten Zeitpunkt z.B. einer Neukompilierung. Deshalb ist es sicherer, auch hier das Rufzeichen zu verwenden, oder die ebenfalls zuverlässige Schreibweise mit Klammern:
Me("Nachname")

nach oben

6.4 Ein Parameter wurde erwartet
http://www.donkarl.com?FAQ6.4 aktualisiert 2007-01-03

Problem

Du hast in einer Abfrage den Bezug auf ein Formular-Steuerelement als Kriterium eingegeben. Also:
Forms!Formularname!SteuerelementName
Wenn du versuchst, ein Recordset auf Basis der Abfrage zu öffnen, erscheint eine Fehlermeldung wie "1 Parameter wurden erwartet, aber 0 wurden geliefert", obwohl das Formular geöffnet ist.

Ursache

DAO greift direkt auf JET zu und versteht daher den Bezug auf Access-Objekte im SQL-Text nicht.

Lösung

Verwende in der Abfrage beim Formularbezug die Funktion Eval:
Eval("Forms!Formularname!SteuerelementName")
Eval sorgt dafür, dass der Ausdruck durch den sog. Expression Service geht, der solche Bezüge auswertet.

Eine andere Möglichkeit: Parameterabfrage per VBA öffnen

nach oben

6.5 Steuerelemente durchlaufen
http://www.donkarl.com?FAQ6.5

Problem

Du möchtest per Code mehrere oder alle Steuerelemente eines Formulares oder Berichtes durchlaufen, um z.B. eine Eigenschaft für diese Elemente in einem Rutsch zu ändern.

Lösung

Eine Variante ist, gleichartige Steuerelemente mit gleichem Namen und einer fortlaufenden Nummer zu benamsen: Liste1, Liste2, Liste3 … Dann kannst du folgendermaßen z.B. die Eigenschaft Sichtbar dieser Steuerelemente ändern:

Dim i As Integer
For i = 1 To 3
  Me("Liste" & i).Visible = False
Next


Du kannst auch z.B. die Eigenschaft Marke (engl. Tag) dazu verwenden, bestimmte Steuerelemente zu kennzeichnen. Die Schleife geht dann durch alle Elemente des Formulares oder Berichtes und prüft Tag:

Dim ctl As Control
For Each ctl In Me.Controls
  If ctl.Tag = "xyz" Then ctl.Visible = False
Next ctl

nach oben

6.6 Aktuelle MDB komprimieren
http://www.donkarl.com?FAQ6.6 aktualisiert 2010-12-20

Problem

Du möchtest per Code die aktuelle mdb komprimieren.

Lösung

Es gibt keinen eingebauten VBA-Befehl dafür. Für A97 bleibt daher als einfache Code-Lösung nur die Krücke mit
SendKeys "%xdk"
die den entsprechenden Menüpunkt aufruft. Dafür muss der Menüpunkt natürlich aktuell sichtbar sein.

Ab A00 gibt's eine Einstellung, um die DB beim Schließen automatisch komprimieren zu lassen (Menü Extras/Optionen/Allgemein).
Von A00 bis A03 funktioniert der Aufruf des Komprimieren-Menüpunkts per Code (Tipp von Access-MVP Juan M. Afan de Ribera aus Barcelona):

CommandBars("Menu Bar"). _
  Controls("Extras"). _
  Controls("Datenbank-Dienstprogramme"). _
  Controls("Datenbank komprimieren und reparieren..."). _
  accDoDefaultAction


Ab der Einführung der Ribbons mit A07 ist das nicht mehr möglich.

Ansonsten gibt's Lösungen mit dem Aufruf anderer mdbs oder Programme
z.B. von Dev Ashish: http://www.mvps.org/access/modules/mdl0030.htm

Von Michael Kaplan gibt's das TSI SOON-Addin für A97 und A00, das die Komprimierung aus der gleichen DB heraus ermöglicht: http://www.trigeminal.com/utility.asp

nach oben

6.7 Andere MDB komprimieren
http://www.donkarl.com?FAQ6.7

Problem

Du möchtest per Code eine andere als die aktuelle mdb komprimieren.

Lösung

Sorge dafür, daß keine Objekte oder Code mit Referenzen auf die zu komprimierende mdb offen sind. Wenn z.B. Tabellen der zu komprimierenden mdb in der aktuellen mdb eingebunden sind, dürfen keine Formulare oder Recordsets geöffnet sein, die auf diesen Tabellen basieren.

Mit Dialogfenster ab A95: RunCommand acCmdCompactDatabase

Ohne Dialogfenster: Kopiere die folgende Funktion in ein Standardmodul.

'*************** CODE START ******************
Function fctCompactOtherDB(strPath As String)
  'Komprimiert die angegebene MDB
  'Aufruf: fctCompactOtherDB "Pfad_und_Name_der_zu_komprimierenden.mdb"

  On Error GoTo myError
    
  DoCmd.Hourglass True
    
  Dim strFile As String
  Dim varDummyPath As Variant
  Dim varDummyFile As Variant
    
  strFile = Dir(strPath)
  varDummyPath = Left$(strPath, Len(strPath) - Len(strFile))
  varDummyFile = varDummyPath & "Dummy.mdb"
  DBEngine.CompactDatabase strPath, varDummyFile
  Kill strPath
  Name varDummyFile As strPath
    
  myExit:
    DoCmd.Hourglass False
    Exit Function
    
  myError:
    Select Case Err.Number
      Case 3005, 3024, 53, 3044, 76
        MsgBox "Die Datenbank konnte nicht gefunden werden.", vbOKOnly
      Case 3196
        MsgBox "Die Datenbank wird zur Zeit verwendet.", vbOKOnly
      Case Else
        MsgBox "Ausnahme Nr. " & Err.Number & ". Das heißt: " & Err.Description
    End Select
    Resume myExit

End Function

'*************** CODE ENDE ******************

nach oben

6.8 Datum an SQL-String übergeben
http://www.donkarl.com?FAQ6.8

Problem

Du erzeugst per Code einen SQL-Ausdruck und möchtest dabei den Wert eines Datumsfeldes als Kriterium verwenden. Du erhältst aber die Fehlermeldung "Syntaxfehler in Ausdruck...".

Ursache

JET-SQL braucht das amerikanische Datumsformat (mm/dd/yy) oder das ISO-Format (yyyy-mm-dd).

Lösung

Da Access intern Datum/Uhrzeit als Zahl vom Typ Double speichert, kannst du das Datum als Double konvertiert übergeben: Str(CDbl(DeinDatumsfeld))
für ein Datum ohne Uhrzeit funktioniert ebenso: CLng(DeinDatumsfeld)

Du kannst auch die Funktion Format verwenden, um das Datum in das US- oder ISO-Format umzuwandeln z.B.

Dim strDatum As String
Dim strSQL As String

strDatum = Format(DeinDatumsfeld, "\#yyyy\-mm\-dd\#")

strSQL = "SELECT * FROM Tabelle WHERE Tabelle.Feld > " & strDatum

nach oben

6.9 Code anhalten für Dialog
http://www.donkarl.com?FAQ6.9

Problem

Du öffnest in einer Prozedur ein Formular und möchtest das Abarbeiten des weiteren Prozedurcodes anhalten, bis im aufgerufenen Formular Daten eingegeben wurden bzw. dieses wieder geschlossen wurde.

Lösung

Öffne das Eingabeformular als Dialog, dann wird der Code angehalten:
DoCmd.OpenForm "MeinDialogFormular", , , , , acDialog

Der Code läuft erst weiter, wenn das Dialogformular geschlossen wurde oder wenn es unsichtbar gemacht wurde, d.h. auch nach einem
Me.Visible = False
im Dialogformular läuft der aufrufende Code weiter und man kann sich auf Felder des nun unsichtbaren Formulares beziehen. Wenn es dann nicht mehr benötigt wird, solltest du das Dialogformular explizit schließen:
DoCmd.Close acForm, "MeinDialogFormular"

nach oben

6.10 Seek bei eingebundenen Tabellen
http://www.donkarl.com?FAQ6.10

Problem

Du öffnest ein DAO-Recordset mit einer eingebundenen Tabelle als Quelle. Falls du dabei den Recordsettyp dbOpenTable angibst, erhältst du eine Fehlermeldung:"Laufzeitfehler 3219: unzulässige Operation" 
Falls du keinen Typ angegeben hast, aber versuchst, mit Seek nach einem Datensatz zu suchen, erhältst du die Fehlermeldung: "Laufzeitfehler 3251: Operation wird für diesen Objekttyp nicht unterstützt!"

Ursache

Ein Recordset auf eingebundene Tabellen kann nicht den Recordset-Typ Table haben. Deshalb ist auch die Seek-Methode nicht möglich, die diesen Typ voraussetzt.

Lösung

Du kannst ein Recordset vom Typ Dynaset verwenden und mit den Find-Methoden suchen (dbOpenDynaset bzw. FindFirst & Co)

Wenn du die Seek-Methode, die i.d.R. schneller ist als FindFirst, weiterhin nutzen möchtest, kannst du die externe Datenbank öffnen und dann wieder ein Recordset vom Typ Table verwenden:

Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = DBEngine.Workspaces(0).OpenDatabase("externe DB")
Set rs = db.OpenRecordset("externe Tabelle", dbOpenTable)

nach oben

6.11 Formatierte Msg-Box nach A97
http://www.donkarl.com?FAQ6.11

Problem

In A97 kann man in der MsgBox-Funktion das @-Zeichen dazu verwenden, Abschnitte verschieden zu formatieren. In Versionen ab A00 funktioniert das nicht mehr.

Ursache

Der VBE (Visual-Basic-Editor) von A00 greift nicht mehr auf die Meldungs-Funktion von Access zurück.

Lösung

Michael Kaplan zeigt, wie man auch in Versionen >=A00 die Access-Funktion nutzen kann, um eine MsgBox zu formatieren:
http://www.trigeminal.com/usenet/usenet015.asp

nach oben

6.12 Info zu Runcommand-Konstanten
http://www.donkarl.com?FAQ6.12 aktualisiert 2014-03-03

Problem

In der Online-Hilfe von A97 und A00 gibt es nur eine Liste aber keine Erläuterung der Konstanten, die man bei der Runcommand-Methode verwenden kann.

Lösung

Terry Wickendens Webseite (englisch) bietet jede Menge Info und Beispiele zum Gebrauch aller RunCommand-Konstanten:
http://access.mvps.org/access/RunCommand/index.htm

Eine Gegenüberstellung der Runcommand-Konstanten und der entsprechenden deutschen Menübefehle gibt es von Christa Gebhardt:
http://www.dbdev.org/ (bei den Downloads)

nach oben

6.13 Mehrere Zeilen auskommentieren
http://www.donkarl.com?FAQ6.13

Problem

Du möchtest beliebig lange Abschnitte in deinem Code mit Kommentarzeichen (einfaches Hochkomma = ' ) versehen bzw. diese Zeichen wieder entfernen und findest keine Möglichkeit dazu im Codefenster.

Lösung

In A97 ist noch keine solche Funktion eingebaut. Es gibt jedoch ein Tool von Dev Ashish und Terry Kreft:
http://www.mvps.org/access/modules/mdl0031.htm

In >=A00 gibt es im VBE (Visual Basic Editor) entsprechende Symbole in der Symbolleiste Bearbeiten. Im Anpassen-Modus für Symbolleisten (rechter Mausklick auf eine Symbolleiste und Anpassen wählen) kannst du die Symbole in die Standardsymbolleiste der VBE kopieren, wo sie besser erreichbar sind.

nach oben

6.14 Warten bis Shell beendet ist
http://www.donkarl.com?FAQ6.14 aktualisiert 2010-05-11

Problem

Du startest mithilfe der Shell-Funktion eine andere Anwendung und möchtest, dass der weitere Code erst abgearbeitet wird, wenn dieser Shell-Prozess beendet ist.

Lösung

Die klassische Lösung bieten die API-Funktionen CreateProcess() und WaitForSingleObject(). Ihre Anwendung zeigt der folgende KB-Artikel:
http://support.microsoft.com/?kbid=209876
Es gibt auch ein Beispiel von Terry Kreft: http://www.mvps.org/access/api/api0004.htm

Eine kürzere Lösung (ab Win2000) ermöglicht die API-Funktion GetProcessVersion. (Tipp von Sven Gallin)
s.a. http://msdn.microsoft.com:80/en-us/library/ms683224(VS.85).aspx
Die Funktion gibt eine Prozess-Id zurück, wobei der aufrufende Prozess 0 ist. Daher braucht man nur in einer Schleife auf ungleich 0 zu prüfen. Hier das übliche Beispiel mit Notepad (in ein Standardmodul kopieren und aufrufen):

Public Declare Sub Sleep _
    Lib "Kernel32" (ByVal dwMilliseconds As Long)

Public Declare Function GetProcessVersion _
    Lib "Kernel32" (ByVal ProcessId As Long) As Long

Sub procShellWait()

    Dim lngHandle As Long

    lngHandle = Shell("NOTEPAD.EXE", 1)
    While GetProcessVersion(lngHandle) <> 0
        DoEvents
        'Sleep verhindert, dass die Prozessorauslastung auf 100% geht
        'Tipp von Michael Zimmermann
        Sleep 1
    Wend

   MsgBox "Process Finished"

End Sub

nach oben

6.15 Text in die Zwischenablage kopieren
http://www.donkarl.com?FAQ6.15

Problem

Du möchtest Text mit VBA in die Zwischenablage kopieren bzw. aus der Zwischenablage holen.

Lösung

Wenn es um Inhalte von Steuerelementen oder um ganze Datensätze in einem Formular geht, dann kann man das gewünschte Objekt auswählen und (ab A97) die passenden RunCommand-Konstanten verwenden, die den Menüpunkten im Bearbeiten-Menü entsprechen:

RunCommand acCmdCut 'Ausschneiden
RunCommand acCmdCopy 'Kopieren
RunCommand acCmdPaste 'Einfügen
RunCommand acCmdPasteAppend 'Am Ende anfügen

Wenn es nicht um Daten geht, die man an der Formular-Oberfläche erwischt, sondern um Variablen, Daten aus Recordsets etc., dann kann man API-Funktionen verwenden.

Text in die Zwischenablage schicken:
http://support.microsoft.com/?kbid=210216

Text aus der Zwischenablage holen:
http://support.microsoft.com/?kbid=210213

nach oben

6.16 Parameterabfrage per VBA öffnen
http://www.donkarl.com?FAQ6.16

Problem

Du möchtest per VBA eine Parameterabfrage öffnen und weißt nicht, wie du die Parameter übergeben kannst.

Lösung

Falls du ein Recordset auf die Abfrage öffnen willst, verwende Code wie diesen:

Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qdf As DAO.QueryDef

Set db = CurrentDb
Set qdf = db.QueryDefs("Meine_Parameter_Abfrage")
qdf.Parameters!MeinParameter1 = "Wert_für_Parameter1_in_Anführungszeichen_falls_er_ein_Text_ist"
qdf.Parameters!MeinParameter2 = Wert_für_Parameter2
'usw.

Set rs = qdf.OpenRecordset(dbOpenDynaset)
'hier folgt brillanter Code, der mit dem Recordset arbeitet
'…
'am Ende so tun, als wär nix gewesen:
qdf.Close: Set qdf = Nothing
rs.Close: Set rs = Nothing
Set db = Nothing


Falls du kein Recordset willst, sondern z.B. bloß eine Aktionsabfrage mit Parametern ausführen, sieht der Code ähnlich aus, nur folgt nach dem Zuweisen der Parameter kein "Set rs…" usw. sondern ein schlichtes:
qdf.Execute

nach oben

6.17 Datensätze zählen
http://www.donkarl.com?FAQ6.17

Problem

Du möchtest feststellen, ob eine Tabelle, Abfrage oder ein Recordset leer ist oder wieviele Datensätze vorhanden sind.

Lösung

Dafür existieren mehrere Ansätze. Die schnellste Variante herauszufinden, ist nicht immer einfach. Am besten mit verschiedener Datensatzanzahl am konkreten Objekt testen.

Für Tabellen und Abfragen gibt's die Domänenfunktion DCount:
MsgBox Dcount("*", "DeineTabelleOderAbfrage")

Eine andere Möglichkeit ist die Verwendung der SQL-Aggregatfunktion Count (s. Online-Hilfe zur "Count-Funktion").

Wenn die Tabelle/Abfrage als Recordset geöffnet wird bzw. grundsätzlich für DAO-Recordsets gibt's die Recordcount-Eigenschaft:

Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset("MeineTabelle", dbOpenDynaset)

If Not rs.BOF Then  'nur wenn überhaupt DS vorhanden sind
  rs.MoveLast 'wichtig, um die korrekte Anzahl an DS zu erhalten
  MsgBox rs.RecordCount
End If


Wenn du nur z.B. vor dem Durchlaufen des Recordsets abbrechen möchtest, falls keine Datensätze enthalten sind, reicht eine Prüfung auf BOF. BOF ist beim Öffnen eines DAO-Recordsets immer True, wenn dieses keine Datensätze enthält, d.h. nach einer Deklaration wie im obigen Beispiel könnte man prüfen:

If rs.BOF Then Exit Sub 'wenn leer, dann raus

Bei ADO gibt's auch ein RecordCount. Die Sache hängt aber vom Cursortyp und der Datenquelle ab. s. Online-Hilfe zur RecordCount-Eigenschaft

nach oben

6.18 Info zu Treeview/Listview
http://www.donkarl.com?FAQ6.18 aktualisiert 2011-12-16

Problem

Du suchst Information und Beispiele zu den ActiveX-Steuerelementen Treeview und/oder Listview.

Lösung

Falls du die Steuerelemente im Rahmen einer Office-Entwickler-Version oder mit VB bekommen hast, such auf der CD nach den Hilfe-Dateien Vbcmn96.hlp (ODE97 bzw. ältere VB-Version) bzw. Cmctl198.chm (MOD bzw. VB 6).

Jörg Ackermann hat auf der 3. Access-Enwickler-Konferenz (AEK) einen Vortrag zu diesem Thema gehalten. Das Skriptum gibt es bei den AEK-Downloads.

Von MS gibt es einige KB-Artikel zum Thema sowie
eine Beispiel-Datenbank für A97
den Treeview-Control-Wizard für A97
Hilfetexte und Beispiele zu Treeview und Listview auf den MSDN-Seiten

nach oben

6.19 Datenbank-Kennwort übergeben
http://www.donkarl.com?FAQ6.19 aktualisiert 2007-07-25

Problem

Du möchtest eine MDB in einer neuen Access-Instanz öffnen und dabei das Datenbank-Kennwort mit übergeben, damit es nicht extra eingegeben werden muss.

Lösung

Anm. Für das DB-Kennwort gibt es - anders als für Benutzername und Passwort - keine Möglichkeit der Übergabe mittels Befehlszeilenparameter in einer Verknüpfung.

Will man eine MDB aus einer anderen MDB per Code öffnen, kann man das Kennwort (bis inkl. Version A00) offiziell nur beim unsichtbaren Öffnen per OpenDatabase übergeben. Also in der Art:

DBEngine.Workspaces(0).OpenDatabase("C:\Foo\Meine.mdb", False, False, ";PWD=Kennwort")

Was das sichtbare Öffnen in einer neuen Access-Instanz per Code betrifft, gibt es ab AX einen neuen Parameter für das Kennwort bei der Methode OpenCurrentDatabase. z.B.

Dim appAcc As Access.Application
Set appAcc = CreateObject("Access.Application")
appAcc.OpenCurrentDatabase "C:\Foo\Meine.mdb", False, "Kennwort"


Für Versionen vor AX gibt es einen Trick von Günther Ritter:

Private Sub cmdOpen_Click()
  Dim db As DAO.Database, strDb As String
  Dim acc As New Access.Application 'weitere Access-Instanz erstellen
  Const strPWD As String = ";pwd=123456"
  strDb = "C:\DbMitKennwort.mdb"
  'Datenbank mit Kennwort öffnen
  Set db = acc.DBEngine.OpenDatabase(strDb, False, False, strPWD)
  acc.OpenCurrentDatabase strDb
  acc.RunCommand acCmdAppRestore 'erforderlich um Applikation nachfolgend zu maximieren
  acc.RunCommand acCmdAppMaximize
  acc.DoCmd.Maximize
  db.Close
End Sub

nach oben

6.20 MDE per Code erstellen
http://www.donkarl.com?FAQ6.20 aktualisiert 2010-04-02

Problem

Du möchtest per VBA aus einer MDB eine MDE machen, wie es sonst nur über den entsprechenden Menüpunkt möglich ist.

Lösung

1. Es gibt einen nicht dokumentierten, aber in den NGs altbekannten SysCmd-Befehl, mit dem man die Umwandlung einer MDB (nicht der aktuellen) durchführen kann:

In A97:
SysCmd 603, "MDBsamtPfad", "MDEsamtPfad"

Falls es mit diesem Einzeiler Probleme gibt, d.h. die Umwandlung nicht immer klappt, versuche die Version mit einer weiteren Access-Instanz. Ab A00 geht's nur mehr über diesen Umweg einer weitere Instanz in der Art:

Dim appAcc As Access.Application
Set appAcc = CreateObject("Access.Application")

appAcc.SysCmd 603 , "MDBsamtPfad", "MDEsamtPfad"

Set appAcc = Nothing


2. Das offizielle Gewürge über die Runcommand-Konstante acCmdMakeMDEFile, Bsp. s. http://www.accessruncommand.com

3. Um die aktuelle MDB in eine MDE umzuwandeln, gibt es für A97 und A00 das Add-In TSI SOON bei http://www.trigeminal.com/utility.asp.

nach oben

6.21 Dezimalzahl an SQL-String übergeben
http://www.donkarl.com?FAQ6.21

Problem

Du erzeugst per Code einen SQL-String und möchtest dabei eine Variable mit Dezimalstellen übergeben (z.B. als Wertzuweisung in einem INSERT INTO). Aufgrund der Ländereinstellung in der Windows-Systemsteuerung wird als Dezimaltrennzeichen ein Komma übergeben statt des für SQL notwendigen Punktes. Du erhältst eine Fehlermeldung wie "Anzahl der Abfragewerte und Zielfelder stimmt nicht überein. (Fehler 3346)".

Lösung

Verwende die Funktion Str(), die für die Übergabe eines Punktes als Dezimalzeichen sorgt. Also z.B.

Dim strSQL As String
Dim dblFoo As Double
dblFoo = 2.5

Obwohl im Code ein Punkt steht, wird an SQL ein Komma übergeben, außer man verwendet:

strSQL = "INSERT INTO Tabelle1 (Bla) VALUES(" & Str(dblFoo) & ")"
oder z.B.
strSQL = "INSERT INTO Tabelle1 (Bla, Blub) SELECT " & Str(dblFoo) & ", 4711 FROM Tabelle2 Where…"

nach oben

6.22 Diagramme programmieren
http://www.donkarl.com?FAQ6.22 aktualisiert 2014-04-15

Problem

Du möchtest ein Graph-Diagramm per VBA anpassen, weißt aber nicht, wie das geht, und findest keine Dokumentation.

Lösung

Die Programmierung eines Diagrammes in Access funktioniert nach dem Prinzip:

Me!MeinDiagrammSteuerelement.ObjektOderEigenschaft = Irgendwas

Um z.B. die Legende des Diagrammes auszuschalten:

Me!MeinDiagrammSteuerelement.HasLegend = False

Die Kunst ist natürlich, die entsprechenden Objekte, Eigenschaften und das Irgendwas zu kennen.

Da die Programmierung von Diagrammen in Excel fast ident ist, hilft meist ein einfacher Trick:
Erstelle in Excel ein Diagramm und lass dir ein Makro der gewünschten Änderungen aufzeichnen. Den dadurch entstandenen Code kannst du, was die Objekte und Eigenschaften des Diagrammes betrifft, fast 1:1 in Access übernehmen und dir auch die Excel-VBA-Hilfe dazu ansehen.
Excel-VBA macht heftig Gebrauch von maskierten Konstanten, Marke "xlirgendwas". Um sie nach Access zu übertragen, kannst du das Direktfenster in Excel öffnen, dir mit ?xlirgendwas den eigentlichen Zahlwert ausgeben lassen und diesen in Access verwenden. Eine andere Variante ist, in Access einen Verweis auf die Excel-Bibliothek zu setzen. Dann kannst du die Excel-Konstanten direkt übernehmen.

Zu Graph gibt es einige verstreute Dokus. z.B.

PPT-Folien von Markus Eischeid zum Vortrag "Diagramme mit Graph" bei der AEK6
Hilfe-Datei für Graph 97: http://support.microsoft.com/?kbid=162883
A97-Diagramm-Beispiele: http://support.microsoft.com/?kbid=186855
MSDN: http://msdn.microsoft.com/en-us/library/office/ff835247(v=office.15).aspx

nach oben