WORD VBA - Userform - 自动填充

时间:2017-03-16 01:04:19

标签: vba automation word-vba userform

我正在尝试在Microsoft Word上的VBA中创建用户表单。 我一直关注http://gregmaxey.com/word_tip_pages/create_employ_userform.html 创建表单。

我非常非常非常喜欢编程,并且基本上只是在我去的时候自学。

当我尝试逐步调用UF

时,我收到“编译错误:函数未定义”

我附上了整个代码供您查看并告诉我哪里出错了,对任何建议都很满意。

模块 - modMain

Option Explicit
Sub Autonew()
Create_Reset_Variables
Call UF
lbl_Exit:
Exit Sub
End Sub

Sub Create_Reset_Variables()
 With ActiveDocument.Variables
    .Item("varFormNumber").Value = " "
    .Item("varTitle").Value = " "
    .Item("varGivenName").Value = " "
    .Item("varFamilyName").Value = " "
    .Item("varStreet").Value = " "
    .Item("varSuburb").Value = " "
    .Item("varState ").Value = " "
    .Item("varPostCode").Value = " "
    .Item("varInterviewDate").Value = " "
  End With
  myUpdateFields
lbl_Exit:
  Exit Sub
End Sub



Sub myUpdateFields()
Dim oStyRng As Word.Range
Dim iLink As Long
 iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
 For Each oStyRng In ActiveDocument.StoryRanges
  Do
    oStyRng.Fields.Update
    Set oStyRng = oStyRng.NextStoryRange
  Loop Until oStyRng Is Nothing
 Next
End Sub

表格 - frmLetter13

Option Explicit
Public boolProceed As Boolean


Sub CalUF()
Dim oFrm As frmLetter13
Dim oVars As Word.Variables
Dim strTemp As String
Dim oRng As Word.Range
Dim i As Long
Dim strMultiSel As String
    Set oVars = ActiveDocument.Variables
    Set oFrm = New frmLetter13
    With oFrm
     .Show
     If .boolProceed Then
      oVars("varFormNumber").Value = TextBoxFormNumber
      oVars("varTitle").Value = ComboBoxTitle
      oVars("varGivenName").Value = TextBoxGivenName
      oVars("varFamilyName").Value = TextBoxFamilyName
      oVars("varStreet").Value = TextBoxStreet
      oVars("varSuburb").Value = TextBoxSuburb
      oVars("varState").Value = ComboBoxState
      oVars("varPostCode").Value = TextBoxPostCode
      oVars("varInterviewDate").Value = TextBoxInterviewDate
    End If
    Unload oFrm
    Set oFrm = Nothing
    Set oVars = Nothing
    Set oRng = Nothing
lbl_Exit
    Exit Sub
End Sub

Private Sub TextBoxFormNumber_Change()

End Sub

Private Sub Userform_Initialize()
    With ComboBoxTitle
        .AddItem "Mr"
        .AddItem "Mrs"
        .AddItem "Miss"
        .AddItem "Ms"
    End With
    With ComboBoxState
        .AddItem "QLD"
        .AddItem "NSW"
        .AddItem "ACT"
        .AddItem "VIC"
        .AddItem "TAS"
        .AddItem "SA"
        .AddItem "WA"
        .AddItem "NT"
    End With
lbl_Exit:
Exit Sub
End Sub

Private Sub CommandButtonCancel_Click()
Me.Hide
End Sub

Private Sub CommandButtonClear_Click()
Me.Hide
End Sub

Private Sub CommandButtonOk_Click()
    Select Case ""
    Case Me.TextBoxFormNumber
        MsgBox "Please enter the form number."
        Me.TextBoxFormNumber.SetFocus
        Exit Sub
    Case Me.ComboBoxTitle
        MsgBox "Please enter the Applicant's title."
        Me.ComboBoxTitle.SetFocus
        Exit Sub
    Case Me.TextBoxGivenName
        MsgBox "Please enter the Applicant's given name."
        Me.TextBoxGivenName.SetFocus
        Exit Sub
    Case Me.TextBoxFamilyName
        MsgBox "Please enter the Applicant's family name."
        Me.TextBoxFamilyName.SetFocus
        Exit Sub
    Case Me.TextBoxStreet
        MsgBox "Please enter the street address."
        Me.TextBoxStreet.SetFocus
        Exit Sub
    Case Me.TextBoxSuburb
        MsgBox "Please enter the suburb."
        Me.TextBoxSuburb.SetFocus
        Exit Sub
    Case Me.ComboBoxState
        MsgBox "Please enter the state."
        Me.ComboBoxState.SetFocus
        Exit Sub
    Case Me.TextBoxPostCode
        MsgBox "Please enter the postcode."
        Me.TextBoxPostCode.SetFocus
        Exit Sub
    Case Me.TextBoxInterviewDate
        MsgBox "Please enter the interview date."
        Me.TextBoxInterviewDate.SetFocus
        Exit Sub
    End Select
'Set value of a public variable declared at the form level.'
    Me.boolProceed = True
    Me.Hide
lbl_Exit:
    Exit Sub
End Sub

2 个答案:

答案 0 :(得分:1)

这里有几个问题。

第一个问题是你没有一个名为UF的例程来Call UF来调用。

您命名为CalUF的例程不应该在UserForm的代码中,而应该在modMain中并重命名为CallUF

由于您没有错误处理程序,因此无需在例程中包含退出点。

您的AutoNew例程可以重写为:

Sub Autonew()
Create_Reset_Variables
CallUF
End Sub

答案 1 :(得分:1)

我已经为您评论了sub myUpdateFields

  

Sub myUpdateFields()       Dim oStyRng As Word.Range       Dim iLink As Long

iLink = ActiveDocument.Sections(1).Headers(1).Range.StoryType
' logically, iLink should be the StoryType of the first header in Section 1
' Why would this be needed in all StoryRanges?
' Anyway, it is never used. Why have it, then?

' This loops through all the StoryRanges
For Each oStyRng In ActiveDocument.StoryRanges

    ' This also loops through all the StoryRanges
    Do
        oStyRng.Fields.Update
        Set oStyRng = oStyRng.NextStoryRange
    Loop Until oStyRng Is Nothing
    'And after you have looped through all the StoryRanges

    ' Here you go back and start all over again.
 Next oStyRng End Sub

坦率地说,我不知道Do循环在这里做了什么。也许确实如此。阅读NextStoryRange property here。我也不知道在内部循环中使用相同的对象变量是否会扰乱外部循环。我不知道这些事情,因为我从来不需要了解它们。所以我想知道为什么你在学校的第二天就需要它们。

您正在设置许多文档变量。这些可以链接到您希望更新的文档中的REF字段。我打赌你的文件只有一个部分,没有脚注,也没有带有字段的文本框。因此,我认为以下代码应该尽你所能,如果不是更多。

Sub myUpdateFields2()

    Dim Rng As Word.Range

    For Each Rng In ActiveDocument.StoryRanges
        Rng.Fields.Update
     Next Rng
End Sub

对您而言,此代码的巨大优势在于您完全理解它。为此,我避免使用像oStyRng这样的名字(可能意味着" StoryRange Object")。确实Word.Range是一个对象。同样,该过程也会为此变量分配StoryRange类型的Range。但最重要的事实是它是Word.Range,因此是Range。当你用铲子来称呼代码时,代码将更容易阅读,而不是用于挖掘地球的金属对象。因此,Word.Range的首选变量名称是" Rng"。但是 - 只是说。无论如何,使用变量名称可以让您自己轻松阅读代码。