I have a script already which can perform a saveas routine for file names that begin with certain characters.
This is the script below.
'launch Excel and open file
Const xlExcel8 = 56
Const xlOpenXMLWorkbook = 51
Set fso = CreateObject("Scripting.FileSystemObject")
Set xlObj = CreateObject("Excel.Application")
Set re = New RegExp
re.Pattern = "^ABC.*\.xlsx$"
re.IgnoreCase = True
For Each f In fso.GetFolder("C:\Users\Jimbo\Documents\_ThisWeek").Files
If re.Test(f.Name) Then
Set xlFile = xlObj.WorkBooks.Open(f.Path)
xlObj.DisplayAlerts = False
xlfile.SaveAs "C:\Users\Jimbo\Documents\_ThisWeek\Weekly Feed File.xls", xlExcel8
xlFile.Close True
End If
xlObj.DisplayAlerts = True
Next
Set re = New RegExp
re.Pattern = "^ABC.*\.xlsx$"
re.IgnoreCase = True
For Each f In fso.GetFolder("C:\Users\Jimbo\Documents\_ThisWeek").Files
If re.Test(f.Name) Then
fso.Deletefile(f.Path)
End If
Next
xlObj.Quit
Can anyone pls assist with updating the script to rename a file instead of performing a saveas?
This is an extremely simple example.
I don't have enough to go on for how you want to rename the file so you need to fill in that logic. I just defined a variable strName that holds a string value for an example.
You would want to set strName inside the If statement to something that works for you and changes on each loop.
If the path or name will be complex, make sure you double quote the variable.
'rename files from one folder to another
option explicit
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim strPath: strPath = "C:\Users\Jimbo\Documents\_AnotherFolder\"
Dim strName: strName = "SetYourNameHere.xls"
Dim re: Set re = New RegExp
Dim oFile
re.Pattern = "^ABC.*\.xlsx$"
re.IgnoreCase = True
For Each oFile In fso.GetFolder("C:\Users\Jimbo\Documents\_ThisWeek").Files
If re.Test(oFile.Name) Then
oFile.move strPath
oFile.name = strName
End If
Next
You already have the file object. Just move it with it's own method to your other folder then use it's name property to set the value to what you want the name to be.
You should add verification that the file doesn't already exist in the folder and handle that situation gracefully.
You can rename a file by using the MoveFile Method
Dim Fso
Set Fso = WScript.CreateObject("Scripting.FileSystemObject")
Fso.MoveFile "Test.txt", "Test2.txt"
Related
New at VbScript so please include all lines if you can.
I have
Source-folder C:\s\ with files with names et_v01.txt, et_v02.txt etc. Destination-folder C:\d\ I only want the latest file to be COPIED from S to D which would be et_v02 since we'll use DateLastModified.
Bonus at destination only keep the latest file if it runs next time when a new version comes in. Thanks in advance and I have searched for this but the others had less than criteria and etc.
Option Explicit
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objSTR, objEND, objTYP, objEXT, objKEY, objFILE
Dim Folder, SubFolder
objSTR = "C:\s\"
objEND = "C:\d\"
For Each objFILE in objFSO.GetFolder(objSTR).Files
If objFILE.DateLastModified > DateAdd("d",-4,now) then
objFILE.Copy objEND
End If
Next
Here try this version:
Option Explicit
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim strSource, strDestination
strSource = "C:\s\"
strDestination = "C:\d\"
Dim objFile, objOldestFileSoFar
For Each objFile in objFSO.GetFolder(strSource).Files
If Not IsEmpty(objOldestFileSoFar) Then
If objFile.DateLastModified > objOldestFileSoFar.DateLastModified Then
Set objOldestFileSoFar = objFile
End If
Else 'This is the first loop, i.e. we have no previous "last mod" to compare against.
Set objOldestFileSoFar = objFile
End If
Next
objOldestFileSoFar.Copy strDestination
Also, I've cleaned up your code a bit to get rid of unused declarations and to apply better naming to your variables. Take those as suggestions if you like, but just keep in mind that adhering to conventions is important.
I have more than 50 files needed to create the pivot table and each file has the same exact formort with different contents. So far, I have finished creating the code for the pivot and it works very well when running alone, however, it failed when I tried to run the code for all workbooks in the same folder. I don't know what happened and why it kept showing that no files could be found despite nothing wrong about the pathname.
Sub DoAllFiles()
Dim Filename, Pathname As String
Dim WB As Workbook
Pathname = "D:\Reports"
Filename = Dir(Pathname & "\*.xls*")
Do While Filename <> ""
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set WB = Workbooks.Open(Pathname & Filename) 'open all files
PivotX WB
WB.Close SaveChanges:=True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Filename = Dir()
Loop
End Sub
Here is the code for pivot and it works very well when running it alone:
Sub PivotX(WB As Workbook)
Dim Lrow, Lcol As Long
Dim wsData As Worksheet
Dim rngRaw As Range
Dim PvtTabCache As PivotCache
Dim PvtTab As PivotTable
Dim wsPvtTab As Worksheet
Dim PvtFld As PivotField
Set wsData = ActiveSheet
Lrow = wsData.Cells(Rows.Count, "B").End(xlUp).Row
Lcol = wsData.Cells(1, Columns.Count).End(xlToLeft).Column
Set rngRaw = wsData.Range(Cells(1, 1), Cells(Lrow, Lcol))
Set wsPvtTab = Worksheets.Add
wsData.Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=rngRaw, Version:=xlPivotTableVersion12).CreatePivotTable TableDestination:=wsPvtTab.Range("A3"), TableName:="PivotTable1", DefaultVersion:=xlPivotTableVersion12
Set PvtTab = wsPvtTab.PivotTables("PivotTable1")
PvtTab.ManualUpdate = True
Set PvtFld = PvtTab.PivotFields("Month")
PvtFld.Orientation = xlPageField
PvtTab.PivotFields("Month").ClearAllFilters
Set PvtFld = PvtTab.PivotFields("Year")
PvtFld.Orientation = xlPageField
PvtTab.PivotFields("Year").ClearAllFilters
Set PvtFld = PvtTab.PivotFields("Fund_Code")
PvtFld.Orientation = xlRowField
PvtFld.Position = 1
Set PvtFld = PvtTab.PivotFields("Curr")
PvtFld.Orientation = xlColumnField
PvtFld.Position = 1
wsPvtTab.PivotTables("PivotTable1").PivotFields("Curr").PivotItems("USD").Position = 1
With PvtTab.PivotFields("Trx_Amount")
.Orientation = xlDataField
.Function = xlSum
.NumberFormat = "#,##0;[red](#,##0)"
End With
wsPvtTab.PivotTables("Pivottable1").RowAxisLayout xlTabularRow
'Remove grand total
wsPvtTab.PivotTables("Pivottable1").RowGrand = False
For Each PvtTbCache In ActiveWorkbook.PivotCaches
On Error Resume Next
PvtTbCache.Refresh
Next PvtTbCache
'Determine filter value
Set PvtFld = PvtTab.PivotFields("Year")
PvtFld.ClearAllFilters
PvtFld.EnableMultiplePageItems = True
With PvtFld
.AutoSort xlmnual, .SourceName
For Each Pi In PvtFld.PivotItems
Select Case Pi.Name
Case "2014"
Case Else
Pi.Visible = False
End Select
Next Pi
.AutoSort xlAscending, .SourceName
End With
'determine filter value
Set PvtFld = PvtTab.PivotFields("Month")
PvtFld.ClearAllFilters
PvtFld.EnableMultiplePageItems = True
With PvtFld
.AutoSort xlmnual, .SourceName
For Each Pi In PvtFld.PivotItems
Select Case Pi.Name
Case "11"
Case Else
Pi.Visible = False
End Select
Next Pi
.AutoSort xlAscending, .SourceName
End With
PvtTab.ManualUpdate = False
End Sub
Any help would be very much appreciated. Thank you very much in advance.
This should solve your problem:
Set WB = Workbooks.Open(Pathname & "\" & Filename)
When I tried using your code, for some reason, it did not retain the backslash you put at the beginning of the "Filename" variable. That would explain why VBA couldn't find the files. Adding it back should between the path name and file name should make it work correctly
I believe you have the answer to your base problem above but I would offer the following 'tweaks' to avoid screen flashing and unrecovered variable assignment.
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Do While Filename <> ""
Set WB = Workbooks.Open(Pathname & "\" & Filename) 'open all files
Call PivotX(WB)
WB.Close SaveChanges:=True
Set WB = Nothing
Filename = Dir()
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
The Set WB = Nothing is really only purposeful on the last pass when WB is not reassigned but your PivotX sub could use several Set nnn = Nothing before exiting. While the reference count is supposed to be decremented (and memory consequently released), that is not always the case. (see Is there a need to set Objects to Nothing inside VBA Functions) In short, it is just good coding practise.
Finally, using Dim Filename, Pathname As String declares Filename as a variant, not a string type. It isn't making any difference here but you should be aware of what your variables are being declared as.
What I've created is a script which pulls the Dell Service code, Username, and Computername, from a computer, and compiles that information into a .csv file. This script will be implemented via Active Directory login scripts, so end users wont have to do a thing.
The problem I'm having though, is everytime a person logs on, it collects their information, and adds it to the list. This means my list could just be full of two people who log onto their computer over and over.
What I would like to happen is for the script to search the .csv file for the specific data collected, and if this data exists, to not enter it.
The code I have so far is this:
'Get Dell Service Tag Info
set ProSet = GetObject("winmgmts:").InstancesOf("Win32_BIOS")
Set ProSet1 = GetObject("winmgmts:").InstancesOf("Win32_SystemEnclosure")
For each Pro in ProSet
For each Pro1 in ProSet1
ServiceTag=Pro.SerialNumber
exit for
Next
exit for
Next
'get username and computername, could also be asked in a batch
Set oShell = WScript.CreateObject("WScript.Shell")
Set oShellEnv = oShell.Environment("Process")
sComputerName = oShellEnv("ComputerName")
sUsername = oShellEnv("username")
dim filesys, filetxt, getname, path
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.OpenTextFile("\\xx.xx.xx.xx\Gathering\DataLog.csv", 8, True, -2)
path = filesys.GetAbsolutePathName("\\xx.xx.xx.xx\Gathering\DataLog.csv")
getname = filesys.GetFileName(path)
filetxt.WriteLine sUsername & ", " & sComputerName & ", " & ServiceTag
filetxt.Close
This is the basic script, without the entry checker.
As for an entry checker, this is what I have tried but it doesn't seem to work:
Set objFSO = CreateObject("Scripting.Dictionary")
Set objFile = objFSO.OpenTextFile ("\\xx.xx.xx.xx\Gathering\Dictionary.txt", 8, True)
' Make comparisons case insensitive.
objList.CompareMode = vbTextCompare
' ... code to read user name and assign to variable strNameOfUser.
If (objList.Exists(strNameOfUser) = False) Then
' Add this user to the dictionary object.
objList(strNameOfUser) = True
' Log this unique user name.
objFile.WriteLine strNameOfuser
End If
Any help is appreciated! Thanks!
(1) Your code is messed up: You store a Dictionary in objFSO and then try to invoke objFSO.OpentextFile()
(2) VBScript can't read and append to a file; so ForAppending (8) won't work; you'll have to read-open the file first, gather the info, close it, append-open and append new user info (if necessary)
(3) Using a dictionary is unnecessarily complex: to fill the dictionary you'll have to read the file from start to end, before you can ask the dictionary whether a specific user exists.
While simply reading the file line by line, you can break the reading as soon as you find the user - then close - open & append - close - done.
UPDATE
Item (3) in code:
Dim goFS : Set goFS = CreateObject( "Scripting.FileSystemObject" )
Dim tsUsers : Set tsUsers = goFS.OpenTextFile(sFSpec, ForReading, True)
Dim bFound : bFound = False
Do Until tsUsers.AtEndOfStream
If 1 = Instr(tsUsers.ReadLine(), sUser) Then
bFound = True
Exit Do
End If
Loop
tsUsers.Close
If Not bFound Then
Set tsUsers = goFS.OpenTextFile(sFSpec, ForAppending, False)
tsUsers.WriteLine sUser
tsUsers.Close
End If
Because I'm a pessimistic worrier: How do you plan to cope with more than one user logging in and write-access the file at the same time?
I have a VBS file that I am trying to use to determine what folders and files are in a certain directory. I believe I have the code written correctly, but whenever I try to write out the file or current directory I get a blank text document with nothing but the root directory written out. Any advice would be greatly appreciated.
Dim NewFile
Function GetFolders (strFolderPath)
Dim objCurrentFolder, colSubfolders, objFolder, files
Set objCurrentFolder = objFSO.GetFolder(strFolderPath)
Set colSubfolders = objCurrentFolder.SubFolders
For Each objFolder In colSubfolders
NewFile.WriteLine(" - " & objFolder.Path)
Set files = folder.Files
For each folderIdx In files
NewFile.WriteLine(" - "& folderIdx.Name)
Next
Call GetFolders (objFolder.Path)
Next
End Function
Dim fso, sFolder
Set fso = CreateObject("Scripting.FileSystemObject")
sFolder = Wscript.Arguments.Item(0)
If sFolder = "" Then
Wscript.Echo "No Folder parameter was passed"
Wscript.Quit
End If
Set NewFile = fso.CreateTextFile(sFolder&"\FileList.txt", True)
NewFile.WriteLine(sFolder)
Call GetFolders(sFolder)
NewFile.Close
You haven't payed sufficient attention to your variable naming. Your script is a good example of the reason why all VBScripts should start with the line:-
Option Explicit
This would highlight all the variables that haven't been declared which in turn will point out typos and inconsistencies in variable naming. Here is how I would write it:-
Option Explicit
Dim msFolder : msFolder = Wscript.Arguments.Item(0)
If msFolder = "" Then
Wscript.Echo "No Folder parameter was passed"
Wscript.Quit
End If
Dim mfso : Set mfso = CreateObject("Scripting.FileSystemObject")
Dim moTextStream : Set moTextStream = mfso.CreateTextFile(msFolder & "\FileList.txt", True)
moTextStream.WriteLine(msFolder)
WriteFolders mfso.GetFolder(msFolder)
moTextStream.Close
Sub WriteFolders(oParentFolder)
Dim oFolder
For Each oFolder In oParentFolder.SubFolders
moTextStream.WriteLine(" - " & oFolder.Path)
Dim oFile
For Each oFile In oFolder.Files
moTextStream.WriteLine(" - " & oFile.Name)
Next
WriteFolders oFolder
Next
End Sub
I need to create A set of empty folders, starting at 10, going to 180. This is the script I'm trying to use, but it just creates 10, and nothing else.
Option Explicit
Dim objFSO, objFolder, strDirectory, i
strDirectory = "\path\to\main\folder"
Set objFSO = CreateObject("Scripting.FileSystemObject")
i = 180
While i < 180
Set objFolder = objFSO.CreateFolder(strDirectory & i)
i = i+1
WScript.Quit
Wend
I'm pretty new to VBScript, so maybe the problem is obvious, but I just don't see it. I also tried using a For loop, but that didn't seem to work at all.
Thanks in advance to anyone who reads this.
I have modified your script as follows:
Option Explicit
Dim objFSO, objFolder, strDirectory, i
strDirectory = "C:\Temp\Test\folder"
Set objFSO = CreateObject("Scripting.FileSystemObject")
i = 10 '' <===== CHANGED!
While i < 180
Set objFolder = objFSO.CreateFolder(strDirectory & i)
i = i+1
''WScript.Quit '' <===== COMMENTED OUT!
Wend
With this script, I managed to create 180 folders.