Seeking support to edit below codes in such a way that it renames all worksheets (excel) similar to their workbooknames within a folder (loop). If workbook has more than one sheet then rename it as workbookname(1),workbookname(2) etc.
Sub EditSheetName()
Dim NewName
NewName = Replace(ActiveWorkbook. Name, ".xl*", "")
ActiveSheet.Select
ActiveSheet.Name = NewName
End Sub
Maybe just a simple loop:
I haven't figured out how to replace the ".xlsx" using a wildcard, I would assume it would be either ".xlsm" or ".xlsx", you can change them in the code
Sub LoopThroughFolder()
Dim MyFile As String, Str As String, MyDir As String, Wb As Workbook
Dim sh As Worksheet
Dim s As String, n As String
Set Wb = ThisWorkbook
'change the address to suite
MyDir = "C:\Users\dmorrison\Downloads\TestFolderLoop\"
MyFile = Dir(MyDir & "*.xls*") 'change file extension
ChDir MyDir
Application.ScreenUpdating = 0
Application.DisplayAlerts = 0
Do While MyFile <> ""
Workbooks.Open (MyFile)
s = ActiveWorkbook.Name
n = Replace(s, ".xls", "") 'change the file extension
i = 1
For Each sh In Sheets
sh.Name = n & "(" & i & ")"
i = i + 1
Next sh
ActiveWorkbook.Close True
MyFile = Dir()
Loop
End Sub
For multiple sheets, you will want an if statement:
Dim s As String, i as Integer
If Sheets.Count=1 Then
s = Replace(ActiveWorkbook.Name,".xlsx","")
ActiveSheet.Name = s
Else
For i = 1 to Sheets.Count
s = Replace(ActiveWorkbook.Name,".xlsx","")
Sheets(i).Name = s & "(" & i & ")"
Next i
End If
I have it this way so the (#) only shows up for multiple. You would only need the loop in the Else section if you don't care.
Related
I inherited VBA code that has not worked since my work updated our version of Excel.
The original code looped through all Excel files in a specific folder.
If data in specific cells was blank or a 0, would rename the whole workbook so I would know what files to delete after the fact.
This is the original code. I don't need it to do all of this anymore.
This is part one:
Sub AllFilesWeekly()
Dim folderPath As String
Dim filename As String
Dim wb As Workbook
folderPath = "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\" 'change to suit
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
filename = Dir(folderPath & "*.xlsx")
Do While filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & filename)
'Call a subroutine here to operate on the just-opened workbook
Call getmetrics
On Error Resume Next
If Not ActiveWorkbook.Name Like "Audit Hub Report Distribution*" Then
ActiveWorkbook.Close
End If
filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
The second part:
Sub getmetrics()
Dim cell As Range
Dim procstring As String, wbname As String
'Dim OQAYTD As String
Dim OQAMTD As String
Dim ORLYTD As String
Dim ORLMTD As String
Dim DR As String
Dim Audits As Long
Dim permonth As String, peryear As String, permonthrl As String, peryearrl As String
Dim RS As Worksheet, AD As Worksheet, QD As Worksheet, ws As Worksheet, YN As Boolean
For Each ws In Worksheets
If ws.Name = "Audit Detail" Then
YN = True
End If
Next ws
If YN = True Then
ActiveWorkbook.Sheets(2).Name = ("Rep Summary")
Set RS = ActiveWorkbook.Sheets("Rep Summary")
Set AD = ActiveWorkbook.Sheets("Audit Detail")
Set QD = ActiveWorkbook.Sheets("Question Detail")
With Sheets("Process Summary")
For Each cell In Range(Range("A3"), Range("A9999").End(xlUp))
If cell.Value = "Record Level YTD" Then
ORLYTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "YTD Quality Average" Then
OQAYTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Record Level Quality Average" Then
ORLMTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Quality Average" Then
OQAMTD = Range(cell.Address).Offset(0, 1).Value
Else
If cell.Value = "Audits" Then
Audits = Range(cell.Address).Offset(0, 1).Value
End If
End If
End If
End If
End If
Next cell
End With
wbname = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4)
peryear = VBA.Format(OQAYTD, "Percent")
permonth = VBA.Format(OQAMTD, "Percent")
peryearrl = VBA.Format(ORLYTD, "Percent")
permonthrl = VBA.Format(ORLMTD, "Percent")
DR = Right(Sheets("Process Summary").Range("A2").Value, Len(Sheets("Process
Summary").Range("A2").Value) - 12)
RS.Range(RS.Range("A1"), RS.Range("IV1").End(xlToLeft)).AutoFilter
RS.Range(RS.Range("A1"), RS.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
AD.Range(AD.Range("A1"), AD.Range("IV1").End(xlToLeft)).AutoFilter
AD.Range(AD.Range("A1"), AD.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
QD.Range(QD.Range("A1"), QD.Range("IV1").End(xlToLeft)).AutoFilter
QD.Range(QD.Range("A1"), QD.Range("IV1").End(xlToLeft)).EntireColumn.AutoFit
Application.DisplayAlerts = False
procstring = wbname & "|" & permonth & "|" & Audits & "|" & peryear & "|" & permonthrl & "|" &
peryearrl & "|" & DR ' & "|" & Users
Debug.Print procstring
Else
Application.DisplayAlerts = False
Dim AWN As String
AWN = ActiveWorkbook.FullName
Debug.Print "Not Audited: " & ActiveWorkbook.Name
ActiveWorkbook.SaveAs "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\Delete -" & Second(Now)
Kill AWN
ActiveWorkbook.Close savechanges:=True
Application.DisplayAlerts = True
End If
End Sub
All I need to do is look at cell D3 on the "Process Summary" tab.
If the value in that space is "0.00%", rename the workbook to delete and loop on until all workbooks are looked at.
I do not need to screen print all the extra numbers any more.
Build a Collection of filenames that match the criteria and then use it to rename the files.
Option Explicit
Sub AllFilesWeekly()
Dim folderPath As String, filename As String
Dim wb As Workbook, ws As Worksheet
Dim col As Collection, n As Long
Set col = New Collection
folderPath = "C:\Users\" & (Environ$("Username")) & "\Desktop\Process Production\" 'change to suit
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
' scan folder
filename = Dir(folderPath & "*.xlsx")
Do While filename <> ""
Set wb = Workbooks.Open(folderPath & filename, True, True) ' update links, readonly
For Each ws In wb.Sheets
If ws.Name = "Process Summary" Then
If Format(ws.Range("D3"), "0.00%") = "0.00%" Then
col.Add wb.Name
End If
End If
Next
wb.Close
n = n + 1
filename = Dir
Loop
' result
MsgBox "Files scanned = " & n & vbCrLf & _
"To delete = " & col.Count, vbInformation, folderPath
' rename
If col.Count > 0 Then
If MsgBox("Continue to rename ?", vbYesNo) = vbYes Then
For n = 1 To col.Count
Name folderPath & col(n) As folderPath & "delete_" & col(n)
Next
MsgBox "Rename done"
End If
End If
End Sub
VBA code not looping through the folder of .csv's
The code below is doing the function I need but is not looping and it would be good to add a line to delete the .csv's once copied
Option Explicit
Private Sub SaveAs_Files_in_Folder()
Dim CSVfolder As String, XLSfolder As String
Dim CSVfilename As String, XLSfilename As String
Dim template As String
Dim wb As Workbook
Dim wbm As Workbook 'The template I want the data pasted into
Dim n As Long
CSVfolder = "H:\Case Extracts\input" 'Folder I have the csv's go
XLSfolder = "H:\Case Extracts\output" 'Folder for the xlsx output
If Right(CSVfolder, 1) <> "\" Then CSVfolder = CSVfolder & "\"
If Right(XLSfolder, 1) <> "\" Then XLSfolder = XLSfolder & "\"
n = 0
CSVfilename = Dir(CSVfolder & "*.csv", vbNormal)
template = Dir("H:\Case Extracts\template.xlsx", vbNormal)
While Len(CSVfilename) <> 0
n = n + 1
Set wb = Workbooks.Open(CSVfolder & CSVfilename)
Range("A1:M400").Select
Selection.Copy
Set wbm = Workbooks.Open(template, , , , "Password") 'The template has a password
With wbm
Worksheets("Sheet2").Activate
Sheets("Sheet2").Cells.Select
Range("A1:M400").PasteSpecial
Worksheets("Sheet1").Activate
Sheets("Sheet1").Range("A1").Select
wbm.SaveAs Filename:=XLSfolder & CSVfilename & ".xlsx", FileFormat:=xlOpenXMLWorkbook
wbm.Close
End With
With wb
.Close False
End With
CSVfilename = Dir()
Wend
End Sub
The code works for the first .csv file I just can't get the loop to keep going through the files. It would also be good to add a line to delete the .csv's once they have been copied
Work with objects. You may want to see How to avoid using Select in Excel VBA. Declare objects for both the csv and template and work with them.
Your DIR is not working because of template = Dir("H:\Case Extracts\template.xlsx", vbNormal) which is right after CSVfilename = Dir(CSVfolder & "*.csv", vbNormal). It is getting reset. Reverse the position as shown below. Move it before the loop as #AhmedAU mentioned.
Copy the range only when you are ready to paste. Excel has an uncanny habit of clearing the clipboard. For example, I am pasting right after I cam copying the range.
Is this what you are trying? (Untested)
Option Explicit
Private Sub SaveAs_Files_in_Folder()
Dim CSVfolder As String, XLSfolder As String
Dim CSVfilename As String, XLSfilename As String
Dim wbTemplate As Workbook, wbCsv As Workbook
Dim wsTemplate As Worksheet, wsCsv As Worksheet
CSVfolder = "H:\Case Extracts\input" '<~~ Csv Folder
XLSfolder = "H:\Case Extracts\output" '<~~ For xlsx output
If Right(CSVfolder, 1) <> "\" Then CSVfolder = CSVfolder & "\"
If Right(XLSfolder, 1) <> "\" Then XLSfolder = XLSfolder & "\"
XLSfilename = Dir("H:\Case Extracts\template.xlsx", vbNormal)
CSVfilename = Dir(CSVfolder & "*.csv")
Do While Len(CSVfilename) > 0
'~~> Open Csv File
Set wbCsv = Workbooks.Open(CSVfolder & CSVfilename)
Set wsCsv = wbCsv.Sheets(1)
'~~> Open Template file
Set wbTemplate = Workbooks.Open(XLSfolder & XLSfilename, , , , "Password")
'~~> Change this to relevant sheet
Set wsTemplate = wbTemplate.Sheets("Sheet1")
'~~> Copy and paste
wsCsv.Range("A1:M400").Copy
wsTemplate.Range("A1").PasteSpecial xlPasteValues
'~~> Save file
wbTemplate.SaveAs Filename:=XLSfolder & CSVfilename & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook
'~~> Close files
wbTemplate.Close (False)
wbCsv.Close (False)
'~~> Get next file
CSVfilename = Dir
Loop
'~~> Clear clipboard
Application.CutCopyMode = False
End Sub
I think must be something like this, adapted to very fast looping through huge of csvs files
reference “Microsoft Scripting Runtime” (Add using
Tools->References from the VB menu)
Sub SaveAs_Files_in_Folder()
Dim myDict As Dictionary, wb As Workbook, eachLineArr As Variant
Set myDict = CreateObject("Scripting.Dictionary")
CSVfolder = "H:\Case Extracts\input\"
XLSfolder = "H:\Case Extracts\output\"
Template = ThisWorkbook.path & "\template.xlsx"
fileMask = "*.csv"
csvSeparator = ";"
csvLineBreaks = vbLf ' or vbCrLf
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.EnableEvents = False
.Calculation = xlManual
'.Visible = False ' uncomment to hide templates flashing
End With
LookupName = CSVfolder & fileMask
Results = CreateObject("WScript.Shell").Exec("CMD /C DIR """ & LookupName & Chr(34) & " /S /B /A:-D").StdOut.ReadAll
filesList = Split(Results, vbCrLf)
For fileNr = LBound(filesList) To UBound(filesList) - 1
csvLinesArr = Split(GetCsvFData(filesList(fileNr)), csvLineBreaks) ' read each csv to array
ArrSize = UBound(Split(csvLinesArr(lineNr), csvSeparator))
For lineNr = LBound(csvLinesArr) To UBound(csvLinesArr)
If csvLinesArr(lineNr) <> "" Then
eachLineArr = Split(csvLinesArr(lineNr), csvSeparator) ' read each line to array
ReDim Preserve eachLineArr(ArrSize) ' to set first line columns count to whoole array size
myDict.Add Dir(filesList(fileNr)) & lineNr, eachLineArr ' put all lines into dictionary object
End If
Next lineNr
Set wb = Workbooks.Open(Template, , , , "Password")
wb.Worksheets("Sheet1").[a1].Resize(myDict.Count, ArrSize) = TransposeArrays1D(myDict.Items)
Set fso = CreateObject("Scripting.FileSystemObject")
csvName = fso.GetBaseName(filesList(fileNr))
Set fso = nothing
wb.SaveAs FileName:=XLSfolder & csvName & ".xlsx"
wb.Close
Set wb = Nothing
Next fileNr
With Application
.ScreenUpdating = True
.DisplayAlerts = True
.EnableEvents = True
.Calculation = xlManual
.Visible = True
End With
End Sub
Function GetCsvFData(ByVal filePath As String) As Variant
Dim MyData As String, strData() As String
Open filePath For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
GetCsvFData = MyData
End Function
Function TransposeArrays1D(ByVal arr As Variant) As Variant
Dim tempArray As Variant
ReDim tempArray(LBound(arr, 1) To UBound(arr, 1), LBound(arr(0)) To UBound(arr(0)))
For y = LBound(arr, 1) To UBound(arr, 1)
For x = LBound(arr(0)) To UBound(arr(0))
tempArray(y, x) = arr(y)(x)
Next x
Next y
TransposeArrays1D = tempArray
End Function
I need to combine workbooks from a folder, and I found the below code which should do exactly what I need. The code is from here.
The issue I am encountering, that the worksheets in my workbooks all have the same long title, and it seems to crash the Sub as excel can't auto rename the sheets due to conflict (e.g. there is no room to append with (2) and (3) etc.).
How can I add onto the code to rename the sheets something arbitrary, e.g. Copied1, Copied 2, etc... ?
Sub MergeWorkbooks()
Dim FolderName As String
Dim directory As String, fileName As String
Dim wb1 As Workbook, wb2 As Workbook
Dim ws As Worksheet
Set wb1 = Workbooks.Add
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder."
.AllowMultiSelect = False
.Show
On Error Resume Next
FolderName = .SelectedItems(1)
Err.Clear
On Error GoTo 0
End With
directory = FolderName & "\"
fileName = Dir(directory & "*.xls?")
Do While fileName <> ""
Set wb2 = Workbooks.Open(directory & fileName)
For Each ws In wb2.Sheets
ws.Copy after:=wb1.Sheets(Sheets.Count)
Next ws
wb2.Close savechanges:=False
fileName = Dir
Loop
End Sub
Use variable i to rename your sheets before moving them to your other book. The i corresponds to the book the sheet came from in your loop.
So the 5th book will have a sheet name of Sheet1 5 and the 6th book will be Sheet1 6 and so on for every sheet in every book.
Dim i As Long
i = 1
Do While Filename <> ""
Set wb2 = Workbooks.Open(directory & Filename)
For Each ws In wb2.Sheets
ws.Name = ws.Name & Chr(32) & i '<-- Rename
ws.Copy after:=wb1.Sheets(Sheets.Count)
Next ws
wb2.Close savechanges:=False
Filename = Dir
i = i + 1 '<-- Increment i for next bok
Loop
This will only work if the code is ran once - If you try to re-run the code on the same books with similar names, the index i will have already been used. If this is a problem, you can rename the sheets to corrospond with the number of sheets that are on the book (wb1.Sheets.Count)
Building off of urdearboy's response, I added user prompts to choose whether a batch rename is wanted, and if it is, to choose the batch name. It's nice to have the option when needed!
Sub MergeWorkbooks()
Dim FolderName As String
Dim directory As String, fileName As String
Dim wb1 As Workbook, wb2 As Workbook
Dim ws As Worksheet
Dim iAnswer As VbMsgBoxResult
Dim xAppend As String
Set wb1 = Workbooks.Add
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder."
.AllowMultiSelect = False
.Show
On Error Resume Next
FolderName = .SelectedItems(1)
Err.Clear
On Error GoTo 0
End With
directory = FolderName & "\"
fileName = Dir(directory & "*.xls?")
'Prompt user to decide if batch rename is required
iAnswer = MsgBox("Would you like to batch rename the worksheets?", vbYesNoCancel + vbQuestion + vbDefaultButton1, "Sort Worksheets")
'vbYes: Rename Worksheets
If iAnswer = vbYes Then
1:
xAppend = InputBox(Prompt:= _
"Enter new batch name for worksheets." _
& vbNewLine & vbNewLine & _
"Sheets will be appended with number based on the order in which they are copied." _
& vbNewLine & vbNewLine & _
"If 'Cancel' is selected, worksheets will be renamed as number only, based on order in which they are copied.", _
Title:="Naming Convention")
If InStr(xAppend, "<") > 0 _
Or InStr(xAppend, ">") > 0 _
Or InStr(xAppend, ":") > 0 _
Or InStr(xAppend, Chr(34)) > 0 _
Or InStr(xAppend, "/") > 0 _
Or InStr(xAppend, "\") > 0 _
Or InStr(xAppend, "|") > 0 _
Or InStr(xAppend, "?") > 0 _
Or InStr(xAppend, "*") > 0 _
Then
MsgBox "Suggested filename contains an invalid character"
GoTo 1
End If
Dim i As Long
i = 1
Do While fileName <> ""
Set wb2 = Workbooks.Open(directory & fileName)
For Each ws In wb2.Sheets
ws.Name = xAppend & i '<-- Rename
ws.Copy after:=wb1.Sheets(Sheets.Count)
Next ws
wb2.Close savechanges:=False
fileName = Dir
i = i + 1 '<-- Increment i for next bok
Loop
'vbNo: Rename Worksheets
ElseIf iAnswer = vbNo Then
Do While fileName <> ""
Set wb2 = Workbooks.Open(directory & fileName)
For Each ws In wb2.Sheets
ws.Copy after:=wb1.Sheets(Sheets.Count)
Next ws
wb2.Close savechanges:=False
fileName = Dir
Loop
'vb Canel: Exit
Else
Exit Sub
End If
End Sub
I have several excel files in folder & want to rename only specific sheets of every file in the folder which contains
viz. GTLB, SALARY, GROC
Every file has a single sheet of above characters, other sheets have different names.
So, if sheet name contains above characters then change it to GROCERY.
thanks in advance
Try using this it will loop through the folder try finding files (excel files) and try looking for the strings in files that have been specified and if match found change the name.
Sub LoopThroughFiles()
'loops through all files in a folder
Dim MyObj As Object, MySource As Object, file As Variant
Dim wbk As Workbook
Dim path As String
Dim st As String
file = Dir("H:\TestCopy\testing\") 'file name
path = "H:\TestCopy\testing\" 'directory path
While (file <> "")
Set wbk = Workbooks.Open("H:\TestCopy\testing\" & file)
MsgBox "found " & file
' path = path & file 'path and filename
Call newloopTrhoughBooks
wbk.Save
wbk.Close
' Call loop_through_all_worksheets(path)
file = Dir
Wend
End Sub
Sub newloopTrhoughBooks()
Dim book As Workbook, sheet As Worksheet, text As String, text1 As String
Dim logic_string As String
Dim logic_string2 As String
Dim logic_string3 As String
logic_string = "GTLB"
logic_string2 = "SALARY"
logic_string3 = "GROC"
For Each book In Workbooks
text = text & "Workbook: " & book.Name & vbNewLine & "Worksheets: " & vbNewLine
For Each sheet In book.Worksheets
text = text & sheet.Name & vbNewLine
text1 = sheet.Name
If StrComp(logic_string, text1) = 1 Or StrComp(logic_string2, text1) = 1 Or StrComp(logic_string3, text1) = 1 Then 'compare file name
ActiveSheet.Name = text1
ActiveSheet.Name = "Change1"
End If
Next sheet
text = text & vbNewLine
Next book
MsgBox text
End Sub
Sub RenameSheets()
Dim MyFolder As String
Dim MyFile As String
Dim wbname As String
MyFolder = "E:\SSS\File Name"
MyFile = Dir(MyFolder & "\*.xls")
Application.ScreenUpdating = False
Do While MyFile <> ""
Workbooks.Open Filename:=MyFolder & "\" & MyFile
With ActiveWorkbook
wbname = "GROCERY"
'For giving filename to sheet1
'Left(.Name, InStr(.Name, ".") - 1)
For Each sheet In ActiveWorkbook.Sheets
If LCase(sheet.Name) Like "*salary*" Or LCase(sheet.Name) Like "*gtlb*" Or LCase(sheet.Name) Like "*groc*" Then
MsgBox "Found! " & sheet.Name
.Sheets(sheet.Name).Name = wbname
.Close savechanges:=True
End If
Next
'.Sheets(1).Name = wbname
'.Close savechanges:=True
End With
MyFile = Dir
Loop
Application.ScreenUpdating = True
End Sub
Sub Merger()
Dim wb As Workbook, sh As Worksheet, fPath As String, fName As String
Set sh = ThisWorkbook.Sheets(1)
fPath = ThisWorkbook.Path 'If files are in a different directory than master, replace path here
If Right(fPath, 1) <> "\" Then fPath = fPath & "\" 'Make sure separator is on end of path
fName = Dir(fPath & "*.xl*") 'get all Excel files in directory
Do
If fName <> ThisWorkbook.Name Then
Set wb = Workbooks.Open(fPath & fName)
With wb.Sheets(1)
If Application.CountA(.Rows(2)) > 0 Then
.UsedRange.Offset().Copy sh.Cells(Rows.Count, 1).End(xlUp)(2)
End If
End With
wb.Close False
End If
fName = Dir
Loop While fName <> ""
ActiveCell.Offset(-34, -7).Range("A1:T1").Select
ActiveCell.FormulaR1C1 = _
"hb_golden_1154317527.txt)"
ActiveCell.Offset(29, 0).Range("A1").Select
End Sub
Like I said I would to insert A1 into each Consecutive line of data not sure where to start.
sample file for excel merged