【发布时间】:2019-07-12 14:56:58
【问题描述】:
This 线程已经快 4 年了,但部分帮助我解决了一个问题。
目前的工作方式:在用户窗体中,根据对组合框的选择,创建了几个复选框并将其链接到自定义类(我需要一个 _Click/_Change-Event)。除了一项缺失的功能外,几乎所有功能都按预期工作:删除复选框如果选择发生变化。
在创建过程中,复选框存储在集合中
col_Checkbox.Add obj_Checkbox(i), obj_Checkbox(i).Name
如果用户更改了 ComboBox 中的选定值,则触发 _Change() 事件并开始重新创建(取决于新的选择,我可能只需要一个 CheckBox 或三个新的 CheckBox)。 重新创建子从删除 col_Checkbox 的每个项目开始,然后将创建 X 个 CheckBoxes 并链接到自定义类。
花了两天时间研究如何解决这个问题后,我想在这里发布我的问题......现在开始真正奇怪的部分:我已经准备好我的问题,用“复制和粘贴”功能写下代码编辑器中的版本(90% 复制和粘贴,10% 将一些数组(需要数据源)更改为一些硬数字)并考虑在新的 excel 表中快速尝试(你知道,也许我忘了复制一些声明等)。
运行我的代码后(忘记了两个全局语句.. ups),整个事情都按预期工作,令我自己感到惊讶。现在我花了更多时间来寻找差异,看起来我没有发现任何差异除了我已经切换为一些硬数字的缺失数组/集合。
那么,也许有人可以帮助我让我的真实代码像我的“准备发布”代码一样工作?我很高兴它的工作原理,但也对它的工作原理感到困惑。
区别: 我的 ComboBox 充满了几个字符串。选择字符串后,VBA 开始在 column2 中查找匹配的案例,并将所有 colum3 加载到一个数组中(该字符串是我的第一个索引)。在第二步中,将数组添加到集合中,但只有唯一字符串(第二个索引),不会添加重复项。
str_ComboBox1_Selected = ComboBox1.Value
'### Array1
Dim i As Long, j As Long
For i = 1 To ln_LastRow
If Cells(i, 2).Value = str_ComboBox1_Selected Then
ReDim Preserve arr_AllIndex(j)
arr_AllIndex(j) = Cells(i, 3).Value
'Debug.Print arr_AllIndex(j)
j = j + 1
End If
Next i
'### Unique-Collection
On Error Resume Next
For Each a In arr_AllIndex
col_Index.Add a, a
Next
On Error GoTo 0
通过 col_Index.Count 我知道我需要多少个 CheckBox。在我的“演示”中,我跳过了这一部分,并在 ComboBox1 中添加了一些数值 (1-6)。 之后我将 col_Index.Count 的每个实例更改为 ComboBox1.Value
这应该是相同的(至少用于演示),对吧?两者都作为我的“For i =”-Loop 的上限。在创建过程中,每个 CheckBox 都有自己的名称,这又是我的集合 (col_Index(i)),而仅 i 作为通用名称 (CheckBox_1; CheckBox_2 vs. CheckBox_NAME1; CheckBox_NAME2)。
< My Code >
im i As Long
Dim str_ObjName As String
For i = 1 To col_Index.Count
ReDim Preserve obj_Checkbox(i)
str_ObjName = "Checkbox_" & col_Index(i)
Debug.Print col_Index(i)
Set obj_Checkbox(i) = UserForm1.Controls.Add("Forms.CheckBox.1", str_ObjName)
col_Checkbox.Add obj_Checkbox(i), obj_Checkbox(i).Name
'Debug.Print str_ObjName
'Debug.Print obj_Checkbox(i).Name
'Debug.Print col_Checkbox.Item(i).Name
Next i
vs
< My Code without col_Index() and some hard numbers >
Dim i As Long
Dim str_ObjName As String
For i = 1 To UserForm1.ComboBox1.Value
ReDim Preserve obj_Checkbox(i)
str_ObjName = "Checkbox_" & i '*Instead of i here would be (collection)(i) to have a proper name
Set obj_Checkbox(i) = UserForm1.Controls.Add("Forms.CheckBox.1", str_ObjName)
col_Checkbox.Add obj_Checkbox(i), obj_Checkbox(i).Name 'The created objectes are stored in a collection for later use
'Debug.Print col_Checkbox.Item(i).Name 'This part works
'Debug.Print str_ObjName
'Debug.Print obj_Checkbox(i).Name
'Debug.Print col_Checkbox.Item(i).Name
Next i
其他一切都是一样的......我尝试使用 debug.print 语句检查某些名称是否不匹配 - 但不,所有三个名称都是相同的(如预期的那样)。
我的删除子是
Dim i As Long
i = 1
Do While col_Checkbox.Count > 0
'Debug.Print obj_Checkbox(i).Name
'Debug.Print col_Checkbox.Item(1).Name
UserForm1.Controls.Remove col_Checkbox.Item(1).Name
'Debug.Print "i=" & i
col_Checkbox.Remove 1
i = i + 1
Loop
End Sub
在这两种情况下(真实和演示),调试语句都显示循环正在按预期工作并计数。 obj_Checkbox(i) 显示与 col_Checkbox.Item(1).Name 相同的语句 - 因此在每个循环之后,该项目都会从我的集合中删除。 但是在我的“真实”文件中,所有复选框都保留并添加到前面的复选框下方,而在我的“演示”文件中,所有复选框都在 _Change()-Event 工作后被删除。
我错过了什么或做错了什么?
如果有人想尝试演示片段,请随意尝试:您只需要一个新的 excel 文件,其中包含一个带有命令按钮的工作表。
对于表 1
Option Explicit
Private Sub CommandButton1_Click()
UserForm1.Show
End Sub
在通用类模块(Class1)中
Option Explicit
Public WithEvents Class1 As MSForms.CheckBox
Public Sub AssignCheckBox(c As MSForms.CheckBox)
Set Class1 = c
End Sub
Private Sub Class1_Click()
Debug.Print Class1.Caption
End Sub
对于通用模块(Module1)
Option Explicit
Global Class1COL As New Collection
Global obj_Checkbox() As Object, col_Checkbox As Collection
Sub Create()
Dim i As Long
Dim str_ObjName As String
For i = 1 To UserForm1.ComboBox1.Value
ReDim Preserve obj_Checkbox(i)
str_ObjName = "Checkbox_" & i '*Instead of i here would be (collection)(i) to have a proper name
Set obj_Checkbox(i) = UserForm1.Controls.Add("Forms.CheckBox.1", str_ObjName)
col_Checkbox.Add obj_Checkbox(i), obj_Checkbox(i).Name 'The created objectes are stored in a collection for later use
'Debug.Print col_Checkbox.Item(i).Name 'This part works
'Debug.Print str_ObjName
'Debug.Print obj_Checkbox(i).Name
'Debug.Print col_Checkbox.Item(i).Name
Select Case True
Case i = 1
With obj_Checkbox(1)
.Top = UserForm1.ComboBox1.Top + 50
End With
Case Else
With obj_Checkbox(i)
.Top = obj_Checkbox(i - 1).Top + 40
End With
End Select
With obj_Checkbox(i)
.Left = UserForm1.ComboBox1.Left
.Height = 35
.Width = 100
.Caption = i
End With
Next i
Application.OnTime Now, "NewClass"
End Sub
Sub NewClass()
Dim CheckBox As Class1, c As Control
Dim i As Long
'Debug.Print "new class"
For i = 1 To col_Checkbox.Count
Set c = col_Checkbox.Item(i)
Set CheckBox = New Class1
CheckBox.AssignCheckBox c
Class1COL.Add CheckBox
Next i
End Sub
Sub Delete()
Dim i As Long
i = 1
Do While col_Checkbox.Count > 0
'Debug.Print obj_Checkbox(i).Name
'Debug.Print col_Checkbox.Item(1).Name
UserForm1.Controls.Remove col_Checkbox.Item(1).Name
'Debug.Print "i=" & i
col_Checkbox.Remove 1
i = i + 1
Loop
End Sub
对于标准用户表单 (UserForm1)
Option Explicit
Sub UserForm_Initialize()
With UserForm1.ComboBox1
.AddItem 1
.AddItem 2
.AddItem 3
.AddItem 4
.AddItem 5
.AddItem 6
End With
With UserForm1
.Top = Application.Top + 50
.Left = Application.Left + 100
End With
Set col_Checkbox = New Collection
End Sub
Sub ComboBox1_Change()
Call Module1.Delete
'First every CheckBox on the Form is deleted
'in between an array is created from a list of all search-terms (ComboBox1 doesn't have numbers)//
'// and a unique-only collection is created. With (collection).count I've got the number of CheckBoxes to be created
Call Module1.Create
'Then X new Boxes will be loaded into the form
End Sub
以防万一有人想看看我的数组到集合例程(也许这里已经有错误了?) 在 ComboBox1_Change 中被调用:
Sub ComboBox1_Change()
Call Modul1.Delete
str_ComboBox1_Selected = ComboBox1.Value
Dim i As Long, j As Long
For i = 1 To ln_LastRow
If Cells(i, 2).Value = str_ComboBox1_Selected Then
ReDim Preserve arr_AllIndex(j)
arr_AllIndex(j) = Cells(i, 3).Value
'Debug.Print arr_AllIndex(j)
j = j + 1
End If
Next i
On Error Resume Next
For Each a In arr_AllIndex
col_Index.Add a, a
Next
On Error GoTo 0
'For i = 1 To col_Index.Count
'Debug.Print col_Index(i)
'Next i
Call Modul1.Create
End Sub
我现在正在处理“测试样本”,因此所有这些通用名称,并非所有引用/变量都被正确声明...在我的测试样本集成到我的“主文件”。
感谢您阅读我的文字墙!
【问题讨论】:
-
我猜这里的内容太多了,人们无法消化 - 一个 更短的问题会得到更多的关注。