如何以编程方式保护用户窗体CommandButton中的Word文档?

时间:2018-06-14 00:28:54

标签: vba ms-word word-vba userform

我有一个MS Word文档,这是一个由顶部的表格组成的10个问题评估,其中包含下面的名称和表格部分等详细信息,每个部分包含1个问题和答案以及所需的书签。该文件的基本要点是;

  1. 在打开时,文档会“隐藏”并显示UserForm以完成所需的问题,包括您的姓名(显示在下面的示例代码中)。
  2. UserForm被“锁定”,关闭它的唯一方法是强制关闭MS Word或单击命令按钮并输入正确的密码。
  3. 使用“下一个”和“上一个”命令按钮实现表单导航。
  4. 在表单的最后是一个“提交”按钮(如下所示),单击时会提示用户确认他们已准备好提交评估,如果“是”,表单会写入{的值。 {1}}控制文档中的相关书签,用封闭的书签替换部分书签,保存文档,编写电子邮件并附上准备发送的文档,然后调整窗口大小并关闭MS Word。
  5. 简而言之,上述功能完美无缺,但经过测试,一些用户设法将他们的一些答案翻倍。

    由于用户位于全国各地,可能很难联系(并试图找出一些用户可能难以解决的事情)所以我得出的结论是最合乎逻辑的原因将是:

    • 用户尚未“启用内容”并且仅在“启用内容”时完成了文档,并被强制通过UserForm完成评估,因此在提交时添加了书签位置的另一个答案。 / LI>

    所以为了克服这个问题,我已经包含了保护文档免于编辑的代码。

    它在各种代码块中按预期保护和取消保护,例如管理员用来关闭用户表单的覆盖,通常用于标记和文档打开时(当然启用了宏)或Userform终止时。 然而保护文档在保存提交之前的行似乎不起作用(缺少更好的术语)。

    当文档在所有实例中打开时,最好保护文档。由于文档是在启用保护的情况下分发的,因此首先它可以正常工作,但是在提交后,如果未启用宏(如果提示),则可以在没有UserForm的情况下打开和编辑保存的版本。

    此代码是缩短版本(省略19个变量,15个书签引用和4个附加书签替换)。我们假设保护/取消保护工作表的示例,密码为“abc123”。

    UserForm

    我已经完成了代码并执行了该行。根据我的理解,整个代码按逻辑顺序排列,我认为没有任何理由不保护文档或重新打开,打开并启用保护,因为它已在保护设置后保存。

    我有一种感觉,这是我在Word VBA中尚未学到的东西或者关于SaveAs代码的东西不能保存保护,有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您正在应用完全只读保护。但是当您保存时,您正在更改文档名称​​和文档类型,从非宏功能到宏功能。这使“只读”状态无效。所以你需要在保存后再次保护,然后进行“普通”保存。

如果您要为表单而不是“只读”实施保护,则可以避免这种情况。由于您没有在文档中设置任何可编辑区域,对于任何一种保护类型,我可以看到您使用哪种区域没有任何区别......

doc.Protect wdAllowOnlyFormFields, True, "abc123"

以下是我的测试代码,并对您发布的内容进行了优化。我做的一个重要更改是在发出Unprotect命令(如果有的话)之前检查保护类型,这是您最初遇到的问题。我使用Document对象,而不是重复ActiveDocument,因为用户可能会以某种方式更改文档。我使用对象而不是Selection作为书签。

Public Sub cmdSubmit_Click()

    Dim confirm As Integer
    Dim yourName As String
    Dim doc As Word.Document
    Dim rngBookmark As Word.Range

    Set doc = ActiveDocument
    confirm = MsgBox("Have you checked all your answers are correct?" & vbNewLine & _
              vbNewLine & "By clicking 'Yes' you are confirming your completion of this Assessment", _
              vbYesNo, "Submission Confirmation")

    If confirm = vbNo Then
        Exit Sub
    ElseIf confirm = vbYes Then
        MsgBox "A new email will open with this document attached." & vbNewLine & _
               vbNewLine & "Please click send and set the security status to 'Un-classified'", _
               vbInformation, "For Your Information"
        yourName = UserForm1.TextBox1.Text

        If doc.ProtectionType <> wdNoProtection Then
            doc.Unprotect "abc123"
        End If
        Set rngBookmark = doc.Bookmarks("name").Range
        rngBookmark.Text = yourName
        doc.Bookmarks.Add Name:="name", Range:=rngBookmark

    End If

    doc.Protect wdAllowOnlyReading, , "abc123"

    doc.SaveAs2 fileName:="c:\Test\Assessment 1_" & yourName, FileFormat:= _
        wdFormatXMLDocumentMacroEnabled, LockComments:=False, Password:="", _
        AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, _
        EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData _
        :=False, SaveAsAOCELetter:=False, CompatibilityMode:=14

    'Saving to a different name, in a different file type, annuls the read-only protection
    'so protect again
    doc.Protect wdAllowOnlyReading, , "abc123"

'Some code executes here to attach the saved document to a new outlook mailitem ready for sending.

    Application.WindowState = wdWindowStateNormal
    Application.Resize 600, 700
    Application.Quit
End Sub