Word Automation: Noneditable - ms-access

I am using Access to send data to a template I created in Word. After it succesfully sends the data I need to make the open Word Document NON-editable.
Also, I notice that after I am done with the Document it prompts to save. Is it possible to remove this prompt, BUT allow the capability to save.
This is the code I am using to do the Word Automation:
' Create a Word document from template.
Dim WordApp As Word.Application
Dim strTemplateLocation As String
Dim myVariable As String
myVariable = “TEST!!”
' Specify location of template
strTemplateLocation = Left(CurrentDb.Name, InStrRev(CurrentDb.Name, "\")) & "test.dot"
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
WordApp.WindowState = wdWindowStateMaximize
WordApp.Documents.Add Template:=strTemplateLocation, NewTemplate:=False
' Replace each bookmark with field contents.
WordApp.Selection.GoTo what:=wdGoToBookmark, Name:="myBookmark"
WordApp.Selection.TypeText myVariable
DoEvents
WordApp.Activate
Set WordApp = Nothing

The Document object has a Saved property which normally changes to False if any changes are made. If you set this property to True then you won't be prompted to save the document when you close it but you can still save it manually (via Save or Save As...) if you want to.
You can use the Protect method of the Document object to restrict the changes which the user can make. For example, you can call it with the parameter wdAllowOnlyReading which will mean that no changes of any kind can be made. You may also need to look at password protecting the document to prevent the user from simply unprotecting it again

This should do what you need. Tested from Excel, not Access, so you'll need to fix the template path
Sub Tester()
' Create a Word document from template.
Dim WordApp As Word.Application
Dim strTemplateLocation As String
Dim myVariable As String
myVariable = "TEST!!"
' Specify location of template
strTemplateLocation = ThisWorkbook.Path & "\test.dotx"
Set WordApp = CreateObject("Word.Application")
With WordApp
.Visible = True
.WindowState = wdWindowStateMaximize
.Documents.Add Template:=strTemplateLocation, NewTemplate:=False
' Replace each bookmark with field contents.
.Selection.GoTo what:=wdGoToBookmark, Name:="myBookmark"
.Selection.TypeText myVariable
DoEvents
With .ActiveDocument
.Protect Type:=wdAllowOnlyReading, Password:="blah"
.Saved = True
End With
.Activate
End With
Set WordApp = Nothing
End Sub

Related

How do I create a dropdown list in a word doc that is using a template?

I am trying to create a dropdown in a word doc that is generated using a template (this is all done through a button click in access). When the code is run, it stops at the line for creating the dropdown and gives the following error:
Run-time error '445':
Object doesn't support this action
I've narrowed down the problem to this line:
Set doc = oWord.Documents.Add(strWordTemplate)
The dropdown appears no problem when 'strWordTemplate' is removed from 'Add()'. That only gives me a blank document with the dropdown though. How can I place a dropdown in the document generated via the template?
strWordTemplate is a file location for a calendar template for word. TemplatePath is a global string constant to where the word templates are held. Ideally, I would be placing the same dropdown list (same values) in each cell of the calendar, but I want to figure out how to get both the template and the dropdown to show up in the same document first
Public Sub MakeCalendar()
Dim strWordTemplate As String
Dim oWord As Object
Dim doc As Word.Document
'Open a Word Doc With the Template
Set oWord = CreateObject("Word.application")
oWord.Visible = False
oWord.DisplayAlerts = False
strWordTemplate = TemplatePath & "Calendar.dot"
Set doc = oWord.Documents.Add(strWordTemplate) 'template is added here
doc.ContentControls.Add wdContentControlDropdownList 'having the template added causes this line to fail
'Show the Word Doc
oWord.DisplayAlerts = True
oWord.Visible = True
End Sub
Tried your (modified) code from excel as I am consider myself Zero in Access (more Accurately i used to run from Access). it works and hope will address your issue as below
and the Code is self explantory
Public Sub MakeCalendar()
Dim strWordTemplate As String
Dim oWord As Object
Dim doc As Word.Document
Dim TemplatePath As String
Dim Tbl As Table, cl As Cell, Rw As Row
'Modify/Delete to your requirement, but take care that last slash ("\") is in place in the path
'it is the most probable cause of error in your code
'It in first place it failed to open the template, but does not give alerts
'as DisplayAlerts set to false and then gives eroor 424 on next line
TemplatePath = "C:\users\user\desktop\"
'Open a Word Doc With the Template
Set oWord = CreateObject("Word.application")
oWord.Visible = True ' modify to your choice
oWord.DisplayAlerts = True ' modify to your choice
strWordTemplate = TemplatePath & "Calendar.dotx"
Set doc = oWord.Documents.Add(strWordTemplate) 'template is added here
Set Tbl = doc.Tables(1) ' Modify to your requirement
For Each Rw In doc.Tables(1).Rows
For Each cl In Rw.Cells
cl.Range.ContentControls.Add wdContentControlDropdownList
Next cl
Next Rw
' Or use your original code
'doc.ContentControls.Add wdContentControlDropdownList 'having the template added causes this line to fail
'Show the Word Doc
oWord.DisplayAlerts = True
oWord.Visible = True
End Sub

Updating formfield before saving a pdf through vba

I'm a beginner with VBA and coding in general and I'm stuck with a problem with my VBA code. Here's what I want to do :
I have two fillable fields (f_autpar_nom and f_autpar_fiche) with my Access database who need to be on my Word file at two formfield (eleves_nom and eleves_numfiche) with a command_click(). Then, my Word document opens and prompts me with a "do you want to save this" and then the Word document save as a PDF and is sent by email.
Everything is working except one thing : The formfields aren't updated when I print the PDF and return the default message I set (which is "erreur").
What I need is to find a way to update the formfield before my messagebox prompt me to send the email.
Here's the code I have with Access
Function fillwordform()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
On Error Resume Next
Error.Clear
Path = "P:\Commun\SECTEUR DU TRANSPORT SCOLAIRE\Harnais\Autorisations Parentales\Autorisation parentale vierge envoyée\Autorisation_blank.docm"
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Set doc = appword.Documents.Open(Path, , False)
With doc
.FormFields("eleves_nom").Result = Me.f_autpar_nom
.FormFields("eleves_numfiche").Result = Me.f_autpar_fiche
appword.Visible = True
appword.Activate
End With
Set doc = Nothing
Set appword = Nothing
End Function
Private Sub Commande47_Click()
Dim mydoc As String
mydoc = "P:\Commun\SECTEUR DU TRANSPORT SCOLAIRE\Harnais\Autorisations Parentales\Autorisation_blank.docm"
Call fillwordform
End Sub
and with Word
Private Sub document_open()
Dim outl As Object
Dim Mail As Object
Dim Msg, Style, Title, Help, Ctxt, Response, MyString
Dim PDFname As String
Msg = "L'autorisation sera sauvegardée et envoyée par email. Continuer?"
Style = vbOKCancel + vbQuestion + vbDefaultButton2
Title = "Document"
Ctxt = 1000
Response = MsgBox(Msg, Style, Title, Help, Ctxt)
If Response = vbOK Then
ActiveDocument.Save
PDFname = ActiveDocument.Path & "\" & "Autorisation Parentale " & FormFields("eleves_nom").Result & ".pdf"
ActiveDocument.SaveAs2 FileName:=PDFname, FileFormat:=wdFormatPDF
Set outl = CreateObject("Outlook.Application")
Set Mail = outl.CreateItem(0)
Mail.Subject = "Autorisation parentale " & FormFields("eleves_nom").Result & " " & FormFields("eleves_numfiche")
Mail.To = ""
Mail.Attachments.Add PDFname
Mail.Display
Application.Quit SaveChanges:=wdDoNotSaveChanges
Else
MsgBox "Le fichier ne sera pas envoyé."
Cancel = True
End If
End Sub
I didn't mean to remove the Set Doc = Nothing. My intention was to point out that whatever changes you made before that command must be lost because they weren't saved. In the code below the document is closed and saved.
Private Sub Commande47_Click()
Dim mydoc As String
mydoc = "P:\Commun\SECTEUR DU TRANSPORT SCOLAIRE\Harnais\Autorisations Parentales\Autorisation_blank.docm"
Call FillWordForm
End Sub
Function FillWordForm(Ffn As String)
Dim appWord As Word.Application
Dim Doc As Word.Document
On Error Resume Next
Set appWord = GetObject(, "word.application")
If Err.Number Then Set appWord = New Word.Application
appWord.Visible = True
On Error GoTo 0
Set Doc = appWord.Documents.Open(Ffn, , False)
' the newly opened document is activated by default
With Doc
.FormFields("eleves_nom").Result = Me.f_autpar_nom
.FormFields("eleves_numfiche").Result = Me.f_autpar_fiche
.Close True ' close the file and save the changes made
End With
Set appWord = Nothing
End Function
However, I also agree with #Kazimierz Jawor that your construct is unfortunate. Basically, the document's On_Open procedure should run when you open the document from Access. Therefore the email is probably sent before you even get to setting the form fields. My suggestion to save the changes is likely to take effect only when you run the code the second time.
The better way should be to send the mail from either Access or Word. My preference would be the latter. It should be easy to extract two values from an Access table using Word, add them to a Word document and mail out the whole thing. I don't see, however, why you should use the Open event to do that. If that choice is the more logical one then doing everything from within Access would be the conclusion.

Using VBA to Create Word Label Sheets, Getting Extra Unwanted Document

I am trying to use VBA to create a label form in Word using data provided from Access. This VBA code works:
Dim appwd As Object
Dim oDoc As Object
Set appwd = CreateObject("Word.Application")
With appwd
.Documents.Add
Set oDoc = .MailingLabel.CreateNewDocumentByID(LabelID:="1359804671")
.Visible = True
.Activate
End With
oDoc.Activate
'Remaining code that creates labels
However, it creates and opens the blank Document1 as well as the Labels2 document I want. How do I prevent it from creating the unwanted Document1, or at the very least close that document again without saving it?
If I comment out the .Documents.Add, then I get
Run-time error '4605':
This method or property is not available because a document window is not active.
Unfortunately, the .MailingLabel object requires a document to be open, so the best alternative is to just close that document as soon as you create your desired one:
Dim appwd As Object
Dim oDoc As Object
Set appwd = CreateObject("Word.Application")
With appwd
.Documents.Add
Set oDoc = .MailingLabel.CreateNewDocumentByID(LabelID:="1359804671")
.Documents(1).Close SaveChanges:=0 'wdDoNotSaveChanges, close the first document
.Visible = True
.Activate
End With
oDoc.Activate

VBA Access object code for DropDownList ContentControls

I am coding an Access database that will collect user input, then open a Word document and fill out various parts of the document.
The problem I am having is it will only work once for Drop Down Lists. Not sure why or where to look to fix this one. There are three types of items I am programmatically filling in. The first is bookmarks, no problem with this. Second is Content Control Checkboxes, these also work with no problems. The third is Content Control Drop Down Lists, this is where the problem is. First time I open the Access Database it works, but if I click the command button again, nothing (for Drop Downs). The main problem is that it doesn't produce an error message, so I am not sure where to look.
I am guessing it has something to do with the objects I am creating to do the drop down updates? any help would be great:
Dim WordApp As Word.Application
Dim strTemplateLocation As String
Dim dir As String
Dim path As String
Dim wDoc As Word.Document
path = Left(CurrentDb.Name, InStrRev(CurrentDb.Name, "\"))
strTemplateLocation = path & "UserDoc.docx"
On Error Resume Next
Set WordApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set WordApp = CreateObject("Word.Application")
End If
WordApp.Visible = True
WordApp.WindowState = wdWindowStateMaximize
WordApp.Documents.Add Template:=strTemplateLocation, newtemplate:=False
With WordApp
'Working Bookmark
.Selection.GoTo what:=wdGoToBookmark, Name:="COMPANY": .Selection.TypeText [fac]
'Working checkbox
If Me.RD = True Then: .ActiveDocument.ContentControls(9).Checked = True
'Works ONCE drop down
Dim objCC As ContentControl
Dim objCE As ContentControlListEntry
Dim ListSelection As String
ListSelection = Me.System_Type.ListIndex + 2
Set objCC = ActiveDocument.ContentControls(1): Set objCE = objCC.DropdownListEntries.Item(ListSelection): objCE.Select
End With
Should I be closing out the objCE and objCC at the end or something?
This is probably your problem:
Set objCC = ActiveDocument.ContentControls(1)
It should be
Set objCC = .ActiveDocument.ContentControls(1)
But much better would be:
Set wDoc = WordApp.Documents.Add(Template:=strTemplateLocation, newtemplate:=False)
and then always use wDoc instead of WordApp.ActiveDocument.
See here: VBA ActiveDocument Concerns / Alternatives?

Microsoft access vba-shift focus from access to word

I am creating and opening a word document through access 2007 vba. The document is created but the focus is not shifted to word. Instead the focus still remains on access form through which am creating the doc. Below is my code:
Dim obj As Word.Application
Dim wor As Word.Document
Dim str As String
str = "C:\hello\folder1\vin.dot"
Set obj = CreateObject("Word.Application")
Set wor = obj.Documents.Add
With wor
.SaveAs str
.Close
End With
obj.Visible = True
obj.Documents.Open str
obj.WindowState = wdWindowStateMaximize
Any sugesstions please.
You can move the focus with AppActivate;
AppActivate "Microsoft Word"
The VBA Word.Application object may have more than one Window associated with it. You may specify which Window to display by using its Caption property.
Since you created a new Word.Application and only created one Document, you may assume that the 1st element (1-based array) is what you want to display in your code.
AppActivate (obj.Windows(1).Caption)
I was able to call the specific window even with other word documents open with the following:
Private Sub but_Click()
'must add tools > references Microsoft Word XX.X Object Library (xx.x is max update)
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
strProjPath = Application.CurrentProject.Path 'get current path
strVerWord = "test" 'i use this to identify paths that can change based on network configs.
posOp = InStr(1, strProjPath, strVerWord) ' find the verification word in the path
strVerPath = "strVerWord filepath\FP\FP\document.docx" 'create string location for document
strPathPlusDBName = Left(strProjPath, posOp - 1) & strVerPath
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
Set WordDoc = WordApp.Documents.Open(FileName:=strPathPlusDBName, ReadOnly:=True) 'open word file in read only
AppActivate WordDoc
End Sub