APIs: Unterschied zwischen den Versionen
Pwania (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Pwania (Diskussion | Beiträge) |
||
Zeile 49: | Zeile 49: | ||
Bei der obigen Suche war mein erster Treffer ein Artikel auf vb@rchive namens '[https://www.vbarchiv.net/tipps/tipp_297-alle-datumsangaben-einer-datei-ermitteln.html Alle Datumsangaben einer Datei ermitteln]'. | Bei der obigen Suche war mein erster Treffer ein Artikel auf vb@rchive namens '[https://www.vbarchiv.net/tipps/tipp_297-alle-datumsangaben-einer-datei-ermitteln.html Alle Datumsangaben einer Datei ermitteln]'. | ||
Hier der Lösungsvorschlag (mit Kommentaren des Orginal-Autoren Dieter Otter): | |||
<span style="Color:green">' zunächst die benötigten API-Deklarationen</span> | |||
<span style="Color:green">' Datei Datum/Zeit</span> | |||
<span style="Color:blue">Private Type </span>FileTime | |||
dwLowDateTime<span style="Color:blue"> As Long</span> | |||
dwHighDateTime<span style="Color:blue"> As Long | |||
End Type</span> | |||
<span style="Color:blue"> | |||
Private Type </span>SYSTEMTIME | |||
wYear<span style="Color:blue"> As Integer</span> | |||
wMonth<span style="Color:blue"> As Integer</span> | |||
wDayOfWeek<span style="Color:blue"> As Integer</span> | |||
wDay<span style="Color:blue"> As Integer</span> | |||
wHour<span style="Color:blue"> As Integer</span> | |||
wMinute<span style="Color:blue"> As Integer</span> | |||
wSecond<span style="Color:blue"> As Integer</span> | |||
wMilliSeconds<span style="Color:blue"> As Integer | |||
End Type</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>CreateFile Lib <span style="Color:gray">"kernel32"</span> _ | |||
Alias <span style="Color:gray">"CreateFileA"</span> <span style="Color:gray">(</span> _ | |||
<span style="Color:blue"> ByVal </span>lpFilename<span style="Color:blue"> As String</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>dwDesiredAccess<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>dwShareMode<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>lpSecurityAttributes<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>dwCreationDisposition<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>dwFlagsAndAttributes<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
<span style="Color:blue"> ByVal </span>hTemplateFile<span style="Color:blue"> As Long</span><span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>CloseHandle Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
<span style="Color:blue"> ByVal </span>hObject<span style="Color:blue"> As Long</span><span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>GetFileTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
<span style="Color:blue"> ByVal </span>hFile<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
lpCreationTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpLastAccessTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpLastWriteTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>SetFileTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
<span style="Color:blue"> ByVal </span>hFile<span style="Color:blue"> As Long</span><span style="Color:gray">,</span> _ | |||
lpCreationTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpLastAccessTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpLastWriteTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>FileTimeToLocalFileTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
lpFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpLocalFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>FileTimeToSystemTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
lpFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpSystemTime<span style="Color:blue"> As </span>SYSTEMTIME<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>SystemTimeToFileTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
lpSystemTime<span style="Color:blue"> As </span>SYSTEMTIME<span style="Color:gray">,</span> _ | |||
lpFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private </span>Declare<span style="Color:blue"> Function </span>LocalFileTimeToFileTime Lib <span style="Color:gray">"kernel32"</span> <span style="Color:gray">(</span> _ | |||
lpLocalFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">,</span> _ | |||
lpFileTime<span style="Color:blue"> As </span>FileTime<span style="Color:gray">)</span><span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> | |||
Private Const </span>GENERIC_READ <span style="Color:gray">=</span> &H<span style="Color:gray">80000000</span><span style="Color:blue"> | |||
Private Const </span>GENERIC_WRITE <span style="Color:gray">=</span> &H<span style="Color:gray">40000000</span><span style="Color:blue"> | |||
Private Const </span>OPEN_EXISTING <span style="Color:gray">=</span> <span style="Color:gray">3</span> | |||
<span style="Color:green">' Datum/Zeit einer Datei ermitteln</span> | |||
<span style="Color:blue">Public Function </span>ReadFileTime<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>lpFilename<span style="Color:blue"> As String</span><span style="Color:gray">,</span> _ | |||
tCreation<span style="Color:blue"> As Date</span><span style="Color:gray">,</span> tLastAccess<span style="Color:blue"> As Date</span><span style="Color:gray">,</span> _ | |||
tLastWrite<span style="Color:blue"> As Date</span><span style="Color:gray">)</span><span style="Color:blue"> As Boolean</span> | |||
<span style="Color:blue"> Dim </span>fHandle<span style="Color:blue"> As Long</span> | |||
<span style="Color:blue"> Dim </span>ftCreation<span style="Color:blue"> As </span>FileTime | |||
<span style="Color:blue"> Dim </span>ftLastAccess<span style="Color:blue"> As </span>FileTime | |||
<span style="Color:blue"> Dim </span>ftLastWrite<span style="Color:blue"> As </span>FileTime | |||
<span style="Color:blue"> Dim </span>LocalFileTime<span style="Color:blue"> As </span>FileTime | |||
<span style="Color:blue"> Dim </span>LocalSystemTime<span style="Color:blue"> As </span>SYSTEMTIME | |||
ReadFileTime <span style="Color:gray">=</span><span style="Color:blue"> False</span> | |||
fHandle <span style="Color:gray">=</span> CreateFile<span style="Color:gray">(</span>lpFilename<span style="Color:gray">,</span> GENERIC_READ<span style="Color:gray">,</span> <span style="Color:gray">0,</span> _ | |||
<span style="Color:gray">0,</span> OPEN_EXISTING<span style="Color:gray">,</span> <span style="Color:gray">0,</span> <span style="Color:gray">0)</span> | |||
<span style="Color:blue"> If </span>fHandle <span style="Color:gray"><></span> <span style="Color:gray">-1</span><span style="Color:blue"> Then</span> | |||
<span style="Color:green">' Zeitinformationen auslesen</span> | |||
<span style="Color:blue"> If </span>GetFileTime<span style="Color:gray">(</span>fHandle<span style="Color:gray">,</span> ftCreation<span style="Color:gray">,</span> ftLastAccess<span style="Color:gray">,</span> _ | |||
ftLastWrite<span style="Color:gray">)</span> <span style="Color:gray"><></span> <span style="Color:gray">0</span><span style="Color:blue"> Then</span> | |||
<span style="Color:green">' Erstellungsdatum</span> | |||
FileTimeToLocalFileTime ftCreation<span style="Color:gray">,</span> LocalFileTime | |||
FileTimeToSystemTime LocalFileTime<span style="Color:gray">,</span> LocalSystemTime | |||
<span style="Color:blue"> With </span>LocalSystemTime | |||
tCreation <span style="Color:gray">=</span> CDate<span style="Color:gray">(</span>Format$<span style="Color:gray">(</span>DateSerial<span style="Color:gray">(.</span>wYear<span style="Color:gray">,</span> _ | |||
<span style="Color:gray">.</span>wMonth<span style="Color:gray">,</span> <span style="Color:gray">.</span>wDay<span style="Color:gray">),</span> <span style="Color:gray">"Short Date")</span> & <span style="Color:gray">" "</span> & _ | |||
Format$<span style="Color:gray">(.</span>wHour<span style="Color:gray">)</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wMinute<span style="Color:gray">,</span> <span style="Color:gray">"00")</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wSecond<span style="Color:gray">,</span> <span style="Color:gray">"00"))</span> | |||
<span style="Color:blue"> End With</span> | |||
<span style="Color:green">' Letzter Zugriff</span> | |||
FileTimeToLocalFileTime ftLastAccess<span style="Color:gray">,</span> LocalFileTime | |||
FileTimeToSystemTime LocalFileTime<span style="Color:gray">,</span> LocalSystemTime | |||
<span style="Color:blue"> With </span>LocalSystemTime | |||
tLastAccess <span style="Color:gray">=</span> CDate<span style="Color:gray">(</span>Format$<span style="Color:gray">(</span>DateSerial<span style="Color:gray">(.</span>wYear<span style="Color:gray">,</span> _ | |||
<span style="Color:gray">.</span>wMonth<span style="Color:gray">,</span> <span style="Color:gray">.</span>wDay<span style="Color:gray">),</span> <span style="Color:gray">"Short Date")</span> & <span style="Color:gray">" "</span> & _ | |||
Format$<span style="Color:gray">(.</span>wHour<span style="Color:gray">)</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wMinute<span style="Color:gray">,</span> <span style="Color:gray">"00")</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wSecond<span style="Color:gray">,</span> <span style="Color:gray">"00"))</span> | |||
<span style="Color:blue"> End With</span> | |||
<span style="Color:green">' Letzte Änderung</span> | |||
FileTimeToLocalFileTime ftLastWrite<span style="Color:gray">,</span> LocalFileTime | |||
FileTimeToSystemTime LocalFileTime<span style="Color:gray">,</span> LocalSystemTime | |||
<span style="Color:blue"> With </span>LocalSystemTime | |||
tLastWrite <span style="Color:gray">=</span> CDate<span style="Color:gray">(</span>Format$<span style="Color:gray">(</span>DateSerial<span style="Color:gray">(.</span>wYear<span style="Color:gray">,</span> _ | |||
<span style="Color:gray">.</span>wMonth<span style="Color:gray">,</span> <span style="Color:gray">.</span>wDay<span style="Color:gray">),</span> <span style="Color:gray">"Short Date")</span> & <span style="Color:gray">" "</span> & _ | |||
Format$<span style="Color:gray">(.</span>wHour<span style="Color:gray">)</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wMinute<span style="Color:gray">,</span> <span style="Color:gray">"00")</span> & <span style="Color:gray">":"</span> & _ | |||
Format$<span style="Color:gray">(.</span>wSecond<span style="Color:gray">,</span> <span style="Color:gray">"00"))</span> | |||
<span style="Color:blue"> End With</span> | |||
ReadFileTime <span style="Color:gray">=</span><span style="Color:blue"> True</span> | |||
<span style="Color:blue"> End If</span> | |||
CloseHandle fHandle | |||
<span style="Color:blue"> End If | |||
End Function</span> | |||
Dazu wurde ebenfalls ein Beispiel-Aufruf mitgegeben: | |||
== Struktur eines API-Aufrufes == | == Struktur eines API-Aufrufes == |
Version vom 16. November 2018, 09:19 Uhr
APIs?!?
Application Programming Interfaces (kurz: APIs) dienen dazu, Aufgaben zu lösen, welche nicht oder nur unzureichend von VBA (bzw. den Office-Anwendungen) gelöst werden können.
Ein Beispiel:
Mithilfe von VBA können wir feststellen, ob eine Datei existiert:
If Dir(strFullName) = "" Then Exit Sub
Mithilfe von VBA und den Anwendungs-Objekten können wir ermitteln, wann eine in der Anwendung geöffnete Datei erstellt wurde (Beispiel aus PowerPoint):
Debug.Print ActivePresentation.BuiltInDocumentProperties.Item("Creation date")
Wenn wir jedoch ermitteln sollen, welche Datei in einem Verzeichnis die älteste ist, wird uns dies nur dann möglich, wenn wir die Dateien einzeln öffnen (vorausgesetzt es handelt sich zum Beispiel bei PowerPoint um Präsentationen, bei Excel um Arbeitsmappen usw.) und dann die Eigenschaft prüfen. Oder wir verwenden eine vom Betriebssystem zur Verfügung gestellte API, welche für jede beliebige Datei die geforderten Informationen ermitteln kann.
Empfohlene Vorgehensweise
Benötigte API finden
Um einen brauchbaren Ansatz für die gesuchte Aufgabe zu finden, empfehle ich die Suche im Internet.
Wichtig: Stellen Sie dazu der gesuchten Anfrage die Worte 'Windows API VB' voran, um die Ergebnisse sinnvoll einzugrenzen (VBA liefert leider oftmals keine guten Treffer):
Die Suche nach 'windows api vb datei erstelldatum' ergab mehrere Treffer, die auf die Seite vb@rchiv verweisen. Diese werden wir uns näher ansehen.
- Der erste Treffer verspricht 'Alle Datumsangaben einer Datei ermitteln'
- Aufgepasst: Das vb@rchiv verfügt auch über Lösungen für VisualBasic, VB.NET und weitere Sprachen. VisualBasic enthält teilweise Befehle für die Anwendungsentwicklung, welche VBA nicht enthält und VB.NET sieht auf den ersten Blick VBA sehr ähnlich, verfügt jedoch über ein völlig anderes Objektmodell, wodurch spezifische Lösungen mit Sicherheit inkompatibel sind.
- Sie werden feststellen, dass die meisten API-Aufrufe sehr komplex und umfangreich sind, weil sie zum Beispiel
- Weitere API-Aufrufe benötigen
- Benutzerdefinierte Datentypen verwenden
- Ich empfehle Ihnen, für Ihre Tests ein eigenes Modul anzulegen und alles, was Sie in einem Suchergebnis gefunden haben, dort hineinzukopieren
- Versuchen Sie dann zu ermitteln, welche Prozedur die Steuerprozedur ist (also die Prozedur, die das Ergebnis liefert)
- Rufen Sie diese Prozedur auf
- Schreiben Sie dazu eine eigene Prozedur
- Ändern Sie bitte (noch) nicht die Originalprozedur!
- Wenn das gefundene Beispiel das gewünschte Ergebnis zurückliefert, prima!
- Wenn nicht:
- Sehen Sie nach, ob Sie eventuell das Problem erkennen können
- Verwenden Sie hierauf nicht zuviel Zeit sondern versuchen Sie den nächsten Vorschlag:
- Suchen Sie eine weitere Beispiellösung
- Hier und da werden Sie Lösungen für Aufgaben finden, die Ihrer ähneln aber nicht entsprechen
- Kopieren Sie trotzdem die komplette angebotene Lösung
- Testen Sie, ob die gefundene Lösung die von Ihnen geforderte Aufgabe erledigt
- Erst wenn Sie sicher sind, dass alles funktioniert, können Sie eventuell einzelne, überflüssig erscheinende Teile in Kommentar setzen (niemals sofort löschen!)
- Wie schon erwähnt sind API-Aufrufe oft sehr komplex und umfangreich. Wenn Sie das Falsche entfernen, kann er danach kaputt sein ...
Lösungsbeispiel anpassen
Bei der obigen Suche war mein erster Treffer ein Artikel auf vb@rchive namens 'Alle Datumsangaben einer Datei ermitteln'.
Hier der Lösungsvorschlag (mit Kommentaren des Orginal-Autoren Dieter Otter):
' zunächst die benötigten API-Deklarationen ' Datei Datum/Zeit Private Type FileTime dwLowDateTime As Long dwHighDateTime As Long End Type Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliSeconds As Integer End Type Private Declare Function CreateFile Lib "kernel32" _ Alias "CreateFileA" ( _ ByVal lpFilename As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ ByVal lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long Private Declare Function GetFileTime Lib "kernel32" ( _ ByVal hFile As Long, _ lpCreationTime As FileTime, _ lpLastAccessTime As FileTime, _ lpLastWriteTime As FileTime) As Long Private Declare Function SetFileTime Lib "kernel32" ( _ ByVal hFile As Long, _ lpCreationTime As FileTime, _ lpLastAccessTime As FileTime, _ lpLastWriteTime As FileTime) As Long Private Declare Function FileTimeToLocalFileTime Lib "kernel32" ( _ lpFileTime As FileTime, _ lpLocalFileTime As FileTime) As Long Private Declare Function FileTimeToSystemTime Lib "kernel32" ( _ lpFileTime As FileTime, _ lpSystemTime As SYSTEMTIME) As Long Private Declare Function SystemTimeToFileTime Lib "kernel32" ( _ lpSystemTime As SYSTEMTIME, _ lpFileTime As FileTime) As Long Private Declare Function LocalFileTimeToFileTime Lib "kernel32" ( _ lpLocalFileTime As FileTime, _ lpFileTime As FileTime) As Long Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000 Private Const OPEN_EXISTING = 3 ' Datum/Zeit einer Datei ermitteln Public Function ReadFileTime(ByVal lpFilename As String, _ tCreation As Date, tLastAccess As Date, _ tLastWrite As Date) As Boolean Dim fHandle As Long Dim ftCreation As FileTime Dim ftLastAccess As FileTime Dim ftLastWrite As FileTime Dim LocalFileTime As FileTime Dim LocalSystemTime As SYSTEMTIME ReadFileTime = False fHandle = CreateFile(lpFilename, GENERIC_READ, 0, _ 0, OPEN_EXISTING, 0, 0) If fHandle <> -1 Then ' Zeitinformationen auslesen If GetFileTime(fHandle, ftCreation, ftLastAccess, _ ftLastWrite) <> 0 Then ' Erstellungsdatum FileTimeToLocalFileTime ftCreation, LocalFileTime FileTimeToSystemTime LocalFileTime, LocalSystemTime With LocalSystemTime tCreation = CDate(Format$(DateSerial(.wYear, _ .wMonth, .wDay), "Short Date") & " " & _ Format$(.wHour) & ":" & _ Format$(.wMinute, "00") & ":" & _ Format$(.wSecond, "00")) End With ' Letzter Zugriff FileTimeToLocalFileTime ftLastAccess, LocalFileTime FileTimeToSystemTime LocalFileTime, LocalSystemTime With LocalSystemTime tLastAccess = CDate(Format$(DateSerial(.wYear, _ .wMonth, .wDay), "Short Date") & " " & _ Format$(.wHour) & ":" & _ Format$(.wMinute, "00") & ":" & _ Format$(.wSecond, "00")) End With ' Letzte Änderung FileTimeToLocalFileTime ftLastWrite, LocalFileTime FileTimeToSystemTime LocalFileTime, LocalSystemTime With LocalSystemTime tLastWrite = CDate(Format$(DateSerial(.wYear, _ .wMonth, .wDay), "Short Date") & " " & _ Format$(.wHour) & ":" & _ Format$(.wMinute, "00") & ":" & _ Format$(.wSecond, "00")) End With ReadFileTime = True End If CloseHandle fHandle End If End Function
Dazu wurde ebenfalls ein Beispiel-Aufruf mitgegeben: