dim t1 as textbox,t2 as textboxcname= set t1=controls.add(Controls.Add("VB.textbox", cname) set t1.container=frame1'假设frame1已经存在cname=。 set t2=controls.add(Controls.Add("VB.textbox", cname) set t2.container=frame2'假设frame2已经存在
dim tx as textboxcname="T1" set tx=controls.add(Controls.Add("VB.textbox", cname) set tx.container=frame1'假设frame1已经存在 tx.tag="g1"cname="T2" set tx=controls.add(Controls.Add("VB.textbox", cname) set tx.container=frame1'假设frame1已经存在 tx.tag="g1" ....... '现在T1,T2都被标记为g1cname="TG1" set tx=controls.add(Controls.Add("VB.textbox", cname) set tx.container=frame1'假设frame1已经存在 tx.tag="g2"cname="TG2" set tx=controls.add(Controls.Add("VB.textbox", cname) set tx.container=frame1'假设frame1已经存在 tx.tag="g2" '现在TG1,TG2都被标记为g2’以此类推,通过tag属性分辨是属于哪个组,使用时候,看tag值,就知道是属于哪个组
用空间数组呗以 Frame1 为例,在Frame1上加一个辅助用的 TextBox 控件,假设名称为 TextFrame1,将该控件的 Index 属性值设置为 0,Visible 设置为 False 然后写如下代码:Option ExplicitPrivate Sub Command1_Click() Dim i As Integer
sorry,真没注意到重写了动态创建的代码,如下,不知是否是你需要的,没怎么调试,看看能运行就贴上来了,理论上来说一定有bug,见谅Option ExplicitPrivate Type T_FRA_TBS fra As frame tbs() As TextBox End TypePrivate fra_tbs() As T_FRA_TBSPrivate Sub Command1_Click() If True = delete_frame(3) Then MsgBox "Delete Frame Done" Else MsgBox "Delete Frame Failed" End If End SubPrivate Sub Command2_Click() If True = delete_tbx(6, 2) Then MsgBox "Delete TextBox Done" Else MsgBox "Delete TextBox Failed" End If End SubPrivate Sub Form_Load() Dim fra_count As Long
' 假设通过函数 get_frame_count 来获取 frame 数量 fra_count = get_frame_count(0) ReDim fra_tbs(fra_count - 1) ' 创建 frame Dim fra_name As String Dim left As Long, top As Long Dim i As Long For i = 0 To fra_count - 1 fra_name = "fra_" + Trim$(Str(i + 1))
If (0 = i) Then Set fra_tbs(i).fra = create_frame(fra_name, , , , , Me) ElseIf (1 = i) Then left = fra_tbs(0).fra.left + 300 + fra_tbs(0).fra.width top = fra_tbs(0).fra.top
Set fra_tbs(i).fra = create_frame(fra_name, , , left, top, Me) Else If (0 = (i Mod 2)) Then left = fra_tbs(0).fra.left Else left = fra_tbs(1).fra.left End If
Select Case condition Case Is = 1 get_textbox_count = 3 Case Is = 2 get_textbox_count = 6 Case Is = 3 get_textbox_count = 2 Case Is = 4 get_textbox_count = 5 Case Is = 5 get_textbox_count = 2 Case Is = 6 get_textbox_count = 4 Case Is = 7 get_textbox_count = 5 Case Is = 8 get_textbox_count = 6 End Select End Function'新建 frame 的函数 Private Function create_frame(ByVal fra_name As String, _ Optional ByVal width As Long = 6200, _ Optional ByVal height As Long = 3000, _ Optional ByVal left As Long = 100, _ Optional ByVal top As Long = 100, _ Optional container As Object = Nothing) As frame Dim frame_new As frame Set frame_new = Nothing
If (Not (container Is Nothing)) Then Set frame_new = Controls.Add("VB.Frame", fra_name, container) Else Set frame_new = Controls.Add("VB.Frame", fra_name) End If
With frame_new .width = width .height = height .left = left .top = top .Visible = True End With
Set create_frame = frame_new End Function'删除 frame 的函数 Private Function delete_frame(ByVal fra_index As Long) As Boolean If (fra_index > UBound(fra_tbs)) Then delete_frame = False Exit Function End If
Controls.Remove (fra_tbs(fra_index).fra.Name)
' 可以考虑用 CopyMemory API 优化 Dim i As Long For i = (fra_index + 1) To UBound(fra_tbs) fra_tbs(i - 1) = fra_tbs(i) Next ReDim Preserve fra_tbs(UBound(fra_tbs) - 1)
delete_frame = True End Function'新建 textbox 的函数 Private Function create_tbx(ByVal tbx_name As String, _ Optional ByVal width As Long = 5500, _ Optional ByVal height As Long = 300, _ Optional ByVal left As Long = 300, _ Optional ByVal top As Long = 30, _ Optional container As Object = Nothing) As TextBox Dim tbx_new As TextBox Set tbx_new = Nothing
If (Not (container Is Nothing)) Then Set tbx_new = Controls.Add("VB.TextBox", tbx_name, container) Else Set tbx_new = Controls.Add("VB.TextBox", tbx_name) End If
With tbx_new .width = width .height = height .left = left .top = top .Visible = True End With
Set create_tbx = tbx_new End Function'删除 textbox 的函数 Private Function delete_tbx(ByVal fra_index As Long, ByVal tbx_index As Long) As Boolean If (fra_index > UBound(fra_tbs)) Then delete_tbx = False Exit Function End If
If (tbx_index > UBound(fra_tbs(fra_index).tbs)) Then delete_tbx = False Exit Function End If ' 可以考虑用 CopyMemory API 优化 Dim i As Long For i = (tbx_index + 1) To UBound(fra_tbs(fra_index).tbs) fra_tbs(fra_index).tbs(i - 1) = fra_tbs(fra_index).tbs(i) Next ReDim Preserve fra_tbs(fra_index).tbs(UBound(fra_tbs(fra_index).tbs) - 1) Controls.Remove (fra_tbs(fra_index).tbs(tbx_index).Name)
delete_tbx = True End Function
谢谢你的热心,我想知道这种方法对事件的响应是如何达到的,还好我已经用另一种方法调试好了,不过用的是是每一次都遍历窗体的方法,感觉很费事。现在对动态控件的响应是这么做的,Private WithEvents NewFrame As Frame'添加 Private WithEvents NewText As TextBox'新建Frame控件 Public Property Set AddFrame(ByVal fData As Frame) Set NewFrame = fData End Property Public Property Get AddFrame() As Frame Set AddFrame = NewFrame End PropertyPrivate Sub NewFrame_Click()’响应建立的frame的事件,比如新建、删除frame及新建删除textbox,你给出的方法好像不能像控件数组一样响应事件(还是我基础太差了),晕啊 MsgBox NewFrame.Name End Sub'可惜WithEvents不能定义数组,正在想办法
dim F() as class1'定义frame数组 dim T() as class1’定义textbox数组,问题出在这里,T()只能获取所有frame数组中的控件,不能分开,只能每次使用时判断
set t1=controls.add(Controls.Add("VB.textbox", cname)
set t1.container=frame1'假设frame1已经存在cname=。
set t2=controls.add(Controls.Add("VB.textbox", cname)
set t2.container=frame2'假设frame2已经存在
set tx=controls.add(Controls.Add("VB.textbox", cname)
set tx.container=frame1'假设frame1已经存在
tx.tag="g1"cname="T2"
set tx=controls.add(Controls.Add("VB.textbox", cname)
set tx.container=frame1'假设frame1已经存在
tx.tag="g1"
.......
'现在T1,T2都被标记为g1cname="TG1"
set tx=controls.add(Controls.Add("VB.textbox", cname)
set tx.container=frame1'假设frame1已经存在
tx.tag="g2"cname="TG2"
set tx=controls.add(Controls.Add("VB.textbox", cname)
set tx.container=frame1'假设frame1已经存在
tx.tag="g2"
'现在TG1,TG2都被标记为g2’以此类推,通过tag属性分辨是属于哪个组,使用时候,看tag值,就知道是属于哪个组
然后写如下代码:Option ExplicitPrivate Sub Command1_Click()
Dim i As Integer
For i = 1 To 9
Load TextFrame1(i)
TextFrame1(i).Left = 100
TextFrame1(i).Height = 45
TextFrame1(i).Width = 3000
TextFrame1(i).Top = TextFrame1(i - 1).Top + TextFrame1(i).Height + 50
TextFrame1(i).Visible = True
Next
End SubPrivate Sub Form_Load()
TextFrame1(0).Visible = False
End SubPrivate Sub Form_Unload(Cancel As Integer)
Dim i As Integer
For i = 1 To 9
Unload TextFrame1(i)
Next
End Sub
其它 Frame 的 TextBox 们类似处理
fra As frame
tbs() As TextBox
End TypePrivate fra_tbs() As T_FRA_TBSPrivate Sub Command1_Click()
If True = delete_frame(3) Then
MsgBox "Delete Frame Done"
Else
MsgBox "Delete Frame Failed"
End If
End SubPrivate Sub Command2_Click()
If True = delete_tbx(6, 2) Then
MsgBox "Delete TextBox Done"
Else
MsgBox "Delete TextBox Failed"
End If
End SubPrivate Sub Form_Load()
Dim fra_count As Long
' 假设通过函数 get_frame_count 来获取 frame 数量
fra_count = get_frame_count(0)
ReDim fra_tbs(fra_count - 1) ' 创建 frame
Dim fra_name As String
Dim left As Long, top As Long
Dim i As Long
For i = 0 To fra_count - 1
fra_name = "fra_" + Trim$(Str(i + 1))
If (0 = i) Then
Set fra_tbs(i).fra = create_frame(fra_name, , , , , Me)
ElseIf (1 = i) Then
left = fra_tbs(0).fra.left + 300 + fra_tbs(0).fra.width
top = fra_tbs(0).fra.top
Set fra_tbs(i).fra = create_frame(fra_name, , , left, top, Me)
Else
If (0 = (i Mod 2)) Then
left = fra_tbs(0).fra.left
Else
left = fra_tbs(1).fra.left
End If
top = fra_tbs(i - 2).fra.top + fra_tbs(i - 2).fra.height + 100
Set fra_tbs(i).fra = create_frame(fra_name, , , left, top, Me)
End If
fra_tbs(i).fra.Caption = fra_name
Dim tbs_count As Long
' 假设通过函数 get_textbox_count 来获取 textbox 数量
tbs_count = get_textbox_count(i + 1)
ReDim fra_tbs(i).tbs(tbs_count - 1)
fra_tbs(i).fra.Caption = fra_tbs(i).fra.Caption + " (" + Trim$(Str(tbs_count)) + ")"
' 为当前 frame 创建 textbox
Dim tbx_name As String
Dim j As Long
For j = 0 To tbs_count - 1
tbx_name = "tbx_" + Trim$(Str(i + 1)) + "_" + Trim$(Str(j + 1))
If (0 = j) Then
top = 500
Else
top = fra_tbs(i).tbs(j - 1).top + fra_tbs(i).tbs(j - 1).height + 50
End If
Set fra_tbs(i).tbs(j) = create_tbx(tbx_name, , , , top, fra_tbs(i).fra)
Next
NextEnd SubPrivate Function get_frame_count(ByVal condition As Variant) As Long
' do sth. to get counts
' 假设有 8 个 frame
get_frame_count = 8End FunctionPrivate Function get_textbox_count(ByVal condition As Variant) As Long ' do sth. to get counts
' 假设每个frame拥有的 textbox 数量分别如下
' 3, 6, 2, 5, 2, 7, 4, 9
Select Case condition
Case Is = 1
get_textbox_count = 3
Case Is = 2
get_textbox_count = 6
Case Is = 3
get_textbox_count = 2
Case Is = 4
get_textbox_count = 5
Case Is = 5
get_textbox_count = 2
Case Is = 6
get_textbox_count = 4
Case Is = 7
get_textbox_count = 5
Case Is = 8
get_textbox_count = 6
End Select
End Function'新建 frame 的函数
Private Function create_frame(ByVal fra_name As String, _
Optional ByVal width As Long = 6200, _
Optional ByVal height As Long = 3000, _
Optional ByVal left As Long = 100, _
Optional ByVal top As Long = 100, _
Optional container As Object = Nothing) As frame
Dim frame_new As frame
Set frame_new = Nothing
If (Not (container Is Nothing)) Then
Set frame_new = Controls.Add("VB.Frame", fra_name, container)
Else
Set frame_new = Controls.Add("VB.Frame", fra_name)
End If
With frame_new
.width = width
.height = height
.left = left
.top = top
.Visible = True
End With
Set create_frame = frame_new
End Function'删除 frame 的函数
Private Function delete_frame(ByVal fra_index As Long) As Boolean
If (fra_index > UBound(fra_tbs)) Then
delete_frame = False
Exit Function
End If
Controls.Remove (fra_tbs(fra_index).fra.Name)
' 可以考虑用 CopyMemory API 优化
Dim i As Long
For i = (fra_index + 1) To UBound(fra_tbs)
fra_tbs(i - 1) = fra_tbs(i)
Next ReDim Preserve fra_tbs(UBound(fra_tbs) - 1)
delete_frame = True
End Function'新建 textbox 的函数
Private Function create_tbx(ByVal tbx_name As String, _
Optional ByVal width As Long = 5500, _
Optional ByVal height As Long = 300, _
Optional ByVal left As Long = 300, _
Optional ByVal top As Long = 30, _
Optional container As Object = Nothing) As TextBox
Dim tbx_new As TextBox
Set tbx_new = Nothing
If (Not (container Is Nothing)) Then
Set tbx_new = Controls.Add("VB.TextBox", tbx_name, container)
Else
Set tbx_new = Controls.Add("VB.TextBox", tbx_name)
End If
With tbx_new
.width = width
.height = height
.left = left
.top = top
.Visible = True
End With
Set create_tbx = tbx_new
End Function'删除 textbox 的函数
Private Function delete_tbx(ByVal fra_index As Long, ByVal tbx_index As Long) As Boolean
If (fra_index > UBound(fra_tbs)) Then
delete_tbx = False
Exit Function
End If
If (tbx_index > UBound(fra_tbs(fra_index).tbs)) Then
delete_tbx = False
Exit Function
End If ' 可以考虑用 CopyMemory API 优化
Dim i As Long
For i = (tbx_index + 1) To UBound(fra_tbs(fra_index).tbs)
fra_tbs(fra_index).tbs(i - 1) = fra_tbs(fra_index).tbs(i)
Next ReDim Preserve fra_tbs(fra_index).tbs(UBound(fra_tbs(fra_index).tbs) - 1) Controls.Remove (fra_tbs(fra_index).tbs(tbx_index).Name)
delete_tbx = True
End Function
谢谢你的热心,我想知道这种方法对事件的响应是如何达到的,还好我已经用另一种方法调试好了,不过用的是是每一次都遍历窗体的方法,感觉很费事。现在对动态控件的响应是这么做的,Private WithEvents NewFrame As Frame'添加
Private WithEvents NewText As TextBox'新建Frame控件
Public Property Set AddFrame(ByVal fData As Frame)
Set NewFrame = fData
End Property
Public Property Get AddFrame() As Frame
Set AddFrame = NewFrame
End PropertyPrivate Sub NewFrame_Click()’响应建立的frame的事件,比如新建、删除frame及新建删除textbox,你给出的方法好像不能像控件数组一样响应事件(还是我基础太差了),晕啊
MsgBox NewFrame.Name
End Sub'可惜WithEvents不能定义数组,正在想办法
dim F() as class1'定义frame数组
dim T() as class1’定义textbox数组,问题出在这里,T()只能获取所有frame数组中的控件,不能分开,只能每次使用时判断
我可能没理解,不过我觉得你一开始说的从数据库读数据,然后分散到各个Frame及各个Frame中的TextBox里面,这个应该是后台自动完成的吧?需要响应什么事件呢?可能我真的没理解你的需求呢,能说明的话,说说看看呢?
程序使用了WithEvents,没找到替代的方法,现在使用遍历窗体控件的方式做出来了,感觉整合到整个程序里会拖长运行时间,老是感觉笨笨的,呵呵