How to open and edit read-only word doc through VBA - vba

I have a macro which should open, edit and copy the contents of read-only documents into a new document, then closes the original ones without saving. On my computer I get a runtime error 6124: "You are not allowed to edit this selection because it is protected."
When I open the document through VBA it says I am restricted with view only, however when I open it manually I get the notification that the author would like me to open it read only, and I can refuse.
The weird thing is I sent the macro to my colleague to test it, and the same code on the same files can do the editing for them.
Is there a setting I am not aware of that allows this to happen?
Is there a way to get VBA to open the read-only document with editing access?
I have tried to change the document attribute through runtime script, but it did not work:
Dim fso, doc As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set doc = fso.GetFile("path")
doc.Attributes = 0
Documents.Open("path")
End Sub

Related

Create a save & print to word button

I am new to the VBA coding. I am currently making a ms access db for printing official letters using mail merge. I have already make that happen. Now I want to make a button that saves the current record to db and simultaneously print to word file using the mail merge option.
It will be really helpful for me if you solve this problem.
Thanks in Advance.
I have a word document that uses mail merge feature and gets its information from the access db. When I use this code it does not open the word document with the current information. It opens the word document with the last saved information.
If I open the word document on its own, from the task bar, it asks if I want to run the SQL and I click yes and everything operates normally. I want to click a button from within access to accomplish this same task to open the contract.
here is the code if it can help:-
Private Sub Command205_Click()
Dim LWordDoc As String
Dim oApp As Object
'Path to the word document
LWordDoc = "C:\Users\.....k Up\01- Proposal\contract.docx"
If Dir(LWordDoc) = "" Then
MsgBox "Document not found."
Else
'Create an instance of MS Word
Set oApp = CreateObject(Class:="Word.Application")
oApp.Visible = True
'Open the Document
oApp.Documents.Open FileName:=LWordDoc
End If
End Sub

Can a Variable be stored in an Excel File that can not be accessed through Excel

I just discovered that in MS Word it is possible to store a Variable in a MS Word File that can not be accessed through the regular interface when running Microsoft Word.
Sub SetMyVariable()
Dim VARNAME As String
VARNAME = "HiddenVar"
ActiveDocument.Variables.Add VARNAME, "My special info"
End Sub
This gets saved in the XML Schema under word\settings.xml
I have tried using the ThisWorkbook Object in Excel, but it doesn't seem to have a Variable object that can be added like in word.
I want to know if there is something similar in Excel to store information/varialbes that get saved with the file.
PS: the closest thing I can think of (and use in codig) is a hidden named range.
You can try with the CustomXMLParts property of the Workbook which from the link seems a generic feature of Office products and available in Excel. Given you noted that a user would have to manually inspect the XML within the unzipped xlsx files then this seems to map to the Word Variables feature. The code sample just substitutes ThisWorkbook for ActiveDocument:
Option Explicit
Sub TextXMLPart()
Dim objXMLPart As CustomXMLPart
'add
Set objXMLPart = ThisWorkbook.CustomXMLParts.Add("<foo>bar</foo>")
'inspect
For Each objXMLPart In ThisWorkbook.CustomXMLParts
Debug.Print objXMLPart.XML
Next objXMLPart
End Sub
The accepted answer to this question (which focuses on Excel and vsto) states that:
Custom XML parts For an application-level add in, this is my preferred method of storing any application data that needs to be persisted in a saved xls file without ever being visible to the user.

VBA Outlook code to open Mail Item and Save As text

I'm receiving Outlook mails that have other Outlook mails (*.msg) as attachments. I need them in txt format (or anything else Word can open).
I seem to have two choices:
1) Save the attachments to my drive as text files, rather than msg files. I have no idea how to do that, either manually or by code.
2) Save the attachments as msg files (I got a macro here on SO that does that), then open each file and save it at txt. But File-->Open in Outlook 2010 has no option for opening msg files. The only way I can see to open the file is to (manually) view the folder in File Explorer and double-click it. Once its open, I can use File-->SaveAs.
3) I could open and save the file in VBA. Or can I? (It seems you can't record a macro in Outlook the way you can in Word or Excel, or I would have tried it.)
EDIT: I tried Dmitri's suggestion, and this seems to work:
Dim oNamespace As NameSpace
Dim oFolder As Folder
' Get a reference to a NameSpace object.
Set oNamespace = Application.GetNamespace("MAPI")
' Open the file containing the shared item.
Set oSharedItem = oNamespace.OpenSharedItem("D:\temp.msg")
' Save the item to the folder.
oSharedItem.SaveAs "D:\temp.txt"
Save the embedded message attachments as MSG files (Attachment.SaveAsFile), then open then using Namespace.OpenSharedItem.
If you want to access the embedded message attachments as messages without saving them, you'd need either Extended MAPI (IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IMessage, ...), C++ or Delphi only) or Redemption (I am its author - it exposes Attachment.EmbeddedMsg property).

How to access a Word public variable in Excel VBA

I'm trying to automate some report generation where Excel VBA is doing all the work. My employer has a standardized set of templates of which all documents are supposed to be generated from. I need to populate one of these templates from Excel VBA. The Word templates utilize VBA extensively.
This is (some of) my Excel VBA code:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
WordApp.Documents.Add Template:="Brev.dot"
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
' more code
End sub
In the Word VBA Autoexec module, a public variable named user is defined and declared. The Userinfo sub from the Utilities module populates user. Both these routines are run without any complaints from VBA. I would then like to be able to access the user variable in my Excel VBA, but I get the following error
Compile Error: Variable not yet created in this context.
How can I access the Word VBA variable in Excel VBA? I thought it more or less was the same?
EDIT: the user variable is a user defined Type with only String attributes. Copying the Word VBA functions that populate the user variable is absolutely doable, just more work than I though was necessary...
In a Word module:
Public Function GetUserVariable() As String '// or whatever data type
GetUserVariable = user
End Function
In an Excel module:
myUser = WordApp.Run("GetUserVariable")
Alternatively, you could be able to replicate the variables value - as it's called user I suspect it is returning some information about a user, or author, of a document. In which case one of the following might be what you're after:
'// Username assigned to the application
MsgBox WordApp.UserName
'// Username defined by the system
MsgBox Environ$("USERNAME")
'// Name of the author of the file specified
MsgBox CreateObject("Shell.Application").Namespace("C:\Users\Documents").GetDetailsOf("MyDocument.doc", 9)
Another option - if you could only add a line of code to the Utilities.UserInfo sub (after setting your public variable):
ActiveDocument.Variables("var_user") = user
Then you could access it easily afterwards in Excel:
Sub GenerateReport() ' (Tables, InputDataObj)
' code generating the WordApp object (works!)
'I am assuming your WordApp object is public, as you don't declare it.
'Capture the new document object
Dim newdoc as Object
set newdoc = WordApp.Documents.Add(Template:="Brev.dot")
' Getting user information from Utilities.Userinfo macro in Document
Call WordApp.Run("Autoexec") ' generating a public variable
Call WordApp.Run("Utilities.UserInfo")
'Get and show the value of "user"
Dim user as String
user = newdoc.Variables("var_user")
msgbox, user
End Sub
This is assuming that useris a string.
EDIT: As it is a requirement to work only on the Excel VBA, I would definely try the approach suggested by Scott and MacroMan - replicating the same functionality of the Word macros in Excel - if possible.
I assume that you've already ruled out the possibility of using an edited copy of the original template, set in a public folder...
For the sake of completness, there is another possibility: actually it is possible to inject VBA code in a Word document without the VBProject Object Model, by "brute force". If you rename a Word document as a .zip file and open it, you will notice a \word\vbaProject.bin file in it. This file contains the VBA project for the document and, in principle, one could add or change VBA code by modifying or replacing it.
I did some tests transplanting code from one document to another by simply copying the vbaProject.bin file, and the concept works. If you are interested in learning more about this file, this topic could be of use.
Notice, however, that to do what you want with such a technique would be somewhat complex (it would involve, for starters, updating zip files from your Excel VBA), and would require a lot of experimentation to mitigate the risk of accidentally corrupting your files. Definetly not recommended if you are looking for an easy and simple solution - but it is possible.

VBA error when opening shared file - reading tags is treated as attempt to modify

I have come across a strange error and am looking for some insights.
Scenario:
A powerpoint file on a shared drive is opened by user A. User B now wants to open the same file, and is presented with a "open as read only?" dialog. User clicks "OK".
The file is opened, and an add-in runs (whenever a file is opened) to check for certain tags on slides, indicating presence of confidential material. This causes an error in the following function:
Function taggedSlide(tagName As String)
' find the slide which is tagged with tagName
Dim oSl As Slide
Set oSl = Nothing
For Each oSl In ActivePresentation.Slides
If Len(oSl.Tags(tagName)) > 0 Then <<<<<<<<<<<<<<< this is the line that causes error
Set taggedSlide = oSl
Exit Function
End If
Next oSl
Set taggedSlide = Nothing
End Function
The function ostensibly loops over all slides in the presentation, looks for a tag called tagName, and returns the slide (or Nothing). It looks like this only involves "read" operations, but the code throws an error at the indicated line.
To make things more interesting, the behavior is different if I simply mark a file as "read only", save it, and open it. The difference seems to be that I can modify the file in that case - I just can't save it. But this file cannot be edited at all, even if I don't save it. And the above "read" operation is treated as a "modification"...
I have the following questions:
Is there a document property that I can read in VBA to tell me this is a "cannot modify" file? I am looking for something akin to ActivePresentation.ReadOnly, but that is set for a "read only" file, and this is different.
Why does the line If Len(oSl.Tags(tagName)) > 0 Then get treated as a "modifying file" operation?
It was difficult to reproduce this error, because I really needed to have two users open the same file (saving the file as read-only was not enough) to make it happen. Looking forward to your insights / comments / answers!