Excel VBA - Run macro on Application open - vba

I've got this Design Template I want to apply to the application by default whenever it's opened. But a document needs to be open in order to apply a Design template. So I have to target some handlers whenever a new or existing workbook is opened/created.
So which approach can I take here?

I think you can use the Workbook_open event. It sounded like that would be sufficient for the behavior that you want, but since you want your macros to be global, you might need to make them into an add in for them.

The add-in approach is best for applying to existing workbooks.
If you're looking to have a standard design template applied to each new workbook, though, I suggest you create a template.
To do this:
Create a new empty workbook
Apply the design template
Save the file as Book.xlt (for Excel 2003; Book.xltx for versions 2007, 2010) in the following folder: %appdata%\Microsoft\Excel\XLSTART\
Each time you create a new workbook (by opening Excel or hitting the "New" button), it'll be generated from this template file.

Related

Excel 365 Formulas - How to save LAMBDA function permanently (for all existing and new files)?

I would like a global solution every time I start Excel365 with my key add-in also firing up.
I defined several LAMBDA custom functions, saved them in my add-in, and I would like to make them available globally - not just only for the current workbook. Is it possible? I tried saving a workbook with definition as an add-in (.xlam) but the formulas are not available. The don't seem to be available when as an add-in. When I am in the add-in parent file on the desktop, all is good and everything is running. But once I post the file back for your as an add-in, The Lambda(s) and the defined name space go away.
You might try creating a template for excel to load when it is opened.
Customizing how Excel starts so it utilized the template.
My additional work around is also simple. If the LAMBDAs were saved in the original Workbook with "Workbook" as the saved parameter. Then each of those worksheets in the original LAMBDA workbook is "infected" with all of the workbook LAMBDAs. Therefore, I simply copy a blank worksheet from the original Workbook to the "new" workbook. Then by virtue of "infection" the new workbook is also newly infected with all of the new LAMBDAs. It works just like COVID, who knew?

Normal.dotm equivalent in Excel for referencing the same single VBA code

Just curiosity.
The only way I know so far is to create an add-in with code, put it in some trusted directory and hope it opens when you need it. The drawback is that it sometimes does not open together with application (e.g. I have a custom UDF in the add-in, I use it in the worksheet and an error is what I get, because the addin hasn't started). For this I have a button on my ribbon which calls a sub in the addin which does nothing, but then the addin is activated the UDF works.
Is there any other efficient way to reference code in another workbooks, like in Word we have normal.dotm template?
Indeed, Excel DOES have a common code file, similar in concept to Word's normal.dotm. It is called Personal.xlsb. I use it myself for common functions that I need for several linked yet independent spreadsheets.
Using Personal.xlsb has some disadvantages too, so you'll have to decide if that works better than the Add-in approach. Note that Personal.xlsb works best when its just one person needing common functions across spreadsheets; its not well suited for multi-user access to the spreadsheets in an enterprise environment.
Some useful links are below to get started. Also just google search "excel Personal.xlsb" and you will find a lot more information:
http://www.rondebruin.nl/win/personal.htm
http://chandoo.org/wp/2013/11/18/using-personal-macro-workbook/
To create an equalevant to normal.dot in Excel do this (at least ver. 2016):
Record a macro from the Developer tab (you likely have to enable this tab first)
This will create the file %appdata%\Microsoft\Excel\XLSTART\PERSONAL.XLSB which is Excel's equalevant to normal.dot
Now unhide the hidden workbook called "PERSONAL.XLSB"
Press Alt+F8 or Alt+F11 to edit the VBA code
Extra: VBA example for SaveAs:
Application.Dialogs(xlDialogSaveAs).Show

How to open add-in automatically on opening excel workbook

I want to know how I can have a workbook automatically open an add-in? The problem is after I create the workbook in code -- call it "A.xlsx" -- I want to add code to it (on creation) that will open the Excel add-in "B.xlam". How do I do this? Creating the workbook is no problem; that part is sorted, and I just want to add the code to that workbook, so that every time it opens it must open the add-in "B.xlam" with it.
From the Developer Ribbon, click Add-Ins,
then click Browse, then navigate to the location of the desired add-in file, then select it, and make sure the checkbox is selected for it.
Alternatively, store the code in PERSONAL.XLS/PERSONAL.XLSB, and these macros/functions will be available to all open workbooks.
If you're somehow asking how to programmatically insert code in to new workbook files, I'm afraid you're out of your element. If you don't know about the Workbook_Open event, nor how to manage your Add-Ins, etc., manipulating the VBE is a pretty high-level operation, and I would not be able to help you with that.
Update from comments
Here is one method that will export VB Components to a specific path, example also includes code to import modules from path to a workbook. You should be able to adapt this to your purposes.
http://www.rondebruin.nl/win/s9/win002.htm
If you have specific problems implementing this solution, please post as a new question.

How do I add a library reference in vba so that it remains added every time I open a new workbook?

Forgive me, I'm still sort of new to this, but...
In vba within Excel, when I go to Tools - References I can add a reference and it works just fine. The box stays checked everytime I reopen that workbook.
However, if I create a new workbook, I have to re-establish the reference to that same library. How do I set this up so that the library reference I want remains checked all the time - at an Excel Application level as opposed to an Excel Workbook level?
Thanks
Follow these steps to Create a personal workbook.
Once you have created the workbook. Simply go to the VBA editor of the personal workbook and add the reference. Close all workbooks and now open a new one. You will see that the reference is already there.
In case the above link ever breaks. Here is a screenshot of that link.
I had the same problem. My solution was to use late binding instead of early binding for my outlook objects setting. With late binding, my code became agnostic of the outlook reference libraries. Thus, the code could easily be used on any computer without checking the referenced libraries. This is much more convivial for making macros for unsavvy users.

Standalone code for Excel

Can VBA code be written to perform actions on any Excel file?
When I create a project in Visual Studio, it asks for an Excel file to be linked to it. All the code that I write is in ThisWorkbook.vb and hence acts only on the Excel file linked to the project.
Ideally, I want a script that:
When the user double-clicks, he/she should be allowed to select an Excel file of choice for the actions to be performed on that file.
If the above is not possible, I'd at least like to invoke the VBA script from within an Excel file.
Basically, the VBA code should be independent of any Excel file.
I looked at VBScript, but the syntax for it seems to differ slightly.
You've mentioned Visual Studio, VBA, and VBScript. The solution I'm outlining works directly with VBA rather than Visual Studio or VBScript. (However, you might adapt Visual Studio (C# or VB) along the lines of what I'm outlining below.) Hope it's helpful, so here goes:
Here's what I do, and, it ultimately results in an .xlam Excel AddIn as #chris above has commented.
Overview
I start with ordinary .xslx workbook, to which I add a VBA project, making it an .xlsm. Then create some VBA Subs (macros). Then create some Excel QAT (Quick Access Toolbar) buttons for the workbook, which are bound to (i.e. they invoke) the VBA subs/macros. Then convert the workbook (with VBA in it) to an .xlam, which is an Excel AddIn. When you're all done, the buttons are accessible from any workbook (and the VBA code has access to any user workbooks as well as those originally in your .xlsm). Further, the workbook associated with the .xlam is invisible. So it just looks like you've added some buttons to the QAT that appear on all users .xlsx windows. The .xlam is pretty easy for users to install (though I provide a buttons to uninstall/reinstall/check version). You can upgrade an .xlam independently of users' workbooks; users' workbooks can thus be data only (.xlsx, no VBA).
Details
Write some Excel Subs you want to use later
You need to be aware that the buttons can only invoke macros (VBA Subs) without parameters, so the macros will have to check things like ActiveSheet and ActiveWorkbook and Selection to figure on what sheet the button was pressed, hence what user data to really operate on. (If you need to refer to your workbook with the VBA code in it, use “ThisWorkbook”). You should be aware that there can be naming conflicts, so try to name the parameterless subs with rather long names, such as MySomewhatUniqueProjectName_button1, etc…
Add Buttons to your .xlsm
Using Excel 2010 (I think this works with 2007 or later), I put workbook-specific buttons on the QAT part of the ribbon, which connect to macros (VBA subs) in the VBA code.
To do this, you from the Quick Access Toolbar customization drop down (the tiny down arrow at the very top row of the Excel window, the last icon from left to right) choose "More Commands…". When the “Customize Quick Access Toolbar” dialog box comes up, from the (2nd) "Customize Quick Access Toolbar:" heading (top to the right), choose "For XYZ.xlsm" from the dropdown instead of the "For all documents (default)". And from under "Choose Commands From:", use "Macros" (instead of “Popular Commands”) from the dropdown. Once you have those two things selected, you can move VBA subs from the left box to the right box using “Add >>”. Each so moved will become buttons visible in your QAT. As you’re doing this you can also edit the icon and text for the buttons, add a separator as needed (I always end with a separator in case other .xlam’s use the QAT). (Now is a good time to save this .xlsm.)
Convert the .xlsm into a .xlam
Then I convert the .xlsm to an Excel add-in, by merely saving it as an .xlam file. This will end up (1) hiding the workbook associated with the code you have (though it is still accessible to itself.). Further, now, (2) the (invisible, as now it's an .xlam) workbook will load whenever Excel is loaded. (To keep this fast for when users use Excel but don’t run my VBA code, I don't run any code when the .xlam is loaded, I only run code when a button is pushed.)
You can manage the AddIn using Excel’s AddIn manager. To update the AddIn, you have to use some trickery. While you can copy over it when Excel is not running, on the other hand, you cannot directly uninstall the AddIn, you can only disable it from Excel. But once disabled, you can delete the .xlam, and relaunch Excel, go to the AddIn manager to try to work with the (now gone) AddIn and you’ll get Excel saying it can’t find it, so do you want to delete it. Say yes, and it will be uninstalled.
FYI, Notes
I keep the .xlsm to edit later, but you can actually debug and edit the .xlam and later convert it back to an .xlsm with a minor bit of trickery: find its "ThisWorkbook" entry in VBA, and then the "IsAddIn" property, set to false, its workbook will suddenly appear and you can save as .xlsm, or edit its workbook and set the property back to true to resave as .xlam directly.)
Answer 1
You can do that in VB.Net too. Just make a regular project. (comment by #SLaks)
This worked for me very well and was exactly what I was looking for.
Answer 2
The very descriptive answer posted by #ErikEidt
I haven't tried this, but it seems like a good and alternative way of getting macros to work.