注册 登录
编程论坛 VB6论坛

动态创建控件数组、及创建的控件数组响应事件

ami1999 发布于 2016-11-09 20:53, 11765 次点击
动态创建控件数组、及创建的控件数组响应事件
环境说明:
1、有三、个窗体。窗体1(find_Frm)/窗体2(opt_Frm)/ 窗体3(print_Frm)
2、find_Frm有按钮,命名为find2_cmd。opt_Frm有optionbutton,命名为optadd(0)
3、要求按find2_cmd以后,在opt_Frm上创建多个optionbutton控件数组optadd(a),且显示窗体2
4、点击optadd(a)任意一个,在窗体3(print_Frm)上显示数据内容。
——————————————————————————————————————
find_frm下 find2_cmd 部分代码如下(a已经赋值)
——————————————————————
    opt_Frm.Show
    ReDim optadd(a)
    For i = 1 To a
    opt_w = Int(i / 30)     
        opt_nm = find2(i) & find1(i)
        Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)
        Load opt_Frm.optadd(i)
        optadd(i).Move 200 + opt_w * 2000, (i - opt_w * 30) * 400, 2000, 375
        optadd(i).Caption = opt_nm
        optadd(i).Visible = True   
        optadd(i).Font = "宋体"
        optadd(i).FontBold = True
        optadd(i).FontSize = 12
    Next i
   ————————————————————————————
opt_frm  下代码(r/w已赋值)
Private Sub optadd_Click(Index As Integer)
    ReDim opt_all(w)
        If optadd(Index).Value = True Then
            For j = 1 To r
                opt_temp = xlSheet.Cells(i, 1)
                If opt_temp = find1(Index) Then
                    For k = 1 To w
                        opt_all(k) = opt_all(k) + xlSheet.Cells(1, k) & ":" & xlSheet.Cells(j, k) & Chr(13) & Chr(13)
                    Next k
                End If
            Next j
        End If
    print_Frm.Show
    print_Frm.Print opt_all(k)
End Sub
 ————————————————————————————
问题:在窗体opt_Frm上可以创建出多个optionbutton控件,但对点击optadd(1 to a)无法做出响应。仅仅对optadd(0)有响应。
百思不得其解,VB小小白,求大神帮助。
24 回复
#2
ami19992016-11-09 23:32
好像问题出在这里
Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)
opt_nm 是个变量,创建的不是控件数组。
可不知道怎么改。
5555555
#3
xss_wl2016-11-10 10:09
别急,有时间我给你弄一下。不过在这之前请你把你的工程文件发上来,你上面描述的不好理解。

[此贴子已经被作者于2016-11-10 10:30编辑过]

#4
ami19992016-11-10 11:28
以下是引用xss_wl在2016-11-10 10:09:58的发言:

别急,有时间我给你弄一下。不过在这之前请你把你的工程文件发上来,你上面描述的不好理解。
只有本站会员才能查看附件,请 登录

辛苦了。我百度了很久都没解决,还得版主帮助。
#5
风吹过b2016-11-10 12:53
因你的工作未带一个测试用的 XLS 文件 ,所以整个工程都无法调试。
概念,控件数组,最少有一个元素在设计阶段已确定的,然后其他元素复制这个元素的实例。
     控件数组,不能在运行时直接创建一个原先不存在的控件数组

在这里面
Public optadd() As OptionButton  '查询后增加控件变量  违反了定义

其次,控件数组的添加,
不能这样        Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", optadd(i)) '添加一个按钮 Public optadd As OptionButton
而应使用  Load Object (Index As Integer) 命令进行添加。

----------------
那么改?
首先,你应该放一个 下标为0 的元素,设置为隐藏。其他属性都设置好来。

使用时:
先 清掉除0下标外的所有的元素
for each obj in optadd
  if obj.index>0 then
     unload obj
  end if
next

然后再根据你的需要添加
load optadd(i)
再接着就是移动位置

        optadd(i).Move 200 + opt_w * 2000, (i - opt_w * 30) * 400, 2000, 375 'object.move left,top,width,height left距离左边, top距离顶端,  width新宽度, height新高度
        optadd(i).Caption = opt_nm '命名
        optadd(i).Visible = True    ' 可见

这三句,不是每个对象都设置,而是程序设计模式直接设置好 下标为0 的元素的属性,或者在代码中指定 下标为0 元素的属性。
这样每次加载时,就会把这个属性复制过去。
'        optadd(i).Font = "宋体"
'        optadd(i).FontBold = True
'        optadd(i).FontSize = 12


#6
xss_wl2016-11-10 13:12
以下是引用ami1999在2016-11-10 11:28:29的发言:


辛苦了。我百度了很久都没解决,还得版主帮助。

把你的工程文件发上来,我直接在你的工程里面给你修改。
#7
ami19992016-11-10 14:05
以下是引用xss_wl在2016-11-10 13:12:11的发言:

 
把你的工程文件发上来,我直接在你的工程里面给你修改。

这个是所有的文件,包含表格的
只有本站会员才能查看附件,请 登录
#8
xss_wl2016-11-10 17:30
回复 7楼 ami1999
你的工程文件里没有包含代码中需要使用的那个"维修厂人员资质情况总表.xls"文件
只有本站会员才能查看附件,请 登录

下面是你给我的整个工程文件,你没有把那个"维修厂人员资质情况总表.xls"文件一起发过来
只有本站会员才能查看附件,请 登录
#9
xzlxzlxzl2016-11-10 17:38
回复 8楼 xss_wl
版主大神不是要搜罗资料吧?我觉得没提供完全可以模拟调试的。
仅就题主一楼问题应该是对控件数组和变量数组未区分清楚造成的。
#10
xss_wl2016-11-10 17:42
回复 9楼 xzlxzlxzl
模拟?他的整个程序就是围绕这个Excel文件展开的,你什么内容都不知道,怎么模拟?我十分愿意看到你模拟的结果。
#11
不说也罢2016-11-10 19:01
opt_frm  下代码(r/w已赋值)
Private Sub optadd_Click(Index As Integer)
    ReDim opt_all(w)
        If optadd(Index).Value = True Then
            For j = 1 To r'这个循环里,有个变量i,它的值貌似一直没有变化
                opt_temp = xlSheet.Cells(i, 1)'楼主,你这个过程里的变量i是怎么使用的?窗体变量还是全局变量还是未赋值的??
                If opt_temp = find1(Index) Then
                    For k = 1 To w
                        opt_all(k) = opt_all(k) + xlSheet.Cells(1, k) & ":" & xlSheet.Cells(j, k) & Chr(13) & Chr(13)
                    Next k
                End If
            Next j
        End If
    print_Frm.Show
    print_Frm.Print opt_all(k)
End Sub

我当前没有VB6环境,不好测试你的工程。请注意上述代码中的注释部分
#12
ami19992016-11-10 20:40
以下是引用xss_wl在2016-11-10 17:42:06的发言:

模拟?他的整个程序就是围绕这个Excel文件展开的,你什么内容都不知道,怎么模拟?我十分愿意看到你模拟的结果。

后上传的文件,带有表格excel的
#13
ami19992016-11-10 20:44
以下是引用不说也罢在2016-11-10 19:01:39的发言:

opt_frm  下代码(r/w已赋值)
Private Sub optadd_Click(Index As Integer)
    ReDim opt_all(w)
        If optadd(Index).Value = True Then
            For j = 1 To r'这个循环里,有个变量i,它的值貌似一直没有变化
                opt_temp = xlSheet.Cells(i, 1)'楼主,你这个过程里的变量i是怎么使用的?窗体变量还是全局变量还是未赋值的??
                If opt_temp = find1(Index) Then
                    For k = 1 To w
                        opt_all(k) = opt_all(k) + xlSheet.Cells(1, k) & ":" & xlSheet.Cells(j, k) & Chr(13) & Chr(13)
                    Next k
                End If
            Next j
        End If
    print_Frm.Show
    print_Frm.Print opt_all(k)
End Sub

我当前没有VB6环境,不好测试你的工程。请注意上述代码中的注释部分

变量r:全局变量。在主窗体load时候,给r赋值。r是execl的行数。
变量i:全局变量。这段代码执行之前,已给i赋值。
i:
    opt_Frm.Show
    ReDim optadd(a)
    For i = 1 To a
    opt_w = Int(i / 30)     
        opt_nm = find2(i) & find1(i)
        Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)
        Load opt_Frm.optadd(i)
        optadd(i).Move 200 + opt_w * 2000, (i - opt_w * 30) * 400, 2000, 375
        optadd(i).Caption = opt_nm
        optadd(i).Visible = True   
        optadd(i).Font = "宋体"
        optadd(i).FontBold = True
        optadd(i).FontSize = 12
    Next i
这段代码执行完,opt_frm窗口在前端,窗口显示多个optionbutton。
我想的是:
点击不同的optionbutton,显示不同的数据。
现在问题是。optionbutton可以建立起来,可点击没有反应。窗体上实现建立的optionbutton(0),可以点击(为方便测试,没有隐藏)。

[此贴子已经被作者于2016-11-10 20:49编辑过]

#14
不说也罢2016-11-10 20:56
以下是引用ami1999在2016-11-10 20:44:56的发言:
变量r:全局变量。在主窗体load时候,给r赋值。r是execl的行数。
变量i:全局变量。这段代码执行之前,已给i赋值。


如果这段代码执行之前,已给i赋值,那么在这个For j = 1 To r的循环里,opt_temp = xlSheet.Cells(i, 1),i值不变, opt_temp这个变量的值始终不变,从而opt_temp = find1(Index)这个条件为真或为假在这个循环里也是始终不变的。

那尼这个循环还有什么意义???

我当前没有VB6环境,不好测试你的工程。你尝试将opt_temp = xlSheet.Cells(i, 1)这一行中的 i 改成 j 这个循环因子试一试。
#15
ami19992016-11-10 21:22
以下是引用不说也罢在2016-11-10 20:56:07的发言:



如果这段代码执行之前,已给i赋值,那么在这个For j = 1 To r的循环里,opt_temp = xlSheet.Cells(i, 1),i值不变, opt_temp这个变量的值始终不变,从而opt_temp = find1(Index)这个条件为真或为假在这个循环里也是始终不变的。

那尼这个循环还有什么意义???

我当前没有VB6环境,不好测试你的工程。你尝试将opt_temp = xlSheet.Cells(i, 1)这一行中的 i 改成 j 这个循环因子试一试。



sorry
opt_temp = xlSheet.Cells(i, 1)
应该是
opt_temp = xlSheet.Cells(j, 1)

#16
不说也罢2016-11-10 21:23
以下是引用ami1999在2016-11-10 21:22:14的发言:

sorry
opt_temp = xlSheet.Cells(i, 1)
应该是
opt_temp = xlSheet.Cells(j, 1)

问题解决了吗?
#17
ami19992016-11-10 21:24
以下是引用不说也罢在2016-11-10 20:56:07的发言:



如果这段代码执行之前,已给i赋值,那么在这个For j = 1 To r的循环里,opt_temp = xlSheet.Cells(i, 1),i值不变, opt_temp这个变量的值始终不变,从而opt_temp = find1(Index)这个条件为真或为假在这个循环里也是始终不变的。

那尼这个循环还有什么意义???

我当前没有VB6环境,不好测试你的工程。你尝试将opt_temp = xlSheet.Cells(i, 1)这一行中的 i 改成 j 这个循环因子试一试。




现在主要的问题是:
建立的动态控件数组,好像没有成功。
控件可以建立多个,好像没有和之前窗体上建立的optadd(0),形成控件数组,都是单独的控件。
所以没法执行Private Sub optadd_Click(Index As Integer)里面的代码。
#18
ami19992016-11-10 21:27
以下是引用不说也罢在2016-11-10 21:23:33的发言:


问题解决了吗?

没解决
       Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)

感觉是问题出在这里
可 不知道怎么改。
#19
ami19992016-11-10 21:31
以下是引用风吹过b在2016-11-10 12:53:28的发言:

因你的工作未带一个测试用的 XLS 文件 ,所以整个工程都无法调试。
概念,控件数组,最少有一个元素在设计阶段已确定的,然后其他元素复制这个元素的实例。
     控件数组,不能在运行时直接创建一个原先不存在的控件数组

在这里面
Public optadd() As OptionButton  '查询后增加控件变量  违反了定义

其次,控件数组的添加,
不能这样        Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", optadd(i)) '添加一个按钮 Public optadd As OptionButton
而应使用  Load Object (Index As Integer) 命令进行添加。

----------------
那么改?
首先,你应该放一个 下标为0 的元素,设置为隐藏。其他属性都设置好来。

使用时:
先 清掉除0下标外的所有的元素
for each obj in optadd
  if obj.index>0 then
     unload obj
  end if
next

然后再根据你的需要添加
load optadd(i)
再接着就是移动位置

        optadd(i).Move 200 + opt_w * 2000, (i - opt_w * 30) * 400, 2000, 375 'object.move left,top,width,height left距离左边, top距离顶端,  width新宽度, height新高度
        optadd(i).Caption = opt_nm '命名
        optadd(i).Visible = True    ' 可见

这三句,不是每个对象都设置,而是程序设计模式直接设置好 下标为0 的元素的属性,或者在代码中指定 下标为0 元素的属性。
这样每次加载时,就会把这个属性复制过去。
'        optadd(i).Font = "宋体"
'        optadd(i).FontBold = True
'        optadd(i).FontSize = 12

for each obj in optadd
  if obj.index>0 then
     unload obj
  end if
next

这段放到里面,没法执行。说 ,未初始化for循环。   我定义了obj变量,,Public obj As Variant
#20
不说也罢2016-11-10 21:31
那我无法帮到你了,现在没有VB6环境。不过也给你处理了一个小问题。
#21
ami19992016-11-10 21:32
以下是引用不说也罢在2016-11-10 21:31:24的发言:

那我无法帮到你了,现在没有VB6环境。不过也给你处理了一个小问题。

感谢帮助。十分感谢!
#22
xzlxzlxzl2016-11-11 11:03
题主可以试着注销掉“Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)”这句,这是动态控件的方法,和控件数组还是有区别的:控件数组是在设计时建立,软件运行时控件已经存在,而动态控件是软件运行时原本没有,通过程序动态建立,动态控件的事件响应还需要进行WithEvents声明,象你这句实际上创建了opt_nm变量设定的名称的控件,不是“optadd”这个名称了。

另回复xss_wl版主:你完全可以自己建立一个同名的excel模拟的,应该数据不重要。我常这样做的。
哎,现正在外面实习,没有调试环境,对题主的问题暂时没法给出正确解答!
#23
ami19992016-11-11 11:26
以下是引用风吹过b在2016-11-10 12:53:28的发言:

因你的工作未带一个测试用的 XLS 文件 ,所以整个工程都无法调试。
概念,控件数组,最少有一个元素在设计阶段已确定的,然后其他元素复制这个元素的实例。
     控件数组,不能在运行时直接创建一个原先不存在的控件数组
 
在这里面
Public optadd() As OptionButton  '查询后增加控件变量  违反了定义
 
其次,控件数组的添加,
不能这样        Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", optadd(i)) '添加一个按钮 Public optadd As OptionButton
而应使用  Load Object (Index As Integer) 命令进行添加。
 
----------------
那么改?
首先,你应该放一个 下标为0 的元素,设置为隐藏。其他属性都设置好来。
 
使用时:
先 清掉除0下标外的所有的元素
for each obj in optadd
  if obj.index>0 then  
     unload obj
  end if
next
 
然后再根据你的需要添加
load optadd(i)
再接着就是移动位置
 
        optadd(i).Move 200 + opt_w * 2000, (i - opt_w * 30) * 400, 2000, 375 'object.move left,top,width,height left距离左边, top距离顶端,  width新宽度, height新高度
        optadd(i).Caption = opt_nm '命名
        optadd(i).Visible = True    ' 可见
 
这三句,不是每个对象都设置,而是程序设计模式直接设置好 下标为0 的元素的属性,或者在代码中指定 下标为0 元素的属性。
这样每次加载时,就会把这个属性复制过去。
'        optadd(i).Font = "宋体"
'        optadd(i).FontBold = True
'        optadd(i).FontSize = 12
 
 

@风吹过b
十分感谢帮助,按照您的办法,已测试成功。
开始测试不成功问题出在:
 For Each obj In opt_Frm.optadd
Load opt_Frm.optadd(i)
没加红色字体部分。
#24
ami19992016-11-11 11:28
以下是引用xzlxzlxzl在2016-11-11 11:03:06的发言:

题主可以试着注销掉“Set optadd(i) = opt_Frm.Controls.Add("vb.optionbutton", opt_nm)”这句,这是动态控件的方法,和控件数组还是有区别的:控件数组是在设计时建立,软件运行时控件已经存在,而动态控件是软件运行时原本没有,通过程序动态建立,动态控件的事件响应还需要进行WithEvents声明,象你这句实际上创建了opt_nm变量设定的名称的控件,不是“optadd”这个名称了。
 
另回复xss_wl版主:你完全可以自己建立一个同名的excel模拟的,应该数据不重要。我常这样做的。
哎,现正在外面实习,没有调试环境,对题主的问题暂时没法给出正确解答!
已按照  风大哥  的方法测试成功。
感谢楼上、以及楼上的楼上……,感谢帮助我大神们。

#25
sswwxx1232016-11-15 22:10
以下是引用xss_wl在2016-11-10 17:42:06的发言:

模拟?他的整个程序就是围绕这个Excel文件展开的,你什么内容都不知道,怎么模拟?我十分愿意看到你模拟的结果。
我看了一下,认为楼上说的是对的,区分概念---控件的问题,与excel无关的
1