【问题标题】:TextBox ClassModule - Change backgroundcolor only on a real value changeTextBox 类模块 - 仅在实际值更改时更改背景颜色
【发布时间】:2019-04-24 14:46:24
【问题描述】:

我有一个带有多个控件(文本框)的用户窗体。这些文本框将通过选择 ListBox 项来填充。 初始化用户窗体时,这些文本框将分配给处理它们的特定类。

我希望 VBA 仅在对值进行真正更改时才更改这些文本框的背景颜色。我所拥有的是,一旦执行更改,BackgroundColor 总是会更改,但这不是我想要的。

示例 #1: 更改前的文本框值: "test" 更改后的文本框值: "test2" --> BackgroundColor 应该改变

示例 #2: 更改前的文本框值: "test" 更改后的文本框值:“test bla”,但我再次输入“test”。 --> BackgroundColor 不应该改变,因为初始值又在 TextBox 中了。

到目前为止我所拥有的:

' **************************************************************
'  Module:  clsTextbox  Typ = Class Module
' **************************************************************

Public WithEvents mTextBoxs As MSForms.TextBox

Private Sub mTextBoxs_Change()

If mTextBoxs.Text = strInitialVal Then
Reset_BackColor
Else
    mTextBoxs.BackColor = RGB(255, 255, 153)
End If
End Sub

Public Sub Reset_BackColor()
    mTextBoxs.BackColor = RGB(255, 255, 255)
End Sub

' **************************************************************
'  Module:  frmEmployee  Type = Userform
' **************************************************************
Dim arrLabels() As New clsLabel, UBoundarrLabels As Integer
Dim arrTextBoxs() As New clsTextbox, UBoundarrTextBoxs As Integer

Private Sub UserForm_Initialize()
    Dim Ctrl As Control, obLabel As MSForms.Label, obTextbox As MSForms.TextBox
    tblName = "tblMitarbeiter"
    Set wb = ThisWorkbook
    Set ws = wb.Sheets("Mitarbeiter")

    i = 0
    For Each Ctrl In Me.Controls
        If Left(Ctrl.Name, 7) = "TextBox" Then
            i = i + 1
            ReDim Preserve arrTextBoxs(i)
            Set obTextbox = Me.Controls("TextBox" & i)
            Set arrTextBoxs(i).mTextBoxs = obTextbox
        End If
    Next Ctrl

    ' Fill Listbox1 with values (Vorname & Nachname) from Table [tblMitarbeiter]
    Dim lngLastRow As Long: lngLastRow = getListLastRow(ws, tblName)
    Dim vArrListBox1() As Variant
    ReDim vArrListBox1(0 To lngLastRow - 1, 0 To 2)
    For j = 1 To lngLastRow
        vArrListBox1(j - 1, 0) = ws.ListObjects("tblMitarbeiter").DataBodyRange(j, 1).Value
        vArrListBox1(j - 1, 1) = ws.ListObjects("tblMitarbeiter").DataBodyRange(j, 2).Value
        vArrListBox1(j - 1, 2) = ws.ListObjects("tblMitarbeiter").DataBodyRange(j, 3).Value
    Next j

    For t = 1 To 4
        Me.Controls("TextBox" & t) = vArrEmployee(t - 1)
    Next t

    strInitialVal = Me.Controls("TextBox2")

End Sub

我的想法是: 如您所见,我尝试在获取文本框(例如 TextBox2)的初始值的模块中声明一个公共变量(strInitialVal),并在执行 mTextBoxs_Change() 事件时检查 strInitialVal 是否与文本框等。 --> 这有效,但仅适用于变量和文本框的 1:1 关系。

如何将所有文本框值加载到数组中?然后检查 TextBox 类中的值。

如果您需要更多信息,请告诉我。我希望我没有违反任何 SO 规则。

【问题讨论】:

  • 将您的初始值存储在 TextBox 的 .Tag 属性中,(或在您的类中的自定义属性中)更容易将其与实际值进行比较。每次在 TextBox 中输入时都会触发 Change-Event,因此最好使用 Afterupdate 或 Exit-event(但不能被 WithEvents 使用。
  • 这么简单,这么好! .Tag 属性是一个非常好的主意!谢谢

标签: excel vba textbox userform


【解决方案1】:

您可以使用集合来保存您的文本框。 在选项显式之后,声明这些集合 Private ColTxtBox As New Collection

那么当动态创建文本框时,这里是一个例子:

`'Create Unit size; textbox
Set TxtBox = New DynamicTxtbox
TxtBox.Row = FormRows
TxtBox.Column = A_Deliv.F_UnitSize
Call TxtBox.InitText(frm_delivery.Frame1, "txtbox" & TxtBox.Row) 'this is the 
constructor
ColTxtBox.Add TxtBox`

但是,如果您已经在表单上创建了所有文本框并且它们是固定的,那么运行所有控件并将它们添加到您的集合中就足够了(如果它是一个文本框!)。然后在您的文本框类中,您可以轻松地遍历所有文本框 - 并使用类似的东西访问它们的当前值

`Private Sub mTextBoxs_Change()
    For Each TxtBox In ColTxtBox
      If InStr(Me.Value,TxtBox.Value) > 0 Then
        Reset_BackColor
      Else 
        mTextBoxs.BackColor = RGB(255, 255, 153)
      End If
    Next TxtBox
 EndS Sub`

【讨论】:

  • 谢谢。我没有得到第一部分,但我可能理解第二部分。但是,如果假设收集了 4 个值并且我将 txtbox2 值更改为其他值,但这等于集合中的一个值,比如说 txtbox4,那么该类会将其识别为“没有变化”,对吗?
  • 好的,谢谢。但是通过 KeyUp 事件实现它并检测是否按下了“Tab 键”并立即删除公共文本框值以及 MouseDown 事件,以防用户通过鼠标左键单击聚焦文本框并声明与上述相同。
  • 尝试像示例中一样添加子 mTextBox_Change()。这行得通吗?
猜你喜欢
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多