How to make .xlam add-in functionalities workbook specific? - excel

Currently my office is using an excel my team created to manage a certain kind of orders. This file has quite a lot of functionalities that are controlled by some hotkeys and a couple of userforms. Every couple of months when we want to add some new functions or repair some bugs every user needs to download the updated file. (The old file becomes unusable when a new version is available.)
​
To make this file more user friendly and to make it easier for us to manage the current version and distributing the new one I started to convert this file to an .xlam add in. I was inspired by a post a couple weeks/month ago about add in distributing in an office setting.
​
The problem I'm facing now is that ones the add in is loaded the add-in setting are used for every open workbook.
How I want the add in to be used is as follows:
When excel is started the add in tab is visible in the ribbon with 1 button visible. When this button is pressed a couple of sheets are added to the workbook with the basic data that is needed. And all the other buttons are now visible and enabled.
​
The problem is that once that activation button is pressed all the other buttons are also visible and usable in every other workbook the user has open or opens.
​
So, my question is, is it possible to make the buttons of the custom ribbon (visible or not visible) workbook specific? And this way the functionalities of the add in only available when the activation button is pressed in that specific workbook. And lastly making the variables defined in the add in also workbook specific?
​
Is this all possible with an .xlam add in or do I need to start with VTSO?
​

It is possible to do this within the file. In your callback, you can use
Call RefreshRibbon(Tag:=""), which won't return any macro matches (by design) and therefore all will be disabled. This is a great resource with several examples.
https://www.rondebruin.nl/win/s2/win013.htm

Related

Creating custom Excel Ribbon Tab, which works in any workbook

I have surfing the net for months already and haven't really found a solution to the following task I would like to perform. Here is a deal.
I am writing a bunch of code in VBA, which basically creates a new worksheet in a workbook with a specific type of calculators (there are many) for job purposes. One sheet - one type of calculator/analysis.
What I want to accomplish is, that due to increasing amount of code - I would like to put everything on to the ribbon, so I can access a macro through that. However, the job is based on to the case-to-case analysis basis, so the each new project requires a new Excel workbook to be created, where I can choose the calculator I want and do the job.
In addition to that, it requires to be launched on all computers with Excel in the network, with ability for me to be able to modify/add a code to the macro, so that all PC's can stay up-to-date simultaneously.
To wrap-up shortly:
There is a bunch of VBA macros (which I'm constantly updating/adding);
I need to access those macros through the Ribbon in any new workbook (not the one macro are located) on a number of computers in the network;
There is a need to provide instant updates of the code for Ribbon and macro users.
SO, is there any solution, like - I create 2 files (one with Ribbon configuration, another with calculators) and drop them into the server folder? Each user access them once during the installation (basically locating the folder, where the addins are located), and if I need to modify something - I do it with those two files in the server folder and that's it.
If it's not real or pretty hard (for non-programmer) to instantly update all the users, the manual update can work out, but the minimum of being able to access the ribbon in each new workbook is a must.
Thank you in advance for help.
Thanks to all of you folks, who contributed on the question. Want to summarize the experience and provide the way I managed to go with it.
1) Get your VBA code
Let's have a code like this. It can be whatever you feel like. To do so, open VBA in the Developers tab or by pressing Alt+F11. Create a new Module, by right clicking on VBAProject > Insert > Module, name it sayMsg in the Properties window and enter the following code:
Sub saySomething()
MsgBox "What's up?"
End Sub
As I said above - this module can contain anything, usually the functional part of your code, which is going to be called out in another module later.
Let's create a new module the same way we created the first one and name it sayRibbon. This separate module contains a call function or so called "button", which runs our subroutine from sayMsg module. Copy > Paste the code below:
Private Sub sayButtons(Control As IRibbonControl)
Select Case Control.ID
Case Is = "saySomething_Btn"
Call saySomething
Case Else
End Select
End Sub
Basically, what we have here is a Case named saySomething_Btn, which is the "button" itself, with its defined call function.
Now save it as Excel Add-in file .xlam and close the program.
Notice: when you choose .xlam from a drop down menu, you will automatically be located in default Microsoft > AddIns folder. In order to save it on your Desktop, first of all choose the file type, and then relocate the folder.
2) XML map by Office RibbonX Editor
The utility above provides you with the option to create a custom tab in the Excel ribbon. Follow the link for download. All installation and use instructions are also available by that link.
After you finish with an install, open OfficeRibbonXEditor.exe file.
File > Open your .xlam file. Now it appeared in the list below.
Right click > Insert Office 2010+ CustomUI Part (or Insert Office 2007 CustomUI Part - depends on the Office version you are running).
Copy > Paste the code below:
Code
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" xmlns:Q="sayRibbon">
<ribbon startFromScratch="false">
<tabs>
<tab idQ = "Q:rxTabUI" label="Say Something" insertAfterMso="TabView">
<group idQ="Q:rxGrpUI" label="Say">
<button id="saySomething_Btn" label="Say Something" onAction="sayButtons" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
Press Validate, in case of issues - the error message will appear (Debug if needed, but you shouldn't in this case).
Now Save and Close the Ribbon Editor. You can only save, when .xlam is not opened by Excel.
3) Access the .xlam Add-In in any WorkBook
The main purpose of such approach was to provide an easy access to the VBA code from any Workbook in Excel and from any machine in the corporate network without actually installing it separately on each individual computer.
It doesn't really matter - do you want to get access only on your PC or local network, the installation process is the same.
Place .xlam file to any location of your choice (local folder or server).
Go to Excel > File > Options > Add-Ins.
Press Go... button below, Browse for the .xlam location and press OK.
Ensure the Add-In is marked in a list. Press OK.
Notice: I would recommend to encrypt your VBA for security reasons, in case if you want to be the one, who actually can edit the code - to eliminate any issues, which may arise if VBA code isn't encrypted.
I have checked the performance on my corporate network, the results are quite satisfying. All the changes you perform in the code are instantly updated among all users after they restart their Excel application.
Don't forget to release the change notes and to keep at least couple of older versions available for people, in case of need or emergency.
As long as the project will evolve, maybe more complex approaches could be used, however due to boundaries I am currently facing, this approach provides the best performance at the moment.

Excel’s cursor/selection focus after inserting content add-ins

In Excel, I’m having my cursor/selection on a specific cell. Up until a recent Office update, the behavior upon inserting an Office.js-powered “content add-in” was like this:
The add-in is being inserted
The container of the web control is focused (you get the resize handles and Excel reveals the Drawing Tools menu) and the focus on the sheet is lost
getSelectedRange() right now would not yield any results but an error
You need to make at least one click into the web control’s area to de-focus the container and focus both the web control and re-focus the cursor/selection on the sheet
getSelectedRange() works now
After a recent update, I’m using Excel for Office 365 Version 16.0.11328.20362 now. And the behavior changed to this:
The add-in is being inserted — unchanged
The container of the web control is focused and the focus on the sheet is lost — unchanged
getSelectedRange() right now would not yield any results but an error — unchanged
Clicks on the web control don’t change the focus anymore, the container keeps being focused!
While the old behavior was already cumbersome as interaction between the add-in and the sheet was not possible directly after add-in insertion (only after at least one click), now not even the workaround of making that single click in the add-in is working anymore.
My original requirement was to read data from the sheet that has been selected just prior to inserting the add-in (just like it works with the native Excel charts). That’s why I had to come up with this one-click workaround in the first place.
What is now the best (if any) way to work with the workbook/sheet right after inserting the add-in with as few quirks as possible?

Debug Excel add-in written by JavaScript API on an existing workbook

I am trying to develop an Excel add-in by using JavaScript API for Excel.
I can already make some samples run, launch debugging under Visual Studio. Every time when i launch debugging, it opens a new workbook of Excel.
However, most of time, I need to debug an add-in on an existing workbook. For instance, here is an add-in sample, which opens a blank workbook and adds blank sheets to it. However, I want it to add blank sheets to an existing (opened) workbook. Does anyone know what I should set to debug it on an existing (opened) workbook? Should I modify some lines of code?
Edit 1:
From http://dev.office.com/docs/add-ins/get-started/create-and-debug-office-add-ins-in-visual-studio
To use an existing document to debug the add-in
In Solution Explorer, choose the add-in project folder.
Note Choose the add-in project and not the web application project.
On the Project menu, choose Add Existing Item.
In the Add Existing Item dialog box, locate and select the document
that you want to add.
Choose the Add button to add the document to your project.
In Solution Explorer, open the shortcut menu for the project, and
then choose Properties.
The property pages for the project appear.
In the Start Document list, choose the document that you added to the
project, and then choose the OK button to close the property pages.
Here is the resulting configuration that you should see:
After that just press F5 (start debugging), and you should be good to go.
~ Michael Zlatkovsky, developer on Office Extensibility team, MSFT
For anyone else running into this same issue (i.e. tying to set up an existing worksheet for debugging) without having to jump through 3 hoops to insert the add-in every time, this worked for me:
Set the Start Document to "New Excel/Word/etc Document"
Hit F5 to start debugging.
The resulting new document will be read-only and it will be in the Debug/Release folder.
Close the document, don't save it.
Copy the document to the folder where your Web Add-In manifest is and renamed it to whatever name you prefer.
Uncheck "Read Only" int the file's properties.
Set the Start Document as described by Michael in his response above.
If you start debug now, the add-in "should" load automatically. If you start without debugging (Ctrl + F5), you should be able to close the document and open it (or a copy of it) from anywhere in the PC and it should load automatically. You can even make changes to your JS code and reload the taskpanes/dialogs and it should take effect.
What did NOT work:
Using a blank start document and saving it after inserting the add-in. Once you save it, it loses its connection to the developer add-in.
If you start any document in debug mode and save it, it will NOT work the next time! If you want to make any changes to it, DO NOT start in debug mode.
I am not sure if any of these quirks are by design or if a Windows/Office update messed it up for me. Regardless, this is a very painful experience compared to developing VSTOs.

Embedding a form into a MultiPage tab in Excel VBA

I am using Excel 2010. I have already created and tested 2 complex forms frmA and frmB. They run and then save data to the workbook when user hits Apply or OK. Now my user wants frmA to be able to call frmB, do some work, then return to frmA. I thought it might look professional if they could be on a MultiPage, but I don’t want to rebuild and retest these forms.
Is there anyway I can create a 2-tab MultiPage form and then make frmA appear on the first tab, frmB appear on the second? Then I can simply handle the communication between the two instead of recoding.
Or maybe I can just paste all the objects and code from each form onto the tabs and do some object renaming. The retesting will be extensive, though.
If not, I will have to do frmA.show, (user clicks Open frmB button), frmA.Hide, frmB.Initialize, frmB.Show, (do some work, hit Apply/OK/Cancel), (update spreadsheet with changes), frmB.Hide/Unload, (frmA.Initialize due to changes), frmA.Show. I have not gotten this to work properly yet – frmA disappears and doesn’t come back, but I will work on it if the MultiPage is not possible.
Maybe you can save me time by pointing me in the right direction.
I am accepting #guitarthrower 's answer:
To answer your question, no you cannot embed one userform in another using Excel VBA. – guitarthrower

What is the best way to package and distribute an Excel application

I've writen an Excel-based, database reporting tool. Currentely, all the VBA code is associated with a single XLS file. The user generates the report by clicking a button on the toolbar. Unfortunately, unless the user has saved the file under another file name, all the reported data gets wiped-out.
When I have created similar tools in Word, I can put all the code in a template (.dot) file and call it from there. If I put the template file in the Office startup folder, it will launch everytime I start Word. Is there a similar way, to package and distribute my code in Excel? I've tried using Add-ins, but I didn't find a way to call the code from the application window.
Simply move your code into an Excel Addin (XLA) - this gets loaded at startup (assuming it's in the %AppData%\Microsoft\Excel\XLSTART folder) but if it's a addin, not a workbook, then only your macros and defined startup functions will be loaded.
If the functions depend on a spreadsheet itself, then you might want to use a combination of templates and addins.
I'm distributing part of an application like this, we have addins for Word, Excel and Powerpoint (XLA, PPA, DOT) and also Office 2007 'ribbon' versions (DOTM, XLAM and PPAM)
The addin startup code creates toolbar buttons if they're not found, this means in any workbook/document/etc they can simply hit the toolbar button to run our code (we have two action buttons and one button that displays a settings dialog)
Templates aren't really the way to go for VBA code, Addins are definitely the way to go...
So to load the toolbars on startup we're using something like.. (checking to see if toolbar exists though - code will run for each worksheet that is opened, but toolbars are persistent for the user session)
Public Sub Workbook_Open()
' startup code / add toolbar / load saved settings, etc.
End Sub
hope that helps :)
I always use an Add-in(xla)/Template(xlt) combination. Your add-in creates the menu (or other UI entry points) and loads templates as needed. It also write data that you want to persist to a database (Access, SQLServer, text file, or even an xls file).
The first rule is to keep your code separate from your data. Then, if you later have bug fixes or other code changes, you can send a new add-in and all of their templates and databases aren't affected.
You can modify the user's personal.xls file, stored in the excel startup directory (varies between Office versions). If you have lots of users though, that can be fiddly.
An alternative way to get over your problem is to store the macro in a template (.xlt) file. Then when the users opens it they can't save it back over the original file, but have to specify a new filename to save it as. The disadvantage of this method is that you then get multiple copies of your original code all over the place with each saved file. If you modify the original .xlt and someone reruns the old macro in a previously-saved .xls file then things can get out of step.
Have you looked into ClickOnce deploying the Excel file?
What about to save an excel to network folder with read only permissions ? The authentication can be done with integrated windows authentication and you don't need to store connection password to the database in the VBA. Then you only need distribute a link to this location to your users only once. If you will do an update, you only change data in that folder without user notice.

Resources