Get clipboard into Watch window when Debugging VBA - vba

I'm running a macro on a word document.
After doing a Selection.Copy and running on, while debugging, I want to be able to see what was actually copied, and if it was mistakenly replaced.
Is there a way to "watch" Windows' clipboard?

I found a way. At the beginning of my code:
Dim obj As New DataObject
obj.GetFromClipboard
I needed to reference Microsoft Forms 2.0 Object Library to have the "DataObject".
At first I couldn't find it on the list - had to browse for FM20.dll.
The second line could be typed on need in immediate window, instead of writing it in the code. I found it easier this way.
Then, in the watch window, I put obj.GetText as a watch expression and voilà!

clipbrd.exe is the Windows clipboard viewer.

Related

Disable Macros from Safe Mode

I wrote a macro that now is causing issues with MS Word. I can only open the document in safe mode and cannot figure out how to delete the macro from safe mode. I don't have access to any of the features in safe mode and the macro isn't even showing up. I tried changing the Trust Center settings but none of those options make a difference. Unfortunately I was very dumb and made it a macro on all documents so I can't open any documents without going into safe mode. help!
To be more specific, I believe the code that broke my MS Word was a OnError GoTo ErrorHandler where I tell it to skip to the next if there is an error. I am working on converting equations to a professional format and some of them don't have the right syntax for the conversion so for now I wanted it to ignore those equations and convert the next equation. That is the only change I have made recently that could be the problem.
An additional edit: the macro is coded to run on open. It was running fine before I added the ErrorHandler. I'm sure this is also a huge part of the problem, but a simple solution may not be the right fix since it automatically runs when I open the document. I can't access anything in safe mode.
If you are talking about the "Normal" document in the project explorer, resetting it is easy.
Simply navigate to %AppData%\Microsoft\Templates and either delete or rename the Normal.docm file. Once you reopen Word it will regenerate a brand new file automatically - one that contains no code.
You created an AutoOpen macro which only fires when a document is opened. Presumably this macro is stored in your Normal template.
When you first start Word the macro should not run as you are not opening a document. If Word doesn’t automatically create a new blank document you can safely do so. You will then be able to access and edit the macro you created.

How to keep executing code after a Documents.add in VBA (Word 2016)?

In our office we are currently using templates containing macro's. We are about to upgrade to Office 2016, but unfortunately the macro's don't work completely as they used to.
The current implentation is that a template is opened from a custom dialogue, and that a Document_New() is called in the template. This does not seem to work anymore: the Document_New() is only called when a template is opened from the file explorer, not when it's opened by a Documents.Add() in another macro.
Alternatively, I found a lot of solutions where Documents.Add is called, and then other functions are being invoked on that new document. For example
Set doc = Documents.Add(Template:=strSkeuze, NewTemplate:=True)
Call MsgBox(doc.Name)
In Word 2016 this doesn't seem to work. The MsgBox isn't invoked and when I step through the code in debugging mode, the code stops executing after the Documents.Add().
However I cannot find anywhere that this is a known change and I am looking for a workaround to still execute code, either from the template like with the Document_New() or from the parent Macro that opens the document.
Could someone tell me whether this is still possible and how to solve this?
You ought to be able to detect the added document using the Application's Document_New event, either that it fires (presuming that you have been using the Document's Document_New event) or by generating the event artificially by counting open documents on the first action taken after the document is added.

Prevent Word macro in Normal.dotm for some templates

I have a Normal.dotm file that contains an AutoNew macro.
This macro is automatically executed each time a new document is created using any other template.
Is there any way I can prevent this automatic behavior for a specific template?
I have a Word VSTO add-in running, so I can hook into Word's events, but so far I havn't found a way to prevent this.
I do know that I can prevent macro execution when using templates programmatically, for example like this:
' Disable auto-macros before opening document
wordApplication.WordBasic.DisableAutoMacros(1)
' Open document
newWordDocument = wordApplication.Documents.Open(template.FullName, ConfirmConversions:=False, [ReadOnly]:=True, AddToRecentFiles:=False, Revert:=True)
' Re-enable auto-macros
wordApplication.WordBasic.DisableAutoMacros(0)
But this solution doesn't work when the user uses a Word template from Windows explorer or the Open-dialog in Word, since in those cases I can't execute code before it's too late already.
Or can I?
I hope someone has a trick for me :-)
-
Edit: While trying different solutions, I discovered something that might help others in similar situations, though unfortunately it doesn't help me.
It seems that if a template contains a module containing an AutoNew (or AutoOpen for that matter), that local macro is executed instead of the one in Normal.dotm.
Example:
Normal.dotm contains the following macro:
Sub AutoNew()
MsgBox "Normal.dotm"
End Sub
Test.dotm contains the following macro:
Sub AutoNew()
MsgBox "Test.dotm"
End Sub
When executing Test.dotm the message "Test.dotm" is displayed, while the message "Normal.dotm" is not displayed.
If the AutoNew macro is removed from the Test.dotm template, the message "Normal.dotm" is indeed displayed.
So it is possible to easily override the auto-macros.
The local versions of AutoNew and AutoOpen can even be empty subs that do nothing. It still works.
This is not possible in my case though, since the template I use is generated by code, and cannot contain macros (because adding macros to templates programmatically requires the user to manually activate the option "Trust access to the VBA project object model", and that's something I cannot ask my customers to do for all users. It's also a security risk.)
Based on the workaround described in the "Edit" part of the question - providing a template with "empty" Auto-macros - it's possible to use the Open XML SDK to create a template and add the VBA project to it in order to provide this functionality. This approach avoids the user needing to allow access to the VBA project on his installation. The only "macro security" that could be triggered is that for not allowing macros to run. But since the client uses macros, anyway, this should not be a major obstacle.
The simplest method is to create as much of the basic template as possible in the Word UI and use this as a starting point.
Since you're unfamiliar with the Open XML SDK, the next step would be to create one (or more) templates in the Word UI using the basic template as the starting point, saving under a different file name.
You can then use Open XML SDK Productivity Tool to see the code required to generate any one of these files, as well as, using the Compare tool, the code for converting the basic template to the derived version. This should give you a decent start with the SDK and it's object model. Once you get a feel for how the Open XML SDK works, if you're familiar with Word's object model, using that provided by the SDK is relatively straight-forward as an effort was made to make it correspond as closely as possible to the "COM" object model.
The VBA project can be added later, but you can also include it in the basic template. That would be the simplest approach.
Include this "starting point" basic template as part of your solution, installing it as part of the solution.
Within the AutoNew macro you can check the AttachedTemplate property. Only if it is a template where you want to apply the cleaning you can execute the respective macros.
Sub AutoNew()
If ActiveDocument.AttachedTemplate <> "Normal.dotm" Then
Exit Sub
End If
' rest of the macro
End Sub
If you don't control the Normal.dotm you can put an empty AutoNew macro in your own templates. As Word only executes the auto macro in the closest context, the macro in the Normal.dotm file would not be executed.
If you don't control the other templates either, you can tell your users to hold down the SHIFT key while creating a document. This prevents the execution of the auto macro.
Probably it is best, however, if you ask the owner of the other system to find another solution that does not rely on polluting the Normal.dotm file.

*.xlam add-in and missing references in a new VBA project / new Excel's instance with the add-in turned on

Repro:
Start Excel and open VBE ALT+F11.
Find Tools and click References.
Scroll down til you find Microsoft Scripting Runtime and tick it.
Save the file as Addin.xlam in the default location which should be something like:
C:\Users\username\AppData\Roaming\Microsoft\AddIns
Close this Excel instance
Start a new instance and open VBE (you should now see the Addin.xlam as the second VBA Project available for the workbook. If you don't open the Developer tab then add-ins and tick the box next to the name to turn it on - save, close, open a new Excel instance)
Add a new standard Module
Open References and you should see only 4 ticked (default)
Scroll down and try to find Microsoft Scripting Dictionary - it ain't there!?
So, this basically means you can't add the reference to the new VBA Project (Book1) because your *.xlam is already using it
but
you can't cross-use the Scripting library because trying
Dim d as Dictionary
in that newly created Module1 fails as it doesn't recognise Dictionary object....
Is this somehow a known bug I have never realised or have I just completely overlooked something? Any workarounds?
The IDE keeps recently used references near the top of the list. Don't scroll down. It's right at the top. I'll admit. This threw me for a loop for a second too.

Word opens for real when trying to fill-in the blanks dynamically?

I'm currently using Word documents as templates where blanks have to be filled dynamically/programmatically in PwoerBuilder.
This has always worked fine until the company moves on Windows 7.
In short, the Word application is opened and made invisible.
Word.Application.Visible = false
Except that sometimes, and I don't know why, once the template is accessed, Word opens itself just as if I had double-clicked the template byself through the Explorer - but I didn't.
So, it asks whether I want to open it in read-only mode, since the application already has a handle on the file. And even if I click [Cancel] not to open the file, Word opens with no document, then the application crashes.
It reports PowerBuilder System Error 35.
Error Number 35.
Error text = Error calling external object function open at line 24 in function of_fusion of object n_cst_9999.
The external object that the application is trying to call a function against is Word.
oleobject lole_word
lole_word = create oleobject
lole_word = ConnectToNewObject("Word.Application")
lole_word.Documents.Open("templatefile.docx")
It may work for a few documents, and after a few, the problem comes up. This is the first time ever I meet with this issue.
I'll be glad to answer anyone's question who's trying to help.
Will, you may try setting DisplayAlerts and FeatureInstall properties on Word Application object.
That hid most of word alerts for us. (The code is from C# project and may not be exactly what you need)
Word.Application.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
Word.Application.FeatureInstall = 0;
You may also try making a copy of the file before opening it to avoid accessing same .docx from different threads - if that may be the case.