I have written some code in Excel VBA which calls a macro in another workbook. The other workbook's VBA code is locked, but I can still run the macro itself. The macro does some calculations, then brings up a dialog box so the user can choose where to save the results.
After running this macro, I need the file path for the results file (to use the results in further calculations).
Is there any way to store the file path chosen by the user? Or alternatively, is there any way of automatically putting a specific file path in the dialog box to save to?
You can not get the file path directly. One workaround could be to use Application.RecentFiles(Application.RecentFiles(i).Path/Application.RecentFiles(i).Name). Unfortunately I don't have excel installed on my PC is I can't test if it really works.
If this workaround don't work, that there is no other way to get the file path. You would have to ask the user to select the file.
Related
I wanted to save all my VBA Project in a Excel workbook (or other type of file if possible) and then embbed it to run in another workbook. I've seen topics about it but only found ways to run the macros opening the first sheet.
I want to run a macro from a first workbook in a second one without opening the first workbook to do it. How can I do that?
Save the file with the macros as a xlam file and Excel can load them each time Excel opens.
You need to open File -> options -> add-ins.
At the bottom there is a button Go to (or something, I don't have English Excel on the current computer.)
Then add the file to the list by clicking Browse and finding the file you just saved as xlam file.
Two scenarios comes to mind:
1) You have a second macro for personal use and can save it locally (save in: %USERPROFILE%\AppData\Roaming\Microsoft\Excel\XLSTART). This will allow you to create quick-buttons for your macros, etc. These types of macros open with Excel and will be separate VBA Projects inside of the default VBA editor.
2) You have a network or drive that multiple users need to access, so each user has a macro in their file (.xlsm or .xlsb), where that internal macro reads Application.Run "filepath\workbookname.xlsb!macro", which also allows you to call a private subroutine (note that you could use Call, but Application.Run will ensure that even Private macros are able to be accessed). This shouldn't require the other workbook be open, though I have personally had one user whose computer always opens the other file, regardless.
Edit:
Third scenario (really 2b):
3) You have files where you want to regularly access another file... you will follow a similar approach to point 2 where you make a macro to Application.Run, though you can save that macro in your XLSTART folder... this will allow you to have a source macro location where others may also want to access and utilize. The source document would allow you to maintain 1 file for many users.
Your answers were great! Great to know about XLSTART folder from #Cyril, but based on #Andreas answer I found my path.
The "problems" with adding an Add-In as #Andreas said, are cause my VBA Project would be avaliable on the VB Editor to every workbook on that computer, and to run my macros I'd have to use Application.Run("workbook.xlam!Macro").
Then I found References, which I have the same features, including I can delete my .xlam file to remove my code, and don't have the problems I mentioned above.
Adding my VBA .xlam file as an reference, it'll be avaliable only to that specific workbook and I can run my macro just like it was on the same workbook.
For general knowledge:
ADDING A REFERENCE:
1- Save your project as an Excel Add-In (.xlam file)
2- Open your target workbook, go to the Visual Basic Editor
3- Go to Tools > References > Browse... find your .xlam file and make sure it's checked.
4- Done! Now you'll see the project on the editor and can run your macros just like it was on the same workbook.
I'd like to have my spreadsheet behave differently depending on how I call it.
From file explorer I can double click on either "UHF-test.xlsm" or its shortcut, "VHF-test.lnk". From VBA or an Excel formula, how do I determine which one was used?
If I can't determine the link name, is there another way to pass information in the command line, something like this BAT file
start "\B" EXCEL \\qcy-win10-it-2\TDS-repository\TDS-UAXTED.xlsm -VHF
The BAT file solution works fairly well, it's a very small file where I can embed some options for running macros. A small downside is that the Excel PATH is not normally in the system execution PATH and needs to be added.
The goal is toI write and maintain one only macro-enabled spreadsheet stored in a network location but with the ability to allow multiple users to use it with different products and parameters without being prompted by a macro on startup.
I still prefer determining the shortcut name if someone has that solution.
I need to modify Excel workbooks from within VBA itself, where the user will point out which workbook to modify, after which a copy of the workbook will be modified and saved under a new name. This can be either an already open workbook, or a closed one on disk, and I need to support all workbook types from 2000 onward (2000-2016, binary, add-ins, templates, etc.). I need to modify the workbook's content as well as any custom UI (ribbon xml) in it. This all has to be done from random Excel installations not under my control.
The problem I'm facing is dealing with password protected workbooks - encrypted ones, i.e. a password for opening. My code needs to be able to handle those, and ideally apply any used password to the saved, updated copy as well.
The code flow is as follows:
let the user select the workbook to modify (via a form)
if the workbook is open:
.SaveCopyAs it to a temp folder
point to the saved copy for further processing
open the user-selected file in a 2nd instance of Excel (invisible)
update the opened temp copy's content
.SaveAs the temp copy to a temp folder without a password and close it
update the closed temp copy's custom UI
re-open the updated temp copy and .SaveAs it again with any password that was on the original workbook
With step 2.1 above, the .SaveCopyAs will save the open workbook and apply any password to the copy as well, which results in step 3 asking for the password in all cases. I cannot remove the pass in step 2.1 by using a .SaveAs, since that will result in the open workbook not being open anymore in the end. It would also only be a half-measure since it doesn't stop the same thing happening with closed files.
In this case, when Excel asks the user for the password (in Excel 2010 at least), the password prompt only shows the filename of the file with an edit box for the pass, all with a popped-up empty 2nd Excel window beneath it open, which is an ugly sight to behold. And it doesn't allow me to capture the entered password as well for step 7.
The best I can do I think is to detect when a closed workbook on disk is encrypted, and show my own password prompt instead before trying to open it. But how to do this? These are the options I can come up with;
When I use Workbooks.Open(Filename:=...), then Excel shows the password prompt, which I like to evade by asking for any pass beforehand myself.
When I use Workbooks.Open(Filename:=..., Password:="notthepassword"), at least Excel won't show a password prompt anymore, workbooks without a password open fine, and those with a pass now generate error 1004. However, I can't act on that to infer that a password is needed, since 1004 is Excel's catch-all error number, and I cannot inspect the Err.Description either for "wrong password" or such, since I do not know the Excel GUI language running on the client. And then there's also Check whether Excel file is Password protected ; when encrypted files have workbook structure protection on as well, apparently Excel won't open them anymore this way - I tested this and it does work with my 2010 Excel, but it's not very encouraging to hear.
Ignoring the ugliness of Excel asking for the pass, reading any Workbook.PasswordXxx property afterwards doesn't reveal anything; they always return the same values in all cases (with or without a password on the workbook).
For OOXML files (.xlsm / .xlsx etc.) I can inspect the file's zip content beforehand for the presence of the two files "EncryptionInfo" and "EncryptedPackage", indicating the file is encrypted, but what about 2000-2003 (.xls) files? There is Microsoft's documentation on the BIFF file structure used in those files telling to check for a FilePass record in the workbook stream; while I know I could implement that logic (there's e.g. the now unsupported Koogra project), I'd rather just not :) (side-question: since when did Microsoft publish these details without first signing NDA's and jumping through their legal hoops?!)
Does anyone have any insight as to how I can make code step 7. above work, short of just living with Excel's prompt and adding a key logger to my app? :)
I'm using Excel 2010 and adding a small VBA macro to a spreadsheet. (The purpose of the macro is to take the data on the active sheet and export it to a CSV file, but that's tangential to the question.) The macro determines the output path for the file using ThisWorkbook.Path. I also added a custom button to the Quick Access Toolbar to activate the macro.
After getting a working algorithm in place in my experimental spreadsheet (Test.xlsm, stored in one path), I made a copy of the spreadsheet in another path and renamed it to _Database.xlsm. Then I opened _Database.xlsm and ran the macro. To my surprise, the file was written to the original path, not the new one. And looking down at the Windows toolbar, I saw that Excel had opened the original file over in its original path as well.
After a lot of jiggering around with code tweaks, checking properties and such I finally found that I could prevent this by opening the copied spreadsheet, removing the Quick Access Toolbar button, re-adding it, and then saving the file. My questions are:
Why isn't the macro "independently portable" along with the spreadsheet? I.e. why does the copy maintain this kind of tie to the original sheet?
Is there a way I can create or modify the macro to make it portable in that sense?
If you want a toolbar/button to travel with a file (ie. not always link back to the original version) then you need to add it to the file itself, not to the QAT. The QAT only "knows" about the actual file you linked the button to.
It might be better to add the macro to your Personal Macro Workbook and then just have it operate on the ActiveWorkbook.
However, if you want to distribute it to other users, you can keep the macro in the "database" workbook and add a custom ribbon part. See: http://www.rondebruin.nl/win/s2/win001.htm
I'm trying to get a simple VBA function to run in an excel (.xlsm) worksheet.
I created this function:
Function abc()
abc = 2
End Function
in Module2, and it worked.
But after I copied the spreadsheet to another system, it now just shows "#name" as if it can't find it. The function shows up on the available list of functions however.
This makes me think there is some kind of setting I need to enable, but I've enabled whatever I was prompted for. Any ideas?
I should've known it was in the trust center:
http://office.microsoft.com/en-us/excel-help/change-macro-security-settings-in-excel-HP010096919.aspx
Basically, hit the ball and poke around until you find "trust" and "enable macros" and select the least secure options.
And then close and re-open the spreadsheet.
I think we may need more information. What version of Excel are you using? Is it different from the destination system version?
You'll want to make sure that Module2 was in the Workbook you copied into the other system. Excel 2007 stores macros on a personal workbook by default sometimes so you'll need to check the the code is actually inside of the .xlsm file.
If you're still stuck and need a quick fix just copy the code text into the new system's Excel workbook directly without making a .xlsm file (create new module in the other system then paste).
If you would like to learn how to put together add-ins you can get started here or here.