How can I "generically" select worksheets from a script - excel

I am writing a script for a workbook that is to be used by multiple departments. The button click imports a weekly report to a master data worksheet, creates a new sheet/Tab, asks what to name that new worksheet (Which will be the week date the report references.), place an MS Query table onto the new sheet, filtered from the master, clears the master sheet and prepares the work book to repeat the same thing when the next weekly report gets added (...and is all working at the moment.). The next time someone updates the workbook, it will the button click to again use the same script to add yet another worksheet for the new week and so on, but, since I started from recorded macros to writing the rest of what I need, everything in the script is referencing the first new worksheet by worksheet name, Like this example:
Application.Goto Reference:="W11_9_2020"
Sheets("W11_9_2020").Select
Range("A1").Select
Here (Above) I would like this to be a generic reference to the latest sheet in the script, not the exact name so it is reusable the next x amount of times the workbook gets updated.
The next time someone updates this, it will still add a new sheet, but once it gets to the part where the query table is created and the new sheet is formatted, data added, blah blah, it's just going to repopulate the first sheet again since it used that sheet name in the script (Or error out).
I tried using:
Set Worksheets(Worksheets.Count) = wsDest1
wsDest1.Range("I1").Select
ActiveCell.FormulaR1C1 = "Week"
wsDest1.Range("J1").Select
ActiveCell.FormulaR1C1 = "Total Shipped"
wsDest1.Range("K1").Select
ActiveCell.FormulaR1C1 = "Total On Time"
wsDest1.Range("L1").Select
ActiveCell.FormulaR1C1 = "Total Late"
wsDest1.Range("L2").Select
..in the hopes of generically using a reference to the latest added worksheet (Which is always "Add after") but doing that brings an error stating that it is an illegal use of a procedure and highlights this line -->> Set Worksheets(Worksheets.Count) = wsDest1.
I guess in trying to write this for unlimited reuse, I would like the sheet references to be variables or something so it always references the latest added sheet before the button click would add another and repeat/rerun the same script for any given new update.
Is there another way to generically(?) identify the latest sheet/tab in the body of the script without the exact sheet name being identified?

Keep in mind that the method to add a new worksheet also returns a reference to that worksheet. So, create the reference when you create the worksheet, and then refer to it later.
Sub AddSheet()
Dim sheetName As String
Dim wsNew As Worksheet
'Get the sheet name, however you're currently doing it
sheetName = "NewSheet"
Set wsNew = Worksheets.Add()
wsNew.Name = sheetName
'Do the rest of the stuff
wsNew.Range("A1").Value = "Hello"
End Sub

Related

Set updated date on the active tab only

I have done some things in SWIFT but this is my first project in VBA.
How can I set a field on an active tab to be the modified date of the tab? I have tried to use a Sub Workbook_open () procedure but this is my first attempt at VBA and after several ours of looking, I am no closer.
Some more detail: This workbook has multiple users who are assigned a specific tab. As their manager I need to know the last time they accessed their tab so I wanted to have that entered programatically. I have a "Reference" tab that holds variables and I have an updated date cell (D2) that is referenced on the individual tabs for each user.
Here is what I have tried but the debugger doesn't get passed the first line :(
`Private Sub Workbook_Open()
Dim Sheet As Worksheet: Set Sheet = ThisWorkbook.Worksheets("Reference")
Dim Entry As Range: Set Entry = Sheets("Reference").Range("D2")
Range(D2).Value = Date
'Debug.Print MyRNG.Value
Entry.Value = Date
End Sub`
Thank you in advance.
You can use the Worksheet_Activate event in the sheet module. It fires when a worksheet is activated. You can write code that puts a date/time stamp into a cell somewhere in the workbook.
Remember, this code goes into the Sheet module, not a code module.
Private Sub Worksheet_Activate()
' this writes just the date into the current sheet's cell A1
[A1] = Date
' this writes the date and time into A1 on Sheet2
ThisWorkbook.Worksheets("Sheet2").Range("A1") = Now
End Sub
Be aware that this code fires when ANYONE activates the sheet. If you want to log activities of specific people only, then you need to add more refinement.

Can't activate sheet: "Object Required"

I got an error 424: Object Required.
It's a very simple script, I can't see where I'm going wrong.
The strange thing is, this worked many times before. I am only getting these errors today.
I rename sheet one as "All Data". Then add another sheet and rename it "List".
The error happens when I try to activate the "List" sheet. Object Required. I guess it can't detect the new sheet? Where am I going wrong? As I said this worked 100 times before.
Sheets(1).Select
Sheets(1).Name = "All Data"
Sheets.Add After:=ActiveSheet
Sheets(2).Select
Sheets(2).Name = "List"
List.Activate ' error happens here
I have also tried List.Select instead of Activate. Same error.
If List is not the VBA name of a sheet it has to be defined:
Dim List As Worksheet
Set List = ThisWorkbook.Worksheets("List")
or make sure the VBA name of that sheet is actually changed to List in the properties window of the VBA editor.
List.Activate activates a sheet which VBA name is List
Worksheets("List").Activate activates a sheet which tab name is List
note that these 2 naming systems are completely independent.
You might benefit from reading
How to avoid using Select in Excel VBA.
Worksheet(1).Name = "All Data"
Worksheet.Add(After:=Worksheet("All Data")).Name = "List"
Worksheet("List").Activate ' don't use activate! see link above
or
Worksheet(1).Name = "All Data"
Dim List As Worksheet
Set List = Worksheet.Add(After:=Worksheet("All Data"))
List.Name = "List"
List.Activate ' don't use activate! see link above
Don't mix Sheets with Worksheets they count differently. Sheets contains all types of sheets like worksheets, chart sheets, etc. but Worksheets only contains worksheets.
If you have 2 worksheets and 1 chart sheet:
Worksheets.Count is 2 but
Sheets.Count is 3.

How to use result of input box as a worksheet name in VBA code

I'm really new at VBA and have learned what I know so far from internet searches, but I cannot find a resolution to my issue.
I have two workbooks, one with information on all of my company's current projects and another with just the active projects. The Active Projects workbook is where we store all the documents that need reviewing for each project. Each project has it's own worksheet.
When I create a new worksheet in the Active Projects workbook, I would like to use a macro to fill in the relevant project information from the All Projects Workbook.
I have seen code that copies cells and ranges from one workbook to another, but they have the sheet names hard coded in. Like this:
'Copy range to in selected row to clipboard
Workbooks("All Project.xlsx").Worksheets("All Open").Range("B" & (ActiveCell.Row)).Copy
'PasteSpecial to paste values, formulas, formats, etc.
Workbooks("Active Projects.xlsm").Worksheets(InputBoxValue).Range("A2").PasteSpecial Paste:=xlPasteValues
I thought to use an input box to ask for the worksheet name where the copied data would be pasted, but after hours of research, I cannot find out to use the result of the input box for the worksheet name.
Thank you for furthering my VBA education
FYI - this is at high risk of someone putting in the wrong sheet name given the nature of free-form text. That is something you will need to handle on your end so I suggest you look up:
How to check if a sheet given name exists on a book
How to loop a InputBox until an acceptable input is given
Dim Sheet_Name As String
'Get Input
Sheet_Name = Application.InputBox("Enter Sheet Name", Type:=2)
'Use Input
MsgBox ThisWorkbook.Sheets(Sheet_Name).Name
Dim InputBoxValue As String
InputBoxValue = InputBox("Enter sheet name")
'PasteSpecial to paste values, formulas, formats, etc.
Workbooks("Active Projects.xlsm").Worksheets(InputBoxValue).Range("A2").PasteSpecial Paste:=xlPasteValues
Below code will rename active sheet :
Sub Rename_Worksheet()
Dim Str As String
Dim Ws As Worksheet
Set Ws = ActiveSheet
Str = InputBox("Please provide new name for Worksheet : " & Ws.Name)
Ws.Name = Str
MsgBox "Worksheet renamed successfully to " & Str
End Sub

Naming a Cell in Excel

I'm trying to create a series of macros to audit some financial models.
The first macro I’m trying to create is one that names the current cell. Why? I want to name the cell, after that I’m going to record a macro to click the “Trace Precedents” and go to the cell that has the relationship.
After that I need to go back to the original cell, thats the named one. That's easy on the go function, but I need to the naming macro working
My recorded code for the naming macro is as follows:
Sub Namer ()
ActiveWorkbook.Names.Add Name:="Name1", RefersToR1C1:="=Workings!R42C6"
ActiveWorkbook.Names("Name1").Comment = ""
End Sub
I have the following problems:
I need to name the current cell on a workbook with a lot of sheets. I’m gonna be moving between sheets but my recorded code has a “fixed” sheet.
How can I fix that? Name the current cell on the current sheet
Something like this should help you ...
Public Sub CreatesNames()
Dim objSheet As Worksheet
For Each objSheet In ThisWorkbook.Worksheets
objSheet.Names.Add Name:="Name1", RefersTo:=objSheet.Range("A1")
Next
End Sub
... something to note, names can be created at the worksheet level or at the workbook level, so, if you're going to be creating the same name across worksheets then you need to use a Worksheet object, not the Workbook object.
So to use the active cell ...
Sheet Level
ActiveSheet.Names.Add Name:="Name1", RefersTo:=ActiveCell
Workbook Level
ActiveWorkbook.Names.Add Name:="Name1", RefersTo:=ActiveCell
I hope that helps.

VBA to check if last cell equals cell on different sheet

I have a spreadsheet that is used to log information. In one sheet you enter the data then VBA updates a second sheet where the info is stored.
I want to write a code that will check if a cell on the last row of the log (which will be changing as it updates each time) equals a cell on the input page.
The aim is to stop someone updating the log twice, I already have an alert that it has been updated but want to put a foolproof system in place to stop an entry being logged twice.
I am new to VBA so do not really know where to start.
The below is an example of achieving this. I have added comments to explain what is happening in the VBA.
In Excel, press Alt+F11
In the project window on the left, expand it if its not already and
double click on 'ThisWorkbook'
If it is not already there, type Option Explicit as the first
thing in the main window. This means the code will not run unless
all variables that are used are declared, this is good practice
Past the below code into the window
With the cursor in the code you can press F8 to run it line by line
to see what is happening or F5 to run it in one go.
You will want to adjust it to your required workbooks, worksheets, and cells/columns.
Public Sub Sample()
'Clearly declare variables, in the case we are using them
'to reference a workbook and a worksheet
Dim WkBk As Workbook
Dim WkSht As Worksheet
'Set the WkBk variable (which was declared as a workbook,
'which means it can only be used for workbook objects.
'I this instance we are refering to ThisWorkbook,
'which is as it sounds.
Set WkBk = ThisWorkbook
'We can now make a reference to a specific worksheet
'within our referenced workbook
Set WkSht = WkBk.Worksheets("Sheet2")
'This IF statement is comparing the value of cell
'A1 on Sheet1 to the the value of the last populated cell
'in column A of Sheet2 (the sheet we created a reference to)
If WkBk.Worksheets("Sheet1").Range("A1") = WkSht.Range("A" & WkSht.Rows.Count).End(xlUp) Then
MsgBox "It was a match"
End If
Set WkSht = Nothing
Set WkBk = Nothing
End Sub

Resources