Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sortieren von Files in vba Filesystemobject

320 views
Skip to first unread message

Wolfgang Weitzel

unread,
Oct 22, 2016, 2:09:53 PM10/22/16
to
Hallo,

ich möchte eine besteiimte Anzahl von Dateien aus einem Order auslesen und in ein Array schreiben. Als Kriterium sind den Dateinamen am Anfang eine Datumsangabe vorangestellt, die ich überprüfen kann.
Mit der nachfolgenden Funktion funktioniert dies auch.
Leider wird beim Zugriff keine Sortierung verwendet, so dass ich nicht die korrekten Daten erhalte.
Wie kann ich über VBA die Dateien im Order absteigen sorteieren, damit ich die korrekten Dateien einlesen kann.

MFG
Wolfgang

Public Sub Rechnungen()
Dim objFSO As Scripting.FileSystemObject, objFolder As Scripting.Folder, objFile As Scripting.File
strSQL = "SELECT Rechnungen.Datum_Rech, Rechnungen.Betrag_Rech " & _
"From Rechnungen " & _
"WHERE (((Rechnungen.ABR_ID)=Eval('[Forms]![F_Uebersicht]![v_ABR_ID]'))) " & _
"ORDER BY Rechnungen.Datum_Rech "
Set objFSO = New Scripting.FileSystemObject
Set rsdb = dbs.OpenRecordset(strSQL)
rsdb.MoveLast
v_X = rsdb.RecordCount
If v_X > 30 Then
MsgBox (" Di Anzahl der Datensätze ist größer" & chrlf & _
" als der vorgesehene Speicher"), vbInformation
Exit Sub
End If
rsdb.MoveFirst
For i = 1 To v_X
For J = 0 To 1
If J = 0 Then _
v_Rechnungen(i, J) = Format(rsdb!Datum_Rech, "yyyy") & "-" & Format(rsdb!Datum_Rech, "mm") & "-" & Format(rsdb!Datum_Rech, "dd")
If J = 1 Then _
v_Rechnungen(i, J) = rsdb!Betrag_Rech
Next J
rsdb.MoveNext
Next i
Set objFolder = objFSO.GetFolder("E:\71 Krankenkosten Abrecchnungen & Belege\Abrechnungen Wolfgang\Belege")
i = 1
For Each objFile In objFolder.Files
v_Pruef = Left(objFile.Name, 10)
If v_Pruef = v_Rechnungen(i, 0) Then
v_Anlagen(i) = objFolder & "\" & objFile.Name
i = i + 1
End If
If i > v_X Then Exit For
Next objFile
rsdb.Close: Set rsdb = Nothing
End Sub

Ka Prucha

unread,
Oct 23, 2016, 3:38:10 AM10/23/16
to
Am 22.10.2016 um 20:09 schrieb Wolfgang Weitzel:
> Hallo,
>
> ich möchte eine besteiimte Anzahl von Dateien aus einem Order auslesen und in ein Array schreiben. Als Kriterium sind den Dateinamen am Anfang eine Datumsangabe vorangestellt, die ich überprüfen kann.
> Mit der nachfolgenden Funktion funktioniert dies auch.
> Leider wird beim Zugriff keine Sortierung verwendet, so dass ich nicht die korrekten Daten erhalte.
> Wie kann ich über VBA die Dateien im Order absteigen sorteieren, damit ich die korrekten Dateien einlesen kann.

Warum nicht in eine temporäre Tabelle speichern und dort sortieren?

Ich habe einmal etwas ähnliches gemacht:
<http://members.aon.at/ka_prucha/page_7_1.html>

Da ich Access auf meinen derzeitigen Rechner nicht mehr habe, kann ich
es aber jetzt nicht überprüfen.

mfg Ka Prucha

Ulrich Möller

unread,
Oct 23, 2016, 6:59:21 AM10/23/16
to
Hallo Wolfgang,

Am 22.10.2016 um 20:09 schrieb Wolfgang Weitzel:
es scheint mir so, daß deine Schleife zum einlesen nicht richtig ist.
Diese vergleicht nur die Dateinamen mit dem vorgegeben Datum und nur,
wenn ein Treffer vorhanden ist, wird das Prüfdatum weiter gezählt. Du
bräuchtest aber einen Vergleich, der jeden Dateinamen gegen jedes
vorgegebene Datum prüft, also zwei ineinander verschachtelte Schleifen.
Da v_Rechnungen bereits sortiert ist, wird in v_anlagen dann auch
automatisch sortiert eingefügt. Kannst du einmal beschreiben, was genau
du erreichen möchtest? Der Sinn der Tabelle und des Arrays geht aus dem
Code nicht ganz hervor. Auch solltest du vor dem Exit Sub das Recordset
schließen, so wie du es am Ende ja auch machst.

Ulrich





Wolfgang Weitzel

unread,
Oct 23, 2016, 12:44:32 PM10/23/16
to
Hallo Ulrich,

ich sammele Rechnungen im PDF Format in einem Verzeichnis.
Die PDF-Files haben am Anfang das Datum als Kennzeichen.
Die Rechnungen werden in einer Datenbank verwaltet.
In zeitlichen Abständen muss mit einer eMail eine Meldung über die eingegangenen Rechnungen weitergeleitet werden, wobei der eMail die PDF-Files beigefügt werden.
Am Anfang hat dies funktioniert. Nun sind die PDF-Files nicht chronologisch erfasst worden, so dass ich hier beim einlesen eine Fehlermeldung erhalte.


MfG
Wolfgang

Ulrich Möller

unread,
Oct 23, 2016, 7:18:15 PM10/23/16
to
Wie ich in meiner vorangegangene Antwort schon beschrieben hatte, sind
die Schleifen nicht ganz richtig, speziell die 2. for-next.
Die Chronologie der Dateien spielt dabei keine Rolle. Ich habe mal dein
Codebeispiel etwas umgeschrieben und um die Anzahl der Vergleiche zu
verringern mal anstatt des FileScriptingObject einfach den Dir Befehl
genommen. Wenn ich davon ausgehe, daß die ID etwas mit den Tagen im
Monat zu tun hat, dann müßte der "Buffer" auch auf 31 mögliche Tage
vergrößert werden

Hier mal eine andere Idee:

Dim avntRechnungen() As Variant
Dim avntAnlagen() As Variant


Public Sub Rechnungen(ByVal pID As Variant, ByVal pPath As String)

Const SQL_STMT As String = "SELECT Rechnungen.Datum_Rech,
Rechnungen.Betrag_Rech " _
& "FROM Rechnungen " _
& "WHERE [Rechnungen]![ABR_ID]={0} " _
& "ORDER BY Rechnungen.Datum_Rech;"

Dim strSQL As String
Dim rst As DAO.Recordset
Dim lngCount As Long
Dim strPath As String
Dim strFilename As String
Dim i As Long

If IsNull(pID) Then
Exit Sub
End If

Erase avntAnlagen

strSQL = Replace(SQL_STMT, "{0}", pID)

Set rst = CurrentDb.OpenRecordset(strSQL,
RecordsetTypeEnum.dbOpenSnapshot)

If rst.RecordCount <> 0 Then
rst.MoveLast
lngCount = rst.RecordCount

If lngCount > 31 Then
' errormsg
Else
ReDim avntRechnungen(lngCount - 1, 1)
rst.MoveFirst
Do Until rst.EOF
avntRechnungen(rst.AbsolutePosition, 0) = Format$(rst(0),
"yyyy\-mm\-dd")
avntRechnungen(rst.AbsolutePosition, 1) = rst(1)
rst.MoveNext
Loop
End If

strPath = pPath

For i = 0 To UBound(avntRechnungen)
strFilename = Dir(strPath & "\" & avntRechnungen(i, 0) & "*",
vbNormal)

If Len(strFilename) > 0 Then
Do
If (Not (avntAnlagen)) = -1 Then
ReDim avntAnlagen(0)
Else
ReDim Preserve avntAnlagen(UBound(avntAnlagen) + 1)
End If

avntAnlagen(UBound(avntAnlagen)) = strFilename
strFilename = Dir()
Loop Until Len(strFilename) = 0
End If
Next
End If

If Not rst Is Nothing Then
rst.Close
Set rst = Nothing
End If
End Sub

Nach Aufruf dieser Prozedur mit der ID (long) und dem Pfad stehen in den
beiden Arrays die Datumswerte und die dazu passenden Dateinamen.
Notfalls könnte man auch noch zusätzlich die Dateinamen mit einem
"Arraysort" sortieren und 'avntAnlagen' könnte man auch vom Datentyp
'String' definieren, wenn man es etwas resourcenschonender machen wollte.

Grüße
Ulrich

Wolfgang Weitzel

unread,
Oct 24, 2016, 4:03:01 AM10/24/16
to
Hallo Ulrich,

danke für den Code.
Beim Test erhalte ich immer die Meldung
"Argument ist nicht optional"
Ich kann nicht erkennen, woran dies liegt.
Gruß
Wolfgang

HR Ernst

unread,
Oct 24, 2016, 4:16:17 AM10/24/16
to
Und warum lässt du beim Öffnen der Datei nicht gleich die Daten nach
Rechnungs-Datum ordnen (durch eine Abfrage (qryReDatum)? Ist das Datum für
die Reihenfolge der Eingabe wichtiger?

--
Gruß

H.-R. Ernst

Wolfgang Weitzel

unread,
Oct 24, 2016, 5:51:13 AM10/24/16
to
Hallo H.-R. Ernst,

die Dateien bestehen aus PDF-Files, die in einem Vereichnis auf der Festplatte liegen. Ich kenn kein Verfahren, wie ich diese in eine Abfrage öffnen kann und dann noch nach dem im Dateinamen enthaltenen Datum eine Sortierung festlege.
Gruß
Wolfgang

Winfried Sonntag

unread,
Oct 24, 2016, 6:41:03 AM10/24/16
to
Am 24.10.2016 schrieb Wolfgang Weitzel:


> danke für den Code.
> Beim Test erhalte ich immer die Meldung
> "Argument ist nicht optional"
> Ich kann nicht erkennen, woran dies liegt.

Einfach mal mit F8 Zeile für Zeile durch den Code wandern, Du solltest
es dann direkt sehen.



Servus
Winfried
--
Access-FAQ: http://www.donkarl.com/AccessFAQ.htm
Access-Stammtisch: http://www.access-muenchen.de
NNTP-Bridge für MS-Foren: http://communitybridge.codeplex.com/
vbeTwister: http://www.vbetwister.com/

Ulrich Möller

unread,
Oct 24, 2016, 6:49:11 AM10/24/16
to
Am 24.10.2016 um 10:02 schrieb Wolfgang Weitzel:
> Public Sub Rechnungen(ByVal pID As Variant, ByVal pPath As String)
<snip>
> End Sub
>
> danke für den Code.
> Beim Test erhalte ich immer die Meldung
> "Argument ist nicht optional"
> Ich kann nicht erkennen, woran dies liegt.

Wahrscheinlich fehlt die Pfadangabe für pPath. Der Aufruf im Formular
sähe dann z.B. so aus:

Rechnungen Me!V_ABR_ID, "F:\RechnungenPDF"

Wenn du den Pfad fest einstellen möchtest, kann der auch global als
Konstante festlegt werden. Der zusätzliche Parameter entfällt und die Zeile

strPath = pPath

wird entsprechend abgeändert.

Ulrich

Wolfgang Weitzel

unread,
Oct 25, 2016, 7:18:34 AM10/25/16
to
Hallo Ulrich,

deinen Code habe ich bei mir nicht zum Laufen gebracht.
Darum habe ich mir entsprechend deiner Anmerkung meine Schleifen angesehen und über eine Ausgabe der Werte geprüft. Hier habe ich nun meinen Fehler gefunden, da ich nach einem Treffer im Filesystemobject nicht von vorne angefangen habe zu suchen.
Habe nun die Schleifen wie im nachfolgenden Code zu sehen geändert und finde nun wieder alle Dateien.
Vielen Dank für die Unterstützung.

Gruß
Wolfgang

Public Sub Rechnungen()
Dim objFSO As Scripting.FileSystemObject, objFolder As Scripting.Folder, objFile As Scripting.File
strSQL = "SELECT Rechnungen.Datum_Rech, Rechnungen.Betrag_Rech " & _
"From Rechnungen " & _
"WHERE (((Rechnungen.ABR_ID)=Eval('[Forms]![F_Uebersicht]![v_ABR_ID]'))) " & _
"ORDER BY Rechnungen.Datum_Rech "
Set objFSO = New Scripting.FileSystemObject
Set rsdb = dbs.OpenRecordset(strSQL)
rsdb.MoveLast
v_X = rsdb.RecordCount
rsdb.MoveFirst
For i = 1 To v_X
For J = 0 To 1
If J = 0 Then _
v_Rechnungen(i, J) = Format(rsdb!Datum_Rech, "yyyy") & "-" & Format(rsdb!Datum_Rech, "mm") & "-" & Format(rsdb!Datum_Rech, "dd")
If J = 1 Then _
v_Rechnungen(i, J) = rsdb!Betrag_Rech
Next J
rsdb.MoveNext
Next i
For i = 1 To v_X
For Each objFile In objFolder.Files
v_Pruef = Left(objFile.Name, 10)
If v_Pruef = v_Rechnungen(i, 0) Then
v_Anlagen(i) = objFolder & "\" & objFile.Name
Exit For
End If
Next objFile
Next

Ulrich Möller

unread,
Oct 26, 2016, 6:35:33 AM10/26/16
to
Hallo Wolfgang,

Am 25.10.2016 um 13:18 schrieb Wolfgang Weitzel:
> For i = 1 To v_X
> For Each objFile In objFolder.Files
> v_Pruef = Left(objFile.Name, 10)
> If v_Pruef = v_Rechnungen(i, 0) Then
> v_Anlagen(i) = objFolder & "\" & objFile.Name
> Exit For
> End If
> Next objFile
> Next
Prinzipiell sollte das so funktionieren. Das Problem ist jedoch, daß die
innere Schleife bei einem ersten positiven Vergleich abbricht und
eventuell weitere vorhandene Dateien, die mit dem gleichen Datum
beginnen, ignoriert. Das kann ja durchaus beabsichtigt sein, nur sollte
man das immer im Hinterkopf behalten, insbesondere dann, wenn man später
diesen Teil nochmal erweitern möchte.

Um die Anzahl der Vergleiche (Anzahl Datumsvorgaben * Anzahl Dateien im
Verzeichnis!) bei einem vollständigem Durchlauf zu begrenzen, würde ich
jedoch die Dir-Methode bevorzugen, weil diese im Gegensatz zum
Filesystemobject mit einem Mustervergleich arbeiten kann. Dadurch
liefert ein Dir-Aufruf nur noch die Dateien zurück, die zum
entsprechendem Datum passen, unabhängig davon, wie viele Dateien noch in
dem Verzeichnis vorhanden sind, die in diesem Moment aber irrelevant sind.

Du könntest also auch explizit diese For-Next Schleife durch eine
entsprechende "Dir-Lösung" ersetzen.

Gruß
Ulrich





Tho...@team-moeller.de

unread,
Nov 5, 2016, 6:33:44 AM11/5/16
to
Hallo Wolfgang,

Am Samstag, 22. Oktober 2016 20:09:53 UTC+2 schrieb Wolfgang Weitzel:
> ich möchte eine besteiimte Anzahl von Dateien aus einem Order auslesen und in ein Array schreiben. Als Kriterium sind den Dateinamen am Anfang eine Datumsangabe vorangestellt, die ich überprüfen kann.
> Mit der nachfolgenden Funktion funktioniert dies auch.
> Leider wird beim Zugriff keine Sortierung verwendet, so dass ich nicht die korrekten Daten erhalte.
> Wie kann ich über VBA die Dateien im Order absteigen sorteieren, damit ich die korrekten Dateien einlesen kann.

Du kannst das Array alphabetisch sortieren lassen:
http://www.team-moeller.de/?Tipps_und_Tricks:Wizhook-Objekt:SortStringArray

HTH
--
Tho...@Team-Moeller.de
Homepage: www.Team-Moeller.de
Blog: Blog.Team-Moeller.de
0 new messages