I'm trying to verify that a sheet exists in my workbook. It will confirm if the sheet name in the workbook exists in my array. If it does not exist then a new worksheet will be added and renamed based on the array. If it does exist, I want the code to continue with checking the next worksheet name.
This is what I have so far but my last array value "Test 7" won't pop up in my new worksheets added. It will only show "Test7" as the new name. Please help!
Dim SheetNames() As Variant
SheetNames()= Array("Test1","Test2","Test3","Test4","Test5","Test6","Test7")
For n =LBound(SheetNames) To UBound(SheetNames)
On Error Resume Next
If Not Worksheets(SheetNames(n)).Name=SheetNames(n) Then
Set cws = wb.Worksheets.Add(After:=ws)
End If
Next
You should cancel the On Error Resume Next as soon as you no longer need it, or you may be hiding unexpected problems in the rest of your code.
Sub tester()
Dim SheetNames() As Variant, ws As Worksheet, wb As Workbook, n As Long
SheetNames() = Array("Test1", "Test2", "Test3", _
"Test4", "Test5", "Test6", "Test7")
Set wb = ThisWorkbook 'for example
For n = LBound(SheetNames) To UBound(SheetNames)
Set ws = Nothing 'reset ws to Nothing
On Error Resume Next 'ignore errors
Set ws = wb.Worksheets(SheetNames(n)) 'try to set `ws`
On Error GoTo 0 'stop ignoring errors
If ws Is Nothing Then 'got a sheet?
Set ws = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
ws.Name = SheetNames(n)
End If
Next
End Sub
Add Missing Worksheets
Option Explicit
Sub AddMissingWorksheets()
Dim SheetNames(): SheetNames = Array( _
"Test1", "Test2", "Test3", "Test4", "Test5", "Test6", "Test7")
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sh As Object, SheetName
For Each SheetName In SheetNames
On Error Resume Next
Set sh = wb.Sheets(SheetName)
On Error GoTo 0
If sh Is Nothing Then ' sheet doesn't exist
wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count)).Name = SheetName
Else ' sheet exists
Set sh = Nothing ' reset for the next iteration
End If
Next SheetName
MsgBox "Missing worksheets added.", vbInformation
End Sub
Related
I use this code to copy 4 sheets to separate workbook. One of them - "1" have formulas inside, method below skips those formulas. Any ideas how to keep three workbook's as value only and one - "1" including the formulas? Part of code responsible for that action below. Thank you in advance.
Sub test()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim Fname As String, ws As Worksheet
Dim InitFileName As String, fileSaveName As String
Fname = Sheets("STRUCTURE").Range("A1").Value
Sheets(Array("STRUCTURE", "2", "3", "1")).Copy
For Each ws In ActiveWorkbook.Worksheets
With ws.UsedRange
.Value = .Value
End With
Next ws
With ActiveWorkbook
fileSaveName = "FILE LOCATION FOLDER " & Sheets("STRUCTURE").Cells(1, 1) & ".xlsx"
.SaveAs fileSaveName
.Close
End With
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
This is what is changing formulas to values:
With ws.UsedRange
.Value = .Value
End With
You have several options to skip the worksheet in question:
Skip the worksheet named 1.
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "1" Then
With ws.UsedRange
.Value = .Value
End With
End If
Next
Only loop over the worksheets in question:
Dim sheetNamesToProcess As Variant
sheetNamesToProcess = Array("STRUCTURE", "2", "3")
Dim i As Long
For i = Lbound(sheetNamesToProcess) To Ubound(sheetNamesToProcess)
With ActiveWorkbook.Worksheets(sheetNamesToProcess(i)).UsedRange
.Value = .Value
End With
Next
I have a workbook with multiple sheets named like dates e.g 12-01-2015, 12-02-2015, .... etc. I would like to create a code that deletes specific sheets if their names are listed in an array.
I created a code but it does not work. My guess is it is related to incorrect statement listed in line starting with "If".
I would really appreciate any tip where I am going wrong
Sub DeleteSelectedSheets()
Dim i As Long
Dim Holidays() As Variant
Holidays = Array("12-3-2015", "12-4-2015")
For Each Worksheet In ActiveWorkbook
If Worksheet(i).Name = Holidays(i) Then
Application.DisplayAlerts = False
Sheets(i).Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Sub DeleteSelectedSheets()
Dim Holidays As Variant
Holidays = Array("Sheet1", "Sheet3", "Sheet5")
For Each Sheet In ThisWorkbook.Sheets
If UBound(Filter(Holidays, Sheet.Name)) > -1 Then
Application.DisplayAlerts = False
Sheet.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
This should work just fine!
With the exception, that will happen regardless the code you are using, where there is only one sheet left and you are trying to delete it, it'll throw an error message!
See the use of LBound() and UBound() :
Sub DeleteSelectedSheets()
Dim i As Long
Dim Holidays() As Variant
Dim wS As Worksheet
Holidays = Array("12-3-2015", "12-4-2015")
For Each wS In ActiveWorkbook
For i = LBound(Holidays) To UBound(Holidays)
If wS.Name <> Holidays(i) Then
Else
Application.DisplayAlerts = False
wS.Delete
Application.DisplayAlerts = True
Exit For
End If
Next i
Next wS
End Sub
It may be better to simply try and delete the worksheet(s) named in the array. Of course, you will need to operate under an On Error Resume Next to guard against the condition where a worksheet named does not exist.
Sub DeleteSelectedSheets()
Dim h As Long, Holidays() As Variant
Holidays = Array("12-3-2015", "12-4-2015")
On Error Resume Next
Application.DisplayAlerts = False
For h = LBound(Holidays) To UBound(Holidays)
Worksheets(Holidays(h)).Delete
Next h
'alternate delete entire array (they need to be all there, fail on partial)
'Worksheets(Holidays).Delete
Application.DisplayAlerts = True
On Error GoTo 0
End Sub
This seems to work:
Sub DeleteSelectedSheets()
Dim i As Long
Dim Holidays() As Variant
Holidays = Array("12-3-2015", "12-4-2015")
For i = Sheets.Count To 1 Step -1
If Sheets(i).Name = Holidays(0) Or Sheets(i).Name = Holidays(1) Then
Application.DisplayAlerts = False
Sheets(i).Delete
Application.DisplayAlerts = True
End If
Next
End Sub
I have the following code which searches the sheets named 1 to 12 in the workbook, and creates two sheets if Sheets from 1 to 12 are found. It takes into account the error if the any of the sheets between 1 to 12 are not present. Everytime one or many sheets can be absent from 1 to 12. Is it possible for me to create another array or change the array contents which will only contain the numbers corresponding to the sheets which are present in the workbook so that I can use this modified array in all the other codes to be applied to those sheets. Kindly suggest a code with which a new modified array can be created of only the existing sheets among 1 to 12.
Sub add_sheets()
Dim MyArr, j As Long
Dim wsarray As Sheets
Dim ws As Worksheet
MyArr = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12")
For j = 0 To UBound(MyArr)
Set ws = Nothing
On Error Resume Next
Set ws = Worksheets(MyArr(j))
On Error GoTo 0
If Not ws Is Nothing Then
ActiveWorkbook.Sheets.Add After:=ws, Count:=2
Sheets(ActiveSheet.Index - 2).Activate
Else
Err.Clear
End If
Next
End Sub
A dictionary is convenient way to keep the list of worksheets
Added benefits of having both sheet Indexes, sheet Names, and Exists Method
This code uses the suggestion in the comments in Sub SetWorksheets() without triggering errors:
Option Explicit 'Add reference to: Tools -> References -> Microsoft Scripting Runtime
Public Sub AddSheets()
Dim wsList As Dictionary
Dim activeWs As Worksheet, wb As Workbook, ws As Worksheet
Application.ScreenUpdating = False
Set wb = ThisWorkbook
Set activeWs = wb.ActiveSheet
Set wsList = New Dictionary: 'wsList.CompareMode = BinaryCompare
SetWorksheets wsList
TestWorksheets wsList, "Initial Worksheets"
While wsList.Count < 12
Set ws = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
With ws
wsList.Add Key:=.Index, Item:=.Name
End With
Wend
TestWorksheets wsList, "Final Worksheets"
DelWorksheets
activeWs.Activate
Application.ScreenUpdating = True
End Sub
Public Sub SetWorksheets(ByRef wsLst As Dictionary, _
Optional ByRef wb As Workbook = Nothing)
Dim ws As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
For Each ws In wb.Worksheets
With ws
wsLst.Add Key:=.Index, Item:=.Name 'Or: d.Add Key:=.Name, Item:=.Index
End With
Next
End Sub
A note, as it may not be very obvious: SetWorksheets() is a Sub and not a Function because the first parameter is passed ByRef and this implies, among other things, that it will be changed inside the Sub. As a result the initial object sent to this sub will also be updated
To test it:
Public Sub TestWorksheets(ByRef wsLst As Dictionary, txt As String)
Dim itm As Variant, msg As String
msg = txt & ": " & vbCrLf & vbCrLf
For Each itm In wsLst
With itm
msg = msg & vbTab & itm & ": " & vbTab & wsLst.Item(itm) & vbCrLf
End With
Next
MsgBox msg & vbCrLf & "Sheet 5 exists: " & vbTab & wsLst.Exists(5)
End Sub
Public Sub DelWorksheets()
Dim itm As Worksheet
Application.DisplayAlerts = False
For Each itm In ThisWorkbook.Worksheets
If itm.Index > 3 Then itm.Delete
Next
Application.DisplayAlerts = True
End Sub
Result:
I found this code here on StackOverflow:
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
.Title = "Please select the file to kill his non colored cells"
.Filters.Add "Excel", "*.xls"
.Filters.Add "All", "*.*"
If .Show = True Then
txtFileName = .SelectedItems(1)
End If
End With
I know this code should select a file in FileDialog.
However, once I have chosen the .xls file, how do I manipulate the file? In other words, where is my file object for me to manipulate?
I would like someone to continue this code to make some simple manipulation on the workbook so I could learn how to do those simple things on a workbook that I opened.
There are two approaches for you (I prefer using first one). In both approaches wb variable stores opened workbook. I commented code in details, but if you have some questions - ask:)
First approach:
Sub test1()
Dim xlFileName
Dim wb As Workbook
xlFileName = GetOpenFilename("Excel (*.xls*),*.xls*", 1, _
"Please select the file to kill his non colored cells")
'if user pressed CANCEL - exit sub
If xlFileName = False Then
MsgBox "User pressed CANCEL"
Exit Sub
End If
'Tries to open workbook with choosen file name
On Error Resume Next
Set wb = Application.Workbooks.Open(xlFileName)
On Error GoTo 0
'If we can't find workbook with choosen path, exit Sub
If wb Is Nothing Then
MsgBox "Can't find file"
Exit Sub
End If
'your code here
wb.Worksheets("Sheet1").Range("A1").Value = "test"
'close workbook with saving changes
wb.Close SaveChanges:=True
Set wb = Nothing
End Sub
Second approach:
Sub test()
Dim xlFileName As String
Dim fd As Office.FileDialog
Dim wb As Workbook
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
.Title = "Please select the file to kill his non colored cells"
.Filters.Add "Excel", "*.xls*"
.Filters.Add "All", "*.*"
If .Show Then
xlFileName = .SelectedItems(1)
Else
'if user pressed CANCEL - exit sub
MsgBox "User pressed CANCEL"
Exit Sub
End If
End With
'Tries to open workbook with choosen file name
On Error Resume Next
Set wb = Workbooks.Open(xlFileName)
On Error GoTo 0
'If we can't find workbook with choosen path, exit Sub
If wb Is Nothing Then
MsgBox "Can't find file"
Exit Sub
End If
'your code here
wb.Worksheets("Sheet1").Range("A1").Value = "test"
'close workbook with saving changes
wb.Close SaveChanges:=True
Set wb = Nothing
End Sub
Here's an example:
Dim wb As Workbook
Dim ws As Worksheet
Dim r As Range
Set wb = Workbooks.Open(txtfilename) ' the file path you selected in FileDialog
Set ws = wb.Worksheets(1)
Set r = ws.Cells(1, 1)
With r
.Value = "Hello world!"
.Interior.Color = RGB(255,20,20) 'bright red
End With
I know little about vba so I am hoping someone can help me.
I have the following code below, it "fill blank cells in column with value above" and works fine.
I need to use it on NON-contiguous coloumns.
Is there a way to add a loop to it so that it will run on [B D H I] columns?
I have tryed to puzzel this out have not got anywhere
Thanks
Sub FillColBlanks()
'by Dave Peterson 2004-01-06
'fill blank cells in column with value above
'http://www.contextures.com/xlDataEntry02.html
Dim wks As Worksheet
Dim rng As Range
Dim Lastrow As Long
Dim col As Long
Set wks = ActiveSheet
With wks
'col = ActiveCell.Column
'or
col = .Range("G2").Column
Set rng = .UsedRange 'try to reset the lastcell
Lastrow = .Cells.SpecialCells(xlCellTypeLastCell).Row
Set rng = Nothing
On Error Resume Next
Set rng = .Range(.Cells(2, col), .Cells(Lastrow, col)) _
.Cells.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "No blanks found"
Exit Sub
Else
rng.FormulaR1C1 = "=R[-1]C"
End If
'replace formulas with values
With .Cells(1, col).EntireColumn
.Value = .Value
End With
End With
End Sub
you could try the below:
Sub FillColBlanks(sColRange as string)
'by Dave Peterson 2004-01-06
'fill blank cells in column with value above
'http://www.contextures.com/xlDataEntry02.html
Dim wks As Worksheet
Dim rng As Range
Dim Lastrow As Long
Dim col As Long
Set wks = ActiveSheet
With wks
'col = ActiveCell.Column
'or
col = .Range(sColRange).Column
Set rng = .UsedRange 'try to reset the lastcell
Lastrow = .Cells.SpecialCells(xlCellTypeLastCell).Row
Set rng = Nothing
On Error Resume Next
Set rng = .Range(.Cells(2, col), .Cells(Lastrow, col)) _
.Cells.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "No blanks found"
Exit Sub
Else
rng.FormulaR1C1 = "=R[-1]C"
End If
'replace formulas with values
With .Cells(1, col).EntireColumn
.Value = .Value
End With
End With
End Sub
so you call that procedure like this:
Call FillColBlanks("B1")
Call FillColBlanks("D1")
Call FillColBlanks("H1")
Call FillColBlanks("I1")