【问题标题】:Why is the For loop replicating the procedure?为什么 For 循环会复制该过程?
【发布时间】:2017-02-22 17:32:38
【问题描述】:

我有一个用户窗体,其中包含 20 个组合框,然后每个组合框旁边分别有 3 个文本框(总共 60 个文本框)。每个组合框都显示相同的两个选项(选项 1 和选项 2)。与组合框相邻的 3 个文本框分别用于描述、项目数量和每件价格。

我使用了一个 For 循环来循环 20 个 Combobox。循环中的代码将文本框中的输入以表格格式写入 Excel 工作表。组合框的目的是将文本框中的输入分成 Excel 工作表上的表格中的两个选项(选择 1 和 2)。

代码似乎适用于第一个组合框,但是当我为第二个组合框及其各自的文本框输入数据时,Excel 工作表上的数据被复制了几次,我不知道为什么。

这是代码:

Dim i as Integer 'row counter
Dim j As Integer
Dim h As Integer
Dim ctrl As Control
Dim num As Integer
Dim txt As Control


For Each ctrl In Me.custom_prices.Controls
    If TypeName(ctrl) = "ComboBox" Then
            If ctrl = "Choice 1" Then
                j = i
                For Each txt In Me.custom_prices.Controls
                If TypeName(txt) = "TextBox" And txt.Tag = "DESCRIPTION" Then
                For num = 1 To 20
                    If txt.Value = "" Then Exit For
                    If Controls("textbox" & num).Value = "" Then Exit For
                    If Controls("textboxprice" & num).Value = "" Then Exit For
                    If Controls("textboxno" & num).Value = "" Then Exit For
                    ActiveCell.Offset(rowOffset:=j, columnOffset:=0).Value = Controls("textbox" & num).Value
                    ActiveCell.Offset(rowOffset:=j, columnOffset:=1).Value = Controls("textboxprice" & num).Value
                    ActiveCell.Offset(rowOffset:=j, columnOffset:=2).Value = Controls("textboxno" & num).Value
                    ActiveCell.Offset(rowOffset:=j, columnOffset:=3).Value = Controls("textboxno" & num).Value * Controls("textboxprice" & num).Value
                    j = j + 1
                    sub_total = sub_total + (Controls("textboxno" & num).Value * Controls("textboxprice" & num).Value)
                Next num
                End If
                Next txt
                i = j
                sub_total_3 = sub_total
                sub_total = 0


            ElseIf ctrl = "Choice 2" Then
                h = i
                For Each txt In Me.custom_prices.Controls
                If TypeName(txt) = "TextBox" And txt.Tag = "DESCRIPTION" Then
                For num = 1 To 20
                    If txt.Value = "" Then Exit For
                    If Controls("textbox" & num).Value = "" Then Exit For
                    If Controls("textboxprice" & num).Value = "" Then Exit For
                    If Controls("textboxno" & num).Value = "" Then Exit For
                    ActiveCell.Offset(rowOffset:=h, columnOffset:=0).Value = Controls("textbox" & num).Value
                    ActiveCell.Offset(rowOffset:=h, columnOffset:=1).Value = Controls("textboxprice" & num).Value
                    ActiveCell.Offset(rowOffset:=h, columnOffset:=2).Value = Controls("textboxno" & num).Value
                    ActiveCell.Offset(rowOffset:=h, columnOffset:=3).Value = Controls("textboxno" & num).Value * Controls("textboxprice" & num).Value
                h = h + 1
                sub_total = sub_total + (Controls("textboxno" & num).Value * Controls("textboxprice" & num).Value)
                Next num
                End If
                Next txt
                i = h
                sub_total_4 = sub_total
                sub_total = 0

            Else: ctrl = ""

                sub_total = sub_total

         End If
    End If
Next ctrl

提前致谢。

【问题讨论】:

  • 猜测这是因为每次您循环访问ComboBoxes 时,您都会循环访问每个TextBox。您需要考虑以某种方式将两者联系在一起。
  • 没错,我也这么认为。我只是不知道该怎么做
  • 我提供了一些示例代码,可以帮助您对控件进行分组。我没有深入研究代码,但它可能会给你一个开始。如果有机会,请告诉我您的想法。

标签: excel vba combobox


【解决方案1】:

("textbox" & num) 类型的术语可能存在问题。文本框是一个字符串,您正试图将它连接到一个整数。 尝试将 num 转换为这样的字符串 ->

("文本框" & CStr(num))

使用 Msgbox 测试 ("Textbox" & CStr(num)) 和 ("textbox" & num) 以查看这样的两个结果 ->

Msgbox "with CStr = " & ("textbox" & CStr(num))

Msgbox "no CStr = " & ("textbox" & num)

如果在将 num 转换为字符串时结果中有不需要的空格,试试这个 ->

("文本框" & Trim(CStr(num)))

【讨论】:

  • 我都试过了,它们都可以工作。我删除了循环文本框,现在该过程重复了两次而不是四次。
【解决方案2】:

您可以使用GroupBox 对控件进行分组

然后我会遍历每个GroupBox,然后遍历每个ComboBoxTextBox

For Each grpb As GroupBox In Me.Controls().OfType(Of GroupBox)()

    For Each cmb As ComboBox In grpb.Controls().OfType(Of ComboBox)()

    Next

    For Each txtb As TextBox In grpb.Controls().OfType(Of TextBox)()

    Next

Next

注意OfType 的使用。当您知道要关注哪些控件时,这会派上用场。现在你不需要像If TypeName(ctrl) = "ComboBox" 这样的代码了。

您现在拥有更多控制权。通过循环访问GroupBox 上的控件,您现在知道哪个TextBox 与哪个ComboBox 相关联,并且您不会一次又一次地迭代相同的TextBox

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2016-12-26
    • 2019-01-09
    • 2011-04-21
    相关资源
    最近更新 更多