I'm currently working on a macro that modifies a standard format of spreadsheet. This will be used for many spreadsheets by several people in my company. So I've created an addin that everyone should be able to install and use.
However not all the spreadsheets will have the same name for each sheet.
Originally I tried referring to the sheets as
Sheet1.Range...
This gives
Run-time error '424':
Object required.
I can make it work with
Worksheets('name_of_worksheet').Range
But this requires the user to change that every time they wish to use the addin in a different spreadsheet, or to rename the sheets.
Is there another way of referencing the 'first' and 'second' worksheets? They will always be in that order and created in that order.
I believe this is to do with having saved the macro as an addin since I've never had this issue.
Thank you!
Edit:
The reformatting of the spreadsheet depends on data found in sheet 1 and sheet 2. So within the macro I need to be able to refer to both of those sheets. The name of the sheets will not always be the same, so I would rather not have to use:
Worksheets('name_of_worksheet').Range
Using Active Sheet is also not ideal since there will only be 1 active sheet, and I need to access both sheets.
Sheets(1).Range
does not work either, I get the error:
Run-time error '424':
Object required.
You could make a ugly hack and loop two sheets.
i = 1
For Each Sht In ThisWorkbook.Sheets
If i = 3 Then Exit For
Debug.Print Sht.Name
i = i + 1
Next Sht
This loops all sheets and when two sheets has been looped the code exits the for loop.
In the loop you could save the sheet names to variables or perhaps use this as the base of your code and add your code instead of the debug line.
Related
I am making an Excel 2016 database. Part of the design are large Consolidated Data worksheets that reference cells in monthly data sheets. For example, the Consolidated Data sheet may reference:
='Datasheet Feb2017'!D3
Although many cell references are more complex:
=IF(ISREF('Datasheet Jun2017'!A1),IF(XLOOKUP($A4,'Datasheet Jun2017'!D4:N4,'Datasheet Jun2017'!D6:N6,NA()) = "", NA(), XLOOKUP($A4,'Datasheet Jun2017'!D4:N4,'Datasheet Jun2017'!D6:N6,NA())),NA())
These references work as intended. When the datasheet exists, it displays the appropriate data. When the datasheet doesn't exist, it displays #N/A. I do this so that as I add additional months of data, the consolidated data worksheet automatically updates. A limited number of these references to not-yet-created workbooks are constructed through INDIRECT.
The only problem is that upon opening the workbook I will always get this message:
This workbook contains links to one or more external sources that could be unsafe.
If you trust these links, update them to get the latest data. Otherwise, you can keep working with the data you have.
This is strange because there are no external links. All references are internal. When I select Update:
We can't updates some of the links in your workbook right now. You can continue without updating their values, or edit the links you think are wrong.
I suspect this is referring to the references to not-yet-created worksheets.
This is a macro-enabled workbook.
How can I prevent both of these dialogues on startup?
I found a solution to an adjacent question that seems to work, from user zerala:
I put this around my startup macro:
ThisWorkbook.UpdateLinks = xlUpdateLinksNever
Application.DisplayAlerts = False
'your macro
ThisWorkbook.UpdateLinks = xlUpdateLinksAlways
Application.DisplayAlerts = True
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.
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/
I am trying to print the active worksheet and another worksheet with general information (in the same workbook) at the same time. (Recto verso, which my printer does automatically, no code needed for that)
In my workbook I have multiple sheets that use the same code for printing. Now I would like to add the sheet with general information called "Huurvoorwaarden" to an array so it is printed automaticaly and at the back side of the active sheet.
I have tried multiple sollutions like dim / set activesheet.name, and codes which I have found on the web. nothing works.
I know that when I would change "activesheet" to Sheet1, that would work, but only for sheet 1.
Could you please help me?
Here is what I have got: (all my older attempts are deleted)
'Print Active Sheet and sheet Huurvoorwaarden
Worksheets(Array("activesheet.name", "Huurvoorwaarden")).PrintOut
The name of the active sheet is not the string literal "ActiveSheet.Name", it is the property ActiveSheet.Name.
So you need to use
Worksheets(Array(Activesheet.Name, "Huurvoorwaarden")).PrintOut
I'm referencing an excel document with the JET database driver, which was working just fine until one day the application failed. Upon further investigation I noticed that the tabs were duplicated in some instances (all tabs actually) - i.e. Tab1$ and Tab1$_. I've researched this issue and found that it is caused by the user applying a filter. Now the filters have been removed, no special formatting, frozen panes, or print formats, but still I have these tabs duplicated. Normally I'd code around this, but since we're in a code freeze I need to come up with an Excel based solution. I want to get rid of those crazy underscored tab names / reverences. I could probably run a program to clean up the file if necessary, to send it back to the users, but I want to explore Excel options first. Thoughts? I have Excel 2010, and access to any other version as well.
The underscore "sheet" is a named range. Is it possible for you to run VBA? if so:
Dim defName As Name
''Either
With ThisWorkbook ''Entire workbook
For Each defName In .Names
MsgBox defName.Name
defName.Delete
Next
End With
''Or
With Sheets("Sheet1") ''Scoped to sheet only
For Each defName In .Names
MsgBox defName.Name
defName.Delete
Next
End With