Deleting Sheets With One Row Excel VBA - excel

I am creating some sheets and would like to delete the ones with only one row. I have tried following two codes but they did not work.
WSCount = Worksheets.Count
For l = 1 To WSCount
Worksheets(l).Activate
If IsEmpty(ActiveSheet.Cells(2, 1)) Then
ActiveSheet.Delete
WSCount = WSCount - 1
l = l - 1
End If
Next l
Below is the second one.
For Each Worksheet in ActiveWorkbook.Worksheets
If IsEmpty(ActiveSheet.Cells(2,1)) Then
ActiveSheet.Delete
End If
Next
The problem I am encountering is when I delete pages, it messes with the for loop. This directly happens at the first code. In the second code, the problem is that I am not activating that sheet so excel does not delete it. I have to put a for loop in that one too, which makes me encounter the same problem at the first code.
There is probably a simple solution but my knowledge is limited so all I could think is putting a for loop.

That's why we always loop backwards when deleting sheets, rows, columns ...
Sub x()
Dim WSCount As Long, l As Long
WSCount = Worksheets.Count
For l = WSCount To 1 Step -1
If IsEmpty(Worksheets(l).Cells(2, 1)) Then
Worksheets(l).Delete
End If
Next l
End Sub
As Scott says, your second bit of would work thus as in your existing code the activesheet never changes so you would only ever delete a single sheet.
For Each Worksheet in ActiveWorkbook.Worksheets
If IsEmpty(worksheet.Cells(2,1)) Then
worksheet.Delete
End If
Next
Also read up on how to avoid select.

Sub deleteSheet()
Application.DisplayAlerts = False
For Each sh In ThisWorkbook.Worksheets
If IsEmpty(sh.Cells(2, 1).Value) Then
sh.Delete
End If
Next
Application.DisplayAlerts = True
End Sub

Related

Skip some worksheets in loop function in Excel VBA

I want to have a button replace the info on MOST sheets with the info from a master sheet when a button is clicked. However, I want it to skip some sheets.
I have the below code that works, but there are 2 sheets I want it to skip when running. How can I specify that is skip the sheets named "Dates" and "Monthly"
Sub Button4_Click()
Dim wsVar As Worksheet
For Each wsVar In ThisWorkbook.Sheets
With wsVar
.Range("B9:M30").Value = Worksheets("BASE").Range("B9:M30").Value
End With
Next wsVar
End Sub
You can use an IF statement to check the name of the worksheet and then act accordingly.
For Each wsVar In ThisWorkbook.Sheets
If wsVar.Name = "foo" Or wsVar.Name = "bar" Then
' do nothing
Else
With wsVar
.Range("B9:M30").Value = Worksheets("BASE").Range("B9:M30").Value
End With
End If
Next wsVar
This code will exclude all sheets listed in the Exclude array. Note that sheets name comparisons are carried out case-insensitive and leading or trailing blanks are deemed unintentional and removed.
Sub Button4_Click()
Dim wsVar As Worksheet
Dim Exclude() As String
Dim i As Integer
Exclude = Split("Dates,Monthly", ",")
For Each wsVar In ThisWorkbook.Worksheets
With wsVar
For i = UBound(Exclude) To 0 Step -1
If StrComp(wsVar.Name, Trim(Exclude(i))) = 0 Then Exit For
Next i
If i >= 0 Then .Range("B9:M30").Value = Worksheets("BASE").Range("B9:M30").Value
End With
Next wsVar
End Sub
With a small change, you might convert this same function to process only listed sheets. To identify sheets for action positively, rather than negatively, is the safe way, generally speaking. But if you decide to do that, please also do rename the array :-)

Excel VBA index out of bounds while using Sheets.delete

After a few iterations of the following code I always get the error that the index was out of bounds.
For i = myworksheet.index To Worksheets.count
Sheets(i).delete
Next i
You shouldn't delete sheets this way.
Consider what you're asking it to do. Let's say you have 5 worksheets- Sheet1, Sheet2.. Sheet 5.
Let's say myworksheet is Sheet3 (i=3).
When the loop starts, i is 3.
Sheet3 is deleted.
The loop restarts and i is now 4.
However, there are now only 4 worksheets. So Sheet5 (i=4) is deleted.
The loop restarts and i is now 5.
However, there are now only 3 worksheets. There is no worksheet with index of 5 to delete.
One (of many) ways to achieve your goal is to do the following:
i = myworksheet.Index
Do Until Worksheets.Count = i - 1
Worksheets(Worksheets.Count).Delete
Loop
One thing to point out with this.. in your code, you appear to be deleting your start sheet myworksheet. Because of this, the Do Until... loop I've created finishes at i-1 to stop after myworksheet is deleted. If you didn't want this to happen, remove the - 1. If you did want this to happen, you need to be aware that it will error if the index of myworksheet is 1 - as all workbooks must contain at least 1 worksheet.
Try the next way, please. In your code, after sheets deleting, the reference not make sense for i bigger then existing maximum (remained) one:
Sub deleteSheets()
Dim sh As Worksheet, ws As Worksheet
Set sh = ActiveSheet
For Each ws In ActiveWorkbook.Sheets
If ws.Index > sh.Index Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Or looping backwards, as #SJR suggested:
Sub deleteSheetsBis()
Dim myworksheet As Worksheet, i As Long
Set myworksheet = ActiveSheet
For i = ActiveWorkbook.Worksheets.count To myworksheet.Index Step -1
Application.DisplayAlerts = False
Sheets(i).Delete
Application.DisplayAlerts = True
Next i
End Sub

Copying and renaming tab VBA

VBA newbie, I am trying to find a way to increase the number of tabs or sheets by copying the last one and then renumbering it. i.e copying tab 150 then relabeling it 151 and so on.
I've figured out a way to copy the sheet with the code below:
Sub CopySheetRename1()
Sheets("150").Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = "LastSheet"
End Sub
But i can't get the new sheet to rename itself.
Any help is appreciated
This perhaps. It's not clear if you have only sheets numbered or others.
Sub CopySheetRename1()
Dim ws As Worksheet
Set ws = Worksheets(Worksheets.Count)
ws.Copy After:=ws
If IsNumeric(ws.Name) Then ActiveSheet.Name = CLng(ws.Name) + 1
End Sub
Try this :
Sub Loadsoftabscreations() 'as many as you want :)
Worksheets("Sheet150").Select
For x = 1 To 300 ' or as many new fresh tabs you want
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "YourTab - " & x
Next x
End Sub
You can set the names in the code as you want.
as per my comment, for copying x number of times:
Sub LoadsoftabscreationsC()
Dim ws As Worksheet
Set ws = Worksheets(Worksheets.Count)
For x = 1 To 10 ' or as many as needed
ws.Copy After:=ws
If IsNumeric(ws.Name) Then Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name
Next x
End Sub

VBA message automation error element not found

I have a workbook that uses a macro and makes many sheets. After one sheet, called Paste, I want to be able to delete the sheets that follow once I am done using them.
I found the following code from https://stackoverflow.com/a/53544169/11615632 and slightly modified it to use in my workbook.
Sub Deleting()
Dim Indx As Long
Dim x As Long
With ThisWorkbook
On Error Resume Next
Indx = .Sheets("Paste").Index
On Error GoTo 0
If Indx <> 1 Then
If .Sheets.Count > 2 And Indx < .Sheets.Count Then
Application.DisplayAlerts = False
For x = .Sheets.Count To Indx + 1 Step -1
.Sheets(x).Delete
On Error GoTo 0
Next x
Application.DisplayAlerts = False
End If
Elseif Indx = 1 Then
Exit Sub
End If
End With
End Sub
However, when I do this it actually works, but I get an error message saying
"Run-time error '-2147319765':
Automation Error
Element not found.
The error is found on the line .Sheets(x).Delete
Since you know that you want to keep two specific sheets ("Value" and "Paste"), instead of using the indexes, which can be a little tricky and may not always work depending on the order/added order of them, I suggest instead looking at the name of each worksheet and delete that way (as mentioned in the comments).
Dim ws as Worksheet
' This next line will suppress the "Confirm Deleting" messagebox
' when you go to delete a worksheet
Application.DisplayAlerts = False
For each ws in ThisWorkbook.Worksheets
If ws.Name <> "Value" and ws.Name <> "Paste" Then
ws.Delete
End If
Next ws
Application.DisplayAlerts = True
(This assumes the macro is stored in the workbook you want to delete the sheets from. If it's not, perhaps it's stored in Personal.xlsb, then switch ThisWorkbook to ActiveWorkbook or something more specific.)

Run Macro that has two For and If statements

I am trying to run a macro that will remove any rows that have a #REF! as well as remove the header. On top of all of that, I would also like for the macro to go through and apply this option for all worksheets except the first one.
When I try to run it acts as if it worked, but when I checked the specific worksheets where this applies nothing has happened.
Sub RemoveGamesOut()
Dim i As Long
Dim ws As Worksheet
Application.ScreenUpdating = False
For Each ws In Worksheets
If ws.Name <> "1962-63 Stats" Then ws.Range ("C6:C5000").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
For i = Range("C" & Rows.Count).End(3).Row To 5 Step -1
If IsError(Cells(i + 1, "C")) = True Then Rows(i).Resize(2).Delete
Next i
Next ws
End Sub

Resources