# [VBScript] Nur Dateien mit einen bestimmten Extension zählen



## amn.ssy (22. Dezember 2011)

Hallo,

wie kann ich den nachfolgenden Code so ergänzen, daß nur Dateien mit einer bestimmten Endung (*.pdf) gezählt werden. Idealerweise möchte ich die ext. ebenfalls über Varialben/konstanten pflegen können. Zur werden noch alle Dateien gezählt.
Bis dahin kam ich mit Google und eigenem "Gripps" ganz gut hin, aber seh ich gerade den Wald vor Bäumen nicht mehr.

Bestimmt geht das Ganze noch eleganter zu lösen (z.B. mit Funktionen für die Prüfungen oder das Sammeln des Outputs in einem Array um die Log erst am Schluss in einem Rutsch zu schreiben). Zukunftsmusik (sie klingt schon in meinen Ohren) wäre die "Konstanten" in einer ini-Datei zu pflegen. Aber bis dahin bin ich schon ganz froh das bisherige geschafft zu haben.
(Das Programm Notepad++ ist nur ein Platzhalter, weil ich das Eigendliche grad nicht auf meiner Mühle zum laufen bekomme)


```
'  ** Changelog V.1.2 21.12.2011 ***
'  # Parameter am Programmanfang
'  # Abfrage nach Existenz der Ordner
'  # Leerstellen in Pfadangaben
'  # Messages nun in log-Datei

'  ** Changelog V.1.3 22.12.2011 ***
'  # Starten von w2m Timer

' ****** Funktionsbeschreibung *****
' wait2move hat den Zweck, zum einen
' Verzeichnisse auf Inhalt und zum
' anderen die Existenz eines Prozess/
' laufenden Programm zu prüfen.
' Soweit ein bestimmtes Verzeichnis 
' leer und das Programm beendet ist, 
' werden Dateien aus einem anderen 
' Verzeichnis in das leere Verzeichnis
' verschoben und das Programm neu
' gestartet.
' ********************************** 

Dim allProcess 
Dim Process 
Dim foundProcess
Dim ext
Dim datanz
Dim pName
Dim pNam2
Dim pRun
Dim pText
Dim pStart
Dim Path1
Dim Path2
Dim pPath
Dim pPath2
Dim eTime

' ************ Parameter ***********
Path1 = "C:\Spools\"
Path2 = "C:\Temp\"
pPath = "C:\Program Files (x86)\Notepad++\"
pName = "notepad++.exe"
pPath2 = "C:\wait2move\"
pName2 = "w2mTimer.vbs"
eTime = Now

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set allProcess = GetObject ("winmgmts:")
Set pStart = CreateObject("Wscript.Shell")
Set oFile = oFSO.OpenTextFile("C:\wait2move\wait2move.log",8,true)
oFile.WriteLine " "
oFile.WriteLine eTime & " wait2move wurde gestartet"

If oFSO.Folderexists (Path1) = True Then
datanz1 = oFSO.GetFolder(Path1).Files.count
Else
oFile.WriteLine eTime & " Der Ordner " & Path1 & " existiert nicht"
oFile.WriteLine eTime & " wait2move wurde beendet"
oFile.close
pStart.Run Chr(34) & pPath2 & pName2 & Chr(34) 
WScript.Quit
End If

If oFSO.Folderexists (Path2) = True Then
datanz2 = oFSO.GetFolder(Path2).Files.count
Else
oFile.WriteLine eTime & " Der Ordner " & Path2 & " existiert nicht"
oFile.WriteLine eTime & " wait2move wurde beendet"
oFile.close
pStart.Run Chr(34) & pPath2 & pName2 & Chr(34) 
WScript.Quit
End If

foundProcess = False

	For Each Process in allProcess.InstancesOf ("Win32_Process")
		If Process.Name = pName Then
			pRun = 1
			pText = "Der Prozess " & pName & " läuft noch"
			foundProcess = True
			Exit for 
		End If 
	Next
	
If foundProcess = False Then 
pRun = 0
pText = "Der Prozess " & pName & " ist beendet"
End If 
Set allProcess = nothing

oFile.WriteLine eTime & " " & datanz1 & " Datei(en) in der Verarbeitung"
oFile.WriteLine eTime & " " & pText 
oFile.WriteLine eTime & " " & datanz2 & " Datei(en) in der Warteschleife" 

IF pRun = 0 and datanz1 = 0 and datanz2 > 0 Then
oFSO.MoveFile Path2 & "*.pdf", Path1
oFile.WriteLine eTime & " " & datanz2 & " Datei(en) übergeben"
pStart.Run Chr(34) & pPath & pName & Chr(34) 
oFile.WriteLine eTime & " Der Prozess " & pName & " wurde gestartet"
oFile.WriteLine eTime & " wait2move wurde beendet"
oFile.close
pStart.Run Chr(34) & pPath2 & pName2 & Chr(34) 
WScript.Quit
Else
oFile.WriteLine eTime & " Fehler aufgetreten:" 
oFile.WriteLine eTime & " Prozess-Status: "& pRun
oFile.WriteLine eTime & " Dateien in Verarbeitung: "& datanz1 
oFile.WriteLine eTime & " Dateien wartend: "& datanz2
End If
oFile.WriteLine eTime & " wait2move wurde beendet"
oFile.close
pStart.Run Chr(34) & pPath2 & pName2 & Chr(34)
WScript.Quit
```


----------



## Yaslaw (22. Dezember 2011)

uh.. ich empfehle dir mit der Tabulator-Taste zu arbeiten um die if..then..else..end sauber zu gestalten.


```
..
If foundProcess = False Then 
	pRun = 0
	pText = "Der Prozess " & pName & " ist beendet"
End If 
Set allProcess = nothing

oFile.WriteLine eTime & " " & datanz1 & " Datei(en) in der Verarbeitung"
oFile.WriteLine eTime & " " & pText 
oFile.WriteLine eTime & " " & datanz2 & " Datei(en) in der Warteschleife" 

IF pRun = 0 and datanz1 = 0 and datanz2 > 0 Then
	oFSO.MoveFile Path2 & "*.pdf", Path1
	oFile.WriteLine eTime & " " & datanz2 & " Datei(en) übergeben"
	pStart.Run Chr(34) & pPath & pName & Chr(34) 
	oFile.WriteLine eTime & " Der Prozess " & pName & " wurde gestartet"
	oFile.WriteLine eTime & " wait2move wurde beendet"
	oFile.close
	pStart.Run Chr(34) & pPath2 & pName2 & Chr(34) 
	WScript.Quit
Else
	oFile.WriteLine eTime & " Fehler aufgetreten:" 
	oFile.WriteLine eTime & " Prozess-Status: "& pRun
	oFile.WriteLine eTime & " Dateien in Verarbeitung: "& datanz1 
	oFile.WriteLine eTime & " Dateien wartend: "& datanz2
End If
..
```

Nun zu deiner Frage.
Obs mit VBScript geht, weiss ich grad nicht. Aber 95% von VBA geht auch mit VBScript. Darum hier mal ein Lösungsansatz mit GetExtensionName() des FileSystemObjects


```
Dim type

type = "png"
If oFSO.GetExtensionName(path) = type Then
    '//TODO: Irgendwas
End Ig
```


----------



## MarcoIT (22. Dezember 2011)

Yaslaw hat gesagt.:


> item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen



Hihi 

Aber Yaslaw war bereits schneller...
type musst du halt dann in pdf abändern

LG
Marco


----------



## amn.ssy (18. Januar 2012)

Hallo,

hab den Gedanken von Yaslaw aufgefasst und so versucht umzusetzten:

```
Dim oFolder1
Dim oFolder2
Dim oFile
Dim nFile
Dim eTime
Dim ext

Set oFSO = CreateObject("Scripting.FileSystemObject")
set oFolder1 = oFSO.GetFolder ("C:\temp")
set oFolder2 = oFSO.GetFolder ("Z:\Input")

eTime = now
ext = "pdf"

For Each oFile In oFolder1.Files
  If oFSO.GetExtensionName(oFile) = ext Then
  MsgBox ext & "-Datei: " & oFile.Name & " gefunden"
	nFile = eTime & "_" & oFile.Name
  MsgBox "Neuer Dateiname: " & nFile
  elseif oFSO.GetExtensionName(oFile) <> ext Then
  oFile.Delete
  End If	
Next

oFSO.MoveFile oFolder1 & "\*.pdf", oFolder2

Set oFSO = nothing	
set oFolder1 = nothing
set oFolder2 = nothing
```

Ich bekomme zwar keine Fehlermeldung, jedoch wird der Dateiname nicht geändert!
Was fehlt?
Sinn und Zweck der "Übung" geht dahin, alle PDF-Dateien im Ordner umzubennen (Datun_Dateiname.pdf) und diese dann in ein andernen Ordner zu verschieben, alle anderen dateien werden gelöscht.


----------



## Yaslaw (18. Januar 2012)

Wo in deinem Code soll denn der Name geändert werden? Irgendwo muss doch noch der Code zum umbennen hin

```
myFile.name = "abc.txt"
'oder
oFSO.getFile("c:\temp\text.txt").name = "nwTest.txt"
```


----------



## amn.ssy (18. Januar 2012)

Hallo,

danke für den Tipp, dennoch stehe ich etwas auf'm Schlauch.
Das Beispiel ist ja für eine einzelne Datei gedacht.
Wie bekomme ich das dynamisch hin?
Ich habs jetzt mal so versucht und denke, daß es zumindest in diese Richtung gehen müßte, wenn ich das Beispiel richt verstanden habe. Syntaktisch scheint das aber nicht zu stimmen.

```
For Each oFile In oFolder1.Files
  If oFSO.GetExtensionName(oFile) = ext Then
  MsgBox ext & "-Datei: " & oFile.Name & " gefunden"
	oFSO.GetFile("'oFolder1 & '\' & oFile'").Name = eTime & "_" & oFile.Name
  MsgBox "Neuer Dateiname: " & oFile
  elseif oFSO.GetExtensionName(oFile) <> ext Then
  oFile.Delete
  End If	
Next
```
Jedenfalls bleibe ich gleich nach der ersten MsgBox (ist nur als Debug-Hilfsmittel gedacht) hängen:
"Datei nicht gefunden". Da ist aber in jedem Fall eine PDF im Ordner.


----------



## Zvoni (18. Januar 2012)

Dir ist klar, dass du mit obigem Code bei beispielsweise 100 Dateien, welche dem Suchkriterium entsprechen, 200 MsgBoxes beantworten musst?


----------



## amn.ssy (18. Januar 2012)

MsgBoxen dieser Art mach ich nur als Debug-Hilfsmittel rein um festzustellen bis wohin das Script arbeitet und ggf. welche Werte meine Variablen haben.
I.d.R gehe ich damit sehr dossiert um, da die meisten Sachen die ich mache unbeaufsichtigt laufen müssen und ich die da natürlich nicht gebrauchen kann.


----------



## Yaslaw (18. Januar 2012)

Du machst da ein wenig Chaos.

*item: *oFile ist ein Objekt. Ergo macht MsgBox "Neuer Dateiname: " & oFile wenig Sinn. Wenn du den Filenamen haben willst, dann solltest du auf die Eigenschaft 'name' des Objektes zugreiffen.
MsgBox "Neuer Dateiname: " & oFile.name

*item: *oFSO.GetFile("'oFolder1 & '\' & oFile'"): Was ist das für ein komischer Pfad?Es gibt glaub kein Pfad der so heisst

```
'oFolder1 & '\' & oFile'
```
Zudem brauchst du da getFile() nicht. Du hast ja bereits das File in dem Objekt oFile.

*item: *Wenn du einen String, in deinem Beispiel den neuen Filenamen mehrfach brauchst, solltest du ihn in eine Variable setzen und nicht mehrmals neu zusammenstellen. Die Fehlerquelle ist damit erheblich reduziert

*item: *Es reicht ein einfaches else. Dein elseif prüft genau das gegenteil vom If. Ergo wenns nicht in den ersten Teil kommt, kommts automatisch in den Zweiten

*item: *Für VB-Code gibts in diesem Forum eigene Tags. Du musst nicht die für PHP verwenden.
[code=vb]Dein Code[/code]

```
For Each oFile In oFolder1.Files
	If oFSO.GetExtensionName(oFile) = ext Then
		MsgBox ext & "-Datei: " & oFile.Name & " gefunden"
		'neuer Dateinamen zusammensetzen
		newName = eTime & "_" & oFile.Name
		'Datei umbenennen
		oFile.name = newName
		MsgBox "Neuer Dateiname: " & newName
	else
		oFile.Delete
	End If    
Next
```


----------



## amn.ssy (18. Januar 2012)

Hi,

ich hab den Code mal versucht so zu übernehmen (so ähnlich hatte ich das schon mal), 
lauf aber in die Fehlermeldung "Ungültige(r) Dateiname o. -nummer" in 20,9

```
Dim oFolder1
Dim oFolder2
Dim oFile
Dim eTime
Dim ext

Set oFSO = CreateObject("Scripting.FileSystemObject")
set oFolder1 = oFSO.GetFolder ("C:\temp")
set oFolder2 = oFSO.GetFolder ("Z:\Input")

eTime = now
ext = "pdf"

For Each oFile In oFolder1.Files
    If oFSO.GetExtensionName(oFile) = ext Then
        MsgBox ext & "-Datei: " & oFile.Name & " gefunden"
        'neuer Dateinamen zusammensetzen
        newName = eTime & "_" & oFile.Name
        'Datei umbenennen
        oFile.name = newName
        MsgBox "Neuer Dateiname: " & newName
    else
        oFile.Delete
    End If    
Next  

oFSO.MoveFile oFolder1 & "\*.pdf", oFolder2

Set oFSO = nothing	
set oFolder1 = nothing
set oFolder2 = nothing
```


----------



## Yaslaw (18. Januar 2012)

Und wie sieht der neue Name aus?


----------



## amn.ssy (18. Januar 2012)

Yaslaw hat gesagt.:


> Und wie sieht der neue Name aus?



Jeder Datei im Verzechnis mit der Extension .PDF soll das aktuelle Datum (now) voran gestellt werden.

(Dateiname.pdf -> 18.01.2012_Dateiname.pdf)

Hab die MsgBox mal direkt unter die newName Zuweisung gesetzt - der Inhalt von newName ist richtig. Offensichtlich mag "er" oFile.name nicht bzw. es steht nicht das drin was erwartet wird.
Das andere ist, daß mit dieser Zuweisung (soweit war ich ja schon mal) ja noch nicht der neue Name auch gespeichert wird.
Idee (gerade eben): kann ich nicht den move-Befehl "missbrauchen"?

z.B. oFSO.MoveFile oFolder1 & "\*.pdf", oFolder2 & "\" & newName

Das ganz müßte dann natürlich in die Schleife und hätte den Vorteil, daß ich nicht erst umständlich alle pdf-Dateien umbenenne und dann verschiebe, sondern gleich wenn Sie gefunden werden, mit neuem Namen ins andere Verzeichnis wandern.


----------



## Yaslaw (18. Januar 2012)

oFile.name sollte schon stimmen. Ev. hat er mit den Punkten im Filenamen Problem. Ich teste das morgen mal


----------



## Zvoni (19. Januar 2012)

Dein Problem ist die Verwendung von


```
eTime=now
```

"Now" ohne Formatierung gibt nämlich "dd.mm.yyyy hh:mm:ss" zurück, und Doppelpunkte im Dateinamen.......

Deine Magie muss lauten:


```
eTime=Format(Now,"dd.mm.yyyy")
```


----------



## Yaslaw (19. Januar 2012)

Mit der Zuweisung ist automatisch der neue Name gespeichert - mindestens bei all meinen Tests


```
'Mein Test der funktioniert
    Dim f   As File
    Set f = fso.GetFile("C:\LocalData\Temp\1.1.1.test10.txt")
    f.Name = "1.1.1.test.txt"
    Set f = Nothing
```


*item: *now() direkt als String auswerten ist sehr suboptimal. Am besten mittels format() in ein String_fromat bringen. Wenn du da noch die Reihenfolge Jahr_Monat_Tag wählst, kriegst du eine Dateiname der nach Datum sortierbar ist: 2012_01_19

```
sTime = format(now, "YYYY_MM_DD")
```

*item: *Das mit dem Move geht auch. Aber auch da gilt. oFolder sind Objekte und keine Strings. Wenn du den Pfad des Ordners brauchst, dann kannst du mit oFolder1.path darauf zugreifen. Und um einen Pfad zu erstellen empfiehlt es sich die FSO-Methode BuildPath() zu verwenden.

*item: *Den Move kannst du auch direkt aus dem File-Objekt oFile machen.

```
sTime =  format(now, "YYYY_MM_DD")
....
    newName = sTime & "_" & oFile.name
    Call oFile.move(oFSO.buildPath(oFilder2.path, newName))
```

Mein Script das funktioniert sieht gerade so aus

```
Dim sDate               As String
    Dim sNewName            As String
    Dim oFile               As Object
    Dim oFolderSource       As Object
    Dim oFSO                As Object
    
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    
    sDate = Format(Now, "YYYY_MM_DD_")
    For Each oFile In oFSO.GetFolder("C:\LocalData\Temp\test").Files
        If oFSO.GetExtensionName(oFile.Path) = "pdf" Then
            sNewName = sDate & oFile.Name
            oFile.Copy (oFSO.BuildPath("C:\LocalData\Temp\test\sub", sNewName))
        End If
    Next oFile

    Set oFSO = Nothing
```


----------

