Etudes for Microsoft Word Programmers

Home ] Up ] Etude 3.1. Working with Document Properties. ] Etude 3.2. Customizing Drag-n-Drop for Document Window ] Etude 3.3. Microsoft Word as Automation Server. ] Etude 3.4. Transcriber ]


Etude 3.1. Working with Document Properties

Task. Microsoft Office Document Properties.

Microsoft Office Document Properties correspond to the information that we observe in the dialog “Document Properties” in Microsoft Word and  Microsoft Excel or in the dialog “Properties” in Microsoft Windows operating system.

You can familiarize yourself with Microsoft Office Document Properties in Appendix [Read!]. There you can find the information about the msoDocProperties and WdBuiltInProperty enumerations, and also the Microsoft Word "Document Properties" dialog and the Microsoft Windows "Properties" dialog that work with document properties are investigated.

 

Every Microsoft Word document has a number of built-in and custom properties. Some built-in properties are editable/available for modifying and the others are not, they have the attribute “read only”. For example, the number of words in the text is a countable property, it is not editable and has the attribute “read only”.

The template "AhDocProperties.dot" is considered in this etude. It works with custom and built-in document properties.

The utility "GetOLEProps.exe" (Window interface) written on C++ is aimed at exporting properties from Microsoft Word documents into a file of XML format.

Resources

Template "AhDocProperties.dot", 32 Kb, ZIP [download].

Utility "GetOLEProps.exe" 108 Kb,  ZIP  [download].
GetOLEProps project source codes [later!].

"GetOLEProps.exe" utility home page.

Functional Specification

Task

The task is to create and test macros intended for working with document properties. It requires the creation of the "AhDocProperties.dot" template with the "AhDocProperties" toolbar aimed at testing macros working with document properties.

Toolbar "AhDocProperties"

The "AhDocProperties" toolbar looks like this:

Button

Macro

Description

Help

AhDocPropertiesHelp

Brief prompt on the toolbar buttons.

Builtin Get

AhDocPropertiesTestBuiltinGet

Gets the value of the three built-in document properties - "Title", "Comments" and "Keywords".

Custom Get

AhDocPropertiesTestCustomGet

Gets the custom property "NewProperty1" value.

Custom Set

AhDocPropertiesTestCustomSet

Sets the custom property "NewProperty1" value.

Custom Delete

AhDocPropertiesTestCustomDelete

Deletes the custom property "NewProperty1" value.

Brief Prompt on the Toolbar Buttons

Brief prompt on the toolbar buttons looks like this:

Getting Built-in Document Properties

Getting the three built-in document properties - "Title", "Comments" and "Keywords" values.

Getting Custom Document Property

Here we are trying to get value of the custom document property "Newproperty1".

If property found then the following message box is displayed.

If property is not found then the following message box is displayed.

Setting Custom Document Property

Here we are setting custom document property "Newproperty1" value to "123".

Deleting Custom Document Property

Here we are deleting custom document property "NewProperty1".

 

Implementation - template AhDocProperties.dot

Let us consider the functions aimed at working with custom and built-in document properties. The functions are placed in the "AhDocProperties" module of the "AhDocProperties.dot" template.

The brief description of the functions is given in the table below:

Function

Description

AhCustPropertyGet

Gets custom document property.

AhCustPropertySet

Sets custom document property.

AhCustPropertyDelete

Deletes custom document property.

AhDocumentPropertyGet

Gets built-in document property.

 

'
' Constants
'
Private Const cbForceSaveAfterPropertyChange As Boolean = False
Private Const strNewPropertyName As String = "NewProperty1"

Prompt

'
' AhDocPropertiesHelp
'
Sub AhDocPropertiesHelp()
MsgBox "Etudes for Microsoft Word Programmers." & vbCrLf & vbCrLf & _
"Etude 3.1. Document Properties." & vbCrLf & _
" © 2000-2008. Evgeny Akhundzhanov. All rights reserved worldwide." & vbCrLf & _
"http://www.transcriber.ru" & vbCrLf & vbCrLf & _
"Template 'AhDocProperties.dot' - " & vbCrLf & vbCrLf & _
"Builtin Get - gets builtin document properties" & vbCrLf & _
"Custom Get - gets custom document properties" & vbCrLf & _
"Custom Set - sets custom document properties" & vbCrLf & _
"Custom Delete - deletes custom document properties"
End Sub
 

Function AhCustPropertyGet

The AhCustPropertyGet function gets the custom property of a document. It returns True if the required property is found and False if not.

'
' AhCustPropertyGet
'
Function AhCustPropertyGet(ByVal Doc As Document, ByVal strPropName As String, ByRef varPropValue As Variant) As Boolean
Dim bFound As Boolean
Dim strName As String
Dim strValue As String

Dim intTag As Long
   
    bFound = False
    Set varPropValue = Nothing
   
    For intTag = 1 To Doc.CustomDocumentProperties.Count
        strName = Doc.CustomDocumentProperties.Item(intTag).Name
        If strName = strPropName Then
            varPropValue = Doc.CustomDocumentProperties.Item(intTag).Value
            bFound = True
            Exit For
        End If
    Next intTag
   
    AhCustPropertyGet = bFound
   
End Function

Subroutine AhCustPropertySet

The AhCustPropertySet procedure gets the document custom property.

'
' AhCustPropertySet
'
Sub AhCustPropertySet(ByVal Doc As Document, ByVal strPropName As String, ByVal varPropValue As Variant, ByVal dwPropType As Long, ByVal bForceSave As Boolean)
Dim bFound As Boolean
Dim strName As String
Dim strValue As String
Dim intTag As Long
 
    bFound = False
   
    For intTag = 1 To Doc.CustomDocumentProperties.Count
        strName = Doc.CustomDocumentProperties.Item(intTag).Name
        If strName = strPropName Then
            Doc.CustomDocumentProperties.Item(intTag).Value = varPropValue
            bFound = True
            Exit For
        End If
    Next intTag

   
    If Not bFound Then
        Doc.CustomDocumentProperties.Add Name:=strPropName, LinkToContent:=False, _
        Type:=dwPropType, Value:=varPropValue   ' msoPropertyTypeString
    End If
   
    If bForceSave Then
        Doc.Saved = False
        ' Doc.Save
    End If
    
End Sub

Subroutine AhCustPropertyDelete

Subroutine AhCustPropertyDelete deletes the document custom property.

'
' AhCustPropertyDelete
'
Sub AhCustPropertyDelete(ByVal Doc As Document, ByVal strPropName, ByVal bForceSave As Boolean)
   
    Dim intTag As Long
    Dim strName As String
    For intTag = 1 To Doc.CustomDocumentProperties.Count
        strName = Doc.CustomDocumentProperties.Item(intTag).Name
        If strName = strPropName Then
            Doc.CustomDocumentProperties.Item(intTag).Delete
            Exit For
        End If
    Next intTag
 
    If bForceSave Then
        Doc.Saved = False
        ' Doc.Save
    End If
 
End Sub

Function AhDocumentPropertySet

The AhDocumentPropertySet function sets the built-in document property.

'
' AhDocumentPropertySet
'
Function AhDocumentPropertySet(ByVal Doc As Document, ByVal wdProperty As Long, ByVal varValue As Variant) As Boolean
    Dim strValue As String
    Dim proDoc As DocumentProperty
   
    With Doc.BuiltInDocumentProperties
        On Error GoTo ErrorLabel
        .Item(wdProperty) = varValue
    End With
   
    AhDocumentPropertySet = True
    Exit Function
   
ErrorLabel:
    AhDocumentPropertySet = False
End Function

Setting Built-in Properties for all Documents in the Folder

The AhTestDocumentPropertySet procedure and the AhGetFilesInFolder function was written to test the AhDocumentPropertySet function. The AhGetFilesInFolder function returns the list of files, the names of which meet the wildcards. The function fills the dynamic data array with the file names.

'
' AhGetFilesInFolder
'
Private Function AhGetFilesInFolder(ByVal strWildCard As String, arrFile() As String) As Long
Dim aFile As String
Dim nFile As Long
    nFile = 0
    aFile = Dir$(strWildCard)
    Do While aFile <> ""
        arrFile(nFile) = aFile
        aFile = Dir$
        nFile = nFile + 1
    Loop
   
    'Reset the size of the array without losing its values by using Redim Preserve
    ReDim Preserve arrFile(nFile - 1)
    AhGetFilesInFolder = nFile
End Function

Subroutine AhTestDocumentPropertySet

The AhTestDocumentPropertySet procedure receives the array of all files of the given folder having the specified file extension. For each file the procedure inserts the predefined value for a number of the document built-in properties. The AhTestDocumentPropertySet procedure was used for setting document properties for all documents of this book.

'
' AhTestDocumentPropertySet
'
Sub AhTestDocumentPropertySet()
Dim nFile As Long
Dim nFiles As Long
Dim strFolder As String
Dim strExtension As String
Dim strWildCard As String
Dim arrFile() As String    ' dynamic array
ReDim arrFile(128)         ' initial size
    strFolder = "D:\AhMSWord\Book"
   
strFolder = strFolder + "\"
    strExtension = "*.doc"
    strWildCard = strFolder + strExtension
   
    nFiles = AhGetFilesInFolder(strWildCard, arrFile)
 
    Debug.Print "Wildcard is <" & strWildCard & ">. Files found = " & nFiles
   
    '
    ' List collected files
    '
    For nFile = 0 To UBound(arrFile)
        Debug.Print arrFile(nFile)
    Next nFile
    Debug.Print vbCrLf
   
    '
    ' Process collected files
    '
    ChangeFileOpenDirectory strFolder
   
    For nFile = 0 To UBound(arrFile)
        Debug.Print "Processing " & arrFile(nFile)
   
        Documents.Open FileName:=arrFile(nFile), ConfirmConversions:=False, ReadOnly:= _
            False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:= _
            "", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", _
            Format:=wdOpenFormatAuto
           
        AhDocumentPropertySet(ActiveDocument, wdPropertyTitle, "
Использование Microsoft Word в программных проектах")
        AhDocumentPropertySet(ActiveDocument, wdPropertySubject, "SUBJECT here...")
        AhDocumentPropertySet(ActiveDocument, wdPropertyAuthor, "Evgeny Akhundzhanov")
        AhDocumentPropertySet(ActiveDocument, wdPropertyManager, "
Евгений Ахунджанов")
        AhDocumentPropertySet(ActiveDocument, wdPropertyCompany, "Private")

        AhDocumentPropertySet(ActiveDocument, wdPropertyCategory, "BOO")
        AhDocumentPropertySet(ActiveDocument, wdPropertyKeywords, "Microsoft Word, VBA, Macros, C++, Software projects")
        AhDocumentPropertySet(ActiveDocument, wdPropertyComments, "© 2001-2006,
Евгений Ахунджанов®. Все права сохранены.")
       
        ActiveDocument.Save
        ActiveDocument.Close
       
    Next nFile
    Debug.Print vbCrLf
End Sub

Function AhDocumentPropertyGet

The AhDocumentPropertyGet function gets the value of the built-in document property.

'
' AhDocumentPropertyGet
'
Function AhDocumentPropertyGet(ByVal Doc As Document, ByVal wdProperty As Long) As String
    Dim strValue As String
    Dim proDoc As DocumentProperty
    With Doc.BuiltInDocumentProperties
        Set proDoc = .Item(wdProperty)
        strValue = proDoc.Value
    End With
    AhDocumentPropertyGet = strValue
End Function

Functions AhDocPropertyGetAnyB and AhDocPropertyGetAnyC

Sometimes arises the necessity in the function, which gets the property by the name irrelative to whether the property is built-in or custom. The AhDocPropertyGetAnyB and AhDocPropertyGetAnyC functions given below solve this problem.

For the AhDocPropertyGetAnyB function the built-in properties have a priority over the custom ones. And for the AhDocPropertyGetAnyC function, vice versa, the custom properties have a priority over the built-in ones.

'
' AhDocPropertyGetAnyB  (BuiltIn property has a priority)
'
Function AhDocPropertyGetAnyB(strPropName As String) As Variant
Dim varValue As Variant ' for debugging
    '
    ' try to get built-in property first
    '
    On Error GoTo LabelTryCustom
    varValue = ActiveDocument.BuiltInDocumentProperties(strPropName).Value
    AhDocPropertyGetAnyB = varValue
    Exit Function
 
LabelTryCustom:
    '
    ' on error try to get custom property
    '
    Err.Clear
    varValue = ActiveDocument.CustomDocumentProperties(strPropName).Value
    AhDocPropertyGetAnyB = varValue
    Exit Function
    '
    ' on error return empty string
    '

    AhDocPropertyGetAnyB = ""
End Function

 

'
' AhDocPropertyGetAnyC (Custom property has a priority)
'
Function AhDocPropertyGetAnyC(strPropName As String) As Variant
Dim varValue As Variant ' for debugging
    '
    ' try to get custom property first
    '

    On Error GoTo LabelTryBuiltIn
    varValue = ActiveDocument.CustomDocumentProperties(strPropName).Value
    AhDocPropertyGetAnyC = varValue
    Exit Function
 
LabelTryBuiltIn:
    '
    ' on error try to get built-in property
    '
    Err.Clear
    varValue = ActiveDocument.BuiltInDocumentProperties(strPropName).Value
    AhDocPropertyGetAnyC = varValue
    Exit Function
    '
    ' on error return empty string
   
'
   
AhDocPropertyGetAnyC = ""
End Function

Testing Function AhDocPropertyGetAny

'
' AhDocPropertyTestGetAny
'
Sub AhDocPropertyTestGetAny()
Dim strPropName As String
Dim strPropVal As String
    strPropName = "Author"
    '
    ' Prepare document with custom Property "Author"
    ' Run this Test macro.
    ' AhDocPropertyGetAnyB("Author") will always return built-in Author
    ' AhDocPropertyGetAnyC("Author") will return custom Author, if it exists.
    '
  strPropVal = AhDocPropertyGetAnyB(strPropName)
  Debug.Print strPropName & " = <" & strPropVal & ">."
  strPropVal = AhDocPropertyGetAnyC(strPropName)
  Debug.Print strPropName & " = <" & strPropVal & ">."
 
End Sub

Saving the Document after Changing its Properties

If you add or change the document properties programmatically and close the document without applying the “Save” command, then the document properties will not be saved after the closing. To save the changed properties the following code should be used:

    ActiveDocument.Saved = False
    On Error Resume Next
    ActiveDocument.Save

In case the new document was opened and the user pressed “Cancel” at saving, the document will not be saved. In the functions given above the document is marked as unsaved and the saving of the document is commented out.

Subroutine AhDocPropertiesTestBuiltinGet

'
' AhDocPropertiesTestBuiltinGet
'
Sub AhDocPropertiesTestBuiltinGet()
If Documents.Count = 0 Then Exit Sub
Dim strReport As String
Dim prop1 As Variant
Dim prop2 As Variant
Dim prop3 As Variant
    prop1 = AhDocumentPropertyGet(ActiveDocument, wdPropertyTitle)
    prop2 = AhDocumentPropertyGet(ActiveDocument, wdPropertyComments)
    prop3 = AhDocumentPropertyGet(ActiveDocument, wdPropertyKeywords)
    strReport = "Title    = <" & prop1 & ">" & Chr(13) & _
                "Comments = <" & prop2 & ">" & Chr(13) & _
                "Keywords = <" & prop3 & ">"
    MsgBox strReport

End Sub

Subroutine AhDocPropertiesTestCustomGet

'
' AhDocPropertiesTestCustomGet
'
Sub AhDocPropertiesTestCustomGet()
If Documents.Count = 0 Then Exit Sub
Dim varPropValue As Variant
Dim strReport As String
    If AhCustPropertyGet(ActiveDocument, strNewPropertyName, varPropValue) Then
        strReport = "Property <" & strNewPropertyName & "> =  <" & varPropValue & ">."
    Else
        strReport = "Property <" & strNewPropertyName & "> was not found."
    End If
    MsgBox strReport
End Sub

Subroutine AhDocPropertiesTestCustomSet

'
' AhDocPropertiesTestCustomSet
'
Sub AhDocPropertiesTestCustomSet()
If Documents.Count = 0 Then Exit Sub
 
Dim strPropName As String
Dim varPropValue As Variant
    strPropName = strNewPropertyName

    varPropValue = "123"
    AhCustPropertySet ActiveDocument, strPropName, varPropValue, msoPropertyTypeString, cbForceSaveAfterPropertyChange
 
    '
    ' report
    '
    Dim strReport As String
    strReport = "Property <" & strNewPropertyName & "> was set to <" & varPropValue & ">."
    If cbForceSaveAfterPropertyChange Then
        strReport = strReport + Chr(13) + "Document was marked as not saved."
    Else
        strReport = strReport + Chr(13) + "Document was not marked."
    End If
    MsgBox strReport
   
End Sub

Subroutine AhDocPropertiesTestCustomDelete

'
' AhDocPropertiesTestCustomDelete
'
Sub AhDocPropertiesTestCustomDelete()
If Documents.Count = 0 Then Exit Sub
   
    On Error Resume Next
    AhCustPropertyDelete ActiveDocument, strNewPropertyName, cbForceSaveAfterPropertyChange
   
    '
    ' report
    '
    Dim strReport As String
    strReport = "Property <" & strNewPropertyName & "> was deleted."
    If cbForceSaveAfterPropertyChange Then
        strReport = strReport + Chr(13) + "Document was marked as not saved."
    Else
        strReport = strReport + Chr(13) + "Document was not marked."
    End If
    MsgBox strReport
   
End Sub

Conclusion

The Microsoft Word Document Properties are studied and the macros working with document properties are considered in this etude. The "AhDocProperties.dot" template containing the AhDocProperties toolbar is created. The toolbar provides interface to the testing macros functions.

Task 1

The template considered above contains the AhTestDocumentPropertySet macro. It is intended to set a number of built-in properties for all Microsoft Word documents in the preset/specified folder.

You can call the AhTestDocumentPropertySet macro only on your own from VBA editor.

Prepare the folder with the documents to set the properties for, change the properties value or the whole set of properties if necessary, directly in the text of the macro. Run the macro.

 

Task 2

In every Microsoft Word document there is a collection of Variables apart from the set of Properties. The Collection of Variables is saved in the Document file.  Unlike the document properties, the variables can not be viewed or edited, there are no menu commands or dialogs for them. You can work with variables only programmatically.

Create the template "AhDocVariables.dot" containing the AhDocVariables toolbar and macros for working with document variables.

Experiment with the written macros.

 

 


Etudes for Microsoft Word Programmers. Etude 3.1. Document Properties and Variables


Unless otherwise noted, all materials on this site are
© 2000-2008 Evgeny Akhundzhanov, All Rights Reserved Worldwide
Microsoft is in no way affiliated with, nor offers endorsement of, this site.
www.transcriber.ru | E-mail the Author.