Send keypress to error messages on opening Word document - vb.net

I am having some problems on sending key strokes to an error message while opening a document.
The document I am trying to open in a Word for Dos 5.5 document that is missing the style sheet, you can manually click ignore and the file opens, but I have 1000+ more file to do this with so i want to automate this.
I am opening this document up in either Office XP, 2003 or 2010 but i cant get the keystrokes to affect the messages.
The code I have been attempting is as follows:
Dim objWord As New Word.Application
Dim objDoc As New Word.Document
objDoc = objWord.Documents.Open(TempDir + ("\\" + fileInf.Name))
System.Threading.Thread.Sleep(5000)
SendKeys.Send("{Enter}")
System.Threading.Thread.Sleep(5000)
SendKeys.Send("{&I}")
System.Threading.Thread.Sleep(5000)
objWord.WindowState = Word.WdWindowState.wdWindowStateNormal
objWord.Visible = True
I have used the visible = true just to see what i going on, but the messages just sit there.

I think sending keyPress is not the best solution for your problem, and this is something you should avoid if you can.
You could instead try to hide Word messages. Possible ways:
Try to disable messages using Application.DisplayAlerts property before you open the file. So it would be:
objWord.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone
Important note from MSDN :
If you set this property to wdAlertsNone or wdAlertsMessageBox,
Microsoft Word doesn't set it back to wdAlertsAll when execution
stops. You should write your code in such a way that it always sets
the DisplayAlerts property back to wdAlertsAll when it stops running.
Try to disable messages by setting other parameters of the Documents.Open method. I am thinking to the Format paramater that you could try to set to wdOpenFormatAllWord to see if it disables messages.
wdOpenFormatAllWord: A Microsoft Word format that is backward compatible with earlier versions of Microsoft Word.
When you write SendKeys.Send("{Enter}"), I guess you have System.Windows.Forms namespace imported so it is equal to System.Windows.Forms.SendKeys.Send("{Enter}").
In my first answer I have suggested, If you really need to use the SendKeys method, to use the one from Excel.Application. (because I was needing coffee..., I was totally focused on Excel although the question was about Word).
Unfortunately, the method is present In Excel but there is NO SendKeys Method in Word.Application Object.

Related

Open Word Document Run-time error '424': Object required

I have a set of functions in an Access database where I am generating Word documents based on a fixed template in a folder.
I am doing this with the function shown below. For easier maintenance, I would like to be able to define the Word-template paths as public constants in the begining of my module. And therefore, I have been trying to create the adjusted function below.
Original function:
Function MyFunc(rs as DAO.Recordset)
Dim objWord As Object
Dim objDoc As Object
...
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open("C:\test_template.docx")
...
End Function
Adjusted function:
Public Const ReminderOneTemplate As Variant = "C:\test_template.docx"
...
Function MyFunc(rs as DAO.Recordset)
Dim objWord As Object
Dim objDoc As Object
...
Set objWord = CreateObject("Word.Application")
for the Word.Documents.Open method in the next, subsequent line of code I have tried this:
Set objDoc = objWord.Documents.Open(ReminderOneTemplate)
...
End Function
and
Set objDoc = objWord.Documents.Open(Chr(34) & ReminderOneTemplate & Chr(34))
...
End Function
But the function keeps returning Run-time error '424' Object required when I use a constant as input to the Word.Documents.Open method.
Can anyone explain why this is the case and what I am doing wrong. Is it not possible to pass a Constant to the Word.Open method?
Thanks.
I refactored your function, using the following sub procedure to test the basic code of creating a Word instance, and then opening an existing document using a constant for the document name.
I used Office 2007 to test the code, and everything worked fine. I don't see anything wrong with your code, what version of Access and Word are you using? Notice that I added some code to test whether the objWord variable is actually assigned a value by the call to CreateObject. I would suggest 2 things to help try to resolve the problem you are having:
1. use a String for the filename. I know the documentation for the Open method of the Documents collection says that the filename argument is a Variant, but the code does seem to work better if it is a String.
2. Make sure you set the instance of Word to be visible, otherwise you clutter up your system with invisible instances of Word (which will not be listed in Task Manager) and the only way to get rid of them is to restart the computer. If the Word instance is visible, you can switch to it and see if Word is displaying any error messages.
You may notice that the Word document my code opens is a macro-enabled .docm file. I did this because I tested whether a document with an Open event-handler that caused a runtime error would show the error message in the code in Access, but it does not.
When I first ran the code with the constant declared as a Variant, I did get an error, but not the Object required error that is giving you a problem. I then noticed that when I re-opened the Word document in Word, that I got an error message from Word that "the last time this document was opened it caused a serious error, are you sure you want to continue to open the document?" I would suggest you make sure that you can open your Word document in Word without errors or problems. I also suggest you add code similar to what I have in the example below to ensure that the objWord variable is indeed being initialized by the CreateObject method -- if CreatObject is failing to create an instance of Word, then objWord will still be Nothing, and might then produce an object required runtime error. (problems in the Registry can make CreateObject fail.)
I'm really sorry, but I have no idea why you are getting the error you are getting. I think if you redeclare the constant as a String, and ensure that you make the Word instance visible, that your code will work! The only problem I had when testing was that the document failed to open until I added the code to make the Word instance visible. But I did not get the same error that you are trying to overcome.
I have develop a library of Access VBA code for exactly this type of task -- using code in Access to create instances of Word, Excel, and to open documents and worksheets. If you think looking at a code library designed to provide easily called procedures and functions for inter-operability among MS Office applications, you can download it from here: [http://www.didjiman.com/business/vbademo/libMSOffice.htm] The code in the library has been tested to work in all versions of MS Office from 2003 though 2016, and is released to the public under the Gnu public license. The code is in a zip archive that contains an Access .accdb file with all the code, and a PDF document discussing the functions and procedures, and how to use them, along with complete code listings.
Public Const ReminderOneTemplate As String = "C:\users\matthew\documents\temp\test document1.docm"
Sub testWord_DocOpen()
Dim objWord As Object
Dim objDoc As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True 'make the Word application window visible
objWord.Application.WindowState = 1 'maximize the Word application window
If (objWord Is Nothing) Then
Debug.Print "Word object NOT initialized."
End If
Set objDoc = objWord.Documents.Open(ReminderOneTemplate)
End Sub

Is there any benefit to opening a file in VBA using a Sub vs using FollowHyperlink

So a little background - I have been using VBA for a few months now to write a program to speed up some of the work I do. This involves opening files, and at the moment I have been opening files with Autocad using the following sub:
Sub OpenAutocadFile(AutocadFile)
If AutocadVariable Is Nothing Then
Set AutocadVariable = CreateObject("AutoCAD.Application")
If AutocadVariable Is Nothing Then
MsgBox "Could not start Autocad"
Exit Sub
End If
Else
Set AutocadVariable = GetObject(, "AutoCAD.Application")
End If
Set AutocadApp = AutocadVariable
AutocadApp.Visible = True
AutocadApp.Documents.Open (AutocadFile)
End sub
Not perfect I know, but it works the majority of the time.
I also have been opening PDF files using:
ActiveWorkbook.FollowHyperlink(PDFFile)
Now my question is, is there any advantage to using one method or the other for opening a file in VBA?
I already know that with the dedicated sub, you can specify what program you want to use whereas with the hyperlink method it uses the default one.
So other than that am I missing something? Does one run faster than the other? Is one method preferable for certain file types whereas the other is for other file types?
The difference is functional, as they do different things to get similar results.
The CreateObject method uses an explicit application to open the reference, while FollowHyperlink uses the default application registered for that protocol, and passes the reference to that.
Which one is preferable is up to the developer, as sometimes you want user expected behaviour ("Open a PDF in my fave PDF viewer") and other times you may not want this. For example, maybe you know that the "open with" handler for this system doesn't do what you or the user wants.
Whether one is faster than the other isn't actually that important, as they are intended for different use cases.

Disable Save As but not Save in Word 2010

I am looking to disable Save As in a Word 2010 file but still allow save. In other words I want users to be able to update the existing file but not create copies. I realize that this is impossible to truly do for people who know workarounds but for the general user I have successfully done this in Excel but am pretty new to word VBA.
When I add the following to a brand new document everything works as intended:
Sub FileSaveAs()
MsgBox "Copies of this file cannot be created. Please save changes in the original document." & _
, , "Copy Cannot be Created"
End Sub
My document has other macros for various command buttons but none of them involve saving the document (under original name or save as). There is also a macro running on open but that is 1 line going to a bookmark. When I try to "save as" in this document I get the message box as intended. When I try to "save" though things get strange: I get the save as dialogue (problem 1). Whether I try to save either under same name or other name the dialogue behaves as it normally would except it doesn't save and the dialogue box opens again automatically essentially creating an endless loop until I hit cancel (problem 2). I also intermittently get a "disk is full" warning pop-up after trying to save which I can dismiss but appears a few minutes later as long as he file is open (perhaps related to autosave?)
Since the macro works in the test file I assumed this strange behavior must be something elsewhere in my code but my document with the other macros saves normally as long as I don't include the save as code above so now I'm totally confused. Before I put up the rest of my code which is lengthy and for the reasons stated above I would not think impact things, I figured I'd ask this:
1. Is there any place other than my other command button macros that could be causing this behavior?
2. Is there a better method people recommend to achieve my ultimate goal of disabling save as but not save?
Thanks in advance for any advice you can provide.
The Word application has a DocumentBeforeSave event. To enable application events I suggest to create a class module by the name of ThisApplication and paste the following code into it.
Option Explicit
Private WithEvents App As Application
Private Sub Class_Initialize()
Set App = Word.Application
End Sub
Private Sub App_DocumentBeforeSave(ByVal Doc As Document, _
SaveAsUI As Boolean, _
Cancel As Boolean)
If SaveAsUI Then
MsgBox "Please always use the ""Save"" command" & vbCr & _
"to save this file.", _
vbExclamation, "SaveAs is not allowed"
Cancel = True
End If
End Sub
Add the following code to your ThisDocument module.
Dim WdApp As ThisApplication
Private Sub Document_Open()
Set WdApp = New ThisApplication
End Sub
You may add the Set App = ... line to your existing Document_Open procedure. After the WdApp variable has been initialised all application events will be received by the ThisApplication class where the DocumentBeforeSave event procedure is programmed not to allow SaveAs.
Of course, this is a blanket refusal for all documents. Therefore you may wish to add code to the procedure to limit the restriction to certain documents only. The proc receives the entire document object with all its properties, including Name, Path, FullName and built-in as well as custom properties. You can identify the files you wish to be affected by any of these.
Note that the WdApp variable will be erased in case of a program crash. If this happens the application events will no longer fire. It may be useful to know that application events occur before document events. This is if you wish to use the application's DocumentOpen event as well as or instead of the document's Document_Open event.

Converting word dialog to VB

It has been a long time since doing any type of coding.
I've been tasked to send a test page (looks like old TV test pattern page) to all of our printers prior to shift start. These pages will help our team determine if there is any physical issues with the printers (bad toner, fuser, etc)
I have found this code and used in a VBA (MS Word).
Sub Sorterprint01()
Dim sPrinter As String
Dim sPrinter1 As String
With Dialogs(wdDialogFilePrintSetup)
sPrinter = .Printer
.Printer = "\\dc999nt09\USPRT_01"
.DoNotSetAsSysDefault = True
.Execute
Application.PrintOut FileName = "\\dc999file\share\7yr\Support\IS_TEAM_LOCAL\TEST SHEETS\BARCODE TEST SORTER01.docx"
.Printer = sPrinter
.Execute
End With
End Sub
I even created a form to print to all or just a specific printer.
Management does NOT want this in a word doc and would prefer to have this in a VB app (even better would be web based).
After extensive research I have found that wdDialogFilePrintSetup is a WORD based dialog and does not work in VB6/2008/2013). I am just getting back into coding and need a quick solution.
Use Automation. If you want to print docx files then you'll need word.
Set word = CreateObject("Word.Application")
With Word.dialogs(wdDialogFilePrintSetup)
etc. Just preface your objects with word..
If using VBScript (which can't access constants - nor can VB6 if you don't add Word as a Reference) you need to specify the actual number that wdDialogFilePrintSetup is equal to.
So
With Word.dialogs(97)

How to edit existing MailItem using WordEditor in Outlook VBA?

So I want to edit my received mails afterwards to add links. If the emails have been received as plain text or HTML I have just edited the appropriate msg.Body or msg.HTMLBody. However, for Rich Text, editing RTFBody directly seems both rather complicated and keeps crashing my Outlook.
I can edit the HTMLBody of Rich Text mails, but it then converts the whole mail to HTML which makes it change appearance and can't handle embedded attachments well.
MSDN talks about MailItem.GetInspector, which returns WordEditor and allows a much easier way of editing documents. Problem is, all examples I've found are of new mails being created, not existing being edited. The following code:
Set objInsp = itm.GetInspector
Set objDoc = objInsp.WordEditor
objDoc.Characters(1).InsertBefore "string"
Generates the following error: Run-time error '4605', This method or property is not available because the document is locked for editing.
Does anyone know a way to unlock the mailitem to allow for editing, alternatively, a way to edit RTFBody that doesn't go belly up? I've tried to set the objDoc.ProtectionType to something that allows writing, but it also says I cannot change the document.
I was facing exactly the same issue (Outlook VBA: Replace inline object with text).
As posted in my comment (soon to be edited to a more polished version, after further testing), you have to use objDoc.UnProtect prior to modifying contents.
I have actually used
'On Error Resume Next ' This will prevent the error message... risky!
Dim odProt As Integer
odProt = objDoc.ProtectionType
If (odProt <> wdNoProtection) Then
Debug.Print "Document is protected with type " & odProt & ", unprotecting temporarily"
objDoc.UnProtect
End If
' ... Write your code
If (odProt <> wdNoProtection) Then
Debug.Print "Restoring protection"
objDoc.Protect (odProt)
End If
objMsg.Display
objMsg.Save
I am not sure if the last two lines are the best, but it worked for me.
Note that having On Error Resume Next will prevent the error message, and you may see that none of your editions has any effect without apparent reason.