Adding array to sheet names - vba

I am using the below code to retain sheets that I need and delete the rest.
Sub DeleteSheets1()
Dim xWs As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each xWs In Application.ActiveWorkbook.Worksheets
If xWs.Name <> "Sheet1" And xWs.Name <> "Sheet2" Then
xWs.Delete
End If
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I have around 6 sheets that I want to retain. I need help modifying the syntax to accommodate multiple sheets. Something like below
if xWs.Name <> ("sheet1", "sheet2"....) then xws.delete

Here arr is an array of the sheets to retain:
Sub DeleteSheets1()
Dim xWs As Worksheet, s As String, i As Long
Dim skp As Boolean
arr = Array("Sheet1", "Sheet2", "Sheet3")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
n = ActiveWorkbook.Worksheets.Count
For i = n To 1 Step -1
s = Sheets(i).Name
skp = False
For Each a In arr
If s = a Then skp = True
Next a
If Not skp Then Sheets(i).Delete
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

The valueInArray boolean function could work the code easier:
Public Function valueInArray(myValue As Variant, myArray As Variant) As Boolean
Dim cnt As Long
For cnt = LBound(myArray) To UBound(myArray)
If CStr(myValue) = CStr(myArray(cnt)) Then
valueInArray = True
Exit Function
End If
Next cnt
End Function
Sub DeleteSheets()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim cnt As Long
cnt = Worksheets.Count
Dim arrWks As Variant
arrWks = Array("Sheet1", "Sheet2", "Sheet3")
For cnt = Worksheets.Count To 1
If Not valueInArray(Worksheets(cnt).Name, arrWks) Then
Worksheets(cnt).Delete
End If
Next cnt
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
The valueInArray function gets value to search for myValue and array where to search for this value myArray. It loops through all elements of the array and if it finds the same String of the passed value, it returns True and exits. If it is not found, it returns False, as this is the default.

Another approach
Sub Test()
Dim ws As Worksheet
Dim arr As Variant
arr = Array("Sheet1", "Sheet2", "Sheet3")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
If Not IsNumeric(Application.Match(ws.Name, arr, 0)) Then ws.Delete
Next ws
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Ok, this one doesn't quite fulfil the requirement of an array, but it's another way of using a single loop.
It looks for an occurrence of the sheet name in the RetainSheets string. Each sheet name is surrounded by | just in case there's a sheet name within a sheet name eet1Sh as an example.
The code will not attempt to delete the last worksheet in the workbook either.
Sub Test()
Dim wrkSht As Worksheet
Dim RetainSheets As String
RetainSheets = "|Sheet1|Sheet2|"
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each wrkSht In Worksheets
If InStr(RetainSheets, wrkSht.Name) = 0 And Worksheets.Count > 1 Then
wrkSht.Delete
End If
Next wrkSht
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Related

Loop through Folder of Excel Workbooks and Append only Workbooks with a Key Word to Master Sheet

I am looking for VBA code that would look through several hundred Workbooks and open only ones that have "cash" in the workbook title. It would then pull the second row of the first worksheet down to the last row and append it to a master worksheet.
Although I see the iteration count reaches all one hundred plus workbooks, the code appends only the first few worksheets and stops. Could anyone provide insight as to why that is happening? Thank you in advance!
Sub Pull_Cash_WB_Names()
Dim filename As Variant
Dim a As Integer
a = 1
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim MyPath As String
Dim strFilename As String
Dim LRow As Long, LCol As Long
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayStatusBar = True
Set wbDst = ThisWorkbook
strFilename = Dir("\\DATA\*Cash*")
Count = 0
Do While strFilename <> ""
Set wbSrc = Workbooks.Open("\\DATA\*Cash*")
Set wsSrc = wbSrc.Worksheets(1)
'copy all cells starting from 2nd row to last column
LRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
LCol = ActiveSheet.Cells(7, Columns.Count).End(xlToLeft).Column
Cells(2, 1).Resize(LRow - 1, LCol).Select
Selection.Copy
'paste the data into master file
wbDst.Sheets(wbDst.Worksheets.Count).Range("A1").PasteSpecial Paste:=xlPasteValuesAndNumberFormats
'counts the number of iterations
Count = Count + 1
Application.StatusBar = Count
wbSrc.Close False
strFilename = Dir()
Loop
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
See fixes/suggestions below
Sub Pull_Cash_WB_Names()
Const PTH As string = "\\DATA\" 'folder path goes here
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim strFilename As String
Dim rngCopy AsRange, rngDest as range
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayStatusBar = True
Set wbDst = ThisWorkbook
Set rngDest = wbDst.Sheets(wbDst.Worksheets.Count).Range("A1") 'start pasting here
strFilename = Dir(PTH & "*Daily*Cash*.csv") '#EDIT#
Count = 0
Do While strFilename <> ""
Set wbSrc = Workbooks.Open(PTH & strFilename) 'full path+name
Set rngCopy = wbSrc.Worksheets(1).Range("A1").CurrentRegion 'whole table
Set rngCopy = rngCopy.Offset(1, 0).resize(rngcopy.rows.count-1) 'exclude headers
rngCopy.Copy
'paste the data into master file
rngDest.PasteSpecial Paste:=xlPasteValuesAndNumberFormats
Set rngDest = rngDest.offset(rngCopy.rows.count) 'next paste goes here...
Count = Count + 1
Application.StatusBar = Count
wbSrc.Close False
strFilename = Dir()
Loop
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Excel VBA, update specific sheets not just the active sheet

I created a script that hides rows in my active sheet if the row has a "-". I would like to apply this to other sheets (i.e. Sheet-ABC, Sheet-DEF) as well. I tried using an array, but was unsuccessful.
Any help is appreciated.
Sub hideRows()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim cell, cell2 As Range, hRws As Range
Set Rng = Sheet15.Range("A52:L359")
Rng.EntireRow.Hidden = False
For Each cell In Range("A52:L359").SpecialCells(xlBlanks)
If cell = "-" And cell.Offset(-1, 0) = "-" Then
If hRws Is Nothing Then
Set hRws = Range(cell, cell.Offset(1, 0))
Else
Set hRws = Union(hRws, Range(cell, cell.Offset(1, 0)))
End If
End If
Next
If Not hRws Is Nothing Then hRws.EntireRow.Hidden = True
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
You can call your hideRows() method inside a for-loop. Something like this:
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
hideRows()
Next

i have 5 worksheets in my excel workbook but i want to specifically protect 3rd and 5th worksheets with password

I have 5 worksheets in my excel workbook but I want specifically protect 3rd and 5th worksheets with password. Have below macro which protects only one sheet. what needs to be added to protect more than one sheet but not all sheets. Kindly guide me.
Thanks in Advance!!
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
MySheet = "Sheet1"
If ActiveSheet.Name = MySheet Then
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "pass" Then
Sheets(MySheet).Visible = True
Application.EnableEvents = False
Sheets(MySheet).Select
Application.EnableEvents = True
End If
End If
Sheets(MySheet).Visible = True
End Sub
Try this:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
MySheet = ActiveSheet.Name
Select Case MySheet
Case "Sheet1", "Sheet3", "Sheet5"
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "pass" Then
Sheets(MySheet).Visible = True
Application.EnableEvents = False
Sheets(MySheet).Select
Application.EnableEvents = True
End If
End Select
Sheets(MySheet).Visible = True
End Sub
But hardcoding the password doesnt make it that safe.

Delete Excel worksheets if not in array

I am having problem to solve the error "time execution error #13: incompatible type". If user creates some worksheet that is not stated in the array, it will be deleted. Can anyone help?
sub DeleteNewSheets()
Dim ws, wsP As Worksheet
Dim ArrayOne As Variant
Application.DisplayAlerts = False
ArrayOne = Array("SheetA", "SheetB", "SheetC", "Sheet_n")
Set wsP = ThisWorkbook.Worksheets(ArrayOne) ' <--- ERROR #13
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> wsP.Name Then ws.Delete
Next ws
Application.DisplayAlerts = True
end sub
Your line of code saying:
Set wsP = ThisWorkbook.Worksheets(ArrayOne)
is trying to set a Worksheet object to an array of many Worksheets. That's like trying to set a single Integer to be an array of Integers.
Try using the following code
Sub DeleteNewSheets()
Dim ws As Worksheet
Dim ArrayOne() As Variant
Dim wsName As Variant
Dim Matched As Boolean
ArrayOne = Array("SheetA", "SheetB", "SheetC", "Sheet_n")
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
Matched = False
For Each wsName In ArrayOne
If wsName = ws.Name Then
Matched = True
Exit For
End If
Next
If Not Matched Then
ws.Delete
End If
Next ws
Application.DisplayAlerts = True
End Sub
If you add an extra For ... Next or For Each ... Next statement to loop through every element in ArrayOne and conditional IFs statement then it should do the work. So your code should be like this
Sub DeleteNewSheets()
Dim ws As Worksheet
Dim ArrayOne As Variant, iSheet As Integer
Application.DisplayAlerts = False
ArrayOne = Array("SheetA", "SheetB", "SheetC", "Sheet_n")
For Each ws In ThisWorkbook.Worksheets
For iSheet = LBound(ArrayOne) To UBound(ArrayOne)
If ws.Name = ArrayOne(iSheet) Then Exit For
If iSheet = UBound(ArrayOne) Then
ws.Delete
End If
Next
Next
Application.DisplayAlerts = True
End Sub
or alternatively
Sub DeleteNewSheets()
Dim ws As Worksheet
Dim ArrayOne As Variant
Application.DisplayAlerts = False
ArrayOne = Array("SheetA", "SheetB", "SheetC", "Sheet_n")
For Each ws In ThisWorkbook.Worksheets
For Each Element In ArrayOne
If ws.Name = Element Then Exit For
If Element = ArrayOne(UBound(ArrayOne)) Then
ws.Delete
End If
Next
Next
Application.DisplayAlerts = True
End Sub
you can check sheets in one loop and delete "bad" ones in one shot as follows:
Option Explicit
Sub DeleteNewSheets()
Dim ws As Worksheet
Dim sheetsToDelete As String
Const GOODSHEETS As String = "\SheetA\SheetB\SheetC\Sheet_n\" '<--| list of good sheets names, separated by an invalid character for sheet names
For Each ws In ThisWorkbook.Worksheets
If InStr(GOODSHEETS, "\" & ws.Name & "\") = 0 Then sheetsToDelete = sheetsToDelete & ws.Name & "\" '<--| update sheets to be deleted list
Next ws
If sheetsToDelete <> "" Then '<--| if the list is not empty
sheetsToDelete = Left(sheetsToDelete, Len(sheetsToDelete) - 1) '<--| remove last delimiter ("\") from it
Application.DisplayAlerts = False
ThisWorkbook.Worksheets(Split(sheetsToDelete, "\")).Delete '<-- delete sheets
Application.DisplayAlerts = True
End If
End Sub

If statement to delete tab if there but move on if page is not there

I have a code that deletes a tab in the worksheet then runs another code. I am currently running into an issue that if the sheet is not there the code gives me an error... I'm wondering if I could make an if statement that looks if the tab is there and if not it moves on and if it is there it will delete it. I have the code that I have written already posted below but I have no idea how to do the if in the delete section.
Thanks!
Sub delete()
Dim ws As Worksheet
Set ws = Worksheets("Workbench Report")
Application.DisplayAlerts = False
ws.delete
Call Sorting
End Sub
Check if the sheet exists first:
Sub delete()
Dim ws As Worksheet
If WorksheetExists("Workbench Report") Then
Set ws = Worksheets("Workbench Report")
Application.DisplayAlerts = False
ws.delete
Call Sorting
End If
End Sub
Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean
Dim wrkSht As Worksheet
If WrkBk Is Nothing Then
Set WrkBk = ThisWorkbook
End If
On Error Resume Next
Set wrkSht = WrkBk.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function
Try this
Sub delete()
Dim i As Integer
i = 1
Application.DisplayAlerts = False
While i <= ActiveWorkbook.Worksheets.Count
Sheets(i).Select
If ActiveSheet.Name = "Workbench Report" Then
ActiveSheet.delete
End If
i = i + 1
Wend
Call Sorting
Application.DisplayAlerts = True
End Sub