I use the code below to create and open a folder from excel when I press a button but I want the created folder to be in the same location like the excel workbook. Can you please help me modif the code? Thank you!
Sub btn1_click()
Dim dir As String
Dim fso As Object
Dim path As String
path = Application.ActiveWorkbook.path
dir = ActiveCell.value
Set fso = CreateObject("scripting.filesystemobject")
If Not fso.folderexists(dir) Then
fso.createfolder (dir)
End If
Call Shell("explorer.exe" & " " & dir, vbNormalFocus)
End Sub
Create and Explore a Subfolder Using the Active Cell's Value
The code is written for any active cell so be a little careful how you use it to not end up with folders in the wrong places.
If you run it by using a button, you are ensuring that it will use the right cell since the active sheet is the one containing the button and containing the active cell.
Sub CreateActiveCellSubFolder()
Const ExploreIfSubFolderExists As Boolean = True
Dim ash As Object: Set ash = ActiveSheet ' it could be a chart
If ash Is Nothing Then ' no active sheet
MsgBox "No visible workbooks open.", _
vbCritical
Exit Sub
End If
If ash.Type <> xlWorksheet Then
MsgBox "The active sheet '" & ash.Name & "' is not a worksheet.", _
vbCritical
Exit Sub
End If
Dim wb As Workbook: Set wb = ash.Parent
If Len(wb.Path) = 0 Then
MsgBox "The workbook '" & wb.Name & "' containing the active sheet '" _
& ash.Name & "' has not been saved yet.", _
vbCritical
Exit Sub
End If
' If the active sheet is a worksheet, it has an active cell at any time,
' no matter what is selected.
Dim aCell As Range: Set aCell = ActiveCell
Dim SubFolderName As String: SubFolderName = CStr(ActiveCell.Value)
If Len(SubFolderName) = 0 Then
MsgBox "The cell '" & aCell.Address(0, 0) & "' is blank.", _
vbCritical
Exit Sub
End If
Dim SubFolderPath As String
SubFolderPath = wb.Path & Application.PathSeparator & SubFolderName
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists(SubFolderPath) Then
MsgBox "The folder '" & SubFolderName & "' already exists.", _
vbInformation
If Not ExploreIfSubFolderExists Then Exit Sub
Else
Dim ErrNum As Long
On Error Resume Next
fso.CreateFolder SubFolderPath
ErrNum = Err.Number
' If ErrNum > 0 Then
' Debug.Print "Run-time error '" & Err.Number & "': " _
' & Err.Description
' End If
On Error GoTo 0
If ErrNum = 0 Then
MsgBox "Created the folder '" & SubFolderName & "'.", _
vbInformation
Else
MsgBox "Could not create the folder '" & SubFolderName & "'.", _
vbCritical
Exit Sub
End If
End If
wb.FollowHyperlink SubFolderPath
End Sub
Related
I am in need of assistance in resolving an issue I have been experiencing when running certain codes, particularly the one listed below. While I comprehend why this error message may appear, I am unsure as to why it is occurring with this particular code. I have been receiving the 'expecting object to be local' error message and 'subscript out of range error message when no sheet with the name is declared in the, despite the code's purpose being to determine if the sheet is already present or not and create it if it does not exist.
I'll be thankful to those who would put a hand into this.
By the way, the code stops at the step of setting the WS.
Sub Check_Sheet_Exists()
Dim WS As Worksheet
Dim SheetName As String
SheetName = "ABCD"
' On Error Resume Next
Set WS = ThisWorkbook.Sheets(SheetName)
If WS Is Nothing Then
Sheets.Add before:=Sheets(Sheets.Count)
ActiveSheet.Name = SheetName
MsgBox "The sheet '" & SheetName & "' was created."
Else
MsgBox "The sheet '" & SheetName & "' already exists."
End If
End Sub
Code stuck here
Someone help me solve this issue, please.
Added an explicit Workbook reference, and cancelling the OERN as suggested by VBasic2008
Sub Check_Sheet_Exists()
Dim WS As Worksheet, wb As Workbook
Dim SheetName As String 'Use Const if the name is fixed...
SheetName = "ABCD"
Set wb = ThisWorkbook
On Error Resume Next 'ignore errors
Set WS = wb.Sheets(SheetName)
On Error GoTo 0 'stop ignoring errors
If WS Is Nothing Then
Set WS = wb.Worksheets.Add(before:=wb.Sheets(wb.Sheets.Count))
WS.Name = SheetName
MsgBox "The sheet '" & SheetName & "' was created."
Else
MsgBox "The sheet '" & SheetName & "' already exists."
End If
End Sub
Add Worksheet With Specific Name
Sub AddWorksheet()
On Error GoTo ClearError
Const PROC_TITLE As String = "Add Worksheet"
Const SHEET_NAME As String = "A\BCD"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Check if sheet name is taken.
Dim sh As Object
On Error Resume Next
Set sh = wb.Sheets(SHEET_NAME)
On Error GoTo ClearError
If Not sh Is Nothing Then
MsgBox "The sheet """ & SHEET_NAME & """ already exists.", _
vbExclamation, PROC_TITLE
Exit Sub
End If
' Add the worksheet.
Dim ws As Worksheet
Set ws = wb.Sheets.Add(Before:=wb.Sheets(wb.Sheets.Count)) ' before last
'Set ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count)) ' last
'Set ws = wb.Sheets.Add(Before:=wb.Sheets(1)) ' first
' Rename the worksheet.
Dim ErrNumber As Long, ErrDescription As String
' Atempt to rename.
On Error Resume Next
ws.Name = SHEET_NAME
ErrNumber = Err.Number
ErrDescription = Err.Description
On Error GoTo ClearError
' Invalid Sheet Name.
If ErrNumber <> 0 Then
Application.DisplayAlerts = False ' to delete without confirmation
ws.Delete
Application.DisplayAlerts = True
MsgBox "Run-time error '" & ErrNumber & vbLf & vbLf _
& ErrDescription & vbLf & vbLf & vbLf & PROC_TITLE & " Info" _
& vbLf & "The name """ & SHEET_NAME & _
""" is invalid. Worksheet not added.", vbCritical, PROC_TITLE
Exit Sub
End If
' Valid Sheet Name
MsgBox "The worksheet """ & SHEET_NAME & """ was added.", _
vbInformation, PROC_TITLE
ProcExit:
Exit Sub
ClearError:
MsgBox "Run-time error '" & Err.Number & vbLf & vbLf _
& Err.Description & vbLf & vbLf & vbLf & PROC_TITLE & " Info" _
& vbLf & "An unexpected error occurred.", _
vbCritical, PROC_TITLE
Resume ProcExit
End Sub
I have been working on my code to get the system to export specific sheet based only on what is visible in the system yet, for some reason I continue to struggle when it is trying to run the export with getting only the specified sheets to export. I know this has to be something simple that I am missing but I am unable to locate what that might be. Any assistance would be greatly appreciated.
Private Sub ExportSheets() 'saves all visible sheets as new xlsx files
Dim ws As Worksheet, wbNew As Workbook
Dim myWorksheets() As String 'Array to hold worksheet names to copy
Dim sFolderPath As String
Dim fs As Object
Dim FileName1 As String
Dim i As Integer
Set wbNew = Application.ThisWorkbook
FileName1 = Range("PMC_Name").Value
sFolderPath = wbNew.Path & "\" & FileName1 & " - Import Templates"
myWorksheets = Split("Chart of Accounts, Custom Mapping File, Custom Chart of Accounts,Conventional Default COA,Conventional Mapping File,CONV Chart of Accounts,HUD Chart of Accounts,Affordable Default COA,Affordable Mapping File,Entities,Properties,Floors,Units,Area Measurement,Tenants,Account Labels,Leases,Scheduled Charges,Tenant Beginning Balances,Vendors,Vendor Beginning Balances,Customers,Customer Beginning Balances,GL Beginning Balances,GL Detail,Bank Accounts,Budgets,Budgeting COA,Budgeting Conventional COA,Budgeting Affordable COA,Budgeting Job Positions,Budgeting Employee List,Budgeting Workers Comp,Expense Pools,Lease Recoveries,Index Code,Lease Sales,Option Types,Clause Types,Lease Clauses,Lease Options,Budgeting Current Budget Import,Job Cost,Draw Model Detail,Job Cost History,Job Cost Budgets,Fixed Assets,Condo Properties,Owners,Ownership Information,Ownership Billing,Owner Charges", ",") 'this contains an array of the sheets. You need to put the real sheet names here.
If Dir(sFolderPath, vbDirectory) <> "" Then
'If the folder does exist error
MsgBox "The folder currently exists, please rename or delete the folder.", vbCritical, "Error"
Exit Sub
'If the folder does not exist create folder and export
End If
MkDir sFolderPath
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Sheets 'for each worksheet
'if it's visible:
If Sheets(myWorksheets(i)).visible Then
Debug.Print "Exporting: " & ws.Name
ws.Copy '(if no params specified, COPY creates + activates a new wb)
Set wbNew = Application.ActiveWorkbook 'get new wb object
wbNew.SaveAs sFolderPath & "\" & ws.Name & ".csv", 23 'save new wb
wbNew.Close 'close new wb
Set wbNew = Nothing 'cleanup
End If
Next ws
Set ws = Nothing 'clean up
Application.ScreenUpdating = False
MsgBox "Sheet Export is now Complete. You can find the files at the following path." & vbNewLine & vbNewLine & sFolderPath, vbExclamation, "Export Sheets Complete"
End Sub
Export Sheets
Sub ExportSheets() 'saves all visible sheets as new xlsx files
Const PROC_TITLE As String = "Export Sheets"
Const SHEET_LIST As String _
= "Chart of Accounts,Custom Mapping File,Custom Chart of Accounts," _
& "Conventional Default COA,Conventional Mapping File," _
& "CONV Chart of Accounts,HUD Chart of Accounts," _
& "Affordable Default COA,Affordable Mapping File,Entities," _
& "Properties,Floors,Units,Area Measurement,Tenants,Account Labels," _
& "Leases,Scheduled Charges,Tenant Beginning Balances,Vendors," _
& "Vendor Beginning Balances,Customers,Customer Beginning Balances," _
& "GL Beginning Balances,GL Detail,Bank Accounts,Budgets," _
& "Budgeting COA,Budgeting Conventional COA,Budgeting Affordable COA," _
& "Budgeting Job Positions,Budgeting Employee List," _
& "Budgeting Workers Comp,Expense Pools,Lease Recoveries,Index Code," _
& "Lease Sales,Option Types,Clause Types,Lease Clauses,Lease Options," _
& "Budgeting Current Budget Import,Job Cost,Draw Model Detail," _
& "Job Cost History,Job Cost Budgets,Fixed Assets,Condo Properties," _
& "Owners,Ownership Information,Ownership Billing,Owner Charges"
Dim swb As Workbook: Set swb = ThisWorkbook
Dim sws As Worksheet: Set sws = swb.Sheets("Sheet1") ' adjust!
Dim PMC As String: PMC = CStr(sws.Range("PMC_Name").Value)
Dim dFolderPath As String
dFolderPath = swb.Path & "\" & PMC & " - Import Templates\"
If Len(Dir(dFolderPath, vbDirectory)) > 0 Then
MsgBox "The folder already exists. " _
& "Please rename or delete the folder.", vbCritical, PROC_TITLE
Exit Sub
End If
MkDir dFolderPath
Dim SheetNames() As String: SheetNames = Split(SHEET_LIST, ",")
Application.ScreenUpdating = False
Dim dwb As Workbook, ssh As Object, SheetName
For Each SheetName In SheetNames
On Error Resume Next
Set ssh = swb.Sheets(SheetName)
On Error GoTo 0
If Not ssh Is Nothing Then ' sheet exists
If ssh.Visible Then ' sheet is visible
Debug.Print "Exporting: " & ssh.Name
ssh.Copy ' creates a single-sheet workbook
Set dwb = Workbooks(Workbooks.Count)
dwb.SaveAs dFolderPath & ssh.Name & ".csv", xlCSVWindows ' 23
dwb.Close SaveChanges:=False
'Else ' sheet is not visible; do nothing
End If
Set ssh = Nothing ' reset for the next iteration
'Else ' sheet doesn't exist; do nothing
End If
Next SheetName
Application.ScreenUpdating = True
MsgBox "Sheet Export is now complete. " _
& "You can find the files in the following path:" & vbLf & vbLf _
& dFolderPath, vbInformation, PROC_TITLE
End Sub
First I selected "Yes" to the question "Change Worksheet Name?". Then the message "Type new Worksheet Name" appears. Instead of typing in a new name and selecting "OK", I select the "cancel" button and my error messages are displayed. How do I avoid seeing the error messages and just let the macro end "quietly"?
Option Explicit ' Force explicit variable declaration.
Sub ChangeSheetName()
Dim Carryon As String
On Error GoTo eh
Carryon = MsgBox("Change Worksheet Name?", vbYesNo)
If Carryon = vbYes Then
Dim shName As String
Dim currentName As String
currentName = ActiveSheet.Name
shName = InputBox("Type new Worksheet name")
ThisWorkbook.Sheets(currentName).Name = shName
End If
Exit Sub
eh:
MsgBox "The following error occured." _
& vbCrLf & "" _
& vbCrLf & "Error Number is: " & Err.Number _
& vbCrLf & "" _
& vbCrLf & "Error Description is: " & Err.Description _
& vbCrLf & "" _
& vbCrLf & "You likely hit the Esc key to stop renaming the Worksheet." _
& vbCrLf & "" _
& vbCrLf & "No worries. You can try again to rename or leave it as is." _
& vbCrLf & "" _
& vbCrLf & "No harm done."
End Sub
You've declared Carryon as a string variable - vbYes (and other messagebox results) are numeric constants.
Change Dim Carryon As String to Dim Carryon As Long
If the user presses "Cancel", the InputBox-Function returns an empty string (""). If you try to use that empty string as a worksheet name, you will get an runtime error (as this is not a valid sheet name) and your error handler is triggered.
To avoid this, simply check if shName is not the empty string before assigning the name.
If MsgBox("Change Worksheet Name?", vbYesNo) <> vbYes Then Exit Sub
Dim currentSheet As Worksheet, shName As String
Set currentSheet = ActiveSheet
shName = InputBox("Type new Worksheet name")
If shName <> "" Then
currentSheet.Name = shName
End If
You can use StrPtr to handle InputBoxes. This is an undocumented function that is used to get the underlying memory address of variable.
Here is an example
shName = InputBox("Type new Worksheet name")
If (StrPtr(shName) = 0) Or (shName = "") Or Len(Trim(shName)) = 0 Then
'~~> StrPtr(shName) = 0 : User Pressed Cancel, or the X button
'~~> shName = "" : User tried to pass a blank value
'~~> Len(Trim(shName)) = 0 : User tried to pass space(s)
Exit Sub ' Or do what you want
Else
MsgBox "Worksheet Name: " & shName
End If
Please, try the next way:
Sub MsgBoxYesNoHandling()
Dim Carryon As VbMsgBoxResult, shName As String
Carryon = MsgBox("Change Worksheet Name?", vbYesNo)
If Not Carryon = vbYes Then Exit Sub
shName = InputBox("Type new Worksheet name")
If Len(Trim(shName)) = 0 Then Exit Sub
'do here whatever you need..
End Sub
Rename Sheet
This will rename any active sheet (worksheet or chart), not just if it's the active sheet in the workbook containing this code (ThisWorkbook). Before exiting, it will show a message box only if it was successful.
Sub RenameSheet()
Const PROC_TITLE As String = "Rename Sheet"
On Error GoTo ClearError ' start main error-handling routine
Dim sh As Object: Set sh = ActiveSheet
If sh Is Nothing Then
MsgBox "No visible workbooks open.", vbExclamation, PROC_TITLE
Exit Sub
End If
Dim OldName As String: OldName = sh.Name
Dim NewName As String, MsgNumber As Long
Do
NewName = InputBox("Input the new sheet name:", PROC_TITLE, OldName)
If Len(NewName) = 0 Then Exit Sub
On Error GoTo RenameError ' start Rename error-handling routine
sh.Name = NewName
On Error GoTo ClearError ' restart main error-handling routine
Select Case MsgNumber
Case 0, vbNo: Exit Do
Case vbYes: MsgNumber = 0 ' reset for the next iteration
End Select
Loop
If MsgNumber = 0 Then
If StrComp(OldName, NewName, vbBinaryCompare) = 0 Then Exit Sub
MsgBox "Sheet renamed from '" & OldName & "' to '" & NewName & "'.", _
vbInformation, PROC_TITLE
End If
ProcExit:
Exit Sub
RenameError: ' continue Rename error-handling routine
MsgNumber = MsgBox("Could not rename from '" & OldName & "' to '" _
& NewName & "'. Try again?" & vbLf & vbLf & "Run-time error '" _
& Err.Number & "':" & vbLf & vbLf & Err.Description, _
vbYesNo + vbQuestion, PROC_TITLE)
Resume Next
ClearError: ' continue main error-handling routine
MsgBox "An unexpected error occurred." _
& vbLf & vbLf & "Run-time error '" & Err.Number & "':" & vbLf & vbLf _
& Err.Description, vbCritical, PROC_TITLE
Resume ProcExit
End Sub
Thank you all for your answers.
I ended up just removing the error handling code and adding an extra If statement.
Sub ChangeSheetName()
Dim Carryon As String
Carryon = MsgBox("Change Worksheet Name?", vbYesNo)
If Carryon = vbYes Then
Dim shName As String
Dim currentName As String
currentName = ActiveSheet.Name
shName = InputBox("Type new Worksheet name")
If shName <> "" Then
ThisWorkbook.Sheets(currentName).Name = shName
End If
End If
End Sub
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
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