【问题标题】:VBA Input Value From Another UserFormB into TextBox From UserFormAVBA将另一个UserFormB的值输入到UserFormA的TextBox
【发布时间】:2018-03-27 03:53:30
【问题描述】:

我有一个 userForm (mappingGuide),它允许用户从一个对用户更友好的名称列表中选择一个 smartyTag

我有第二个用户表单 (conditionalBuilder),我想在双击文本字段时调用这个用户表单,以便用户可以查找要应用的 smartyTag(如果他们不不知道)。

所以逻辑是:

  1. 打开条件生成器
  2. 双击字段文本框
  3. mappingGuide 打开
  4. 从列表框中选择一个智能标签
  5. 将 smartytag 值填充到 conditionalBuilder 的字段文本框中
  6. 卸载映射指南

我认为我在完成要求时遇到的问题是,当我自己加载表单时,我找不到设置已加载 instance 的 conditionalBuilder 的 fieldName 文本框文本的方法(请参阅最后下面的代码块)。我一直在寻找,但无法弄清楚。

相关代码如下:

conditionalBuilder 从自定义 UI 功能区加载

Sub RunCode(ByVal Control As IRibbonControl)

    Select Case Control.ID

        Case Is = "mapper": LoadMappingGuide
        Case Is = "conditional": LoadConditionalBuilder

    End Select

End Sub

Sub LoadConditionalBuilder()

    Dim conditionalForm As New conditionalBuilder
    conditionalForm.Show False

End Sub

双击fieldName的事件然后加载mappingGuide

Private Sub fieldName_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

    Me.hide
    Dim pickField As New mappingGuide
    pickField.Show False

End Sub

smartTag 列表框点击事件然后尝试将选择放入 fieldName(或者如果未加载表单则选择)

Private Sub smartTagList_Click()

    If smartTagList.ListIndex > -1 And smartTagList.Selected(smartTagList.ListIndex) Then

        Dim smartyTag As String
        smartyTag = smartTagList.List(smartTagList.ListIndex, 2)

        If isUserFormLoaded(conditionalBuilder.Name) Then
            '*** ---> below is my issue how to reference instance of form 
            conditionalBuilder.fieldName.Text = smartyTag
            conditionalBuilder.Show
        Else
            Selection.Range.Text = smartyTag
        End If

    End If

    Unload Me

End Sub

如果有更好的设置也很高兴知道。我将表单分开,因为用户可以使用几个级别创建标签。

【问题讨论】:

  • 更好的方法是在表单上使用属性。
  • 你试过了吗:UserForms("TheNameOfUserForm")
  • @cyboashu - 您能否详细说明或在答案中绘制出来或提供链接以获取更多信息?
  • @MaciejLos - 是的。没用。
  • @CallumDA,你是对的,这就是为什么我赞成你和 [cyboashu] 的答案。这只是另一个想法。 ;)

标签: vba ms-word userform


【解决方案1】:

这就是我的做法,有点矫枉过正,但如果有多种形式,这将是有益的。

模块 1:

 Option Explicit

    Sub test()
        frmMaster.Show False
    End Sub

表格1:frmMaster:

Option Explicit
'/ Declare with events
Dim WithEvents frmCh As frmChild

Private Sub TextBox1_DblClick(ByVal cancel As MSForms.ReturnBoolean)
    handleDoubleClick
End Sub
Sub handleDoubleClick()

    If frmCh Is Nothing Then
        Set frmCh = New frmChild
    End If

    frmCh.Show False

End Sub

'/ Handle the event
Private Sub frmCh_cClicked(cancel As Boolean)
    Me.TextBox1.Text = frmCh.bChecked
End Sub

表格2:frmChild:

Option Explicit

Event cClicked(cancel As Boolean)
Private m_bbChecked As Boolean

Public Property Get bChecked() As Boolean
    bChecked = m_bbChecked
End Property

Public Property Let bChecked(ByVal bNewValue As Boolean)
    m_bbChecked = bNewValue
End Property

Private Sub CheckBox1_Click()
    Me.bChecked = Me.CheckBox1.Value
    '/ Raise an event when something happens.
    '/ Caller will handle it.
    RaiseEvent cClicked(False)
End Sub

【讨论】:

  • 谢谢。我得研究这个。这超出了我目前的理解水平,但我认为可能非常有用。
【解决方案2】:

您可以使用一个演示者类来控制用户表单实例并在它们之间传递值。我模拟了一些类似的东西给你一个想法。

演示者
这是一个类模块,它创建用户窗体,控制它们的范围,并捕获由 条件生成器。它使在之间传递值变得超级容易 用户表单。

Private WithEvents CB As ConditionalBuilder
Private MG As MappingGuide

Public Sub ShowCB()
    Set CB = New ConditionalBuilder
    CB.Show vbModal
End Sub

Private Sub CB_ShowMappingGuide()
    Set MG = New MappingGuide
    MG.Show vbModal
    CB.UpdateTB1 Value:=MG.SmartTag
End Sub

条件生成器
这有一个简单的功能来更新你的文本框,还有一个在演示者中引发动作的事件。

Public Event ShowMappingGuide()

Public Function UpdateTB1(Value As String)
    TextBox1.Value = Value
End Function

Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    RaiseEvent ShowMappingGuide
End Sub

映射指南
TypeProperty 可能有点矫枉过正,因为我们只需要映射指南中的一个值,但这仍然是一种很好的做法。

Private Type TView
    Tag As String
End Type
Private this As TView

Public Property Get SmartTag() As String
    SmartTag = this.Tag
End Property

Private Sub UserForm_Initialize()
    Tags.List = Array("a", "b", "c")
End Sub

Private Sub Tags_Click()
    this.Tag = Tags.List(Tags.ListIndex, 0)
    Me.Hide
End Sub

我有一个最终的标准模块来创建演示者。这就是你要挂在丝带上的东西。

Public Sub ShowProject()
    With New Presenter
        .ShowCB
    End With
End Sub

第 1 步(双击文本字段)


第 2 步(选择“b”)


第 3 步(结果)

【讨论】:

  • 这也太棒了。谢谢你。我将不得不研究这个,因为它对我来说有点新。再次感谢;)
  • 乐于助人!如果您有任何问题,请尽管问:)
  • 我的一个问题是,您的示例中两个表单的代码仍然进入用户表单模块,对吗?而且我也可以在 mappingGuide 表单中使用With Events,这是正确的,因为它也会根据用户的选择自行调用,并采取某些操作。
  • 是的,是的,你可以 - 虽然如果我没记错的话,VBA 的一个怪癖是你不能用 Private WithEvents MG... 编译你的 Presenter,直到你的 MappingGuide 中有相应的 Public Event SomeEvent /跨度>
【解决方案3】:

我实际上是通过将下面的块放在 IF 中来解决这个问题的

    Dim uForm As Object
    For Each uForm In VBA.UserForms
        If uForm.Name = conditionalBuilder.Name Then
            uForm.fieldName.Text = smartyTag
            uForm.Show
        End If
    Next

【讨论】:

    猜你喜欢
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    相关资源
    最近更新 更多