Move files to folders based on first X characters of filename (vbs) - windows

Hello my coding friends.
Sorry to ask this, but I thought it might be quicker to ask if someone has a script like this lying around.
I have about 2000+ files of audio mp3 files logged for a radio station I'm at, and I'd like to put them in to folders according to their recorded log date.
(Yes, I've now fixed the recording to do this correctly from now on, but this is in referent to what I've been doing with it: https://stephenmonro.wordpress.com/2015/05/22/setting-up-an-audio-logger/ )
The files I have are like this: (YYYYMMDD_HH00)
logs\20150424_0300.mp3
logs\20150424_0400.mp3
logs\20150424_0500.mp3
etc.
What I'd like is something like this:
\logs\8 digit date\filename with the same 8 digit date.mp3
Actual
\logs\20150424\20150424_0300.mp3
\logs\20150424\20150424_0400.mp3
\logs\20150424\20150424_0500.mp3
etc.
This is my pseudo code, I've made, but as I'm a little pressed for time and don't have hours to mess around guessing, I just wondered if anyone knew how to do it quickly.
A .VBS file is my prefered language.
Do
Read a filenames first 8 characters {left(8, filename)} (the date)
If not exist, create a folder called that first 8 characters
Move that file into the folder name
Loop (until all files are moved to the right locations)

Your pseudocode looks spot on to me. Assuming every file in your logs folder is consistently named, here's how it could be accomplished using the FileSystemObject library:
Const LOGS_FOLDER = "c:\logs"
Dim objFSO, objFile, strDate, strSub
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each objFile In objFSO.GetFolder(LOGS_FOLDER).Files
strDate = Left(objFile.Name, 8)
strSub = objFSO.BuildPath(LOGS_FOLDER, strDate)
' Create the folder if it doesn't already exist...
If Not objFSO.FolderExists(strSub) Then objFSO.CreateFolder strSub
' Move the file into its proper folder. Use "\" to indicate dest is folder...
objFile.Move strSub & "\"
Next

Related

Looping over all databases in a directory

I need to loop over all databases in a certain directory, where the database name is ACPwxyz.mdb, where wxyz is the equivalent to an MMYY value for the period that database was used for.
E.g., the database for July 2017 would be ACP0717.mdb.
I've never written in VB6 before and I totally hate it, but it's an extension to an existing project so I'm stuck with it!
Is there a way of looping over all files in a directory, checking if the file name follows the format of ACPwxyz.mdb or not, and if it does, then opening a connection to it?
I've looked around a bit and see Dir(x, y), but I'm not sure if I can use this in this situation?
Any tips would be appreciated.
You can use Dir, yes.
If you use something like this:
Dim strFile As String
strFile = Dir(yourDBPath, "ACP????.mdb") ' mdb for MS-Access files
Do Until strFile = ""
If Len(strFile) = 11 Then ' Ensure the DB file name is 11 characters, which yours are
'Do something // You can also check the file name doesn't = a certain name if needed
End If
strFile = Dir
Loop
Dir accepts either an asterisk (*), or a question mark (?) as wildcards in file names, so this will look for any database in the set path that is called ACP followed by 4 characters.

Error Saving File in Document Folder of Library

I am writing an HTA file with VBScript as the scripting language. I have a function where the user is prompted to choose the folder in which they would like to save a document. I didn't write this code myself, but instead borrowed it from here.
Function SelectFolder(myStartFolder)
Dim objFolder, objItem, objShell
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0, "Select Folder to Save New File", 0, myStartFolder)
If IsObject(objFolder) Then SelectFolder = objFolder.Self.Path
End Function
I call this function in another one in order when I make the file and prompt the user to choose where to save it:
Sub Example()
Dim destPath, destFile, objWorkbook
destPath = SelectFolder(libPath)
destPath = destPath & "\Sample Export"
Set destFile = CreateObject("Excel.Application")
Set objWorkbook = destFile.Workbooks.Add()
objWorkbook.SaveAs(destPath)
(code to edit excel file)
End Sub
Example() works fine except when someone chooses to save their document in one of the four default libraries in Windows (Documents, Music, Pictures, Videos). In that case, I receive an error saying "The file could not be accessed" and indicating the error is at the line that says "objWorkbook.SaveAs(destPath)". The error box then gives me the following suggestions:
Make sure the specified folder exists
Make sure the folder that contains the file is not read-only
Make sure the file name does not contain any of the following characters: < > ? { } : | or *
Make sure the file/path name doesn't contain more than 218 characters.
The error occurs when I open the HTA file and click a button calling Example(), which then opens a dialog box to ask the user to choose the file location. When Documents, Music, Pictures, or Videos is chosen, a "Script Error" box pops up with the error message listed above. I am not familiar enough with VBScript to know what the problem is exactly. I would appreciate any suggestions as to what to do.
I don't know exactly what the solution to the above issue was. However, I noticed that the path I pass to SelectFolder had a typo in it. libPath was supposed to be to the %userprofile% from the environment variable. However, I had pluralized "userprofiles" so that it was %userprofiles% instead. This took me to somewhere that looked right but wasn't. I fixed the typo and now BrowseForFolder takes me to C:/Users/*username* like it's supposed to. It turns out that I was being sent to the Desktop location because of the fourth argument in BrowseForFolder, instead of the user profile like I wanted.

Iterate over pre-filtered list of folders

I'm working with a client's flat folder structure that has a single folder containing 45k subfolders with 8-digit folder names, e.g. 51023231. I have a small script that ripples through them and copies them into a bin-sorted set of subfolders elsewhere on the network (for use with SharePoint), such that the first 5 digits are used as a parent folder, i.e. the contents of 51023231 are copied into 51023\51023231. It works perfectly well, and I've managed to some modest optimisation when dealing with folders new to the destination.
However, it can take an hour or so to run over the entire 45k set of folders doing folder by folder comparisons, I was wondering if it was possible to run a system-level query to return only an initial list of folders whose modification dates were after a given point, and then run the existing script over that. I've done the usual Google-is-your-friend type trawl, and keep hitting the idea of using WMI to do this, but I don't get much further. Is this because it simply isn't possible with VBScript?
Any pointers gratefully received.
It's possible with VBScript using WMI. It's not something you'd be able to do using the FileSystemObject, if that's what you're implying.
You can query WMI's Win32_Directory class to filter folders by modified date. The only tricky part is the datetime format used by WMI. But the SWbemDateTime class can convert a VBScript date to a datetime value.
Here's an example:
' Create a datetime value for use in our WMI query...
Dim dt
Set dt = CreateObject("WbemScripting.SWbemDateTime")
dt.SetVarDate DateSerial(2015, 8, 31)
Dim objWMI
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
' Find all subfolders of 'c:\some\path' that were modified > 2015/08/31
Dim objFolders
Set objFolders = objWMI.ExecQuery("select * from Win32_Directory" _
& " where Drive='C:' and Path='\\some\\path\\' and LastModified>'" & dt & "'")
Dim objFolder
For Each objFolder in objFolders
WScript.Echo objFolder.Name
Next

needing help creating a script to find if a folder has been modified in the last day and if not create a txt file in a location

I'm trying to create a script that finds if a folder hasn't been modified in the last day and create a text file in a location. However if it has been modified in the last day I want it to quit the script.
At the moment, I have only been able to create one (due to my basic knowledge of VBscripting) that finds if a folder exists and if so creates a script.
This however, doesn't work as the subfolder is created daily with a new name and obviously this means my script would have to be changed daily which is pointless.
I need to have the parent folder read and a text file created in another locationif the last modified date isn't < 1 day.
This is the script so far:
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists("c:\test") Then
wsscript.quit
Else
dim filesys, filetxt, getname, path
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.CreateTextFile("c:\test\test.txt", True)
path = filesys.GetAbsolutePathName("c:\test\test.txt")
getname = filesys.GetFileName(path)
filetxt.WriteLine("file doesnt exist.")
filetxt.Close
End If
I know I need to change the .folderExists line to something like
if file.DateLastModified > dateadd("h", -24, Now) then
I would like a day parameter rather than an hour; I know this means turning the h into a d but I am unsure past that.
it has been solved by Mr Bond! the wonderful man he is. however i now have another question, any idea how to add a command to send an outlook email into this? as the else option.
Use the DateLastModified property of the Folder object.
If objFSO.GetFolder("c:\test").DateLastModified >= Date - 1 Then
' Folder modified within last day
Else
' Folder modified more than a day ago
End
There's no need to use DateAdd() to add/subtract days. You can just use integer arithmetic.
Note that this will yield a time of zero/midnight. So it's really checking to see if the folder was modified since the start of the day yesterday, not in the last 24 hours. That may or may not be what you want.

Vbscript - Compare and copy files from folder if newer than destination files

I'm trying to design this script that's supposed to be used as a part of a logon script for alot of users. And this script is basically supposed to take a source folder and destination folder as basically just make sure that the destination folder has the exact same content as the source folder. But only copy if the datemodified stamp of the source file is newer than the destination file.
I have been thinking out this basic pseudo code, just trying to make sure this is valid and solid basically.
Dim strSourceFolder, strDestFolder
strSourceFolder = "C:\Users\User\SourceFolder\"
strDestFolder = "C:\Users\User\DestFolder\"
For each file in StrSourceFolder
ReplaceIfNewer (file, strDestFolder)
Next
Sub ReplaceIfNewer (SourceFile, DestFolder)
Dim DateModifiedSourceFile, DateModifiedDestFile
DateModifiedSourceFile = SourceFile.DateModified()
DateModifiedDestFile = DestFolder & "\" & SourceFile.DateModified()
If DateModifiedSourceFile < DateModifiedDestFile
Copy SourceFile to SourceFolder
End if
End Sub
Would this work? I'm not quite sure how it can be done, but I could probably spend all day figuring it out. But the people here are generally so amazingly smart that with your help it would take alot less time :)
Your algorithm looks good. Practically speaking, you would need to get the Files using a FileSystemObject, and retrieve their respective DateLastModified properties. You can do a DateDiff on the two dates to compare which is earlier.
Slightly modified examples from DevGuru:
Dim filesys,demofile, date1, date2
Set filesys = CreateObject("Scripting.FileSystemObject")
Set demofile = filesys.GetFile("filename1")
date1 = demofile.DateLastModified
demofile = filesys.GetFile("filename2")
date2 = demofile.DateLastModified
If DateDiff("d", date1, date2) > 0 Then
'date2 is more recent than date1, comparison by "day" ' ** Improvement **
End If
Edit: Misspelled the URL.
Improvement
In the comment, "date1" and "date2" have been exchanged.
The MSDN document says:
If date1 refers to a later time than date2, the DateDiff function returns a negative number.
http://msdn.microsoft.com/en-us/library/xhtyw595(v=vs.84).aspx
Your code looks reasonable. Just look out for readonly files and such.
You can use the FileSystemObject to do the actual file operations, just look at:
http://msdn.microsoft.com/en-us/library/6kxy1a51%28VS.85%29.aspx

Resources