Category: API Calls

Array definieren mal anderst

By , 27. Februar 2014

Arrays werden entweder per Array() Anweisung definiert, oder auch durch den Split() Befehl.
Auf eine andere bzw. erweiterte Möglichkeit bin ich kürzlich gestoßen beim Entwickeln eines Benutzersteuerelementes mit VB6.
Dort ging es u.a. darum, Steuerelemente beim Klick auf einen Button zu plazieren und sichtbar zu machen.

Die Größe und Position der Steuerelemente habe ich dabei wie folgt definiert:

Private Sub Form_Open(Cancel As Integer)
    Dim sizeArr(8) As Variant
    Dim i As Long
    sizeArr(0) = Array("cmdClose", 2350, 23, 306, 975)
    sizeArr(1) = Array("Linie1", 47, 2412, 2066, 2066)
    sizeArr(2) = Array("Linie2", 47, 2412, 697, 697)
    sizeArr(3) = Array("lblMonat", 23, 47, 454, 2381)
    sizeArr(4) = Array("zurueck", 142, 120, 227, 227)
    sizeArr(5) = Array("vor", 142, 2160, 227, 227)
    sizeArr(6) = Array("MonatJahr", 120, 480, 255, 1575)
    sizeArr(7) = Array("Heute", 2066, 47, 255, 2381)
    sizeArr(8) = Array("Rechteck1", 23, 47, 2280, 2381)

Das bedeutet also, jedem einzelnen Array-Element wurde ein weiteres Array zugewiesen.
Der Zugriff auf einen bestimmten Wert, z.B. auf „lblMonat“ lautet dann: sizeArr(3)(0)

Und um wieder zum Beispiel aus der Praxis zurückzukommen, hier der restliche Code, der die Steuerelemente dimensioniert, positioniert und sichtbar schaltet:

    For i = LBound(sizeArr) To UBound(sizeArr)
        With Controls(sizeArr(i)(0))
            .Top = sizeArr(i)(1)
            .Left = sizeArr(i)(2)
            .Height = sizeArr(i)(3)
            .Width = sizeArr(i)(4)
            .Visible = True
        End With
    Next i
End Sub

Bis dahin
© 2014 Andreas Vogt

Clouden Sie noch oder wie wichtig sind Ihnen Ihre Daten?

By , 15. Februar 2014

Die Zeit der Goldgräberstimmung in der Cloud Server Branche außerhalb der EU ist längst vorbei, zu tief sind doch die emotionalen Gräben die uns die NSA beschert hat. Für mich war es immer schon klar dass in die Cloud keine betriebswichtigen Daten gehören. Meine Denkweise war aber eher die dass in einem Rechtsstreit ServerHardware und entsprechende auch die Daten beschlagnamt werden könnten – dass aber die NSA die Cloud direkt anzapfte, Hersteller von Internetdiensten dazu verpflichten Hintertürchen einzubauen etc. etc. – diese Dimension haben sich wohl die wenigsten ausgemalt, ich auch nicht.

Die ganze Spionagetätigkeit läuft unter dem Aspekt der Terrorabwehr, und verschleiert vollkommen, dass es auch um handfeste Wirtschaftsspionage geht.

Hintertuerchen Gut, dann eben wieder lokale Lösungen mit eigenem und teuren Rechenzentrum. Das wäre auch bislang eine sichere Bank gewesen, bis zu dem entsprechenden Spiegel-Beitrag vor etwa 6 Wochen.
Die NSA hat ganze Lieferungen von PC Hardware abgefangen, aufgeschraubt und Spionage-Tools verbaut als Hintertürchen, um so an Daten und Kontrolle über den PC zu kommen. Das ganze klingt nach einem übertriebenen Science-Fiction Roman – doch die Wirklichkeit hat diese Lektüre bereits überholt.

Viele „flüchten“ jetzt zu Cloud-Anbietern innerhalb Europa vorallem auch innerhalb Deutschland. Was bleibt ist die Frage ob auch hier es so weit kommt bzw. ob es nicht längst auch so weit ist.
Das digitale Wettrüsten hat längst begonnen und ist im vollen Gange.

Also schauen Sie ruhig mal nach Ihrem PC unter dem Schreibtisch, nicht dass dort ein Hintertürchen aufsteht.

Meint der Autor.

Quelle: http://www.spiegel.de/netzwelt/netzpolitik/…
© 2014 Andreas Vogt

Abfrage oder Tabelle ‚Zeichengetrennt‘ in Textdatei speichern

By , 13. Februar 2014

Die landläufige Methode eine Abfrage oder eine Tabelle als Txt-Datei zu speichern ist die Docmd.OutputTo() Methode.
Informationen dazu findet ihr hier: http://msdn.microsoft.com/en-us/library/office/…

Um aber Zeichengetrennte Textdateien zu erstellen, d.h. jede Zeile ein Datensatz, jedes Feld in der Zeile durch einen Separator getrennt, muss man die Methode Docmd.TransferText() incl. Exportspezifikation erstellen. http://msdn.microsoft.com/en-us/library/office/… Das wäre sicherlich der einfachste Weg.

Falls aber die Exportspezifikation aber nicht mehr genügt, kann man mittels Output-Stream eine Textdatei zu erstellen, eine Abfrage oder Tabelle in ein Recordset packen und zeilenweise durchlaufen und in die Textdatei zu schreiben. Und mit den Worten von Jean Pütz sag ich: „ich hab da mal was vorbereitet“:

Sub Table2Textfile(ByVal Outputfile As String, ByVal TableName As String, _
                   Optional Separator As String = ";", _
                   Optional titlebar As Boolean = False)
    
    Dim rs As DAO.Recordset
    Dim strTableRow As String
    Dim filenum As Long
    Dim i As Long
    filenum = FreeFile

    Set rs = CurrentDb.OpenRecordset(TableName)
    Open Outputfile For Output As #filenum

    'Spaltenköpfe
    If titlebar Then
        For i = 0 To rs.Fields.Count - 1
            strTableRow = strTableRow & rs(i).Name & Separator
        Next i
        strTableRow = Left(strTableRow, Len(strTableRow) - Len(Separator))
        Write #filenum, strTableRow
        strTableRow = vbNullString
    End If

    Do While Not rs.EOF
        For i = 0 To rs.Fields.Count - 1
            strTableRow = strTableRow & rs(i) & Separator
        Next i
        strTableRow = Left(strTableRow, Len(strTableRow) - Len(Separator))
        Write #filenum, strTableRow
        strTableRow = vbNullString
        rs.MoveNext
    Loop
    Close #filenum
    rs.Close
    Set rs = Nothing
End Sub

Dies ist eine universelle Prozedur mit dem man Abfragen bzw. Tabellen schnell in eine separierte Liste bringen kann.
In einer Schleife über alle Recordset-Felder wird der String zusammengestellt, welcher in die Textdatei gespeichert wird.
Ebenso die Spaltenköpfe welche mit rs(Zeilennummer).Name auszulesen sind.

Die Prozedur welche obige Prozedur aufruft sieht dann z.B. so aus:

Sub Tester()
    Table2Textfile "c:\users\Public\test4711.txt", "qryTeilnehmer", ";", True
End Sub

Anstatt eines Separators als String kann man natürlich auch VBA-Konstanten verwenden, z.B. vbTab bietet sich hier an, Verwendung ohne Anfürungszeichen!

Ein Wermutstropfen bleibt aber übrig. In der erstellten Textdatei sind die einzelnen Textzeilen in Anführungszeichen. D.h. vor dem Weiterverarbeiten müsste man eventuell mittels FileSystemObject ran gehen und die einzelnen Zeilen bearbeiten – oder falls per VBA die Weiterverarbeitung stattfindet kann man die Bereinigung auch im VBA-Code machen.

Bis dahin
© 2014 Andreas Vogt

Statistikfunktionen in Abfragen verwenden

By , 18. Januar 2014

Zur statistischen Auswertung von Datenreihen können in Abfragen Funktionen eingesetzt werden wie z.B. AVG() für den aritmetischen Mittelwert oder StDev() für die Standardabweichung.
Eine nicht ganz triviale Aufgabe wäre es z.B., wenn man das gespeicherte Bestelldatum von Bestellungen in einer Tabelle hat, und jetzt den durchschnittlichen Bestellabstand in Tagen ermitteln möchte.

Manuell ist das leicht zu lösen indem man die Abstände zur nächsten Bestellung in Tagen aufsummiert und durch die Anzahl Bestellungen -1 dividiert. Beispiel:

  1. Bestellung: 12.10.2013
  2. Bestellung: 18.10.2013
  3. Bestellung: 23.10.2013
  4. Bestellung: 02.11.2013
  5. Bestellung: 14.11.2013

Die Bestellabstände sind: 6 Tage, 5 Tage, 10 Tage und 12 Tage.
In Summe 33 Tage geteilt durch 5-1 ergibt einen durchschnittlichen Bestellabstand von 8,25 Tagen.

Möchte man das nun in einer Abfrage berechnen lassen, brauchen wir also immer das Datum vom aktuellen Daten und das Datum vom folgenden Datensatz. Daher müssen wir die Bestell-Tabelle 2x in die Abfrage einbinden einmal mit Alias T1 und einmal mit Alias T2, und der Bedingung dass das Bestelldatum von T2 kleiner dem Bestelldatum von T1 sein muss. Fangen wir also erst mal damit an die Bestellabstände aufzulisten:
Read more »

Steuerung von Fußschalter oder Joystick

By , 16. Januar 2014

Um Ereignisse zu erfassen die von einem Fußschalter oder einem Joystick ausgelöst werden, kann man sich der Methoden von DirectX bedienen. Im vorliegenden Beispiel wird die Version DirectX8 verwendet, d.H. Sie benötigen einen gültigen Verweis auf die „DirectX 8 für Visual Basic Type Library“. Dazu benötigen Sie die registrierte Datei dx8vb.dll auf Ihrem Computer.
Nach dem nun der Verweis gesetzt wurde kann mit der Deklaration der Objekte begonnen werden. Dazu verwende ich die Early-Binding Variante um die DirectX-Konstanten verwenden zu können:
Im Deklarationsteil des Formulars:

Private Const BufferSize As Long = 10
Private DX As DirectX8
Private DI As DirectInput8
Private DIEnum As DirectInputEnumDevices8
Private DIDevice As DirectInputDevice8
Private hEvent As Long
Implements DirectXEvent8

Im Load-Ereignis werden die Objekte dann Instanziert:

    Set DX = New DirectX8
    Set DI = DX.DirectInputCreate
    Set DIEnum = DI.GetDIDevices(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY)
    ' kein Gerät gefunden dann Abbruch
    If DIEnum.GetCount = 0 Then Exit Sub

Die Verwendeten Konstanten beim Zugriff auf die Geräte können hier nachgelesen werden:
DirectInput8::EnumDevices
Read more »

Umrechnung Minuten/Sekunden in Zeitangabe

By , 24. Mai 2012

Konvertierungsfunktionen wie Minuten oder Sekunden in Zeitangabe zu konvertieren. sollte an und für sich kein Problem sein. Wenn die Rechenarithmetik von Access uns keinen Strich durch die Rechnung machen würde. Angenommen man hat 400 Minuten und teilt diese durch 60 und weisst das Ergebnis einer Long-Variablen zu, um die Stunden zu erhalten: 400/60 = 6.66666667. Dieses einem Long-Wert zugeordnet ergibt aber 7!
Ein Trick ist die Teilung mit einem Backslash, also 400\60. Diese Division gibt immer die Zahl vor dem Komma zurück, Nachkommastellen werden einfach abgeschnitten.

Fangen wir mal mit den Funktionen an. Diese am besten in einem Modul plazieren:

Public Function ConvertMintoTime(varM As Long)
    Dim hours As Long
    Dim minutes As Long

    hours = varM \ 60
    minutes = varM - hours * 60
    
    ConvertMintoTime = Format(hours, "00") & Format(minutes, "\:00") & ":00"
End Function

Public Function ConvertSectoTime(varS As Long)
    Dim hours As Long
    Dim minutes As Long
    Dim seconds As Long

    hours = varS \ 3600
    minutes = (varS - hours * 3600) \ 60
    seconds = varS - hours * 3600 - minutes * 60
    
    ConvertSectoTime = Format(hours, "00") & Format(minutes, "\:00") & Format(seconds, "\:00")
End Function

In der ersten Funktion werden die Minuten durch 60 geteilt um die Stunden zu erhalten. Im zweiten Schritt wird die Differenz zwischen den Minuten und den Stunden x 60 ermittelt, um die Minuten zuerhalten, was letztendlich nichts anderes als der Rest der ersten Division ist.

In der zweiten Funktion haben wir Sekunden, daher teilen wir durch 3600 für die Stunden. der Rest dieser Division wird dann durch 60 geteilt für die Minuten, und der letzte Rest bildet dann die Sekunden ab.
Per Format() Funktion wird die Ausgabe der Funktion aufbereitet.

Der Aufruf kann z.B. aus einem Formular oder anderen Modul erfolgen, da die Funktionen den Gültigkeitsbereich Public besitzen. Dieser könnte z.B. so aussehen:

Sub test()
    Dim t As Long
    t = 4000

    MsgBox t & " Sekunden sind Umgerechnet: " & ConvertSectoTime(t)
    MsgBox t & " Minuten sind Umgerechnet: " & ConvertMintoTime(t)
End Sub

Das wars schon, also eigentlich bis auf den Fallstrick mit dem Teil-Strich nichts besonderes.

Bis dahin
Andreas Vogt © 2012

BCD-Code erleichtert die Auswahl von Entitäten

By , 15. April 2012

BCD-Code ist vielen sicherlich noch von früher aus dem Informatikuntericht bekannt. Ich kam damit das erste mal während meiner Ausbildung duch BCD-Codierschalter in Berührung. Beim BCD-Code wird jede Ziffer einer Dezimalzahl einzeln dualkodiert. BCD-Code wird auch 8-4-2-1 Code genannt, weil die zweierpotenzen diese Ziffern ergeben. Damit lässt sich jede Ganzzahl darstellen.

Beispiel: 14: 8+4+2 oder 22: 16+4+2 usw.

Wie nützt uns jetzt dies bei Access? Der Aufbau des Codes hat auch einen zusätzlichen Effekt. Und zwar ist jede Zahl im Code (1, 2, 4, 8, 16….) größer als die Summe aller darunter liegender Zahlen, und zwar immer genau um 1 größer. Beispiel: 64 > 32+16+8+4+2+1.

Wenn man jetzt einen Enum Definiert dann nicht mehr mit 1, 2, 3…. sondern mit 1, 2, 4…

Ich glaub ich mach jetzt am besten erst mal ein Beispiel:

Option Explicit

Private Enum eAuswahl
    vbArbeiter = 1
    vbAngestellte = 2
    vbTechniker = 4
    vbführungskräfte = 8
    vbBerater = 16
    vbAlle = 32
End Enum

Read more »

Kodieren und Dekodieren von Texten

By , 8. April 2012

Kürzlich bin ich auf eine relativ alte Methode wieder gestoßen um Texte zu kodieren. Dabei verschiebt man einfach die Buchstaben im Wort um eine definierte Anzahl stellen. Ein bekannter Vertreter dieser Art ist Rot13. (Rotate by 13). Solche Kodierer haben den Vorteil dass sie erstens wieder dekodiert werden können – was gleichzeitig aber auch ihr Nachteil in Bezug auf Sicherheit ist – und zweitens dass es bekannte Algorithmen in verschiedenen Programmiersprachen gibt. Teilweise findet man auch im internet Online-Tools die Texte kodieren bzw. dekodieren können.
Dies sollte man wissen wenn man Text-Daten in einer Tabelle verschlüsseln möchte. Jeder der die Kodierungsmethode herausfindet kann es auch wieder lesbar machen.

Um hier ein wenig Sicherheit hineinzubringen sollte man den Kodier-Algorithmus nach eigenen Vorgaben anpassen. Über Ostern hatte ich wohl ein bisschen Zeit, und hab da mal etwas gebastel.
Meine Idee war kein fester Verschiebefaktor vorzugeben, sondern in Ahhängigkeit der Stelle eines Buchstabens im Wort vergrößerten Faktur. Also der erste Buchstabe um z.B. 15 verschieben, den zweiten um 15 usw., und beim nächsten Wort wieder bei 15 anfangen. Ich nenne diesen Algorithmus mal Rot15plus.
Read more »

Rückruffunktionen (Callback Functions) in Access anwenden

By , 6. April 2012

Hallo liebe Leser,
beim Schmökern in diversen Foren bin ich auf Rückruffunktionen gestoßen, die ich bislang selbst nicht einsetzte. Eine Rückruffunktion ist eine Funktion, die als Parameter einer anderen Prozedur übergeben wird. Die Rückruffunktion selbst kann auch eigene Parameter haben die auch übergeben werden. Dadurch kann man eine allgemeine Prozedur erstellen, deren Verhalten erst durch die übergebene Rückruffunktion bestimmt wird. Das Verhalten dieser allgemeinen Prozedur kann sich mit jedem Aufruf ändern.

Dadurch kann man eine Access-Anwendung erstellen, mit einer Art Programm-Schnittstelle – bei PHP Entwicklern auch als Hook bekannt – die später hinzugefügte Module nutzen können, um eigene Funktionen auszuführen. Dies bedeutet aber auch, dass eine vom Entwickler ungewollte Prozedur ausgeführt werden könnte die auch Schadcode enthalten kann. Man sollte den Einsatz nachfolgend vorgestellter Methode also genau planen.

Da beim Übergeben von Parametern Access nicht den Datentyp „Funktion“ kennt, muss man da ein wenig tricksen. Statt dessen übergibt man den Funktionsname als String und den/die erforderlichen Parameter. Wie genau das geht zeigt nachfolgender Code.

Erstellen Sie zu erst ein Standardmodul. Beginnen wir anschließend mit der „neutralen“ Prozedur.

Function apply_to(ByVal funktion As String, ByVal werte As Variant) AS Variant
    Dim ergebnis() As Variant
    Dim i As Long
    Dim e As Variant
    For i = LBound(werte) To UBound(werte)          'Schleife über alle Werte
        e = Eval(funktion & "(" & werte(i) & ")")   'rufe die Rückruffunktion mit Parameter auf
        ReDim Preserve ergebnis(i)                  'Wertebereich des Rückgabearrays erweitern
        ergebnis(i) = e                             'und hänge den Rückgabewert an das Array an.
    Next i
    apply_to = ergebnis
End Function

Read more »

Dateipfade im Griff

By , 2. März 2012

Jeder hat sicherlich mal das Problem gehabt in seiner Access-Anwendung mit Dateipfaden klar zu kommen. Sei es der Pfad zu Bildquellen, oder zu externen Datenbanken.

Auf eine Idee dazu hat mich heute eine Frage im Access-o-Mania Forum gebracht, wobei ich spontan an CurrentdbC denken musste. Bei CurrentdbC wird ein Objekt über eine Property zugänglich gemacht, das gleiche geht ja auch mit einer String. darauf hab ich ein bisschen gebastelt und eine sehr brauchbare Lösung erarbeitet die ich euch nicht vorenthalten möchte.

Wie gewohnt erstellt man zuerst eine Tabelle wo die Pfade gespeichert werden:


Das Feld Pfad habe ich als Memo-Feld ausgeführt.
Read more »

OfficeFolders theme by Themocracy