VBA always crash on Excel 2010 - excel

I have some code that I make using Excel 2013. It works perfectly and when I try to run it on Excel 2010, the excel always does not respond, restarting the program and closing. I try to reopen it and the file sometimes goes with read-only or recovery mode so I can't even run my macro even I enable it.
Is there any way to fix this without updating the excel? any ideas?
NB: the laptop with Excel 2010 is not mine, it's my user laptop so if possible, I prefer to not change anything inside the laptop
here's the code
Public Const paramFolderPath = "C:\Users\Documents\Data"
Sub Sheet1()
Application.ScreenUpdating = False
OpenWorkbooks paramFolderPath 'Path collected from the folder parameter
Application.ScreenUpdating = True
End Sub
Sub OpenWorkbooks(sourceFolder As Variant)
Dim sourceFile As String 'Filename obtained by DIR function
Dim masterWb, Sourcewb As Workbook 'Used to loop through each workbook
Dim ext As String
On Error Resume Next
Application.ScreenUpdating = False
Set masterWb = ThisWorkbook
sourceFile = Dir(sourceFolder & "\") 'DIR gets the first file of the folder
Do While sourceFile <> ""
ext = Right(sourceFile, Len(sourceFile) - InStrRev(sourceFile, "."))
If sourceFile <> ThisWorkbook.Name And (ext = "xlsm" Or ext = "xlsx") Then
Workbooks.Open Filename:=sourceFolder & "\" & sourceFile, ReadOnly:=True
Set Sourcewb = ActiveWorkbook
'Copy only the first sheet of a workbook
Sourcewb.Worksheets(1).Copy after:=masterWb.Sheets(masterWb.Worksheets.Count)
'Close the source workbook
Sourcewb.Close SaveChanges:=False
Set Sourcewb = Nothing
End If
sourceFile = Dir 'DIR gets the next file in the folder
Loop
On Error GoTo 0
Application.ScreenUpdating = True
End Sub

Loop Through Files in a Folder
Option Explicit
Public Const paramFolderPath = "C:\Users\Documents\Data"
Sub GetFirstWorkSheets()
ImportFirstWorksheets paramFolderPath
End Sub
Sub ImportFirstWorksheets(ByVal sFolderPath As String)
Const ProcName As String = "ImportFirstWorksheets"
Dim fCount As Long
Dim wbCount As Long
Dim wsCount As Long
On Error GoTo ClearError
Const ExtensionsList As String = "xlsm,xlsx"
' Check if files in folder.
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
Dim sFileName As String: sFileName = Dir(sFolderPath)
If Len(sFileName) = 0 Then
MsgBox "No files found in '" & sFolderPath & "'.", _
vbExclamation, ProcName
Exit Sub
End If
Dim Extensions() As String: Extensions = Split(ExtensionsList, ",")
Dim dwb As Workbook: Set dwb = ThisWorkbook
Dim dwbPath As String: dwbPath = dwb.FullName
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim swb As Workbook
Dim Ext As String
Dim sFilePath As String
Do While Len(sFileName) > 0
fCount = fCount + 1
Ext = Right(sFileName, Len(sFileName) - InStrRev(sFileName, "."))
If IsNumeric(Application.Match(Ext, Extensions, 0)) Then
wbCount = wbCount + 1
sFilePath = sFolderPath & sFileName
If StrComp(sFilePath, dwbPath, vbTextCompare) <> 0 Then
Application.DisplayAlerts = False
On Error GoTo WbError
Set swb = Workbooks.Open(sFilePath, , True)
On Error GoTo ClearError
Application.DisplayAlerts = True
End If
If Not swb Is Nothing Then
If swb.Worksheets.Count > 0 Then ' only first worksheet
wsCount = wsCount + 1
swb.Worksheets(1).Copy After:=dwb.Sheets(dwb.Sheets.Count)
End If
swb.Close SaveChanges:=False
Set swb = Nothing
End If
End If
sFileName = Dir ' next file in folder
Loop
SafeExit:
On Error Resume Next
If Not Application.EnableEvents Then
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
MsgBox "Files Found: " & fCount & vbLf _
& "Workbooks Found: " & wbCount & vbLf _
& "Worksheets Copied: " & wsCount, vbInformation, ProcName
On Error GoTo 0
Exit Sub
WbError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume Next
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume SafeExit
End Sub

Related

VBA Opening Save Window Despite Events and Alerts Being Off

All I am trying to do is save one sheet out of the workbook to a new workbook in the same folder.
But every time I run my code, excel interrupts the execution and opens up the Save As window where you have to select the folder and name of the file, which I have never seen before.
Any Ideas on how to circumvent this? I have Events and Alerts off.
Code:
Sub Export_Data()
Dim ws As Worksheet, wb As Workbook
Dim name As String
Dim lcol As Double, lrow As Double
Dim path As String
Set ws = ThisWorkbook.Worksheets("EMPLOYEES")
Application.DisplayAlerts = False
Application.EnableEvents = False
path = "C:\Users\PATH\"
Set wb = Workbooks.Add
ws.Copy Before:=wb.Sheets(1)
On Error Resume Next ' Need this because I get a runtime error 1004, though it still saves it regardless
wb.SaveAs Filename:=path & "People_Data" & ".xlsx", FileFormat:=51 '''' Here is where it opens the save as window??????
wb.Sheets("Sheet1").Delete
wb.Close SaveChanges:=True
Application.DisplayAlerts = True
Application.EnableEvents = True
End Sub
Save a Worksheet to a New Workbook
If nothing else, this should shed some light on what's going on. Your feedback is expected.
Sub SaveWorksheetToNewWorkbook()
Const ProcName As String = "SaveWorksheetToNewWorkbook"
Dim Success As Boolean
On Error GoTo ClearError
Const SOURCE_WORKSHEET_NAME As String = "EMPLOYEES"
Const DESTINATION_FOLDER_PATH As String = "C:\Test"
Const DESTINATION_FILE_NAME As String = "People_Data.xlsx"
Application.ScreenUpdating = False
' Check if the destination path exists.
Dim pSep As String: pSep = Application.PathSeparator
Dim dFolderPath As String: dFolderPath = DESTINATION_FOLDER_PATH
If Right(dFolderPath, 1) <> pSep Then dFolderPath = dFolderPath & pSep
Dim dFolderName As String: dFolderName = Dir(dFolderPath, vbDirectory)
If Len(dFolderName) = 0 Then
MsgBox "The path '" & dFolderPath & "' doesn't exist.", _
vbExclamation, ProcName
Exit Sub
End If
Dim dwb As Workbook
' Check if the destination workbook, or a workbook with the same name,
' is open.
On Error Resume Next
Set dwb = Workbooks(DESTINATION_FILE_NAME)
On Error GoTo ClearError
If Not dwb Is Nothing Then
If StrComp(dwb.Path & pSep, dFolderPath, vbTextCompare) = 0 Then
MsgBox "The destination workbook '" & DESTINATION_FILE_NAME _
& "' is open." & vbLf & "Close it and try again.", _
vbExclamation, ProcName
Else
MsgBox "A workbook with the same name as the destination file ('" _
& DESTINATION_FILE_NAME & "') is open." _
& vbLf & "Close it and try again.", vbExclamation, ProcName
End If
Exit Sub
End If
' Export the worksheet.
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = swb.Worksheets(SOURCE_WORKSHEET_NAME)
sws.Copy ' creates a copy as a new single-worksheet workbook
Set dwb = Workbooks(Workbooks.Count)
Dim ErrNumber As Long
Dim ErrDescription As String
Application.DisplayAlerts = False ' overwrite without confirmation
On Error Resume Next
dwb.SaveAs dFolderPath & DESTINATION_FILE_NAME
ErrNumber = Err.Number
ErrDescription = Err.Description
On Error GoTo ClearError
Application.DisplayAlerts = True
dwb.Close SaveChanges:=False ' just got saved
If ErrNumber <> 0 Then
MsgBox "' Run-time error '" & ErrNumber & "':" & vbLf _
& ErrDescription & vbLf & vbLf _
& "This error occurred while attempting to save the workbook.", _
vbCritical, ProcName
Exit Sub
End If
Success = True
ProcExit:
On Error Resume Next
If Success Then
MsgBox "Worksheet saved to new workbook.", vbInformation, ProcName
End If
On Error GoTo 0
Exit Sub
ClearError:
MsgBox "' Run-time error '" & Err.Number & "':" & vbLf _
& Err.Description & vbLf & vbLf _
& "This error occurred quite unexpectedly.", _
vbCritical, ProcName
Resume ProcExit
End Sub

runtime Error 9 when opening excel workbook in a folder to copy specific sheet

I need help to handle runtime error 9.
My goals is to create a new workbook that compile specific sheet (Master User) from all excel workbook in a folder.
I'm stuck while using "on error goto" because i don't get it how to set the program while error (sheet doesn't exist) goto next workbook.
My code now cause me stuck in an never ending loop on a workbook that didn't have "master user" sheet
Sub Master()
Dim MyFiles As String
Dim Path As String
Dim myExtension As String
Dim Filename As String
Workbooks.Add.SaveAs Filename:="Master", FileFormat:=51
Path = "D:\My Document\"
myExtension = "*.xls*"
MyFiles = Dir(Path & myExtension)
On Error GoTo test
DoAgain:
Do While MyFiles <> ""
Workbooks.Open (Path & MyFiles)
Sheets("master user").Select
ActiveSheet.Rows(1).Copy
Workbooks("Master.xlsx").Activate
Sheets.Add After:=Sheets(Sheets.Count)
Range("A1").PasteSpecial xlPasteAll
If InStr(MyFiles, ".") > 0 Then
Filename = Left(MyFiles, InStr(MyFiles, ".") - 1)
End If
ActiveSheet.Name = Filename
Workbooks(Filename).Activate
Application.CutCopyMode = False
ActiveWorkbook.Close SaveChanges:=False
MyFiles = Dir
Loop
Workbooks("Master.xlsx").Activate
ActiveWorkbook.Close SaveChanges:=True
test:
ActiveWorkbook.Close SaveChanges:=False
Resume DoAgain
ActiveWorkbook.Save
End Sub
Copy Worksheet Ranges From Multiple Workbooks to a New Workbook
The Workbooks
The workbook containing this code (ThisWorkbook).
The source workbook i.e. each workbook (file) found in the source folder.
The destination workbook i.e. a newly added workbook that will be copied to.
Description
This will copy the first row of a same-named worksheet of each workbook (file) found in a folder to a newly added (and renamed) worksheet (multiple) of a new workbook (one).
Option Explicit
Sub CreateMaster()
Const ProcName As String = "CreateMaster"
On Error GoTo ClearError
' Source
Const sFolderPath As String = "D:\My Document\" ' maybe a missing 's'?
Const sFilePattern As String = "*"
Const sExtensionPattern As String = ".xls*"
Const swsName As String = "Master User"
' Destination
Const dFileName As String = "Master.xlsx"
' You never mentioned the destination path ('Master.xlsx') so I chose
' the same path as the path of the workbook containing this code.
' Omitting this path will lead to unexpected results (errors).
Dim dFilePath As String: dFilePath = ThisWorkbook.Path & "\"
Dim dFileFormat As XlFileFormat: dFileFormat = xlOpenXMLWorkbook
' Check if the source folder exists.
If Len(Dir(sFolderPath, vbDirectory)) = 0 Then
MsgBox "The folder '" & sFolderPath & "' doesn't exist.", _
vbCritical, ProcName
Exit Sub
End If
' Return the paths of the files of the source folder in a collection.
Dim sFilePaths As Collection
Set sFilePaths = CollFilePaths(sFolderPath, sFilePattern, sExtensionPattern)
If sFilePaths Is Nothing Then ' no files found
MsgBox "No '" & sExtensionPattern & "'- files found in folder '" _
& sFolderPath & "'.", vbCritical, ProcName
Exit Sub
End If
Application.ScreenUpdating = False
Dim swb As Workbook
Dim sws As Worksheet
Dim sFilePath As Variant
Dim dwb As Workbook
Dim dws As Worksheet
Dim dwbCreated As Boolean
' Loop through the elements (file paths) of the collection.
For Each sFilePath In sFilePaths
Set swb = Workbooks.Open(sFilePath)
' Attempt to create a reference to the source worksheet.
On Error Resume Next
Set sws = swb.Worksheets(swsName)
On Error GoTo ClearError
If Not sws Is Nothing Then ' source worksheet exists
' Add a new worksheet/workbook.
If dwbCreated Then ' destination workbook created
Set dws = dwb.Worksheets _
.Add(After:=dwb.Sheets(dwb.Sheets.Count))
Else ' destination workbook not created
Set dwb = Workbooks.Add(xlWBATWorksheet) ' one worksheet
Set dws = dwb.Worksheets(1)
dwbCreated = True
End If
' Attempt to rename the destination worksheet.
On Error Resume Next
dws.Name = Left(swb.Name, InStrRev(swb.Name, ".") - 1)
On Error GoTo ClearError
' Copy source to destination.
sws.Rows(1).Copy dws.Rows(1)
Set sws = Nothing
'Else ' source worksheet doesn't exist
End If
swb.Close SaveChanges:=False
Next sFilePath
If dwbCreated Then
dwb.Worksheets(1).Activate
Application.DisplayAlerts = False ' overwrite without confirmation
dwb.SaveAs dFilePath & dFileName, dFileFormat
Application.DisplayAlerts = True
dwb.Close
MsgBox "Master created.", vbInformation, ProcName
Else
MsgBox "Non of the opened workbooks contained a worksheet " _
& "named '" & swsName & "'.", vbExclamation, ProcName
End If
Application.ScreenUpdating = False
ProcExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the paths of the files of a folder in a collection.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function CollFilePaths( _
ByVal FolderPath As String, _
Optional ByVal FilePattern As String = "*", _
Optional ByVal ExtensionPattern As String = "*") _
As Collection
Const ProcName As String = "CollFilePaths"
On Error GoTo ClearError
Dim pSep As String: pSep = Application.PathSeparator
Dim foPath As String: foPath = FolderPath
If Right(foPath, 1) <> pSep Then foPath = foPath & pSep
Dim ePattern As String: ePattern = ExtensionPattern
If Left(ePattern, 1) <> "." Then ePattern = "." & ePattern
Dim fiName As String: fiName = Dir(foPath & FilePattern & ePattern)
If Len(fiName) = 0 Then Exit Function
Dim coll As Collection: Set coll = New Collection
Do Until Len(fiName) = 0
coll.Add foPath & fiName
fiName = Dir
Loop
Set CollFilePaths = coll
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Function

Efficient way to copy images and data from multiple source workbook to a single workbook

I have the following code to copy images from one workbook to another. The code opens the source workbook/sheet, copies the image then closes the workbook. This process repeats multiple times. Is there a more efficient way to do this? maybe bypassing the clipboard?
I only need to copy 1 image(named "Picture 4") and 2-3 cell values per source workbook/sheet. I have 7-8 source workbook.
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS1.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("B7").PasteSpecial
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS2.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("G8").PasteSpecial
So the fast solution is here:
Turn off Screen Updating and then turn it on again afterwards, I implemented some time measurement in my code to visualize this:
Option Explicit
Sub copy_images_original()
Dim dstWS As Worksheet
Set dstWS = ThisWorkbook.Sheets(1)
Dim srcWB As Workbook
Dim srcWS As Worksheet
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS1.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("B7").PasteSpecial
srcWB.Close
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS2.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("G8").PasteSpecial
srcWB.Close
End Sub
Sub CalculateRunTime_Seconds()
'PURPOSE: Determine how many seconds it took for code to completely run
'SOURCE: www.TheSpreadsheetGuru.com/the-code-vault
Dim StartTime As Double
Dim SecondsElapsed As Double
'Remember time when macro starts
StartTime = Timer
'*****************************
Call turn_app_off
Call copy_images_original
Call turn_app_on
'*****************************
'Determine how many seconds code took to run
SecondsElapsed = Round(Timer - StartTime, 2)
'Notify user in seconds
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Sub turn_app_off()
With Application
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
End Sub
Sub turn_app_on()
With Application
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub
What has now improved?
Your srcWBs will now be closed, your original source code didnt do that.
In my scenario here, the execution time improved from 2 Secs to 1,4 Secs.
So your Code runs 25% faster without much effort.
Hope you find my suggestion fair enough.
With best regards
Create a Report
I was assuming that the destination workbook and the workbook containing this code, ThisWorkbook, are the same.
Adjust the values in the constants section.
Run only the createReport procedure. The function getFilePathsInFolder is being called by it.
Since ThisWorkbook will not have an "xlsx" extension, the statement If StrComp(FilePaths(fp), dstFilePath, vbTextCompare) <> 0 Then is redundant, but I'm leaving it because you might one day change the file extension to "xls*" when the code could do some damage.
Abstract
It will look in the specified folder and write all .xlsx files to an array. It will loop through the array and open each workbook to copy the picture, specified by its index, and paste it and write the specified cell values, to the specified locations of the destination workbook, closing each source workbook afterwards.
The Code
Option Explicit
Sub createReport()
Const ProcName As String = "createReport"
On Error GoTo clearError
' Source
Const Extension As String = "xlsx"
Const srcName As String = "sheetwithimage"
Const srcList As String = "A1,A2,A3" ' add more
Const picIndex As Long = 1
' Destination
Const dstName As String = "Sheet1"
Const dstList As String = "B1,B2,B3" ' add more
Const picAddress As String = "B7"
Const colOffset As Long = 5
' Write file paths from Source Folder Path to File Paths array.
Dim wbDst As Workbook: Set wbDst = ThisWorkbook
Dim srcFolderPath As String: srcFolderPath = wbDst.Path
Dim FilePaths As Variant
FilePaths = getFilePathsInFolder(srcFolderPath, Extension)
Dim srcCells() As String: srcCells = Split(srcList, ",")
Dim dstCells() As String: dstCells = Split(dstList, ",")
' Use a variable for lower and upper if inside another loop.
' Split ensures that lower is 0, so no need for lower variable.
Dim CellsUB As Long: CellsUB = UBound(srcCells) ' or 'Ubound(dstCells)'
Dim dst As Worksheet: Set dst = wbDst.Worksheets(dstName)
Dim dstFilePath As String: dstFilePath = wbDst.FullName
' Declare new variables occurring in the following loop.
Dim wbSrc As Workbook
Dim src As Worksheet
Dim srcCount As Long
Dim fp As Long
Dim n As Long
Application.ScreenUpdating = False
' We don't care if 'FilePaths' is zero, one or five-based, since we
' cannot use fp because of 'ThisWorkbook'; hence 'srcCount'.
For fp = LBound(FilePaths) To UBound(FilePaths)
' We have to skip 'ThisWorkbook'. Using 'StrComp' with 'vbTextCompare'
' is a great way for comparing strings case-insensitively i.e. 'A=a'.
' '0' means it is a match.
If StrComp(FilePaths(fp), dstFilePath, vbTextCompare) <> 0 Then
Set wbSrc = Workbooks.Open(FilePaths(fp), True, True)
Set src = wbSrc.Worksheets(srcName)
src.Pictures(picIndex).Copy
dst.Range(picAddress).Offset(, srcCount * colOffset).PasteSpecial
For n = 0 To CellsUB ' 'Split'
dst.Range(dstCells(n)).Offset(, srcCount * colOffset).Value _
= src.Range(srcCells(n)).Value
Next n
wbSrc.Close SaveChanges:=False
srcCount = srcCount + 1
End If
Next fp
' Save and/or inform user.
If srcCount > 0 Then
dst.Range("A1").Select
wbDst.Save
Application.ScreenUpdating = True
If srcCount = 1 Then
MsgBox "Data from 1 workbook transferred.", vbInformation, "Success"
Else
MsgBox "Data from " & srcCount & " workbooks transferred.", _
vbInformation, "Success"
End If
Else
MsgBox "No matching workbooks found in folder '" & srcFolderPath _
& "'!", vbCritical, "Fail"
End If
ProcExit:
Exit Sub
clearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
Function getFilePathsInFolder( _
FolderPath As String, _
Optional ByVal ExtensionPattern As String = "", _
Optional ByVal FirstIndex As Long = 0) _
As Variant
Const ProcName As String = "listFilePathsInFolder"
On Error GoTo clearError
With CreateObject("Scripting.FileSystemObject")
Dim fsoFolder As Object
Set fsoFolder = .GetFolder(FolderPath)
Dim FilesCount As Long
FilesCount = fsoFolder.Files.Count
If FilesCount > 0 Then
Dim n As Long
n = FirstIndex - 1
Dim OneD As Variant
ReDim OneD(FirstIndex To FilesCount + n)
Dim fsoFile As Object
If ExtensionPattern = "" Then
For Each fsoFile In fsoFolder.Files
n = n + 1
OneD(n) = fsoFile.Path
Next fsoFile
getFilePathsInFolder = OneD
Else
For Each fsoFile In fsoFolder.Files
If LCase(.GetExtensionName(fsoFile)) _
Like LCase(ExtensionPattern) Then
n = n + 1
OneD(n) = fsoFile.Path
End If
Next fsoFile
If n > FirstIndex - 1 Then
ReDim Preserve OneD(FirstIndex To n)
getFilePathsInFolder = OneD
Else
Debug.Print "'" & ProcName & "': " _
& "No '" & ExtensionPattern & "'-files found."
End If
End If
Else
Debug.Print "'" & ProcName & "': " _
& "No files found."
End If
End With
ProcExit:
Exit Function
clearError:
Debug.Print "'" & ProcName & "': Unexpected error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function

VBA Loop directory removing (by sheet name) all sheets but one from each workbook

I have previously posted on here about using VBA to loop through a folder and remove known passwords from each workbook therein. Thought I could use the same code and just insert code the removes all sheets except one (by reference to sheet name), but no such luck.
Any VBA pros out there that can help?
Sub loop_sheets_del()
Dim MyFile as String, str As String, MyDir = "[directory]"
MyFile = Dir(MyDir & "*.xlsx")
ChDir MyDir
Application.ScreenUpdating = 0
Application.DisplayAlerts = 0
Do While Myfile <> ""
Workbooks.Open (MyFile)
If ws.Name <> "name of sheet to keep" Then
ws.Delete
End If
Next ws (error indicates problem is here)
ActiveWorkbook.Close True
End With
MyFile = Dir()
Loop
End Sub
Delete Sheets
In the current setup, the following will delete all sheets except the one named Master in all files with the xls* extension (e.g. xls, xlsx, xlsm: do not use wild characters in the code; it is covered by Instr) in the specified folder F:\Test\2020\64504925 and all of its subfolders.
The Code
Option Explicit
' Run only this sub after you have adjusted the path, the worksheet name
' and the file extension.
Sub loopSubFolders()
Application.ScreenUpdating = False
loopSubFoldersInitialize "F:\Test\2020\64504925", "Master", "xls"
Application.ScreenUpdating = True
MsgBox "Sheets deleted.", vbInformation, "Success"
End Sub
Sub loopSubFoldersInitialize(ByVal FolderPath As String, _
ByVal SheetName As String, _
Optional ByVal FileExtension As String = "")
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
loopSubFoldersRecursion fso, fso.GetFolder(FolderPath), SheetName, _
FileExtension
End Sub
Sub loopSubFoldersRecursion(fso As Object, _
fsoFolder As Object, _
ByVal SheetName As String, _
Optional ByVal FileExtension As String = "")
Dim fsoSubFolder As Object
Dim fsofile As Object
For Each fsoSubFolder In fsoFolder.SubFolders
loopSubFoldersRecursion fso, fsoSubFolder, SheetName, FileExtension
Next
If FileExtension = "" Then
For Each fsofile In fsoFolder.Files
'Debug.Print fsofile.Path
Next
Else
For Each fsofile In fsoFolder.Files
If InStr(1, fso.GetExtensionName(fsofile.Path), _
FileExtension, vbTextCompare) > 0 Then
Dim wb As Workbook
Set wb = Workbooks.Open(fsofile.Path)
deleteSheetsExceptOneByName wb, SheetName
Debug.Print fsofile.Path
wb.Close SaveChanges:=True
End If
Next fsofile
End If
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Deletes all sheets in a workbook except the one specified
' by its name.
' Remarks: The code uses the dictionary to hold all the sheet names.
' Only if the specified sheet exists, it will be removed from
' the dictionary and the remaining sheets in it will be deleted
' in one go. Otherwise no action will be taken.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function deleteSheetsExceptOneByName(Book As Workbook, _
ByVal SheetName As String) _
As Long
' Initialize error handling.
Const ProcName As String = "deleteSheetsExceptOneByName"
On Error GoTo clearError ' Turn on error trapping.
' Validate workbook.
If Book Is Nothing Then
GoTo NoWorkbook
End If
' Define dictionary.
With CreateObject("Scripting.Dictionary")
.CompareMode = vbTextCompare
' Write sheet names to dictionary.
Dim sh As Object
For Each sh In Book.Sheets
.Add sh.Name, Empty
Next sh
' Validate sheet name string.
If Not .Exists(SheetName) Then
GoTo NoSheet
End If
' Remove sheet name string from the dictionary.
.Remove (SheetName)
' Validate number of sheets.
If .Count = 0 Then
GoTo OneSheet
End If
' Delete sheets.
Application.DisplayAlerts = False
Book.Sheets(.Keys).Delete
Application.DisplayAlerts = True
deleteSheetsExceptOneByName = .Count
GoTo SheetsDeleted
End With
NoWorkbook:
Debug.Print "'" & ProcName & "': No workbook ('Nothing')."
GoTo ProcExit
NoSheet:
Debug.Print "'" & ProcName & "': No sheet named '" & SheetName _
& "' in workbook."
GoTo ProcExit
OneSheet:
Debug.Print "'" & ProcName & "': Sheet '" & Book.Sheets(SheetName).Name _
& "' is the only sheet in workbook."
GoTo ProcExit
SheetsDeleted:
If deleteSheetsExceptOneByName > 1 Then
Debug.Print "'" & ProcName & "': Deleted " _
& deleteSheetsExceptOneByName & " sheets in workbook."
Else
Debug.Print "'" & ProcName & "': Deleted 1 sheet in workbook."
End If
GoTo ProcExit
clearError:
Debug.Print "'" & ProcName & "': " & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
On Error GoTo 0 ' Turn off error trapping.
GoTo ProcExit
ProcExit:
End Function
You're missing the first part of the requisite For Each loop.
Also best to use a Workbook variable to refer to each workbook being opened and modified:
Do While Myfile <> ""
Dim MyWB As Workbook
Set MyWB = Workbooks.Open(MyFile)
For Each ws in MyWB.Worksheets
If ws.Name <> "name of sheet to keep" Then
ws.Delete
End If
Next
myWB.Close True
MyFile = Dir
Loop
Just for the sake of completeness I added the code and checked if the sheet to be kept exists so in case it doesn't, there isn't an error raised.
Read the code's comments.
Public Sub DeleteSheetsExceptInFiles()
Dim targetFile As String
Dim targetDirectory As String
Dim keepSheetName As String
Dim str As String
' Basic error handling
On Error GoTo CleanFail
' Define directory, file and sheet name
targetDirectory = "C:\Temp\"
targetFile = Dir(targetDirectory & "*.xlsx")
keepSheetName = "name of sheet to keep"
' Speed up process
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' Loop through files
Do While targetFile <> ""
Dim targetWorkbook As Workbook
Set targetWorkbook = Workbooks.Open(targetDirectory & targetFile)
' Check if sheet to keep exists
Dim targetSheet As Worksheet
Dim keepSheetExists As Boolean
On Error Resume Next
keepSheetExists = targetWorkbook.Worksheets(keepSheetName)
On Error GoTo CleanFail
' Proceed if sheet exists
If keepSheetExists = True Then
For Each targetSheet In targetWorkbook.Worksheets
' Delete all sheets except the one to keep
If targetSheet.Name <> keepSheetName Then
targetSheet.Delete
End If
Next targetSheet
End If
targetWorkbook.Close True
targetFile = Dir()
Loop
CleanExit:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Exit Sub
CleanFail:
Debug.Print "Something went wrong: " & Err.Description
Resume CleanExit
End Sub

Fastest way to put files in a network folder / saveas or filecopy?

I want to save Excel files in both the local drive and in the network folder. Currently I am doing it with SaveAs (local) and another SaveAs (network), is it faster to do a SaveAs then FileCopy?
Code below:
Sub SaveAs()
Dim ws As Worksheet
Dim ws_console As Worksheet
Dim long_col_number As Long
Dim long_sheets_count As Long
Dim arr_sheet_names As Variant
Dim str_password As String
Dim str_datetoday As String
Dim str_datetoday_path As String
Dim str_datetoday_network_path As String
str_datetoday = Format(Date, "yyyy-mm-dd")
str_datetoday_path = "C:\Users\" & Environ("Username") & "\Desktop\Report\" & str_datetoday
str_datetoday_network_path = "\\servername\data\reports\US Reports Daily\" & str_datetoday
If Dir(str_datetoday_path, vbDirectory) = "" Then
MkDir (str_datetoday_path)
MsgBox "Making directory"
End If
If Dir(str_datetoday_network_path, vbDirectory) = "" Then
MkDir (str_datetoday_network_path)
End If
For Each ws In ThisWorkbook.Worksheets
If ws.CodeName = "AILD_01_Console" Then
Set ws_console = ws
Exit For
End If
Next ws
long_col_number = 0
For long_col_number = 1 To 8
long_sheets_count = Application.WorksheetFunction.CountA(ws_console.Range(Cells(16, long_col_number), Cells(24, long_col_number)))
arr_sheet_names = ws_console.Range(Cells(16, long_col_number), Cells(15 + long_sheets_count, long_col_number))
arr_sheet_names = Application.WorksheetFunction.Transpose(arr_sheet_names)
Worksheets(arr_sheet_names).Copy
ActiveWorkbook.SaveAs _
Filename:=str_datetoday_path & "\" & ws_console.Cells(15, long_col_number) & " - " & Format(Date, "yyyy-mm-dd"), _
FileFormat:=51
ActiveWorkbook.SaveAs _
Filename:=str_datetoday_network_path & "\" & ws_console.Cells(15, long_col_number), _
FileFormat:=51
ActiveWorkbook.Close False
Next long_col_number
ws_console.Activate
End Sub
Thank you very much for all the help.

Resources