我在excel 2007上创建了一个具有6x6排列组合框的用户窗体。最后一行和最后一列是'all up'框,它们应该具有基于各自行/列的值。其余25(5x5)个组合框有3个值(红色,琥珀色,绿色),当用户选择一个值时,组合框显示该值,背景颜色为选中的值(我这样做是通过创建一个函数在一个模块中并在每个combobox_change()内调用它。
我在编写最后一行和列框时遇到问题。基本上,如果对于第1行说,甚至只有一个“红色”,第1行(1,6)上的最后一个框应该自动变为红色。如果没有红色,但有一个'琥珀色',最后一个方框应该变成'琥珀色'。如果有“红色”和“琥珀色”,则应优先考虑“红色”。列的类似逻辑也是如此。
到目前为止我尝试过:
在userform代码中:
Private Sub Txt_Score_1_1_Change() 'This is for row 1 column 1 on the matrix'
Call ScoreChange.ScoreChange("Txt_Score_1_1")
在一个模块中:
Public Sub ScoreChange(ctrlName As String)
If Scorecard.Controls(ctrlName).Value = "R" Then
Scorecard.Controls(ctrlName).BackColor = vbRed
ElseIf Scorecard.Controls(ctrlName).Value = "G" Then
Scorecard.Controls(ctrlName).BackColor = vbGreen
ElseIf Scorecard.Controls(ctrlName).Value = "A" Then
Scorecard.Controls(ctrlName).BackColor = vbYellow
Else
Scorecard.Controls(ctrlName).BackColor = vbWhite
End If
For i = 1 To 5
For j = 1 To 5
If Scorecard.Controls("Txt_Score_" & i & "_" & j).Value <> "" Then
If Scorecard.Controls("Txt_Score_" & i & "_" & j).Value = "R" Then
Scorecard.Controls("Txt_Score_" & i & "_6").Value = "R"
Scorecard.Controls("Txt_Score_6_" & j).Value = "R"
ElseIf Scorecard.Controls("Txt_Score_" & i & "_" & j).Value = "A" Then
Scorecard.Controls("Txt_Score_" & i & "_6").Value = "A"
Scorecard.Controls("Txt_Score_6_" & j).Value = "A"
End If
End If
Next j
Next i
End Sub
上述方法可以在更改时更改组合框的各个颜色,但会在“总计”/“全部向上”框中分开。
我认为要实现上述目标需要做的是我需要编写一个代码来识别特定行/列的所有组合框何时被填充,然后将这些值存储在数组中,并识别在数组中,最后一个框的值。
如何实现这一目标的任何帮助将不胜感激。
此外,如果在其他地方发布了类似的内容,我会道歉,但我做了很多研究,找不到任何东西。
感谢。
答案 0 :(得分:1)
我认为可能有一种更简单的方法来攻击这项任务,当然也是一种更简单的方式来消费所有ComboBox_Change
事件。
如果我理解你的问题,你说你有一个5乘5'子'组合框的矩阵。然后,您有5个“父级”控件,这些控件根据行子项的选择而变化,5个“父级控件”对列的子项执行相同操作。
因此,您可以创建两个类。我称他们为clsChild
和clsParent
。子类捕获更改事件,然后通知行和列父项已发生更改。父类包含其子项列表,并根据子项的选择运行着色规则。
就规则而言,我已经创建了Enum
您的颜色,其中红色最低,白色最高,所以您只需将任何一个孩子的最低'得分'给父母着色控制。
我保留了与ComboBoxes的帖子相同的命名约定,但我不明白为什么'父'控件是Comboboxes - 当然你不希望用户能够更改它们?我冒昧地使用命名约Labels
为行Lbl_Score_R1 ... R5
和列Lbl_Score_C1 ... C5
。{/ p>
这种方法的优点在于你只需要将孩子和父母之间的关系绑定一次,然后简单地在他们之间传递控制对象。这将避免每次发生更改事件时都必须进行笨拙的字符串操作。
所以,代码......
我。插入一个新类并将其命名为clsChild
。添加以下代码:
Option Explicit
Private WithEvents mCtrl As MSForms.ComboBox
Private mMum As clsParent
Private mDad As clsParent
Private mLight As Lights
Public Property Set Mum(val As clsParent)
Set mMum = val
Set mMum.ChildInLine = Me
End Property
Public Property Set Dad(val As clsParent)
Set mDad = val
Set mDad.ChildInLine = Me
End Property
Public Property Set Ctrl(val As MSForms.ComboBox)
Set mCtrl = val
With mCtrl
.List = Array("R", "A", "G", "W")
.ListIndex = 3
End With
End Property
Public Property Get Light() As Lights
Light = mLight
End Property
Private Property Let Light(val As Lights)
mLight = val
With mCtrl
Select Case mLight
Case Lights.Red: .BackColor = vbRed
Case Lights.Amber: .BackColor = vbYellow
Case Lights.Green: .BackColor = vbGreen
Case Lights.White: .BackColor = vbWhite
End Select
End With
If Not mMum Is Nothing Then mMum.ConsumeChildChanged
If Not mDad Is Nothing Then mDad.ConsumeChildChanged
End Property
Private Sub mCtrl_Change()
Select Case mCtrl.Value
Case Is = "R": Light = Red
Case Is = "A": Light = Amber
Case Is = "G": Light = Green
Case Else: Light = White
End Select
End Sub
II。插入另一个新类并将其命名为clsParent
并添加以下代码:
Option Explicit
Private mCtrl As MSForms.Label
Private mChildren As Collection
Private mLight As Lights
Public Property Set Ctrl(val As MSForms.Label)
Set mCtrl = val
Set mChildren = New Collection
End Property
Public Property Set ChildInLine(val As clsChild)
mChildren.Add val
End Property
Public Sub ConsumeChildChanged()
Dim lowest As Lights
Dim oChild As clsChild
lowest = White
For Each oChild In mChildren
With oChild
If .Light < lowest Then
lowest = .Light
End If
End With
Next
Light = lowest
End Sub
Private Property Get Light() As Lights
Light = mLight
End Property
Private Property Let Light(val As Lights)
mLight = val
With mCtrl
Select Case mLight
Case Lights.Red: .BackColor = vbRed
Case Lights.Amber: .BackColor = vbYellow
Case Lights.Green: .BackColor = vbGreen
Case Else: .BackColor = vbWhite
End Select
End With
End Property
III。在任何Module
的顶部添加以下内容:
Public Enum Lights
Red
Amber
Green
White
End Enum
IV。最后将以下内容添加到您的UserForm
代码中:
Option Explicit
Private mMum(1 To 5) As clsParent
Private mDad(1 To 5) As clsParent
Private mChild(1 To 5, 1 To 5) As clsChild
Private Sub UserForm_Initialize()
Dim i As Integer, j As Integer
For i = 1 To 5
Set mMum(i) = New clsParent
Set mMum(i).Ctrl = Me.Controls("Lbl_Score_R" & i)
Set mDad(i) = New clsParent
Set mDad(i).Ctrl = Me.Controls("Lbl_Score_C" & i)
Next
For i = 1 To 5
For j = 1 To 5
Set mChild(i, j) = New clsChild
With mChild(i, j)
Set .Ctrl = Me.Controls("Txt_Score_" & i & "_" & j)
Set .Mum = mMum(i)
Set .Dad = mDad(j)
End With
Next
Next
End Sub