Translate

Montag, 3. Dezember 2012

Problematik TreeView / ListView & co, die durch ein Sicherheitsupdate von Microsoft im August 2012 entstanden ist

Das Microsoft Update vom 14. August 2012 hat eine Änderung an den ActiveX-Steuerelementen der Bibliothek MSCOMCTL.OCX vorgenommen, welche die meisten in Betrieb befindlichen TreeView- und ListView-Steuerelemente untauglich machte.

Unter folgenden Link wird aufgezeigt, wie die Probleme entstehen und wie Sie diese beheben können: http://www.access-im-unternehmen.de/861

Vor ein noch größeres Problem stehen Office-Entwickler die das Update eingespielt haben. Den die entwickelten VBA-Dateien mit der neuen MSCOMCTL.OCX Version 6.1.98.34, laufen nicht mehr auf Ziel-Rechner die nicht diese Version enthalten. Diese sind also nicht mehr abwärts kompatible.

Daher sollten alle die mit den folgenden ActiveX Controls 6.0 (SP6) arbeiten wollen, das Update nicht installieren: Microsoft Slider / TabStrip / StatusBar / Toolbar / ImageComboBox / TreeView / ListView / ProgressBar / ImageList

So können Sie die Version 6.1.98.33 wiederherstellen:
1. MSCOMCTL.OCX unregistrieren
2. Folgenden regAst löschen: [HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1]
3. Die alte Version MSCOMCTL.OCX (6.1.98.33) ins system32 reinkopieren und registieren.
4. Anschließend noch unbedingt folgende Einträge im RegKey HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\ löschen:
{0B314611-2C19-4AB4-8513-A6EEA569D3C4} Microsoft Slider Control 6.0 (SP6)
{24B224E0-9545-4A2F-ABD5-86AA8A849385} Microsoft TabStrip Control 6.0 (SP6)
{627C8B79-918A-4C5C-9E19-20F66BF30B86} Microsoft StatusBar Control 6.0 (SP6)
{7DC6F291-BF55-4E50-B619-EF672D9DCC58} Microsoft Toolbar Control 6.0 (SP6)
{87DACC48-F1C5-4AF3-84BA-A2A72C2AB959} Microsoft ImageComboBox Control 6.0 (SP6)
{95F0B3BE-E8AC-4995-9DCA-419849E06410} Microsoft TreeView Control 6.0 (SP6)
{979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6)
{A0E7BF67-8D30-4620-8825-7111714C7CAB} Microsoft ProgressBar Control 6.0 (SP6)
{F91CAF91-225B-43A7-BB9E-472F991FC402} Microsoft ImageList Control 6.0 (SP6)
 
Zusatz-Info:
Registrierung unter Win64 Bitmit folgenden Befehle:
RegSvr32.exe -u c:\Windows\SysWow64\MSCOMCTL.ocx
RegSvr32.exe c:\Windows\SysWow64\MSCOMCTL.ocx

Für die 32-bit-Version kommen diese Befehle zum Einsatz:
RegSvr32.exe -u c:\Windows\System32\MSCOMCTL.ocx
RegSvr32.exe c:\Windows\System32\MSCOMCTL.ocx

Die Version MSCOMCTL.OCX 6.1.98.33 ist unter http://www.access-im-unternehmen.de/861 zum herunterladen zu finden.

Montag, 15. Oktober 2012

Nachhaltig Excel-Blatt mit VBA ansprechen.



Um ein Excel-Blatt per VBA anzusprechen wird oft der Index oder den Namen des Blattes verwendet. Dies kann jedoch in der Praxis zu Fehlern führen, sobald das Blatt sich an einer anderen Stelle befindet oder umbenannt wurde. Besser ist den CodeName zu verwenden.

Variante 1: Verwendung des Indexes
Sub Var1()
  Dim ws As Worksheet
  Set ws = Worksheets(1)
  ws.Name = "Januar"
End Sub
Der Nachteil dieser Variante ist, sobald das Blatt vom Anwender verschoben
wird, verwendet der VBA-Code das falsche Blatt.

Variante 2: Verwendung des Blattnamens
Sub Var2()
  Dim ws As Worksheet
  Set ws = Worksheets("Tabelle1")
  ws.Name = "Januar"
End Sub
Der Nachteil dieser Variante ist, sobald das Blatt vom Anwender umbenannt
wird, erzeugt der VBA-Code einen Fehler. Spätestens beim 2. Aufruf erhalten wir
zwangsläufig einen Fehler.

Variante 3: Verwendung des Objektnamens (CodeName)
Sub Var3()
  Dim ws As Worksheet
  Set ws = Tabelle1
  ws.Name = "Januar"
End Sub
Diese Variante ist optimal. Der Code kann beliebig oft ausgeführt werden
ohne einen Fehler zu erzeugen.

Sollte jedoch das Blatt sich nicht in der aktiven Arbeitsmappe befinden, kann dieses nicht mit dem CodeName angesprochen werden!

Mit der folgenden Funktion wird dies doch möglich:
Public
Function GetSheetFromCodeName(CodeName As String, _
 
Optional Sheet As Object, _

 
Optional InWorkbook As Workbook) As Boolean 

  If InWorkbook Is Nothing Then Set InWorkbook = ThisWorkbook
  For Each Sheet In InWorkbook.Sheets
    If StrComp(Sheet.CodeName, CodeName, vbTextCompare) = 0 Then
     GetSheetFromCodeName = True
      Exit For
    End If
  Next 
End Function
 
Beispielaufruf:
Sub Var4()
  Dim ws As Worksheet
  If GetSheetFromCodeName("Tabelle1", ws, Workbooks("Datei.xls")) Then
    ws.Name = "Januar"
  Else
    MsgBox "An den Programmierer: Der Codename ist nicht vorhanden!", vbCritical
  End If
End Sub
Anmerkung:
Gleichzeitig wird mit der Funktion GetSheetFromCodeName geprüft, ob das Objekt gar vorhanden ist. Diese Funktion kann auch nur für diese Prüfung benutzt werden.
Ich würde empfehle immer diese Funktion zu verwenden. Falls der Programmierer sicherstellt, dass das Objekt immer vorhanden ist, kann auch die IF-Abfrage weggelassen werden.

Beispielaufruf:
Sub Var5()
  Dim ws As Worksheet
  GetSheetFromCodeName "Tabelle1", ws
  ws.Name = "Januar"
End Sub

Montag, 18. Juni 2012

Datenbankzugriff per VBA via DAO

Um auf eine Access-Datenbank zuzugreiffen benötigt VBA einen Verweis auf Ihre aktuelle installierte DAO-Schnittstellen.
Diese lautet für MS-Access 2002/2003 "Microsoft DAO 3.6 Object Library"
Ab Version 2007 "Microsoft Office 12.0 Access Database engine object Library"
Ab Version 2010 "Microsoft Office 14.0 Access Database engine object Library"

Möchten Sie ohne Verweis mit DAO arbeiten (Late Binding),
dann sieht die Codierung folgendermaßen aus:
Dim
oDAO As Object, oDB as Object 
Set oDAO = CreateObject("DAO.DBEngine.36")
'
Ab Access 2007: DAO.DBEngine.120
Set oDB = oDAO.OpenDatabase("Datei.mdb")
 
Sollte Access 2007/2010 auf dem System nicht installiert sein, kann man 
die Access DAO Engine unter folgenden Link downloaden:
http://www.microsoft.com/de-de/download/details.aspx?id=13255

Montag, 4. Juni 2012

Zur EM: Excel Soccer 2012

Excel Soccer 2012 

Laden Sie jetzt den kostenfreien Excel-EM-Planer, der nicht nur einen Spielplan aller Partien und Infos zu den Stadien enthält, sondern Ihnen auch die Möglichkeit gibt, zusammen mit Freunden oder Kollegen ein Tippspiel zu veranstalten.

http://de.excel-soccer.de/downloads/

Mittwoch, 22. Februar 2012

Kontextmenüleisten in Access einfach erstellen

Haben Sie schon mal in Access Kontextmenüleisten (Rechte-Maustaste-Menü) angepasst oder gar selbst angelegt?

Es geht, ist aber nicht ganz einfach, bzw. es ist nicht sehr Bedienerfreundlich.

Und ab Access 2007?
Die neue Microsoft Office-Oberfläche bietet keine Möglichkeit die bestehende Kontextmenüleisten zu ändern und auch keine eigenen zu erstellen.
Es gibt nur noch den Umweg über die Programmierung, was recht aufwendig ist.


Für MS Access gibt es nun ein schickes Tool der Access Shortcut Menu Creator mit dem dies ohne Programmierung möglich ist.

Dieser kann hier heruntergeladen werden:
http://abiss.dasat.com/downloads/public/asmc.zip

Beispiel für eine sinnvolle Änderung einer bestehenden Kontextmenüleiste:
"Ich möchte mit der rechten Maustaste auf ein Formularobjekt im Datenbank-/Navigationsfenster direkt sein Klassenmodule aufrufen"

Und so gehen Sie im Access Shortcut Creator vor:
1. Wähle die Kontextmenüleiste "Datenbankfomular", ab Access 2007 die Leiste "Navigationsbereich
-Popup für die Anzeige"
2. Klicke auf Schaltfläche Hinzufügen
3. Suche nach Befehl "code" und füge diesen hinzu

Sonntag, 5. Februar 2012

BUG in der Komprimierfunktion in MS Access 2010

Mit Autowert-Felder (Inkrement) ohne PrimaryKey können Sie eine böse Überraschung erleben, nach dem Sie die Komprimierfunktion in MS Access 2010 ausgeführt haben.
Es kann passieren, dass der nächst automatisch vergebene Wert nicht unbedingt der letzter eingetragener Wert + 1 ist.

Die Folge ist, dass Ihr Autowert-Feld keine eindeutigen Nummern mehr enthält!
Dies kann zwar mit einem Index ohne Duplikate verhindert werden, aber eine Fehlermeldung bekommen Sie dennoch.
Es kann also sein, dass gar kein Datensatz mehr angelegt werden kann, bis das Autowert-Feld einen Wert erzeugt, der noch nicht in der Tabelle vorhanden ist.
Beheben können Sie dies, über folgende Aktionsabfrage:
INSERT INTO MeineTabelle ( MeinAutowertFeldname ) SELECT 6223 FROM MeineTabelle

Wobei der Wert 6223, Ihr nächster gewünschtrer Wert ist.

Der Fehler stellt sich jedoch wieder ein, sobald Sie die Komprimierungsfunktion unter MS Access 2010 wieder laufen lassen.

Dauerhaft bekommen Sie den Fehler nur im Griff, wenn Sie auf Ihr Autowert-Feld den PrimaryKey setzen.

Mit dem folgenden Beispiel können Sie den Fehler reproduzieren: www.abiss.de/downloads/public/Fehler2010Beispiel.zip
Bei Eingabe eines neuen Datensatzs erscheint im Feld ID der Wert 6224. Brechen Sie den Datensatz ab und machen den Vorgang erneut, wird der nächste Wert 6225 angeboten usw. Hier soweit alles korrekt.

Nach komprimierung der Datenbank unter MS Access 2000/2002/2003/2007, wird wieder der Wert 6224 oder höher erzeugt.
Nach komprimierung der Datenbank unter MS Access 2010, wird der Wert 4401, 4402 usw... erzeugt!

Hinweis: Dieser Fehler in der Komprimierungsfunktion betrifft nur MS Access 2010.

Montag, 2. Januar 2012

Montag einer Kalenderwoche ermitteln

So wie es wichtig ist die Kalenderwoche aus einem Datum ermitteln zu können (Siehe hier), ist es durchaus öfters mal von nöten das erste Datum (Montag) einer Kalenderwoche zu ermitteln.


In Access:
DatSeriell([Jahr];1;4)+[KW]*7-7-(DatSeriell([Jahr];1;2) Mod 7)

Die Felder [Jahr] und [KW] sind zu ersetzen durch ihre Feldnamen.


In Excel:
=DATUM(A2;1;4)+A1*7-7-REST(DATUM(A2;1;2);7)

Der Bezug A1 verweist auf ihre Zelle mit dem Kalenderwochenwert und der Bezug A2 verweist auf ihre Zelle mit dem Jahreswert.


In VBA:

Public Function FirstDateOfCalWeek(cWeek As Byte, Optional cYear As Variant) As Date
    If IsMissing(cYear) Then cYear = Year(Date)
    FirstDateOfCalWeek = DateSerial(cYear, 1, 4) + cWeek * 7 - 7 - (DateSerial(cYear, 1, 2) Mod 7)
End Function


Ausgegangen wird von den europäischen Standards, d.h.: 
  • der erste Tag der Woche ist der Montag
  • die erste Woche eines Jahres ist jene, die mindestens 4 Tage hat