MS Word VBA 在文件关闭/退出时检查空文本表单字段。

huangapple go评论64阅读模式
英文:

MS Word VBA to check for empty text form fields upon file close/exit

问题

需要在文件退出或关闭时运行MS Word宏,以检查特定指定的文本字段(传统表单字段,而不是内容控件)是否为空。

我已经使用了一些代码,它会弹出一个相当具有侵入性的警告框。但它也取决于用户选择该字段,然后宏会在进入或退出时弹出一个警告框,根据表单字段属性菜单中指定的方式。我有几个字段,"Text1","text2",然后是text7到11。问题是,用户必须选择一个字段才能使此代码工作,而且警告框基本上会使他们陷入死循环,甚至在关闭文件之前。我还必须为每个字段创建一个新模块,其中包含下面的代码。也许在这里最好的解决方案是在文件关闭和/或退出时运行的宏,该宏会说:“嘿,你忘记填写这些字段,它们是 '强制性的',所以请回去完成它们,谢谢!” 你们觉得呢?

Sub MustFillIn3()
    If ActiveDocument.FormFields("Text2").Result = "" Then
        Do
            sInFld = InputBox("Request date required, please fill in below.")
        Loop While sInFld = ""
        ActiveDocument.FormFields("Text2").Result = sInFld
    End If
End Sub
英文:

I need to have a MS Word Macro check upon file exit or file close, that certain specified text fields (legacy form fields, not content control) are empty.

I have used some code that is a pretty intrusive warning box. But its also contingent on the user selecting that field then the macro pops up a warning box either upon entry or exit, as specified in the form field properties menu. I have several fields,"Text1", "text2", then text7 thru 11. Trouble is, the user MUST select a field to get this code to work, on top of that, the warning box basically sends them into a death loop before they can even close the file. I also have to make a new module for each of field with the code below. Perhaps the best solution here is a macro that runs on close and/or exit of the file, which says "Hey you forgot to fill out these fields, they are 'mandatory' so go back and do that please, thanks!" What do you all think?

Sub MustFillIn3()
    If ActiveDocument.FormFields("Text2").Result = "" Then
        Do
            sInFld = InputBox("Request date required, please fill in below.")
        Loop While sInFld = ""
        ActiveDocument.FormFields("Text2").Result = sInFld
    End If
End Sub

答案1

得分: 0

是的,只需在ThisDocument对象中的事件处理程序Document_Close中编写检查代码,就像这样:

Sub Document_Close()
    Dim ff As FormField, sInFld As String, msgShown As Boolean, d As Document, i As Byte
    'Dim ffNameDict As New Scripting.Dictionary, ffNameSpecCln As New VBA.Collection
    Dim ffNameDict As Object, ffNameSpecCln As New VBA.Collection
    
    
    Dim arr(7) As String, j As Byte
    arr(0) = "location": arr(1) = "request_date": arr(2) = "site"
    arr(3) = "UPC": arr(4) = "Current_LOA": arr(5) = "Req_LOA"
    arr(6) = "You Lost this One!!"
    
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
        
                'to a specific name list?
                'ffNameSpecCln.Add "Specific Name HERE " & i, "Text" & i
                ffNameSpecCln.Add arr(j), "Text" & i
                j = j + 1
        End Select
    Next i
     
    Set ffNameDict = CreateObject("Scripting.Dictionary")
    Set d = ActiveDocument
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
            'ffNameDict("Text" & i) = "Text" & i
            ffNameDict("Text" & i) = ffNameSpecCln.Item("Text" & i)
        End Select
    Next i
    For Each ff In d.FormFields
        If ff.Result = "" And ffNameDict.Exists(ff.Name) Then
            If Not msgShown Then
                MsgBox "Hey you forgot to fill out these fields, they are 'mandatory' so go back and do that please, thanks!", vbExclamation
                msgShown = True
            End If
            Do
'                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ff.Name + " is the current text fields to fill in !")
                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ffNameDict(ff.Name) + " is the current text fields to fill in !")
            Loop While sInFld = ""
            ff.Result = sInFld
        End If
    Next ff
    d.Save
End Sub
  • 注意:此图像中的Private修饰符应该被移除,以便在appWord_DocumentBeforeSave事件处理程序中调用(上面的代码已经设置好)。

这个检查子程序在当前文档关闭时触发,与ff是否有焦点无关(即,用户不必选择一个字段)。

英文:

Yes, just write the check code in the event handler procedure Document_Close in ThisDocument object, like this

Sub Document_Close()
    Dim ff As FormField, sInFld As String, msgShown As Boolean, d As Document, i As Byte
    'Dim ffNameDict As New Scripting.Dictionary, ffNameSpecCln As New VBA.Collection
    Dim ffNameDict As Object, ffNameSpecCln As New VBA.Collection
    
    
    Dim arr(7) As String, j As Byte
    arr(0) = "location": arr(1) = "request_date": arr(2) = "site"
    arr(3) = "UPC": arr(4) = "Current_LOA": arr(5) = "Req_LOA"
    arr(6) = "You Lost this One!!"
    
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
        
                'to a specific name list?
                'ffNameSpecCln.Add "Specific Name HERE " & i, "Text" & i
                ffNameSpecCln.Add arr(j), "Text" & i
                j = j + 1
        End Select
    Next i
     
    Set ffNameDict = CreateObject("Scripting.Dictionary")
    Set d = ActiveDocument
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
            'ffNameDict("Text" & i) = "Text" & i
            ffNameDict("Text" & i) = ffNameSpecCln.Item("Text" & i)
        End Select
    Next i
    For Each ff In d.FormFields
        If ff.Result = "" And ffNameDict.Exists(ff.Name) Then
            If Not msgShown Then
                MsgBox "Hey you forgot to fill out these fields, they are 'mandatory' so go back and do that please, thanks!", vbExclamation
                msgShown = True
            End If
            Do
'                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ff.Name + " is the current text fields to fill in !")
                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ffNameDict(ff.Name) + " is the current text fields to fill in !")
            Loop While sInFld = ""
            ff.Result = sInFld
        End If
    Next ff
    d.Save
End Sub
  • note: The Private modifier in this image should be removed in order to be called in the appWord_DocumentBeforeSave event handler (code above already set)
    MS Word VBA 在文件关闭/退出时检查空文本表单字段。

This check sub is triggered when the current document is closed and is not related to whether ff has focus or not (ie. the user Doesn't MUST select a field ).

Option Explicit

Public WithEvents appWord As Word.Application
 
Private Sub appWord_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
    ThisDocument.Document_Close
End Sub

MS Word VBA 在文件关闭/退出时检查空文本表单字段。

You have to run this sub to Register Event_Handler to Word Application.

Option Explicit

'https://learn.microsoft.com/en-us/office/vba/word/concepts/objects-properties-methods/using-events-with-the-application-object-word
Public X As New app 
Public Sub Register_Event_Handler() 
    Set X.appWord = Word.Application 
End Sub

> "物件類別模組" = class modules

> "模組" = modules

> "表單" = user form

> "Microsof Word 物件" = Microsof Word object

MS Word VBA 在文件关闭/退出时检查空文本表单字段。

As for the details, you should adjust them yourself. Try to understand the code I have given you to simulate it. Come back to StackOverflow and ask a new question when you encounter difficulties and problems in the implementation.

I've used the text field to test:
MS Word VBA 在文件关闭/退出时检查空文本表单字段。

Is this yours?

Before closing the document check if it has been modified

Option Explicit

Public WithEvents appWord As Word.Application
 
Private Sub appWord_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
    If Not Doc.Saved Then
        If MsgBox("Do you want to save?", vbOKCancel + vbQuestion) = vbOK Then
            Doc.Save
        Else
            Doc.Close wdDoNotSaveChanges
        End If
    End If
End Sub

Private Sub appWord_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
    MS_Word_VBA_to_check_for_empty_text_form_fields_upon_file_close_exit
End Sub

MS Word VBA 在文件关闭/退出时检查空文本表单字段。

  • Comment out the event handler Document_Close code and Registering an event handler when a document is opened:
Option Explicit

rem now can be Private, because there is no other place to call this procedure
Private Sub Document_Close()
    'MS_Word_VBA_to_check_for_empty_text_form_fields_upon_file_close_exit
End Sub


Private Sub Document_Open()
    Register_Event_Handler ' See previous code
End Sub

MS Word VBA 在文件关闭/退出时检查空文本表单字段。

  • Extract the code to become a separate checker procedure or method:
Sub MS_Word_VBA_to_check_for_empty_text_form_fields_upon_file_close_exit()
    Dim ff As FormField, sInFld As String, msgShown As Boolean, d As Document, i As Byte
    'Dim ffNameDict As New Scripting.Dictionary, ffNameSpecCln As New VBA.Collection
    Dim ffNameDict As Object, ffNameSpecCln As New VBA.Collection
    
    
    Dim arr(7) As String, j As Byte
    arr(0) = "location": arr(1) = "request_date": arr(2) = "site"
    arr(3) = "UPC": arr(4) = "Current_LOA": arr(5) = "Req_LOA"
    arr(6) = "You Lost this One!!"
    
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
        
                'to a specific name list?
                'ffNameSpecCln.Add "Specific Name HERE " & i, "Text" & i
                ffNameSpecCln.Add arr(j), "Text" & i
                j = j + 1
        End Select
    Next i
     
    Set ffNameDict = CreateObject("Scripting.Dictionary")
    Set d = ActiveDocument
    For i = 1 To 11
        Select Case i
            Case 1, 2, 7, 8, 9, 10, 11 '"Text1", "text2", then text7 thru 11.
            'ffNameDict("Text" & i) = "Text" & i
            ffNameDict("Text" & i) = ffNameSpecCln.Item("Text" & i)
        End Select
    Next i
    For Each ff In d.FormFields
        If ff.Result = "" And ffNameDict.Exists(ff.Name) Then
            If Not msgShown Then
                MsgBox "Hey you forgot to fill out these fields, they are 'mandatory' so go back and do that please, thanks!", vbExclamation
                msgShown = True
            End If
            Do
'                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ff.Name + " is the current text fields to fill in !")
                sInFld = InputBox("Request date required, please fill in below." + vbCr + vbCr + _
                                    "@" + ffNameDict(ff.Name) + " is the current text fields to fill in !")
            Loop While sInFld = ""
            ff.Result = sInFld
        End If
    Next ff
    d.Save
End Sub

MS Word VBA 在文件关闭/退出时检查空文本表单字段。

huangapple
  • 本文由 发表于 2023年6月1日 20:08:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定