Access sub in a sheet when workbook is closed - excel

I want that whenever the workbook is closed a Sub from a sheet(sheet13) should be called, but as shown in the screenshot Im getting the error Invalid or unqualified reference.
By now I have tried
B2_Click
!Sheets("sheet13").B2_click
!Sheets("Employee Names").B2_click
Thisworkbook.Sheets("Employee Names").B2_click
And I am getting an error every time.

Your last example should work, so I would direct my troubleshooting towards the method you are calling. Try this in a new workbook:
In ThisWorkbook module
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Worksheets("Sheet13").Test
End Sub
And in Sheet13 module
Sub Test()
MsgBox "Closing"
End Sub
If that works, you have a starting point.

First off, the easy solution as already mentioned by others:
ThisWorkbook.Sheets("January").Something (string is case sensitive!)
There are multiple ways to reference a Sheet, and there are different types of names for worksheets. You have to differentiate between the "CodeName" and the "Name".
You will easily find more information on the difference between those two.
The main differences are, that the Name can be changed by the user, it is the name visible on the tab at the bottom of the Excel Interface.
The CodeName can only be changed through the VBA Interface.
The CodeName and the Name are usually identical when creating a worksheet (Sheet1, etc..).
To Reference a Sheet by Name you can use this code:
ThisWorkbook.Sheets("SomeName").SomeFunction()
The CodeName can be used directly like this: Sheet2.SomeFunction(), but I'd recommend changing the CodeName to something meaningful/expressive first!
(Name) is the CodeName, Name is the visible Name
More information on the Bang operator ! can be found here:
https://rubberduckvba.wordpress.com/2018/03/15/vba-trap-default-members/
Extensive Answer on referencing Sheets:
https://stackoverflow.com/a/41481428/10223558

Related

Is it not a good Idea to use the Set Worksheets method multiple times during code execution?

I am attempting to copy different images to different worksheets of my Workbook using the following code below. I am changing the Target Worksheet Dynamically in a different sub, with a String Variable in the Global Declarations section. I can see the variable being passed to the sub and in fact it works the first pass through the code, but when I attempt to change the "TargetSheetIni" variable to a new sheet, it continues to use the first original sheet as it loops through.
Can you not change a target sheet after using the Set keyword? Should I refer to the sheet directly instead?
Sub Test1()
Dim TargetWS, SourceWS As Worksheet
Set TargetWS = Worksheets(TargetSheetIni)
Set SourceWS = Worksheets("Images")
DoEvents
SourceWS.Shapes(CurrentImageId).Copy
DoEvents
TargetWS.Paste Range(ColumnLetter2 & RwCnter)
DoEvents
End Sub
I think I may have figured it out. As far as I can tell the issue may be that I used the Copy Sheet Functionality in Excel when I originally created the target sheets. And even though I renamed the sheets both on the tab below and in the project editor... for some reason VBA kept targeting only the original sheet
I proved this by changing my code around to explicitly call the sheet I wanted to target like so:
ActiveWorkbook.Worksheets("Sheet2").Paste Range("I2")
And even doing that it would target sheet 1 for the paste command instead of the expected sheet 2. I deleted the three copy sheets and created a new one from scratch and re-executed code and now it targets sheet 2 as expected.
I found this article that sort of explains it I guess...
https://www.spreadsheetsmadeeasy.com/7-common-vba-mistakes-to-avoid/
Ok my last answer may have not been correct. It appears as though for some reason inserting an ws.activate caused my code to start workin.g
Very frustrating fix. as I have always heard to avoid using that.

Excel VBA refer to worksheet that uses icon/emoji as part of name

I'm using Excel for Office 365 MSO 64-bit.
I want to write a VBA macro that selects different worksheets in a workbook based on the worksheet's name.
For example, I have two lines of VBA code that activate a workbook and then select a specific sheet in the workbook by the sheet's name.
Windows("myworkbook").Activate
Sheets("mysheet").Select
However, I have to work with some sheets that contain icons or emojis in them. For example, there is a worksheet that has this name: "🚑 Patient".
If I try to paste the icon/emoji into VBA like this: Sheets("🚑 Patient").Select, the icon does not show up in the VBA editor. Instead, I get Sheets("????? Patient").select.
I have also tried to use ChrW() to encode? the ambulance character (see here: https://www.compart.com/en/unicode/U+1F691)
When I run this macro below), I get an invalid procedure call or argument as noted below.
Sub SelectWeirdSheet()
Windows("MYWorkbook.xlsx").Activate
x = ChrW(128657) ' get invalid procedure call or argument here
Sheets(x & " Patient").Activate
End Sub
I also tried code for ambulance... also tried ChrW(&H1F691), but I get the same error.
My suspicion is that I am using the wrong argument for ChrW(), but I'm lost.
edit: So, the docs say that my argument for ChrW() is out of range. That helps explain the error, but I'm still missing a work-around.
Question: Is there a way to refer to use VBA to select worksheets that have an icon/emoji as part of their name?
I know you can also refer to worksheets by index number like this Sheets(3).Select.
However, there will be instances where I don't know the index of the sheet ahead of time, but I will know the name of the sheet, so it is preferable for me to call the worksheets by name.
Thank you.
In addition to the self-answered response, when working in a single workbook, the coder can assign a CodeName to the sheet in the VBA IDE, and then use that CodeName directly. This is really only valid if the Sheet is not re-created (i.e. is a permanent sheet in the book) at any stage, because a new/copied sheet will be automatically given a new CodeName by Excel.
For example, if given the CodeName shtPatient (see picture bellow), the code could be:
Sub SelectWeirdSheet()
' Windows("MYWorkbook.xlsx").Activate '<-- this approach has limitations
shtPatient.Activate ' See my comment below about the limitation - this will not work as expected in this example.
End Sub
Note: https://stackoverflow.com/a/10718179/9101981 explains why not to use Activate, but I have left the code as-is for the purposes of this answer. Also look at Using Worksheet CodeName and Avoiding .Select & .Activate. Another limitation noted is that the CodeName is only valid for the workbook that the code is in - so may not be applicable in this case.
I have highlighted the CodeName parts of the IDE in the image below, see how "Test Patient" is not called "Sheet7", but instead has a meaningful name that I gave it in the properties window below.
In order to properly address the emoji, it should be split into two separate unicode characters.
In this case, it would be x = ChrW(&HD83D) & ChrW(&HDE91)
Those two unicode characters make up the ambulance emoji.
So, this Macro now works.
Sub SelectWeirdSheet()
Windows("MYWorkbook.xlsx").Activate
x = ChrW(&HD83D) & ChrW(&HDE91)
Sheets(x & " Patient").Activate
End Sub
Found the solution on reddit of all places https://www.reddit.com/r/excel/comments/6pq1r1/vba_how_can_i_write_emojis_using_chrw/

Invalid use of property Excel VBA

Sub test()
Worksheets("Sheet1").Range("A1").Value = 20
End Sub
This simple code is giving error when I compile it.
activesheet. works fine.
I want to know whats resulting in an error and how to fix it...
looks like it's not identifying the sheets, workbook etc.
The answer depends on which error you get. There can be 2 issues:
1. Workbook not specified
You have more than one workbook and Excel is looking in the wrong workbook for your sheet named "Sheet1", then you need to specify the workbook.
Workbooks("my-workbook").Worksheets("Sheet1").Range("A1").Value = 20
or if it is in the workbook where the code is running at it is better to use
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = 20
Note that you should avoid ActiveWorkbook which is not very reliable.
2. Wrong worksheet name
There is no worksheet named Sheet1. Check your worksheet names. Note that there are different ways to specify a worksheet.
Specify by number
Worksheets(1).Range("A1")
This uses the position of the worksheet in the tab bar below the worksheets. Note that is not very reliable because position can easily be changed by moving the tabs around.
Specify by tab name
Worksheets("Sheet1").Range("A1")
This is probably the most common method. The worksheet is specified by its tab name. This is more reliable than by number.
Specify by VBA name
Sheet1.Range("A1")
Here the VBA name of the sheet is used. This name can only be changed in the VB editor and is not visible to the user, and has nothing to do with the tab name. Using this ensures that the VBA code still works on the desired worksheet even if a user changes the tab name of the worksheet.
So if the tab name is Sheet1 its VBA name can be Sheet5 and it can be on position 3 in the tab bar.
Using this example …
Worksheets("Sheet1").Range("A1")
Sheet5.Range("A1")
Worksheets(3).Range("A1")
… are all 3 accessing the exact same worksheet just by different names. So better to use meaningful names (and no numbers) here to not confuse.

Copy all named ranges to another workbook

So I've been fussing with the Microsoft Support answer to this question but their code is simply not working. I'm confused about how they do not define x, or maybe x always equals a variable in VBA? Anyway, I am trying to copy all named ranges in one workbook and bring them over to another workbook. I have to do this for 50-odd workbooks and there are 30-40 named ranges in the base workbook. I really do not want to have to copy-paste these buggers manually. Here's the code they gave for this problem:
Sub Copy_All_Defined_Names()
' Loop through all of the defined names in the active
' workbook.
For Each x In ActiveWorkbook.Names
' Add each defined name from the active workbook to
' the target workbook ("Book2.xls" or "Book2.xlsm").
' "x.value" refers to the cell references the
' defined name points to.
Workbooks("trial run.xlsm").Names.Add Name:=x.Name, _
RefersTo:=x.Value
Next x
End Sub
Running this gives me the following error:
and highlights the following code:
"trial run.xlsm" is just a blank workbook and is saved as macro-enabled; this is my target workbook. Seems silly to have to ask for help debugging a macro that microsoft wrote, but I'm kinda at the end of my rope here.
For the original page I got this from, see here: Microsoft Support
This is what my named ranges look like:
Hard to tell but I suspect that your RefersTo string is >256 characters: If so it will fail because VBA cannot handle refersto strings>256 characters.

Trying to reference another worksheet in active workbook

I am trying to make another worksheet active when command button is clicked, but I'm staying within the same active workbook:
Sub Submit_Warranty()
'Set warranty data worksheet as active page
Sheets("Sheet2").Activate
'Show the submit warranty user form
Warranty_Input.Show
End Sub
I keep getting "subscript out of range" error. Any ideas?
If the code you posted is everything, then that error pretty much has to be from an invalid reference. So my guess would be that the actual displayed name is something like "Warranty_Data", while "Sheet2" is likely the VBA object name (maybe you're using them in reverse).
There are a lot of ways to select a worksheet, with various advantages and disadvantages. When it comes to selecting by name, the major gotcha to watch out for is that sheets actually have two names assigned, and you're employing both methods of selection in the code you posted. The one name is what's displayed in the sheet's workbook tab, the other name is internal to VBA. Here's a screenshot to demonstrate how to use both types of names.

Resources