Ms Access - VBA - 以编程方式创建带有大小的标签
Ms Access - VBA - Create Labels Programatically with Size
我正在尝试创建 Labels & Textboxes
并根据变量计数动态地为其分配一些值 NoOfRecords
(问题是我事先不知道我有多少控件'将需要。数量将由特定 table 中有多少记录驱动。
我的表单名称是 frmDashboard
我试过的是
Set cNN = Nothing
Set rsfnum = Nothing
Dim strconnfnum As String
Set cNN = CurrentProject.Connection
Set rsfnum = New ADODB.Recordset
strconnfnum = "SELECT nz(employeename,'') as employeename from employees"
rsfnum.Open strconnfnum, cNN, adOpenKeyset, adLockOptimistic
'Number of Records in Employees tables
NoOfRecords = rsfnum.RecordCount
For x = 1 To NoOfRecords
Set ctrl = CreateControl("frmDashboard", acLabel, acDetail, , "", 0 + (x * 300), 0, 300, 240)
ctrl.ControlName = "lblDynamic_control_" & x
Controls("lblDynamic_control_" & x).Caption = x
Set ctrl1 = CreateControl("frmDashboard", acTextBox, acDetail, , "", 0 + (x * 300), 0, 300, 240)
ctrl1.ControlName = "txtDynamic_control_" & x
Controls("txtDynamic_control_" & x).Value= x
Next x
我在这里面临 2 个问题
1) 如何像下面这样依次显示标签和文本框
(下一个标签和文本框应该正好在顶部下方。)
2)以上代码抛出如下错误
好的 - 免责声明我在这里完全是新手 - 但我调查了这个并且显然 VBA 不会让你创建控件(即 'set ctrl' 或 'set ctrl1' 命令) 在运行时。这些必须在设计时创建,并根据运行时的动态输入使其可见。
如果 NoOfRecords 有最大值,我可能建议在设计时对所有可能的 ctrls 进行预编码(使用循环),并根据运行时的动态输入使数字变为 visible/active .
至于组织标签和文本框的布局,这也将作为设计循环的一部分完成。如下面的文档所述,每个 ctrl 的左上角的位置可以在 'left' 和 'top' 命令的 CreateControl 方法中指定(您当前将其设置为 left = 0+( x*300), 顶部 = 0 ).只需在通过 ctrl 创建进行迭代时对 x 和 y 坐标添加必要的调整。
CreateControl 方法文档:https://msdn.microsoft.com/en-us/library/office/aa221167%28v=office.11%29.aspx
希望对您有所帮助!
您看到的错误是正确的,当您最终将数据库作为编译的拆分数据库分发时无法克服。
这里的技巧是提前创建您可能需要的所有控件。然后你需要贴上标签,让它们在表格上按顺序排列。所以像 Text1
、Text2
、Label
、Label2
。这样你就可以通过它们的索引(这将是你的字段在你的记录集中的索引)遍历每个 textbox/label 组合。
Private Function ReBindControls()
Dim rs As DAO.Recordset 'if you are using ADO then replace this with ADODB.Recordset
If IsNull(Combo99) Then
Exit Function
End If
Set rs = CurrentDb.OpenRecordset(Combo99) ' If you are using ADO use the appropriate ADO method to open the recordset
Dim fs As DAO.Fields 'if you are using ADO then replace this with ADODB.Fields
Set fs = rs.Fields
Dim f As Integer
Dim aLabel As Label, aTextBox As TextBox
Set Me.Recordset = rs
For f = 0 To fs.Count - 1
Set aLabel = Controls("Label" & f)
aLabel.Caption = fs(f).Name
aLabel.Visible = True
Set aTextBox = Controls("text" & f)
aTextBox.ControlSource = fs(f).Name
aTextBox.Visible = True
aLabel.Move 1 * 1440, f * 1440 / 2
aTextBox.Move 2.5 * 1440, f * 1440 / 2
Next f
End Function
Function clearBindings()
Dim c As Integer
Dim aLabel As Label, aTextBox As TextBox
For c = 0 To maxIndexOfControls
Set aTextBox = Controls("text" & c)
aTextBox.ControlSource = ""
Set aLabel = Controls("Label" & c)
aLabel.Visible = False
aTextBox.Visible = False
aLabel.Move 0, 0
aTextBox.Move 0, 0
Next c
End Function
如果你同时调用这两个
Private Sub Combo99_Change()
clearBindings
ReBindControls
End Sub
你可以得到这些结果
我正在尝试创建 Labels & Textboxes
并根据变量计数动态地为其分配一些值 NoOfRecords
(问题是我事先不知道我有多少控件'将需要。数量将由特定 table 中有多少记录驱动。
我的表单名称是 frmDashboard
我试过的是
Set cNN = Nothing
Set rsfnum = Nothing
Dim strconnfnum As String
Set cNN = CurrentProject.Connection
Set rsfnum = New ADODB.Recordset
strconnfnum = "SELECT nz(employeename,'') as employeename from employees"
rsfnum.Open strconnfnum, cNN, adOpenKeyset, adLockOptimistic
'Number of Records in Employees tables
NoOfRecords = rsfnum.RecordCount
For x = 1 To NoOfRecords
Set ctrl = CreateControl("frmDashboard", acLabel, acDetail, , "", 0 + (x * 300), 0, 300, 240)
ctrl.ControlName = "lblDynamic_control_" & x
Controls("lblDynamic_control_" & x).Caption = x
Set ctrl1 = CreateControl("frmDashboard", acTextBox, acDetail, , "", 0 + (x * 300), 0, 300, 240)
ctrl1.ControlName = "txtDynamic_control_" & x
Controls("txtDynamic_control_" & x).Value= x
Next x
我在这里面临 2 个问题
1) 如何像下面这样依次显示标签和文本框
(下一个标签和文本框应该正好在顶部下方。)
2)以上代码抛出如下错误
好的 - 免责声明我在这里完全是新手 - 但我调查了这个并且显然 VBA 不会让你创建控件(即 'set ctrl' 或 'set ctrl1' 命令) 在运行时。这些必须在设计时创建,并根据运行时的动态输入使其可见。
如果 NoOfRecords 有最大值,我可能建议在设计时对所有可能的 ctrls 进行预编码(使用循环),并根据运行时的动态输入使数字变为 visible/active .
至于组织标签和文本框的布局,这也将作为设计循环的一部分完成。如下面的文档所述,每个 ctrl 的左上角的位置可以在 'left' 和 'top' 命令的 CreateControl 方法中指定(您当前将其设置为 left = 0+( x*300), 顶部 = 0 ).只需在通过 ctrl 创建进行迭代时对 x 和 y 坐标添加必要的调整。
CreateControl 方法文档:https://msdn.microsoft.com/en-us/library/office/aa221167%28v=office.11%29.aspx
希望对您有所帮助!
您看到的错误是正确的,当您最终将数据库作为编译的拆分数据库分发时无法克服。
这里的技巧是提前创建您可能需要的所有控件。然后你需要贴上标签,让它们在表格上按顺序排列。所以像 Text1
、Text2
、Label
、Label2
。这样你就可以通过它们的索引(这将是你的字段在你的记录集中的索引)遍历每个 textbox/label 组合。
Private Function ReBindControls()
Dim rs As DAO.Recordset 'if you are using ADO then replace this with ADODB.Recordset
If IsNull(Combo99) Then
Exit Function
End If
Set rs = CurrentDb.OpenRecordset(Combo99) ' If you are using ADO use the appropriate ADO method to open the recordset
Dim fs As DAO.Fields 'if you are using ADO then replace this with ADODB.Fields
Set fs = rs.Fields
Dim f As Integer
Dim aLabel As Label, aTextBox As TextBox
Set Me.Recordset = rs
For f = 0 To fs.Count - 1
Set aLabel = Controls("Label" & f)
aLabel.Caption = fs(f).Name
aLabel.Visible = True
Set aTextBox = Controls("text" & f)
aTextBox.ControlSource = fs(f).Name
aTextBox.Visible = True
aLabel.Move 1 * 1440, f * 1440 / 2
aTextBox.Move 2.5 * 1440, f * 1440 / 2
Next f
End Function
Function clearBindings()
Dim c As Integer
Dim aLabel As Label, aTextBox As TextBox
For c = 0 To maxIndexOfControls
Set aTextBox = Controls("text" & c)
aTextBox.ControlSource = ""
Set aLabel = Controls("Label" & c)
aLabel.Visible = False
aTextBox.Visible = False
aLabel.Move 0, 0
aTextBox.Move 0, 0
Next c
End Function
如果你同时调用这两个
Private Sub Combo99_Change()
clearBindings
ReBindControls
End Sub
你可以得到这些结果