Modul erstellen

Worauf muss ich achten wenn ich aus folgendem Code ein modul erstellen möchte

Private Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" \_
 (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, \_
 ByVal dwShareMode As Long, lpSecurityAttributes As Any, \_
 ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, \_
 ByVal hTemplateFile 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 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 CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) \_
 As Long 

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

' CreateFile dwDesiredAccess Konstanten
Private Const GENERIC\_READ = &H80000000 ' Nur Lesen
Private Const GENERIC\_WRITE = &H40000000 ' Nur Schreiben

' CreateFile dwShareMode Konstanten
Private Const FILE\_SHARE\_READ = &H1
Private Const FILE\_SHARE\_WRITE = &H2

' CreateFile dwCreationDisposition Konstanten
' ===========================================
' Erstellt eine neue Datei und überschreibt eine bereits vorhandene
Private Const CREATE\_ALWAYS = 2
' Erstellt eine neue Datei nur, wenn sie noch nicht existiert
Private Const CREATE\_NEW = 1
' Öffnet eine bereits vorhande Datei bzw. erstellt diese, 
' wenn sie noch nicht existiert
Private Const OPEN\_ALWAYS = 4
' Öffnet eine bereits vorhandene Datei
Private Const OPEN\_EXISTING = 3
' Öffnet eine bereits vorhandene Datei und löscht den Inhalt
Private Const TRUNCATE\_EXISTING = 5

' CreateFile dwFlagsAndAttributes
' ===============================
Private Const FILE\_ATTRIBUTE\_ARCHIVE = &H20 ' Archiv
Private Const FILE\_ATTRIBUTE\_HIDDEN = &H2 ' Versteckt
Private Const FILE\_ATTRIBUTE\_NORMAL = &H80 ' Normal
Private Const FILE\_ATTRIBUTE\_READONLY = &H1 ' Schreibgeschützt
Private Const FILE\_ATTRIBUTE\_SYSTEM = &H4 ' Systemdatei
' Datei wird beim Schließen gelöscht 
Private Const FILE\_FLAG\_DELETE\_ON\_CLOSE = &H4000000
' Es wird kein Puffer/Cache benutzt
Private Const FILE\_FLAG\_NO\_BUFFERING = &H20000000
' Erlaubt gleichzeitiges Lesen und Schreiben
' (nicht bei Windows 95, 98, CE)
Private Const FILE\_FLAG\_OVERLAPPED = &H40000000
' Erlaubt Case-Sensitive Dateinamen 
Private Const FILE\_FLAG\_POSIX\_SEMANTICS = &H1000000
' Richtet den Puffer für einen Random-Access Zugriff aus
Private Const FILE\_FLAG\_RANDOM\_ACCESS = &H10000000
' Richtet den Puffer für einen sequentuellen Zugriff aus
Private Const FILE\_FLAG\_SEQUENTIAL\_SCAN = &H8000000
' Nutzt keinen Platten-Cache, sondern schreibt direkt in die Datei
Private Const FILE\_FLAG\_WRITE\_THROUGH = &H80000000

' Datumsinformationen einer Datei ermitteln (Erstellungsdatum)
Private Sub Command1\_Click()
 Dim hFile As Long
 Dim Retval As Long
 Dim CTime As FILETIME
 Dim STime As SYSTEMTIME
 Dim Dummi As FILETIME


 ' Datei öffnen (nicht Erstellen, falls nicht vorhanden)
 hFile = CreateFile("c:\autoexec.bat", GENERIC\_READ, FILE\_SHARE\_READ, \_
 ByVal 0&, OPEN\_EXISTING, FILE\_ATTRIBUTE\_ARCHIVE, 0&amp:wink:

 If hFile = -1 Then
 MsgBox "Die Datei wurde nicht gefunden", vbOKOnly + vbInformation, \_
 "Fehler" 
 Exit Sub
 End If

 ' Erstellungsdatum ermitteln
 GetFileTime hFile, CTime, Dummi, Dummi

 ' Konvertieren nach "Lokale Zeitzone"
 FileTimeToLocalFileTime CTime, CTime

 ' In Systemzeit umwandeln
 FileTimeToSystemTime CTime, STime

 ' Ausgabe des Datums
 MsgBox "Die datei wurde erstellt am: " & STime.wDay & "." & \_
 STime.wMonth & "." & STime.wYear, vbOKOnly + vbInformation, \_
 "Erstellt am"

 ' Resourcen wieder frei geben
 CloseHandle hFile
End Sub

[MOD] Pre-Tags eingefügt.

Der Code ist offensichtlich für ein Formularmodul gedacht - du musst halt die entsprechende Schaltfläche bereitstellen usw.

Ansonsten ist die Frage wohl eher, was du erreichen willst (Und womit? Was soll das werden? Ein VB6-Programm? Ein Access-VBA-Modul?) - wenn du die Prozeduren allgemein zugänglich machen willst, musst du sie Public deklarieren.

Warum nimmst du nicht einfach das FileSystemObject der Scripting Runtime? Das ist doch weitaus benutzerfreundlicher als derartige API-Aufrufe!

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)

Moin,
ich habe das Problem (ein Thema tiefer im FOrum) das bei vereinzelten Files das Änderungsdatum falsch ausgegeben wird. Also möchte ich bei diesen datein das erstellungsdatum erfragen.
Aber ich würde die abfrage nur als Modul in mein Projekt aufnehmen.

Meinst du wenn ich einen Ordner rekursiv durchsuche mit API und die datumsabfrage mit FSO das ich die suche dadurch ausbremse ? hier gilt wohl probieren :confused:

mfg joe

Unter www.vbfun Rekursive suche, kannst du die API Funktion Runterladen, schaue einfach unter VB Classic, das kann man ja auch ins Excel importieren

Gruss Sebastian

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hmmm…

Hast du Performance-Probleme? Warum machst du die Dateisuche nicht mit dem FSO? Komfortabler ist das allemal und sooo langsam nun auch wieder nicht!

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)

Am saubersten ist es, wenn man Datumsangaben (wenn man sie überhaupt als String handhaben will) im ISO-Format (yyyy-mm-dd) anlegt. Mit allem anderen handelt man sich Einstellungsabhängigkeiten ein.

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)

Hi,

Hast du Performance-Probleme? Warum machst du die Dateisuche
nicht mit dem FSO? Komfortabler ist das allemal und sooo
langsam nun auch wieder nicht!

doch, ist es. Joes Lösung ist 20 mal so schnell. :smile:

Mit FSO benötigt mein Rechner für das Durchsuchen des Verzeichnisses ‚Programme‘ rund 90 Minuten, mit der API knapp 5 Minuten.

(XP, Athlon 2800)

Gruß, Rainer

Hmmm… dann hast du wohl 60 x so viele Programme installiert wie ich - bei mir dauert das rekursive Durchlaufen von „C:\Programme“ mit dem FSO eineinhalb Minuten… Zum Gegentest mit der API-Lösung bin ich jetzt zu müde (Ich glaube gerne, dass sie schneller ist, aber sooo viel schneller!? Da glaube ich dann eher, dass du mit dem FSO Mist gemacht hast (z.B. beim rekursiven Abstieg das FSO immer wieder neu instantiiert hast…)

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)

Hallo,

Hmmm… dann hast du wohl 60 x so viele Programme installiert
wie ich -

*gg* möglich, daß ich ein paar Dateien mehr auf der Platte habe als Du, aber eher unwahrscheinlich.

bei mir dauert das rekursive Durchlaufen von
„C:\Programme“ mit dem FSO eineinhalb Minuten… Zum Gegentest
mit der API-Lösung bin ich jetzt zu müde (Ich glaube gerne,
dass sie schneller ist, aber sooo viel schneller!? Da glaube
ich dann eher, dass du mit dem FSO Mist gemacht hast (z.B.
beim rekursiven Abstieg das FSO immer wieder neu instantiiert
hast…)

Möglich, daß mein Code nicht optimal ist …

Option Explicit

Dim MyFSO As Object

Sub ScanDir(ScanPfad)
 Dim PathObject As Object
 Dim FileObject As Object
 Dim FileNow As Object
 Dim SubFolders As Object
 Dim SubFoldersNow As Object

 Set PathObject = MyFSO.getFolder(ScanPfad)
 Set FileObject = PathObject.Files
 For Each FileNow In FileObject
 List1.AddItem FileNow
 Next

 Set SubFolders = PathObject.SubFolders
 For Each SubFoldersNow In SubFolders
 List1.AddItem SubFoldersNow
 ScanDir (SubFoldersNow.ParentFolder + "\" + SubFoldersNow.Name)
 Next
End Sub

Private Sub Command1\_Click()
 Set MyFSO = CreateObject("Scripting.FileSystemObject")
 List1.Visible = False
 ScanDir ("C:\Programme")
 List1.Visible = True
End Sub

Siehst Du den Fehler?

Gruß, Rainer

Nein, einen Fehler sehe ich nicht - im Wesentlichen habe ich es genau so gemacht (allerdings um den Listenfeld-Kram bereinigt: 2 Minuten für 65036 Dateien in 5288 Verzeichnissen…) Ich neige eher dazu, zu vermuten, dass du Opfer eines Äpfel-mit-Birnen-Vergleichs bist. Hast du im Fall der API-Funktion auch das Listenfeld jeweils dateiweise aktualisiert?

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)

Hallo,

Hast du im Fall
der API-Funktion auch das Listenfeld jeweils dateiweise
aktualisiert?

die Zeile eingefügt, wie im Beispiel mit FSO, ja. Die Liste ist aber unsichtbar, aktualisiert wird sie erst am Schluß, sonst bremst die Liste.

Ich hatte beide Prozeduren zusammen in einem Programm, habe die Liste jeweils vorher gelöscht und mal per FSO, mal per API mit den selben Daten gefüllt und die benötigte Zeit anzeigen lassen. Faktor 20! :smile:

Verstehe ich das richtig, daß FSO - (’ Scripting File System Object’) als Script abgearbeitet wird, nicht wie der Rest des VB-Programms in Maschinencode compiliert wird? Dafür, daß das durch einen Interpreter muß, ist es dann schon wieder richtig schnell.

Das geht ohne FSO auch noch mit Dir$, ist aber auch nicht schneller. :smile: FSO wird wohl Dir$ verwenden, der Weg über die API mit ‚FindNextFile‘, den ich bei AVB gefunden habe ist wirklich so viel schneller. Joe will damit ganze Fileserver synchronisieren, dabei spielt die Geschwindigkeit dann schon eine erhebliche Rolle.

(Das Programm habe ich aber nicht gesichert, im Moment habe ich wenig Lust, das noch mal zusammen zu kopieren … :smile:)

Gruß, Rainer

Nein, „Scripting“ heisst in diesem Zusammenhang, dass man damit Scripts schreiben kann - das Teil ist halt eine DLL und wird in einer systemnahen Sprache geschrieben sein (und selber natürlich auch API-Calls und diese nicht über den Umweg von VB-Konstrukten verwenden). Aber ich bin nicht MS und kenne die Dinge auch nur von der Oberfläche her…

Gruß aus dem Norden
Reinhard Kraasch

(http://www.dbwiki.de - das Datenbank-Wiki)