How to make the new document visible after creating from a template? - vba

I use the macro Word letter template to generate customized letters. After I run the macro, the new document is not in focus, and is behind other documents that are opened.
The new document hasn't been saved, so the name of the document is "Document XX"
I tried ActiveDocument.Activate, and the code below. The letter template is a macro userform.
Dim odoc As Document
Set odoc = Documents.Add("\\XXXX\LetterTemplate.dotx", Visible:=True)
How do I bring the active document into view?

The Active Document is already active.
Try:
oDoc.Activate
It should have become the active document when created and at the front. Do you have other code involving screenupdating?

A radical approach is to minimize all open application windows. Then when your code opens a document, it will be the only window displayed.
Sub MinimizeAll()
Dim shell As Object
Set shell = CreateObject("shell.application")
shell.MinimizeAll
Set shell = Nothing
End Sub
You and your end-users will have to decide if that is an acceptable approach because this can be an annoying solution on two-monitor systems.

Related

VBA Ribbon Bar Integration

I have an Excel macro that performs a few functions on a document (Creates as form, and a few emails) all from MS-Word documents. If the macro is executed from the main spreadsheet (where the macro is), everything works normally. I want to place this macro on the ribbon allowing a user to launch it without having (or knowing where the main excel document is located or having it open). I created a sub to check to see if the spreadsheet was open and modified the ribbon to include an icon for the macro.
Which works. However, when launched from the ribbon while the main Excel spreadsheet is not open, it opens the workbook and runs the macro in entirety (Without executing the open workbook line of the macro). I assume the spreadsheet is being open because the macro that is being called resides with it (makes sense). Since the macro is dependent on the data contains in the spreadsheet, I need to allow the users to modify it and then re-running the macros from the ribbon again.
Does anyone have a recommended approach or best practices? Thank you in advance.
Sub MainForm()
Dim WorkingFolder As String
Dim File01 As String 'Main Excel Data File, where all data is
Dim File02 As String 'Preliminary Email to send to user
Dim File03 As String 'Final Email to Send to user when production is complete
Dim wb As Workbook
WorkingFolder = "C:\Temp\"
File01 = "01-MainData.xlsm"
File02 = "02-PreProductionEmail.docx"
File03 = "03-FinalProductionEmail.docx"
If wbIsOpen(File01) = True Then
MsgBox "Workbook Is Open"
Run ("'C:\Users\Guest\Nextcloud\Documents\Excel Forms\02-TEST-Production Request-Data.xlsm'!CreateProductionForm")
Else
MsgBox "The Main Datafile is not open, verify the last row before re-runing", vbOKOnly, "Not Open"
Set wk = Workbooks.Open(WorkingFolder & DataFile)
End If
End Sub
The Guide mentioned by Ricardo was not quite what I needed but it was helpful and did put me on the right track. Thank you again Ricardo. To get this working, I needed to do the following.
1 - Make the procedure above its own separate *.xlam file (saved as an add-in).
2 - Add the add-in to start automatically via the developers tab
3 - Add the Macro to the Ribbon.
I have modified the sample above to included the open statement along with the statement that executes a macros from another workbook.
Appreciate the guidance.

Word VBA Runtime Error 5460 on second Documents.Add in global template

For a customer, I have created a Global template with a ’New Document” button that shows a userform letting the user create a new document from a choice of templates, e.g. Letter, Invoice, etc.
Recently, we have added the choice Report.
The code executed from this userform is very simple, using e.g.
Documents.Add Template:="Letter.dotm", NewTemplate:=False
to create the new documents.
The Report template is – by my standards – quite complex, with AutoNew and AutoClose macros, an EventClassModule, it writes to and reads from the CustomDocumentProperties, opens several specific Word documents from where it copies text and pastes it into the Report document, etc.
The first time a new Report is created it works as planned; but the second time (in the same Word session) the Report option is used, a ‘Runtime Error 5460’ occurs. And after that, any of the other document options returns the same error.
Quitting Word and starting a new Word session sets everything back to normal, until the Report template again is called the second time.
Strangely enough, the Report template works with no errors when new documents based on it are created directly from Explorer, as many times in the same Word session as needed.
The problem occurs in Word 2016 (365) with Windows 7 Pro, but not in Word 2013 with Windows 10.
Anybody that has ever experienced anything like this?? Help is really appreciated.
Runtime Error 5460: 'A file error has occured.'
Debug is not possible.
The Report template has thousands of lines of code and I have not been able to find out if it is in fact code in the Report template that causes the error, or code in the Global template.
As said, the Report template works fine when used from Explorer, and when called via the Global template in 2013 everything works there too.
Problem solved!
I followed the advice from #macropod and added the path also.
In stead of just using
'…
If OptionButton3.Value = True Then
Documents.Add Template:="Report.dot", NewTemplate:=False
End If
'…
I changed the code to:
Private Sub CommandButton1_Click()
Dim strPath As String
strPath = Options.DefaultFilePath(wdWorkgroupTemplatesPath)
Dim wdApp As Word.Application
Set wdApp = GetObject(, "Word.Application")
'…
If OptionButton3.Value = True Then
wdApp.Documents.Add Template:=strPath & "\Report.dot", NewTemplate:=False
End If
'…
End Sub
Thanks!!

VBA - Internet Data Scrape & Download File & Copy Paste Data

Summary: We need to go to a website, download an Excel file, and copy&paste the data into an Excel template file all automatically.
Current Problem: My current VBA code opens IE, does the data scrape and downloads the file automatically without any problems. However, ONLY in Break Mode that it opens the downloaded workbook and copy&paste the data into the template.
What Didn't Work: I tried multiple ideas like Sleep, Application.Wait, and DoEvents. Unfortunately, it keeps getting stuck on the same line. The code does not recognize a Workbook has been open and can't find the data to copy&paste. Only after I enter into the Break Mode that the file will eventually open.
Observation: Security Settings on Excel removed so I do not receive a warning message when opening a file.
This snippet is part of a loop which will make the same procedure you will find below for 5 different files. After it downloads each file, it copies&paste the data into my template.
Any idea & solution is totally welcomed!
Please find my code below:
sub test()
'-----------------------------------
'Code to do the Data Scrape in here. It works fine.
'-----------------------------------
Dim o As IUIAutomation
Dim e As IUIAutomationElement
Dim h As Long
Dim wkbook As Workbook
Dim Cwkbook As String, ThisWkbook As String
'Code to Automate IE Download
Set o = New CUIAutomation
h = ieApp.hWnd
h = FindWindowEx(h, 0, "Frame Notification Bar", vbNullString)
If h = 0 Then Exit Sub
Set e = o.ElementFromHandle(ByVal h)
Dim iCnd As IUIAutomationCondition
Set iCnd = o.CreatePropertyCondition(UIA_NamePropertyId, "Open")
Dim Button As IUIAutomationElement
Set Button = e.FindFirst(TreeScope_Subtree, iCnd)
Dim InvokePattern As IUIAutomationInvokePattern
Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
InvokePattern.Invoke
'Download Completed and File Should be opened.
DoEvents
Application.Wait Now + #12:00:10 AM#
'Even after using DoEvents & Application.Wait, the code won't open the workbook until it goes into Break Mode.
'Code to find Downloaded Workbook which will come named either as X or Y.
ThisWkbook = ThisWorkbook.Name
For Each wkbook In Application.Workbooks
If Left(wkbook.Name, 9) = "XXXXXXXXX" Or Left(wkbook.Name, 9) = "YYYYYYYYY" Then
Cwkbook = wkbook.Name
'-----------------------------------
'Code to Copy&Paste data in here. It works fine.
'-----------------------------------
End If
Next
End Sub
You will need the UIAutomationClient reference to make the code work. If you get an error when including it (like I did), add "Microsoft Visual Basic for Applications Extensibility" reference and run the code below:
Sub MyUIAutomation()
'----------------------------------------------------
'Add UIAutomation as VBA Reference
'----------------------------------------------------
Dim VBProj As VBIDE.VBProject
Set VBProj = ThisWorkbook.VBProject
VBProj.References.AddFromFile Environ("systemroot") & "/system32\uiautomationcore.dll"
Set VBProj = Nothing
End Sub
UPDATE 8.28.17: I tried a work around to copy/paste the data only when a Workbook is opened. The idea would be to finish my main "data extract" code. After the code is finished the Workbooks should open as it was behaving before, and the second code would trigger, copying/pasting the data.->
Run VBA macro whenever any workbook is opened
Outcome: It is still not working. It would only open the last workbook of the whole loop and copy&paste the data of it. The other 4 previous files wouldn't open.
UPDATE 8.31.17 Another work around failed. I tried to create an User Form, where the user would have to click on 5 different buttons. The idea is to check if my problem was the looping. Each button would extract the file and after that my Copy&Paste Macro would trigger.
Outcome: It did not work as well. I figure that while I have my "User Form" open excel recognizes that a macro is running. If I run it under Break Mode it will still open the file and copy the data.
I believe it would be important to other people know that I found a solution to my own problem.
The main problem was that my original code was structured this way:
'Open IE -> Search for a specific criteria -> Download File -> Open File -> Copy&Paste File.
It would repeat the above procedure 5 times for each different file I need.
The code would run perfectly under break mode. However, when you actually ran it, it wouldn't bring over the data from the downloaded file.
FIX: It is a work around. I separated my code into pieces. The first piece is going to search, download, and open the file I want. The second piece will only trigger when a file with a specific name is opened. It will then perform all the remaining steps I need.
I used the Workbook_Open event to do such thing:
Private Sub Workbook_Open()
The third and last piece, is a form created using shapes like circles, squares, and text box. It actually looks way nicer than an userform. Each circle performs like a button and will trigger the download of a specific file when clicked.
Now the code is structured like:
'1. Form using Shapes, each circle activates a specific script
'2. 5 Scripts -> Open IE, Search for a specific criteria, Download File, Open File
'3. 1 Script. Only Triggers when Excel Workbooks are opened. It will then only copy the data over if it meets certain criteria (such as filename).

Update linked fields in Word document from Excel VBA

I am trying to automatically update certain information (such as names, dates and numbers) across 3 different Word documents by putting the data into a spreadsheet and linking to the respective cells from Word. The spreadsheet has some Macros in it which auto-update parts of the spreadsheet internally.
Everything is working fine, except for updating the links in the Word documents.
When trying to update a link in Word by right-clicking on it and selecting the "update link" option it brings up the Macro warning dialog for the spreadsheet, asking whether I want to activate Macros or not. It doesn't do this just once but constantly during the 20s or so the update process takes (which seems unusually long to me). So updating the link works, but only if you're willing to click the "activate Macros" button of a few dozen times.
I tried to automate updating all fields in a document from Word with VBA, but that has the same problem, it also brings up the Macros dialog constantly for half a minute.
Here's my code for that:
Sub UpdateFields()
ActiveDocument.Fields.Update
End Sub
I also tried to update the Word documents directly from the spreadsheet, but that does not work either, because when Excel tries to open a Word document via VBA the program stops executing and trows this error:
"Excel is waiting for another application to complete an OLE action."
Clicking ok and waiting does not help because the error message reappears after a few seconds, and the only way to stop it is to manually kill the Excel process.
Here's my Excel Macro code:
Sub LoopThroughFiles()
Path = Application.ActiveWorkbook.Path
Dim WordFile As String
WordFile = Dir(Path & "\*.doc")
Do While Len(WordFile) > 0
Run Update(Path & "\" & WordFile)
WordFile = Dir
Loop
End Sub
Function Update(Filepath As String)
Dim WordDoc As Word.Document
Set WordApplication = CreateObject("Word.Application")
Set WordDoc = WordApplication.Documents.Open(Filepath) 'This produces the error
ActiveDocument.Fields.Update
End Function
Note that the only files in the folder are the 3 documents and the spreadsheet, and the program does find the files without any problems.
I have searched for solutions online but I did not really find anything, which I found odd, since it seems like a pretty common thing that someone would do with VBA.
Then again, I have very little experience with VBA, so I might be completely missing the point and there is a super simple solution I am just not aware of.
I think I see the error, which is a silent failure, becuase the document contains links, there is an open dialog waiting for you to say "yes" or "no" to update the links.
We can suppress this dialog by disabling the automatic link updates (WordApplication.Options.UpdateLinksAtOpen = False).
Function Update(Filepath As String)
Dim WordApplication As Word.Application
Dim WordDoc As Word.Document
Dim updateLinks As Boolean
Set WordApplication = CreateObject("Word.Application")
updateLinks = WordApplication.Options.UpdateLinksAtOpen 'capture the original value
WordApplication.Options.UpdateLinksAtOpen = False 'temporarily disable
Set WordDoc = WordApplication.Documents.Open(Filepath)
WordDoc.Fields.Update
'MsgBox "Links updated in " & WordDoc.Name
'## Save and Close the Document
WordDoc.Save
WordDoc.Close
'## reset the previous value and Quit the Word Application
WordApplication.Options.UpdateLinksAtOpen = updateLinks '
WordApplication.Quit
End Function
Also, remember to Save and Close the document, and Quit the word application inside the function.
I made this other modification:
In your function, ActiveDocument is not an object in Excel, so you would need to qualify it, otherwise that line will also throw an error. Rather than refer to WordApplication.ActiveDocument, I just simply refer to the WordDoc which you have already assigned.

Updating/creating Table of Contents in Word using VBA

I'm new to VBA. I'm trying to update the Table of Contents in my Word document everytime I open the document, but it does not seem to update it at all.
In ThisDocument I've done the following:
Private Sub Document_Open()
ActiveDocument.TablesOfContents(1).Update
End Sub
Can anyone help me?
The issue is probably the use of Document_Open - you have to set up the event in the template, not the document you are opening. You can also use an Auto_Open macro. Note that ActiveDocument may also be part of the culprit - the document you open may not yet be the actual active document when you kick the Document_Open event - you may need to set a reference to the document you're opening like:
Dim doc As Document
set doc = Documents.Open(your path here)
doc.TablesOfContents(1).Update
Finally, your Macro Security settings could be disallowing anything from executing.
In all cases, have a good read of Take Control of Microsoft Word Through Events and Running a macro automatically when a document is created, opened or closed.