I am trying to delete all unnecessary sheets from an activeWorkbook, but Sheet1 because it will be my primary sheet with initial raw data in it. When I run the following code, my sheets gets deleted, but I get this error once it reaches my last remaining sheet. Run-time error '1004': A workbook must contain at least one visible worksheet.
FYI: I am writing this macro in personal macro book so i can use it for all other excel spreadsheets.
Sub deleteSheets()
Dim ws As Worksheet
Application.DisplayAlerts = False
For Each ws In ActiveWorkbook.Worksheets
If Not ws Is Sheet1 Then ws.Delete
Next ws
End Sub
If Not ws Is Sheet1 Then ws.Delete
The Boolean expression {object1} Is {object2} evaluates reference equality: it will be True if {object1} is {object2}.
Here ws is a worksheet in ActiveWorkbook, and Sheet1 is (presumably) a global identifier referring to the CodeName of a sheet that exists in ThisWorkbook - which may or may not be the currently active workbook.
If ThisWorkbook isn't the ActiveWorkbook, reference equality will fail for every single sheet, and that loop will attempt to delete them all, which is why you're getting that error.
Unless you want to delete sheets in ThisWorkbook, you can't use reference equality to make that check.
You can go by Index, or by name - in any case it's a good idea to ensure there's more than a single sheet in the workbook you're working with:
For Each ws In ActiveWorkbook.Worksheets
Debug.Assert ActiveWorkbook.Worksheets.Count > 1
If Not ws.Name = "Sheet1" Then ws.Delete
Next
Verify that the sheet you mean to delete has the expected index (1) and/or the expected name; use the Project Explorer (Ctrl+R) and the Properties (F4) toolwindows for that. Bear in mind that the (Name) property is the sheet's CodeName identifier, which you can only use/access in the VBA project of ThisWorkbook; you'll want to verify its Name property - that's the user-modifiable "tab name" of the worksheet.
dim i as Integer
dim ws as Worksheet
For i = 2 to ActiveWorkbook.Worksheets.Count
Sheets(2).Delete
Next
Related
I have a VBA code where I want to skip "Sheet1". However, the Loop skips "Sheet1", and then Ends the Sub. It does not move to the Next ws.
There are 7 Worksheets..
How do I fix this please?
Sub BrandRank_()
Dim wb As ThisWorkbook
Dim ws As Worksheet
Dim TableName As String
Dim LstObj As ListObjects
For Each ws In ThisWorkbook.Worksheets
With ws
If .Index <> 1 Then
'Insert Table
.ListObjects.Add(xlSrcRange, .Range("A3"), .Range("A3").End(xlDown).End(xlToRight), xlYes).Name = TableName
'Apply a filter to "C3" (Largest to Smallest)
.AutoFilter.Sort.SortFields.Clear
.AutoFilter.Sort.SortFields.Add2 Key:=.Range("C3"), SortOn:=xlSortOnValues, Order:=xlDescending
.AutoFilter.ApplyFilter
.ListObjects(TableName).ShowAutoFilterDropDown = False
End If
End With
Next ws
End Sub
Your VBA probably loops through the sheets of your Personal.xlsb.
If you are running macros from the external file, then, please, use thisWorkbook property to refer to the workbook that contains your macro code. ThisWorkbook, for example, is the only way to refer to an add-in workbook from inside the add-in itself.
The ActiveWorkbook property doesn't return the add-in workbook; it returns the workbook that's calling the code. It would be even better to refer to a particular workbook directly by name (see below)
I would also suggest considering referring to a sheet by its name, otherwise your code may break unexpectedly if you (or someone else) changes the order of sheets, adds hidden sheets etc.
For Each wsSheet In Workbooks("NameOfYourBook").Worksheets
If wsSheet.Name <> "TOC" Then
'Put your code here
End If
Next wsSheet
You may also use the .CodeName property.
See the details.
(Sorry in advance for my poor English: not first Language :) )
I am writing a VBA Excel 2003 routine that runs through 50+ worksheets in a file, copies the worksheets (just as a temp copy) one by one and then performs actions on them before removing these temporary copies and returning the result of it's calculations on the worksheets content.
To be more precise: the code is called from an external file with a single (hidden) worksheet inside. When I open the file it runs a code to create a new toolbar in Excel, when I press a button on the toolbar, the code I have described above runs.
I know that not saving a file and performing many and many copies triggers this error, but now it is triggering at the first attempt (I have closed and reopened everything multiple times to be sure I am not keeping the not saved situation with me).
This is the code triggering the problem, I am sorry for poor formatting:
ActiveWorkbook.Worksheets("NAME OF THE FIRST WORKSHEET I WANT TO COPY").Copy ThisWorkbook.Worksheets("HiddenSheet")
Disclamer: the name of the worksheet is found by a For..Next cycle through the ActiveWorkbook.Worksheets array, but the code is not working even if i hard-code the name myself.
Here is a larger chunk of the code, to be clearer:
Set sourceWorkbook = ActiveWorkbook
For index = 1 To sourceWorkbook.Worksheets.Count
sourceWorkbook.Activate 'not sure if this is even needed
Set currWorksheet = sourceWorkbook.Worksheets(index)
currWorksheet.Copy ThisWorkbook.Worksheets("HiddenSheet")
Next index
The result is now consistently:
Run-time Error '1004'
Copy method of worksheet class failed.
I thank everybody in advance for the help!
Some useful guidelines:
Option Explicit
'Copy sheet
Sub CopySheet()
Dim ws1 As Workbook, ws2 As Workbook
'It's better to declare sheets and avoid activate
Set ws1 = Workbooks("Book1")
Set ws2 = Workbooks("Book2")
'Copy sheet "Test" from ws1(Book1) to ws2 (Book2) after all sheets
ws1.Worksheets("Test").Copy After:=ws2.Worksheets(Sheets.Count)
End Sub
Option Explicit
'Copy a range
Sub CopyRange()
Dim ws1 As Workbook, ws2 As Workbook
'It's better to declare sheets and avoid activate
Set ws1 = Workbooks("Book1")
Set ws2 = Workbooks("Book2")
'Copy from ws1(Book1), sheet "Test" & range A1:A5 to ws2 (Book2), sheet "sheet1" & range A1
ws1.Worksheets("Test").Range("A1:A5").Copy
ws2.Worksheets("Sheet1").Range("A1").PasteSpecial Paste:=xlPasteValues
End Sub
I hope this is a simple question...
My understanding is that "ActiveWorkbook" returns the currently active workbook, even if the macro was run in a different workbook (this is why I almost always use "ThisWorkbook" instead).
And "ActiveSheet" returns the currently active worksheet, even if the macro was run in a different workbook (or different worksheet).
So how can I get the worksheet which currently has focus within a specific workbook, even if that workbook is not the currently active one?
You can do this by fully qualifying .ActiveSheet
Example:
Private Sub test()
Dim wb As Workbook
Set wb = Workbooks.Add
'Change the name of Sheet1 in the second workbook
'so it's not confused with Sheet1 in the first workbook.
wb.Sheets("Sheet1").Name = "Foo"
ThisWorkbook.Activate
MsgBox wb.ActiveSheet.Name
End Sub
When I reference Excel worksheets using the CodeName property, how do I fully qualify them including the workbook reference?
I want to guard against a scenario with two different workbooks open and two sheets having the same CodeName. I use ThisWorkbook because I want to reference the workbook the code is running from.
I imagine something like this:
Dim tgWs As Worksheet
Set tgWs = ThisWorkbook.WsSummary
tgWs.Cells(1,1).Value = "Test"
where WsSummary is the sheet's codename.
Referring to a sheet by its codename always implies the sheet in ThisWorkbook, i.e. the workbook that contains the code you are executing.
There seems to be no straightforward way to fully qualify a sheet in a different workbook using its codename.
This function will help you do this:
Function GetSheetWithCodename(ByVal worksheetCodename As String, Optional wb As Workbook) As Worksheet
Dim iSheet As Long
If wb Is Nothing Then Set wb = ThisWorkbook ' mimics the default behaviour
For iSheet = 1 To wb.Worksheets.Count
If wb.Worksheets(iSheet).CodeName = worksheetCodename Then
Set GetSheetWithCodename = wb.Worksheets(iSheet)
Exit Function
End If
Next iSheet
End Function
Example usage:
GetSheetWithCodename("Sheet1", Workbooks("Book2")).Cells(1, 1) = "Sheet1 in Book2"
GetSheetWithCodename("Sheet1", ActiveWorkbook).Cells(1, 1) = "Sheet1 in ActiveWorkbook"
GetSheetWithCodename("Sheet1").Cells(1, 1) = "Sheet1 in ThisWorkbook"
Note that the last line is equivalent to simply saying:
Sheet1.Cells(1, 1) = "Sheet1 in ThisWorkbook"
because, as mentioned above, referring to a sheet by its codename always imply the sheet in ThisWorkbook.
You can do this by adding the second Workbook as a reference, and calling the workbook by the VBA Project name.
Obviously, it's a good idea to change the VBA project name from the default 'VBAProject'!
I tested this by creating two new workbooks each with one sheet, with a value of 1 or 2 in cell A1. The VBA projects were named 'Proj1' and 'Proj2', and the worksheets' CodeNames were left as 'Sheet1'.
This is the code I used:
Sub test()
Debug.Print Proj1.Sheet1.Cells(1, 1)
Debug.Print Proj2.Sheet1.Cells(1, 1)
End Sub
Yielding an output of:
1
2
Worksheets can be referred to by their codename when the code is in the same workbook so fully qualifying is not necessary. You can't refer to another workbooks sheet by codename directly unless you loop each sheet and check the codename
so this is enough without needing to create a variable
with WsSummary
.Cells(1,1).Value = "Test"
end with
Sheet1.Cells(1, 1) = "Sheet1 in ThisWorkbook" without the ThisWorkBook prefix works fine without any extra methods
Dim wb as Workbook
Dim ws as worksheet
Set wb = "Your Workbook full path and name"
For each ws in wb.worksheets
If ws.codename = "Your Codename" then exit for
next ws
ws will now contain the reference to the worksheet in other workbook with the desired codename with no user changeable dependencies
Hope this helps
I am trying to create an Tracker. Need help with these ideas:
When the Excel book is opened, it must show only the "Tracker" Worksheet. All other sheets need to be hidden. Now am using the code {sheet.visible = xlveryhidden} But the code is too long, I have to include each sheet name. I need help with a code to show only the Tracker sheet but to hide all other sheets in the workbook.
I've included two comboboxes as year and month. Also included a Command button OK & Cancel. When clicked on OK, it has to verify the IF condition and show a specific sheet. I have no issues with that. it is showing a specific sheet. But I need a single line code to hide all other sheets
I have also included a "New Tracker" Command button. When Clicked on it, it must include a New sheet. Also too let the user to rename it. This worksheet must also be hidden once saved.
I aware the process is simple, but not sure how to complete it.
To hide all but the Tracker worksheet
Sub hidesheets()
Dim ws As Worksheet, wb As Workbook 'Create the variables we'll use for our worksheet and workbook objects.
Set wb = Excel.ActiveWorkbook 'Set the workbook variable to equal the active workbook. This can also be set to equal a named workbook if you want.
For Each ws In wb.Worksheets 'Loop through each worksheet in the workbook.
If Not ws.Name = "Tracker" Then 'If the worksheet's name isn't "Tracker" then...
ws.Visible = xlSheetVeryHidden 'Set it to very hidden.
Else 'If it is the "Tracker" worksheet, then ...
ws.Visible = xlSheetVisible 'Set it to visible.
End If 'End the IF/THEN statement.
Next ws 'Repeat for the next worksheet in the workbook.
End Sub
You'll have to modify this if you want it to work with a command button or do something with another worksheet. But it should get you started. I'd do it but I don't quite have the time right now.