【问题标题】:Loop Help and Goto循环帮助和转到
【发布时间】:2018-02-18 21:22:43
【问题描述】:

我有 3 个工作表。前两个让我转换成两个数组(array1array2),然后在它们之间进行计算以创建第三个。

我创建的宏利用了这段代码---

Z = 1

For x = 1 To UBound(array1, 1)
    For y = 1 To UBound(array2, 1)
        If array1(x, 4) = 0 Then
            GoTo Line1
        End If
        If array1(x, 1) = array2(y, 1) And array1(x, 2) = array2(y, 3)Then
            If array1(x, 4) > array2(y, 5) Then
                array3(z, 1) = array1(x, 3)
            ElseIf array1(x, 4) = array2(y, 5) Or array1(x, 4) < array2(y, 5) Then
                array3(z, 1) = array1(x, 3)
            End If
            z = z + 1
        End If
    Next y
Line1:
Next x

它需要一段array1 并通过array2 循环它并在array3 中创建一个结果

基本上当array1(x, 4) = 0 时,我需要它转到下一个X。如果没有GoTo Line1,我无法弄清楚如何循环这个。

如果我将它向下移动,那么它将继续循环通过array2(y),而不是移动到下一个X。如果我将它移到上面,那么 y 会重置并再次运行 For y 循环

还在使用GoTo Line X,这是 VBA 中的不良做法。我是否应该总是尽量避免使用它。我对它还很陌生。

【问题讨论】:

  • goto 可能很有用,但它也非常强大,所以最好先确保您理解所有内容,然后再将其粘贴到代码中。但在您的情况下,您可能需要使用它
  • 请正确缩进您的代码并删除空行。 Goto 通常不需要(On Error Goto ... 语句除外)。在常规代码中避免它。
  • @Tomalak 这个代码有必要吗?我不确定另一种格式化方式
  • 测试相反的情况并删除 go-to 并将代码放在 if 中。
  • @UserX 正如我所说,GoTo 从来都不是必需的。使用它会增加代码中出现错误的可能性,并增加头痛的可能性。

标签: vba loops goto


【解决方案1】:

编写依赖于GoTo 的代码被广泛认为是不好的风格。

VB(A) 有一些内置结构,用于其需要GoTo 的错误处理方式。这些是不可避免的。应该避免所有其他的。

在这种情况下,这相当容易,您可以用Exit For 打破For 循环:

Z = 1

For x = 1 To UBound(array1, 1)
    For y = 1 To UBound(array2, 1)
        If array1(x, 4) = 0 Then Exit For
        If And array1(x, 1) = array2(y, 1) And array1(x, 2) = array2(y, 3) Then
            If array1(x, 4) > array2(y, 5) Then
                array3(z, 1) = array1(x, 3)
            ElseIf array1(x, 4) = array2(y, 5) Or array1(x, 4) < array2(y, 5) Then
                array3(z, 1) = array1(x, 3)
            End If
            z = z + 1            
        End If
    Next y
Next x

替代(多一层嵌套):

For x = 1 To UBound(array1, 1)
    If array1(x, 4) <> 0 Then
        For y = 1 To UBound(array2, 1)
            If And array1(x, 1) = array2(y, 1) And array1(x, 2) = array2(y, 3) Then
                If array1(x, 4) > array2(y, 5) Then
                    array3(z, 1) = array1(x, 3)
                ElseIf array1(x, 4) = array2(y, 5) Or array1(x, 4) < array2(y, 5) Then
                    array3(z, 1) = array1(x, 3)
                End If
                z = z + 1            
            End If
        End If
    Next y
Next x

【讨论】:

  • 感谢@tomalak。我不知道命令的出口。那会直接在下一个 Y 之后将其带到行中吗?
  • @UserX,是的。请注意Exit For 只存在一层For 循环。
  • @tomalak,值得一提的是GoTo 并不总是很糟糕。是的,它可能对 99% 的情况都不好,但有时 如果 用于向前跳转 时它会很有用。 breaking nested loops 就是一个例子。是的,另一种方法是使用单独的函数,但使用多个局部变量,最终会得到更复杂的代码,而在这种情况下使用 GoTo 不会造成任何伤害。
  • 当您足够好地识别出 1% 的用例(实际上可能比这还少)时,GoTo 可能有理由使用,那么您就不需要询问它。只要你要问,你不够好,千万不要用,很简单。就我个人而言,我还没有找到一个有效的用例,通过重构没有更好的替代方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多