I am trying to run a macro which creates a pdf which work fine. When the excel file gets signed, the excel file gets automatically protected.
Problem: I have a button on the worksheet which needs to be pressed to create the pdf documnet. However this can not be done because the button has also got protected and cant be press. Is there anyway around this?
However if i try save the excel file as manaully as pdf it works.
Points to bear in mind
If the worksheet gets unprotected the signatures get removed.
Small around that will not delete the signatures
If the excel sheet is saved as a different name the signatures remain.
So if i am able to get the button to work . The workbook could be saved as different name ( in macro), and then save as pdf which will contain signatures.
Right click on the button and click on Format Control; go to the Protection Tab and untick Locked checkbox. It will then still be available when the sheet is Protected.
I have a macro-enabled Excel template which contains a ribbon button pointing to a macro sub. The button assignment still points to the source template, however, instead of the sub in the new document. If I create a document and then move or delete the template, I'm no longer able to use the button in the new document:
I've noticed that the ribbon button seems have the macro's source template path hard-coded, and there isn't any place I can find in ribbon customization UI to change it:
I'm certain this has been asked before, but I've tried a number of different ways of searching for it without coming up with anything.
I found this which talks about a button on a form, not a ribbon, and I found this which seems to be generating "shapes" programmatically and assigning their action; neither of these two are relevant.
This is the closest I've found, but whereas the QAT customization tab has the option for setting the target:
the ribbon customization tab does not have that. Any help would be greatly appreciated.
I have written some code for an excel spreadsheet. This sub has been added to the ribbon using the standard customizations found in File -> Options -> Customize Ribbon. What is funny though, is that the customization will run the Sub on the EXACT EXCEL FILE that the Sub is written in, i.e. the original.
My users copy the excel file and make adjustments and then run the sub (by clicking the customized button in the ribbon), which then opens the ORIGINAL template file and runs the code. This actually works fine - and I like it because it runs the TEMPLATE code on the ACTIVE sheet. But the only problem is it is also OPENING the original template file. How do I get it to close? Remember it is not the ActiveSheet anymore.
One possible answer is to check if the template is open, then close it (using a static reference), but I would prefer something a little more elegant than that.
You should be able to find the template/original using ThisWorkbook.
Also, if you deliver your workbook's code as a .xlam instead of .xlsm, it will be opened, but there won't be a window for it, so users won't see it.
Not sure if you're using this already, but you might also want to use "for this workbook only" when adding ribbon buttons for a .xlam . (Delivering as .xlam allows you to install buttons from a workbook into the ribbon, without relying on file path and without needing your users to also install buttons (they install .xlam instead).)
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.
I have added a toolbar menu for my macro, so I can just press the button and it runs my macro from any excel document. Every time I run the macro though, it opens the source file containing the macro. Is there a way that it won't open the source file and just run the macro? (even opening and closing wouldn't too much of an issue, but I'd prefer not opening it at all)
I haven't been able to find any information about this, so all help to get me started is appreciated.
You can't pull code out of the air to run it; Excel's going to have to open the file the code's stored in to run the code.
If I understand it correctly, you can create an Excel add-in from your code and have the add-in load automatically when Excel starts. Your code will always be available in that case.
This seems like a good place to start:
http://msdn.microsoft.com/en-us/library/aa140990(v=office.10).aspx
USE YOUR PERSONAL MACRO WORKBOOK
Open the VBEditor and find the module containing your macro.
Copy that code.
Now in the VBProject Panel on the left, locate your PERSONAL.XLS or PERSONAL.XLSB project. This is the project where you store macros you want available at all times. Add a module to that project and put your code into it.
Now update your "button" so that it points to the macro in that workbook and you're good to go.
On the off chance your PERSONAL.XLS project does not exist, use the macro recorder to record a "junk" macro and be sure to set it to "Store Macro In: Personal Macro Workbook"... that will create it for you the first time.