A worksheet can be identified by its name such as in this example:
Dim mysheet As Worksheet
Set mysheet = ThisWorkbook.Sheets("My Sheetname")
Now I wonder if a worksheet can be identified other than by its name, for example by some unique id or some property or whatever.
My problem is following:
Referring to the code snippet above: if a user changes the name of the worksheet (e.g. from "My Sheetname" to "Your Sheetname"), the snippet obviously won't work anymore.
This is a very good article that explains that it is better to use the SheetID (also called codename) instead of the Sheet Name.
Quoting:
The Codename property is the internal name that Excel uses to identify
each sheet. Unlike the Worksheet.Name property, the Codename remains
the same regardless of sheet name, or sheet order.
The code name can also be changed so that it is more descriptive:
ThisWorkbook.VBProject.VBComponents("Sheet1").Name = "Revenue_Actuals"
and then
Revenue_Actuals.Range("C2").value = 10
works fine.
Using codenames (such as Sheet1.Range("C1").value) is a good idea, however changing code names at runtime as above is not considered good practice by some developers (see for example, comments on the article of the link above).
Using the sheet index is another way to go, but I personally prefer the code name.
Finally, this article lists many ways that a sheet or workbook can be referenced.
I hope this helps!
You can just access them by index like e.g. for the second sheet
Set mysheet = ThisWorkbook.Sheets(2)
Related
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/
So there are a few ways to set a worksheet in Excel.
set WS = Sheets("Name Here!")
set WS = WB.Sheets("Name Here!")
set WS = shNameOfTheSheetObject
However, there doesn't seem to be a way to do:
set WS = WB.shNameOfTheSheetObject
I'd like to know how, if it's possible, I can get this type of reference to work. I like being very, very explicit with my code (Perhaps too much so), and it'd be useful to know if I have multiple workbooks open that I'm handling.
I think there is a slight confusion on how the access via the code name works. When you get a worksheet via ThisWorkbook.Worksheets("SheetName") you query a collection on the workbook; when you use the code name, you get the corresponding component of the VBA project containing your project, which implements the Worksheet interface.
Both are the same object, but the resolution of the identifier takes a different path: a workbook does not know about the VBA components. Consequently, as #Comintern mentioned in the comments, you can only use the project name of the containing VBA project as further qualifier. That name is whatever you set it to via the project properties dialog. If you do not change it, it will always be VBAProject in Excel, which is not very helpful.
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.
I am new to excel vba and I have some questions regarding referencing a worksheet
I noticed that when I used
Worksheets(3)
The worksheet would be obtained according to the sequence of the worksheet in the workbook
When I used
Worksheets("Name")
It would be retrieved according to the name of the worksheet
However, I found that both approach is troublesome because for method 1, I need to fix the sequence of the worksheet. Once I dragged the worksheet around, the reference would become incorrect.
Method 2 would need me to fix the work sheet name , which is not that flexible.
I noticed that at the left panel of VBA editor, under the Microsoft Excel Objects, whenever the worksheet is created, a new sheet like
Sheet1 (Name) would be created.
Is there any way that I could reference the worksheet based the the Sheet1 variable, which I could fixed it so that I could freely drag the sheet around or change the worksheet name?
Thanks.
The name you refer to is called the CodeName. You can refer to a sheet by this name.
Eg, for your example Sheet1 (Name) can be referenced as
Worksheets("name")
or
Sheet1
Eg Worksheets("name").Activate or Sheet1.Active would both work
Note that you can change this name to something meaningful in the Properties window of the VBA IDE, but you can't change it at run time
A friend of mine works as an analyst for an insurance company, and uses Visual Basic for Applications (VBA) to write scripts.
Since her company has offices in different European countries, she needs to make the scripts as language-independent as possible.
One issue that came out recently is how to handle Excel documents and refer to sheets (eg. Sheet1, Sheet2) without having to translate this term in the major European languages.
Does someone know if Excel provides a list of constants that she could use to access different pieces of information regardless of the localized version of Windows/Excel?
Thank you.
You should never use hard-coded names of worksheets to refer to them in VBA.
Dim s As Worksheet
For Each s In ActiveWorkbook.Sheets
DoSomethingWith s
Next s
or
Set s = ActiveSheet
DoSomethingWith s
or
Set s = ActiveWorkbook.Sheets.Add()
DoSomethingWith s
or
Dim i As Long
With ActiveWorkbook.Sheets
For i = 1 To .Count
DoSomethingWith .Item(i)
Next i
End With
In cell references however, using actual sheet names is inevitable. These references could be built on demand by VBA. Existing references (in cell functions) are kept up to date by Excel automatically.
In the VBA editor, you can rename worksheet objects; this totally separate from the worksheet name displayed on the tab at the bottom of the screen.
I usually rename them something like wksData and wksSummary, and use code like
wksSummary.Range("A1").Value = "abc"
Users can rename the worksheets as they wish, but the VBA reference remains the same.
The name of the worksheet can be retrieved, as in the example below:
MsgBox wksSummary.Name