Document Properties


Document Built-in Properties

objDocument.BuiltinDocumentProperties(wdBuiltInProperty.wdPropertyTimeLastPrinted 

Document Custom Properties

objDocument.CustomDocumentProperties 

DSOFile.dll - Accessing Document Properties without opening the files

Microsoft makes an ActiveX DLL available called dsofile.dll, which allows you to read & write the document properties of an Office file without opening the file in a document editing window.


This includes a template called ListProps.dot that will use dsofile to list all the Office documents in a folder, including whichever of the built-in document properties you want to have.
Download and register dsofile.dll using regsvr32.
Copy the ListProps template into your Word startup folder.
Start Word. A new entry will appear in the Tools menu.
Select the entry. In the dialog that appears, select the properties you want to include in your list, select the folder you want to have listed, and select the template you want to use as the document type for the list.
ListProps then uses dsofile to open each file in turn, get the properties, and puts the list into a table. Works with available properties of Word, Excel & PowerPoint files.



How to use a single VBA procedure to read or write both custom and built-in Document Properties

When you work with Document Properties in code, most people end up with two functions or subroutines, one to write built-in Document Properties and one for custom Document Properties; because in each case the object used to refer to the Document Properties is different - you have to use the CustomDocumentProperties and BuiltinDocumentProperties collection as appropriate. But this can be very inconvenient.
Writing Document Properties
However, you can write a procedure which checks whether the property you want to write the value for is custom or built-in, and then uses the appropriate collection. (Note: If you are not familiar with calling subroutines with arguments, see: How to cut out repetition and write much less code, by using subroutines and functions that take arguments).


Public Sub WriteProp(sPropName As String, sValue As String, _ 
      Optional lType As Long = msoPropertyTypeString)
'In the above declaration, "Optional lType As Long = msoPropertyTypeString" means
'that if the Document Property's Type is Text, we don't need to include the lType argument
'when we call the procedure; but if it's any other Prpperty Type (e.g. date) then we do

Dim bCustom As Boolean
  On Error GoTo ErrHandlerWriteProp

'Try to write the value sValue to the custom documentproperties
'If the customdocumentproperty does not exists, an error will occur
'and the code in the errorhandler will run
  ActiveDocument.BuiltInDocumentProperties(sPropName).Value = sValue
'Quit this routine
  Exit Sub

Proceed:
'We know now that the property is not a builtin documentproperty,
'but a custom documentproperty, so bCustom = True
  bCustom = True

Custom:
'Try to set the value for the customproperty sPropName to sValue
'An error will occur if the documentproperty doesn't exist yet
'and the code in the errorhandler will take over
  ActiveDocument.CustomDocumentProperties(sPropName).Value = sValue
  Exit Sub

AddProp:
'We came here from the errorhandler, so know we know that
'property sPropName is not a built-in property and that there's
'no custom property with this name
'Add it
  On Error Resume Next
  ActiveDocument.CustomDocumentProperties.Add Name:=sPropName, _
    LinkToContent:=False, Type:=lType, Value:=sValue

  If Err Then
'If we still get an error, the value isn't valid for the Property Type
'e,g an invalid date was used
    Debug.Print "The Property " & Chr(34) & _
     sPropName & Chr(34) & " couldn't be written, because " & _
     Chr(34) & sValue & Chr(34) & _
     " is not a valid value for the property type"
  End If

  Exit Sub

ErrHandlerWriteProp:
  Select Case Err
    Case Else
'Clear the error
   Err.Clear
'bCustom is a boolean variable, if the code jumps to this
'errorhandler for the first time, the value for bCustom is False
   If Not bCustom Then
'Continue with the code after the label Proceed
     Resume Proceed
   Else
'The errorhandler was executed before because the value for
'the variable bCustom is True, therefor we know that the
'customdocumentproperty did not exist yet, jump to AddProp,
'where the property will be made
     Resume AddProp
   End If
  End Select
End Sub

We could call the above procedure like this:
Sub Test()
'Author is a built-in property
  Call WriteProp(sPropName:="Author", sValue:="William Shakespeare")

'Date Updated is a custom document property
  Call WriteProp(sPropName:="Date Updated", sValue:="11 Mar 2001", _
    lType:=msoPropertyTypeDate)
End Sub


Reading Document Properties

The same principle can be used when reading Document Properties:

Function ReadProp(sPropName As String) As Variant 
Dim bCustom As Boolean
Dim sValue As String

  On Error GoTo ErrHandlerReadProp
'Try the built-in properties first
'An error will occur if the property doesn't exist
  sValue = ActiveDocument.BuiltInDocumentProperties(sPropName).Value
  ReadProp = sValue
  Exit Function

ContinueCustom:
  bCustom = True

Custom:
  sValue = ActiveDocument.CustomDocumentProperties(sPropName).Value
  ReadProp = sValue
  Exit Function

ErrHandlerReadProp:
  Err.Clear
'The boolean bCustom has the value False, if this is the first
'time that the errorhandler is runned
  If Not bCustom Then
'Continue to see if the property is a custom documentproperty
    Resume ContinueCustom
  Else
'The property wasn't found, return an empty string
    ReadProp = ""
    Exit Function
  End If
End Function

We could call the function like this:

Sub Test() 
Dim PropVal As String
  PropVal = ReadProp("Author")
  Debug.Print PropVal
  PropVal = ReadProp("Date Completed")
  Debug.Print PropVal
End Sub


© 2022 Better Solutions Limited. All Rights Reserved. © 2022 Better Solutions Limited TopPrevNext