I am trying to trigger a macro to run when an Excel document is opened.
The problem I am running into is that all of my code resides within an Excel add-in. The Workbook_Open event doesn't work because I can't put the code in individual documents, I need it to reside in the add-in and run whenever any document is opened.
Is there a way to modify the Workbook_Open event or is there another way to trigger a macro when a different document is opened?
You need to use an Application event. There is a good writeup on how to do this at Chip Pearson's site here.
Related
I'm using Outlook 2007. I have no experience with Windows programming or VBA, as all of my background is on Unix systems. I am attempting to have Outlook save each incoming emails as text file, and then a run a python script which will parse this text file.
I found this question which seems to provide some VBA code to accomplish the first task, but I'm not sure how to utilize it. I open the Visual Basic Editor, but have no idea how to proceed from there. I tried saving the text as a module, but when I attempt add "run a script" in an Outlook rule, no scripts are available. What am I doing wrong?
EDIT: Clarification.
I'm assuming you're familiar with coding at some level, even if not on Windows. You may want to do some general background reading on Outlook VBA; some resources on this would be a Microsoft article, this article from OutlookCode, and so on - there's a ton of resources out there with walkthroughs and examples.
Addressing your specific question: take a look at this Microsoft KB article, which describes how to trigger a script from a rule.
The key to getting started once you've gotten your VBA editor open is to double-click a module on the left, for example ThisOutlookSession (under 'Microsoft Outlook Objects').
That should give you an editor you can paste code into. Bear in mind that (per the above MS page) your procedure must accept a MailItem object, which will be the item that the rule has in hand, so the linked example you gave would have the first couple of lines changed from:
Sub SaveEmail()
Dim msg As Outlook.MailItem
' assume an email is selected
Set msg = ActiveExplorer.Selection.Item(1)
' save as text
[...]
...to:
Sub SaveEmail(msg As Outlook.MailItem)
' save as text
[...]
Essentially you're being handed a MailItem rather than having to create it and connect it to the selected item in Outlook.
To achieve the second task of 'running a script' on the file, I'm assuming that you want your VBA to make changes to the file after it's been saved? This is pretty straightforward in VBA, and you'll find lots of examples for it. One pretty simple outline is in this answer.
Edit based on comments: to launch an external tool, you can use either the Shell command if you don't need to wait for it to complete, or you can use one of the many Shell-and-wait implementations floating around, for example this popular one. Or, you can use the WScript approach in this answer.
Note that you'll need to ensure Outlook is set to allow macros to run, and you will probably want to sign your code.
Problem: Need to read/capture the text of Windows pop-up messages that is generated by non-VB applications.
Situation:
I've a VB6 app, part of which requires processing an excel workbook. A non vb-6 pop-up window (as attached screen) "FILE CONVERSION IN PROGRESS" comes up, while opening an new version of excel-sheet from an old MS Excel app. And automatically it closes alos.
Requirement: I want to capture that pop-up occurance in the code. And then write a conditional statement code for the 'cancel' button click event of that non vb-6 pop-up.
Can anyone suggest something?
You can access other applications with the following APIs:
FindWindow() to locate the main window of what you're looking for
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499%28v=vs.85%29.aspx
GetWindow() to navigate through the HWNDs of the application so you can get to the button
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx
GetWindowText() to access the text from a control (it cannot be an Edit control)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520%28v=vs.85%29.aspx
You'll want to use Spy++ (which can be downloaded) to see what the class name you're looking for when it comes up and to figure out the hierarchy to navigate properly.
You'll need to use the API Text Viewer to get the API declarations so you can use them in VB6 properly.
I want to write a custom save as dialog that is hooked into the File -> "Save As" of most Windows program. This custom dialog will allow the user to enter their username, password, destination folder and uploads the file to the web server via a POST. If the user clicks cancel, it will call the original file dialog.
I've been reading up about Windows API hooking and this is vaguely how I think I would approach this:
Intercept "Save As"
Display my custom dialog, return some temporary path on the drive
Let the program write file to the temporary path, assume it calls WINAPI CreateFile(...) for now
Read the temporary file and upload to web server
Clean up temporary file
But I still can't get my head around the steps required to pull this off. Assuming I can intercept the "Save As" and CreateFile function, how do I detect the CreateFile was called from a "Save As" and not just any random file creation? I can think of a hack where I keep track of the time difference of when the File dialog got open and CreateFile got called.
My alternative solution is to use the existing file dialog and create a special folder on the disk, that is constantly monitored. When a file gets written there it will call an external program that uploads the file. I haven't looked into how to do this yet. I suspect this is easier.
UPDATE
As a first baby step, I wrote a .NET task tray application that allows the user to enter their login details and a folder to monitor. Whenever a file gets dropped in there there it will upload to the web server. So far it seems to work. Now I just need to figure out how to add a nice shortcut to the left pane of the file dialog. Once that's done I think I got a solution I'm happy with.
There is no need to hook or patch anything. Create a shell namespace extension that supports IStorage::CreateStream and implements it by returning a stream that POSTs its data to the Web server. The user can then choose to save the file to your namespace extension in order to upload the file.
Hooking the standard save dialog requires you to inject a DLL into every running process and have it replace the import stub of the the Win32 API GetSaveFileName() function in the process's PE header (something anti-virus and anti-malware apps are not likely to be happy about).
Then there is the new-style save dialog that was introduced in Vista using the new IFileSaveDialog COM interface instead of GetSaveFileName(). For that, you would have to uninstall and replace Microsoft's default FileDialog COM object with a custom implementation.
That does not count custom-made save dialogs, which you are not likely to hook.
If, by some miracle, you can hook the dialog and have it return a custom path of your own creation, you don't need to hook CreateFile() itself, Just monitor the folder that you create for your purposes. Place it where it is unlikely that any other app (or user) besides you will write files to. You can create a custom subfolder in the user's or system'ss AppData folder for that purpose. You can use SHGetSpecialFolderPath() and/or SHGetKnownFolderPath() to find those folders.
The tricky part will be detecting when the file is finished being written to and has been closed. You will have to monitor the folder for changes, such as with ReadDirectoryChangesW() or SHChangeNotifyRegister(), and periodically open new/modified files for exclusive access. If a file is still open by someone else, you won't be able to open it yourself. But once you do open it, you can do whatever you want with it.
I have written a code to create a new menu in MS Word and do some functions. I have written VBScript code in the scripting window which opens when i do Alt+F11.
I cannot send the code to the customer and have to bundle it in an exe file or some other file and send it to user.
How do i do that.
If i create an exe file when the user runs it the menu button should be cretaed in MS Word on users machine.
Thanks
Creator
The simplest options are:
Add the VBA to the normal template and you can make it run when Word loads to add your menu items.
Create an add-in from the macro project (These can be read only/password protected)
Create a managed/VSTO add-in
I have developed a Outlook polling service that does the following:
The service is not a windows service but a rich client.
It is developed in Visual Basic 6.
The "robot" basicly polls outlook for new mails
If a new mail is found the Attachment.SaveAsFile(path) is used to save each attachment.
When I save Excel files (xls) extension. Outlook will launch Excel and Excel will pop-up with the following message with older xsl files (prior excel 2000).
"Do you want to save the changes to 'SaveAttFromBlaBla.xsl'?
"Microsoft Office Excel recalculates formulas when opening files last saved by an earlier version of Excel."
Does anyone know of a way to not have the pop-up occur? And by default select "Yes" to recalculate?
Thanks
Use
Excel.Application.DisplayAlerts = False
Works with Word as well.