進階|教你使用自定義屬性功能管理 Word 文件中的待定內容

紫色的鳶尾花發表於2021-02-01

在使用 Word 製作合同等格式文字的過程中,經常會需要處理一些「待定內容」,例如簽署方的全稱、簽署日期等。對此,常見的處理方法是用 [*]、下劃線等方式做標記,等確認後再填上。

這種方法是有很多缺陷的。如果待定內容很多,逐個輸入這些「標記」和事後查詢替換都很麻煩,而且容易遺漏(更別提它們真的很醜)。有什麼辦法可以更方便地插入、管理和更新這些待定內容呢?換種問法,Word 文件中有沒有什麼合適的地方存放這些資訊呢?

提到 Word 文件屬性,我們一般會想到建立日期、修改日期這些檔案系統屬性,或者作者、標題這些文件標準屬性。但實際上, Word 也支援使用者建立「自定義屬性」,其名稱和值都可以自由設定。不僅如此,Word 還提供了專門的文件屬性設定介面,相當於附贈了「待定資訊管理器」的功能。

進一步想到,域(Field)功能可以讀取文件屬性的值、插入到正文中,並且具有自動更新的特性;兩者結合,就是我們需要的解決方案。

假定我們正在起草一份協議,其中甲乙雙方的名稱和簽署日期都是待定的,並且將在協議中反覆出現。我們先嚐試手動將這些資訊新增為自定義屬性,然後透過域插入到文件中。

首先,單擊「檔案」>「資訊」>「屬性」>「高階屬性」(對於 Mac,單擊「檔案」>「屬性」),然後切換到「自定義」選項卡。

然後,在「名稱」框中,為自定義屬性鍵入一個名稱。例如,對於甲乙雙方的名稱,可以分別命名為「partyA」「partyB」等;對於簽署日期,可以命名為「ExeDate」。

接著,在「型別」列表中選擇資料的型別,然後在「值」框中輸入屬性的值。例如,甲乙方的名稱應該是文字,而簽署日期應該選為日期。

需要注意,日期型別的資料必須以系統當前區域設定對應的日期格式輸入。對於簡體中文系統,這個格式一般是 yyyy-MM-dd(形如 2021-01-10),而英文系統則一般是 M/d/yyyy(形如 1/10/2021)。如果你不能確定,可以到 Windows 系統的「設定」>「時間和語言」>「地區」下的「地區格式」,或 macOS 的「系統偏好設定」>「語言和地區」中檢視。

接下來,我們透過域將自定義屬性插入到正文中。點選「插入」>「域」,然後在彈出的對話方塊中選擇 DocProperty 域,並在域程式碼輸入框中透過 DOCPROPERTY "自定義屬性名稱" 的格式指定要插入到正文的屬性。例如,如果要插入甲方的名稱,對應的域程式碼應是 DOCPROPERTY partyA。

點選確定,就可以看到相應的文字被插入到了正文中。

對於日期型別的屬性,我們還可以進一步指定其格式,只要在域程式碼的結尾追加 \@ <格式> 即可。

例如,對於中文合同,我們希望插入形如「2021年1月10日」這樣的日期:

{ DOCPROPERTY ExeDate \@ "yyyy年M月d日" }

而對於英文合同,我們希望得到的格式就是「January 10, 2021」:

{ DOCPROPERTY ExeDate \@ "MMMM d, yyyy" }

如果日後需要修改這些待定內容,只要回到自定義屬性對話方塊,更新相應的屬性值,然後全選文件內容按 F9 鍵更新域,就可以看到所有用上述方法插入的資訊都被統一更新了。此外,在 Word 的預設設定下,域也會在列印(包括列印為 PDF)時自動更新。

當然,如果只是用上面的手動方法插入自定義屬性和域程式碼,似乎並沒有快捷到哪裡去。但屬性和域功能的優點就在於可以方便地透過  VBA 實現自動化

與本文相關的 VBA 介面有兩個。首先是 CustomDocumentProperties 物件,它的 Add 方法可以向文件追加自定義屬性:

.Add (Name, Type, Value)

其中, Name 引數和  Value 引數分別為自定義屬性的名稱和值。 Type引數為自定義屬性的型別 (MsoDocProperties),與本文相關的主要為 msoPropertyTypeString(文字型別)和  msoPropertyTypeDate(日期型別)。例如,如果要追加一個名為 partyA的文字自定義屬性,則執行:

ActiveDocument.CustomDocumentProperties.Add _ 
    Name:=newPropName, _
    Type:=msoPropertyTypeString, _
    Value:="Acme Co."

我已經預先寫好了一些本文操作相關的 VBA 函式供使用。在 Word 中按 Alt-F11 組合鍵(對於 Mac,按 Option-F11)開啟 VBA 編輯器。在左側邊欄中雙擊 Normal > Microsoft Word Objects > ThisDocument,然後貼上如下程式碼:

Sub newCustomProp()
Dim newPropName As String
Dim newPropVal As String
newPropName = InputBox("New Property Name", "New Property Name")
newPropVal = InputBox("New Property Value", "New Property Value", "[*]")
' If same property already exists, delete and update it
For Each Prop In ActiveDocument.CustomDocumentProperties
    If Prop.Name = newPropName Then
        Prop.Delete
    End If
Next Prop
With ActiveDocument.CustomDocumentProperties
    .Add Name:=newPropName, _
        LinkToContent:=False, _
        Type:=msoPropertyTypeString, _
        Value:=newPropVal
End With
End Sub
Sub insCustomProp()
Dim propName As String
Dim propNameDoesExist As Boolean
propName = InputBox("Insert Custom Property", "Property Name")
propNameDoesExist = False
For Each Prop In ActiveDocument.CustomDocumentProperties
    If Prop.Name = propName Then
        propNameDoesExist = True
    End If
Next Prop
' Complain if no such property exists
If propNameDoesExist = False Then
    MsgBox ("Property Not Found.")
    Else
    ActiveDocument.Fields.Add Range:=Selection.Range, Type:=wdFieldDocProperty, Text:=propName
End If
End Sub
Sub setAgtExeDate()
Dim newExeDate As Date
' Get user-input execution date, default to today
newExeDate = InputBox("Execution Date", "Set execution date to: ", Date)
' Delete old ExeDate
For Each Prop In ActiveDocument.CustomDocumentProperties
    If Prop.Name = "ExeDate" Then
        Prop.Delete
    End If
Next Prop
With ActiveDocument.CustomDocumentProperties
    .Add Name:="ExeDate", _
        LinkToContent:=False, _
        Type:=msoPropertyTypeDate, _
        Value:=newExeDate
End With
End Sub
Sub insAgtExeDateFmtC()
Dim dateFmtC As String
' Use ChrW() to insert CJK chars properly
dateFmtC = "yyyy" & ChrW(&H5E74) & "M" & ChrW(&H6708) & "d" & ChrW(&H65E5)
ActiveDocument.Fields.Add Range:=Selection.Range, _
 Type:=wdFieldDocProperty, Text:="ExeDate \@ " & """" & dateFmtC & """"
End Sub
Sub insAgtExeDateFmtE()
Dim dateFmtE As String
dateFmtE = "MMMM d, yyyy"
ActiveDocument.Fields.Add Range:=Selection.Range, _
 Type:=wdFieldDocProperty, Text:="ExeDate \@ " & """" & dateFmtE & """"
End Sub

上述程式碼中,前兩個函式分別用來建立/更新和插入自定義屬性:

  • newCustomProp:建立一個新的文字型自定義屬性,依次提示輸入屬性名稱和值(預設為「[*]」),如果該屬性已存在,則更新為新輸入的值

  • insCustomProp:插入指定名稱的自定義屬性到正文

我日常工作中要處理簽署日的情況尤其多,所以專門寫了幾個處理簽署日的函式:

  • setAgtExeDate:建立一個名為「ExeDate」的自定義函式用於存放簽署日(預設為今天),如果「ExeDate」已存在,則更新為新輸入的值

  • insAgtExeDateFmtC(insAgtExeDateFmtE):插入「ExeDate」屬性中儲存的簽署日到正文,並修改為中文(英文)的常見日期格式

此後,點選「檢視」>「宏」>「檢視宏」(對於 Mac,「工具」>「宏」>「宏…」),在彈出的對話方塊中雙擊相應函式名,就可以快速執行相關功能。對於 Windows 版的 Word,還可以進入「檔案」>「選項」>「自定義功能區」,將上述函式建立為工具欄中的按鈕。

Mac 版 Word 沒有這種功能,但可以透過 KeyboardMaestro、Alfred 等工具實現類似效果,只要將如下格式的 Apple Script 建立為 Marco/Workflow 並分配快捷鍵即可:

tell application "Microsoft Word"
    activate
    run VB macro macro name "<宏名稱>"
end tell


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69971301/viewspace-2755104/,如需轉載,請註明出處,否則將追究法律責任。

相關文章