Ms word 使用ContentControls将LastSavedBy名称、日期和时间信息插入Word表单

Ms word 使用ContentControls将LastSavedBy名称、日期和时间信息插入Word表单,ms-word,word-contentcontrol,Ms Word,Word Contentcontrol,我已经设置了一个包含不同部分的word表单,每个部分由单独的人完成。 表单的每个部分包括使用命名内容控件设置的下拉列表或自由文本字段的组合。 在每个部分的末尾都有一个字段供工作人员记录其姓名、日期(日历图标),以及一个带有相关宏的命令按钮,用于保存表单并在该部分完成后保护数据。 虽然这样可以保护数据,但不会阻止人员A填写表格并输入人员B的姓名。注意,这不是预期的,但出于监管目的需要可追溯性 我想更新宏以保护各节,保存文件(当前正在工作),然后在保存后立即让宏直接在手动输入的名称和日期下填充另一个

我已经设置了一个包含不同部分的word表单,每个部分由单独的人完成。 表单的每个部分包括使用命名内容控件设置的下拉列表或自由文本字段的组合。 在每个部分的末尾都有一个字段供工作人员记录其姓名、日期(日历图标),以及一个带有相关宏的命令按钮,用于保存表单并在该部分完成后保护数据。 虽然这样可以保护数据,但不会阻止人员A填写表格并输入人员B的姓名。注意,这不是预期的,但出于监管目的需要可追溯性

我想更新宏以保护各节,保存文件(当前正在工作),然后在保存后立即让宏直接在手动输入的名称和日期下填充另一个字段,其中包含上次保存人的Microsoft高级属性以及日期和时间。这将确认用户

我下面的宏(InsertMSSavedDetails())将提取Microsoft所需的数据,但前提是我手动单击表单并运行宏,然后它将保存在我单击表单的任何位置,而不会保存到命名的ContentControl框。我想自动化这最后一步,这样它就不依赖于用户,并且数据与特定的部分相关联

我的表格包含以下代码:

Module
Sub ProtectFieldsSections2()
' protects Sections 1 and 2
If MsgBox("Do you want to Lock and Protect this section from further editing?", vbYesNo) = vbNo     
Then Exit Sub
Dim sec As Section
Dim cc As ContentControl

Set sec = ActiveDocument.Sections(2)
For Each cc In sec.Range.ContentControls
cc.LockContents = True
Next cc
End Sub

This document:
Private Sub CommandButton2_Click()
ProtectFieldsSection1
ProtectFieldsSection2
ActiveDocument.Save
End Sub
用于添加Microsoft数据的当前代码-技术上可行,但不是以我需要的方式:

Sub InsertMSSavedDetails()
'
ActiveDocument.SelectContentControlsByTitle ("MSSavedDetails")
    Selection.TypeText Text:="Check data: "
    Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "LASTSAVEDBY  ", PreserveFormatting:=True
    Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "SAVEDATE  \@ ""d/MM/yyyy h:mm:ss am/pm"" ", PreserveFormatting:=True
End Sub
第二个问题是,当第一次选择Sub-CommandButton2_Click时,只需添加一次。如果我要更新子命令Button2\u单击,如果不重复保存、插入Microsoft数据、保存、插入Microsoft数据的循环,我将如何停止

注意:使用word vs PDF格式。目前,该表格以word格式使用,转换为PDF格式,并以电子方式签名,但这不允许其他人将其信息添加到其余部分。AdobeLiveCycler已被用于设计PDF表单,但在维护图像和图形方面存在问题,并且AdobeReader也遇到了其他问题,因此我们可以选择继续使用word


谢谢。

我不确定我是否完全理解了这些问题,但是

插入字段代码LASTSAVEDBY和SAVEDATE的问题在于,除非您“锁定”它们,否则它们的值将始终反映最近的保存。此外,如果希望字段进入内容控件,则必须使用富文本内容控件

也许最好

  • 保存文档

  • 获取基础属性值(上次由savedby和SAVEDATE显示的属性值)并插入它们

  • 保存文档

  • 如果您有名为(例如)的内容控件

    等等

    然后

    • 您知道用户单击了哪个命令按钮,因此您知道要处理的是哪个部分

    • 然后,您的代码可以如下所示

       Private Sub CommandButton2_Click()
       ProtectFieldsSection1
       ProtectFieldsSection2
       With ActiveDocument
         .Save
         .SelectContentControlsByTitle("Section1LastSavedBy")(1).Range.Text = _
           .BuiltinDocumentProperties("Last Author").Value
         .SelectContentControlsByTitle("Section1SaveDate")(1).Range.Text = _
           format(.BuiltinDocumentProperties("Last Save Time").Value,"D/MM/YYYY h:mm:ss am/pm")
         .Save
       End With
      
       End Sub
      
    如果希望基于节号以编程方式构造内容控件名称,可以

    如果要锁定内容控件以防止进一步编辑,可以

    我不确定您在这里遇到了什么问题:

    “第二个问题是,当第一次选择Sub-CommandButton2_-Click时,只需添加一次。如果要更新Sub-CommandButton2_-Click,如果不重复保存、插入Microsoft数据、保存、插入Microsoft数据的循环,我将如何停止?”

    除非您使用的是保存事件。如果这是问题所在,我们可以重新考虑这一部分

    <> P>很难阻止人们篡改Word中的数据,但我个人会考虑保存这些值的副本,例如,自定义XML部分(未映射到控件)或文档变量-也可能加密它们-您可以使用Windows Cuto API来实现。


    顺便说一句,我怀疑您现有代码的问题在于。SelectContentControlsBytle没有选择正常意义上的控件。它只是返回一个具有该名称的控件集合。

    我缺少Private,在我找到它的地方没有文档记录。从名称空间否定trl dv。
     Private Sub CommandButton2_Click()
     ProtectFieldsSection1
     ProtectFieldsSection2
     With ActiveDocument
       .Save
       .SelectContentControlsByTitle("Section1LastSavedBy")(1).Range.Text = _
         .BuiltinDocumentProperties("Last Author").Value
       .SelectContentControlsByTitle("Section1SaveDate")(1).Range.Text = _
         format(.BuiltinDocumentProperties("Last Save Time").Value,"D/MM/YYYY h:mm:ss am/pm")
       .Save
     End With
    
     End Sub