多个复选框=文本框中的文本



我正在尝试构建一个表单。我想要多个复选框来将文本添加到文本框中。我无法做到这一点,没有定义太多!我在最初的场景中使用了3个复选框。现在我必须使用12个复选框。我想知道是否有一种更简单的方法来构建它。

休耕展示了我对原版3的习惯。我真的很感激你的帮助,这样我在接下来的12年里就不用这么做了,这将是一个很大的收获!提前谢谢!


Private Sub SUE_Click()
If SUE.value = True And SUD.value = False And SUG.value = False Then
StartUp.Value = "E DEGD"

Else
If SUD.value = True And SUE.value = False And SUG.value = False Then
StartUp.Value = "D DEGD"

Else
If SUG.value = True And SUD.value = False And SUE.value = False Then
StartUp.Value = "G DEGD"

Else
If SUD.value And SUE.value And SUG.value = True Then
StartUp.Value = "D DEGD, E DEGD, G ALT DEGD"
Else
If SUD.value And SUE.value = True Then
StartUp.Value = "D DEGD, E DEGD"

Else
If SUE.value And SUG.value = True Then
StartUp.Value = "E DEGD, G ALT DEGD"

Else
If SUD.value And SUG.value = True Then
StartUp.Value = "D DEGD, G ALT DEGD"
Else
If SUE.value = False Then
StartUp.Value = ""

Else
If SUD.value = False Then
StartUp.Value = ""

Else
If SUG.value = False Then
StartUp.Value = ""

End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End Sub

我真的不认为这是一条路。每次需要添加复选框时,您都会得到大量的代码行。

对于以下内容,您唯一需要做的就是:

  1. 使用所需的所有复选框创建用户表单(跟踪标题(
  2. 总之,根据需要创建尽可能多的字符串提供程序对象(可能是复选框的数量(,为它们提供所需的字符串和链接到的复选框的标题
  3. 向字符串生成器注册字符串提供程序
  4. 为表单提供字符串生成器

您需要做的是:

  • 创建StringProvider类(您需要创建一个类模块(作为遵循

这是一个非常简单的类,包含3条信息:

  1. 要生成的字符串
  2. 启用/禁用状态
  3. 链接到的复选框的标题(区分大小写(

这个对象被设计用来存储您想要作为输出的字符串值,例如";E DEGD';,以及链接到它的复选框(例如代码中的"SUE"、"SUD"(的名称(实际上是标题(。


Option Explicit

Private Type TValueProvider
value As String
IsEnabled As Boolean
LinkledTB As String
End Type

Private this As TValueProvider

Public Property Get value() As String
value = this.value
End Property

Public Property Let value(v As String)
this.value = v
End Property

Public Property Get IsEnabled() As Boolean
IsEnabled = this.IsEnabled
End Property

Public Property Let IsEnabled(b As Boolean)
this.IsEnabled = b
End Property

Public Property Get LinkedTB() As String
LinkedTB = this.LinkledTB
End Property

Public Property Let LinkedTB(textboxname As String)
this.LinkledTB = textboxname
End Property
  • 一个字符串生成器类,具有以下代码:这个类将存储所有字符串提供程序对象。调用时,UpdateString((子将a(遍历已注册的字符串提供程序(按添加顺序(,并触发StringUpdated事件,该事件用于通知UserForm字符串已更新,并且需要显示它

Option Explicit

Private Type TStringBuilder
stringproviders As Collection
End Type

Public Event StringUpdated(newstring As String)

Private this As TStringBuilder

Private Sub class_initialize()
Set this.stringproviders = New Collection
End Sub

Public Sub UpdateString()
Dim k As Variant
Dim sp As StringProvider
Dim arr() As String
Dim i As Long

Dim EnabledStringProviders As Collection
Set EnabledStringProviders = New Collection

For Each k In this.stringproviders
Set sp = k
If sp.IsEnabled Then
EnabledStringProviders.Add sp
End If
Next k

If EnabledStringProviders.Count = 0 Then
RaiseEvent StringUpdated(vbNullString)
Else
ReDim arr(EnabledStringProviders.Count - 1)

For Each k In EnabledStringProviders
Set sp = k
arr(i) = sp.value
i = i + 1
Next k

RaiseEvent StringUpdated(Join(arr, ", "))

End If

End Sub

Public Sub RegisterStringProvider(sp As StringProvider)
this.stringproviders.Add sp
End Sub

Public Function getSringProviderFromTBName(name As String)
Dim sp As StringProvider
Dim k As Variant

For Each k In this.stringproviders
Set sp = k
If sp.LinkedTB = name Then
Set getSringProviderFromTBName = sp
Exit Function
End If
Next k

Err.Raise vbObjectError + 1, , "Could not find stringprovider with name: " & name
End Function

这将容纳字符串提供程序的集合。当调用UpdateString((时,它将遍历字符串提供程序,并在更新后检索它们的值。

  • 您还需要checkbox对象的包装器,它看起来像这样:

Option Explicit

Private WithEvents WrappedTB As MSForms.CheckBox
Private pstringbuilder As stringbuilder

Public Sub Initialize(ByVal tb As MSForms.CheckBox, sb As stringbuilder)
Set WrappedTB = tb
Set pstringbuilder = sb
End Sub

Private Sub wrappedTB_Change()
Dim sp As StringProvider
Set sp = pstringbuilder.getSringProviderFromTBName(WrappedTB.Caption)

sp.IsEnabled = WrappedTB.value

pstringbuilder.UpdateString
End Sub

此包装器的作用是捕获Checkbox_change事件。每当复选框更改状态时,就会调用wrappedTB_Change((子。它从字符串生成器请求链接到复选框的字符串提供程序,然后调用字符串生成器对象的UpdateString方法。请注意,字符串生成器保留对字符串提供程序的引用,因此对字符串提供器的更新会自动反映在字符串生成器中。

  • 您的表单应该如下所示:

Option Explicit

Private WithEvents pstringbuilder As stringbuilder
Private wrappers As Collection

Private Sub UserForm_initialize()
Set wrappers = New Collection
End Sub

Public Sub ShowDialog(sb As stringbuilder)
Dim wrapper As ChkBoxWrapper
Dim c As Control
Set pstringbuilder = sb

' This code discovers how many checkboxes you have in the userform, and creates one
' wrapper per checkbox. It supplies each wrapper with the same stringbuilder object
' the wrappers are then stored in the wrappers collection.
' That way you don't need to know how many checkboxes there are at compile time.

For Each c In Me.Controls
Set wrapper = New ChkBoxWrapper
If TypeName(c) = "CheckBox" Then
wrapper.Initialize c, sb
wrappers.Add wrapper
End If
Next c

Me.Show

End Sub

Private Sub pstringbuilder_StringUpdated(s As String)
' This handles the event from the stringbuilder object.
TextBox1.value = s
End Sub

作为一个使用示例,这是模块1:


Public Sub main()

Dim frm As UserForm1
Set frm = New UserForm1

Dim sp1 As StringProvider
Dim sp2 As StringProvider

Set sp1 = StringProviderFactory("Toto", "CheckBox1") ' This is where you associate the string you want to output with the checkbox Caption
Set sp2 = StringProviderFactory("Titi", "CheckBox2")

Dim sb As stringbuilder
Set sb = New stringbuilder

' Then you register each stringprovider with the stringbuilder. 
sb.RegisterStringProvider sp1 
sb.RegisterStringProvider sp2

frm.ShowDialog sb



End Sub


Private Function StringProviderFactory(value As String, linked_TB_name As String) As StringProvider
' Just a helper function to create stringproviders
Dim sp As StringProvider
Set sp = New StringProvider
sp.value = value
sp.LinkedTB = linked_TB_name
Set StringProviderFactory = sp
End Function

我希望这能有所帮助。代码可以有很大的改进,但希望这能让你开始。

最新更新