For循环在第一次迭代后终止-Excel VBA

时间:2013-02-18 04:27:29

标签: excel vba excel-vba

我正在尝试做一个简单的循环,我将一些变量声明为数组条目。我最初使用它们作为要覆盖的变量,但是当我读到这些变量不会在循环中每次都自动覆盖时更改它。

我的问题是这个循环在第一次迭代后终止(没有错误)。我似乎无法弄明白为什么......

代码主要是为每个cons_sum(i,2)i表格中的行找到Pre-Summary,并将另一个表格BOPE中的一些数据相加,然后将该总和插入Pre-Summary

这是我的第一篇文章,我正在教自己vba所以请原谅任何代码失败。

这是我的代码:

Option Explicit

Sub Create_GAR080()
    Consmonth = Sheets("GAR080").Range("B2").Value

    Sheets("Pre-Summary").Select

    LastRow_summary = Cells(Rows.Count, "A").End(xlUp).Row
    LastRow = 156
    LastCol = 16

    Dim cons_sum() As Variant
    ReDim cons_sum(LastRow_summary, 4)

    For i = 1 To LastRow_summary Step 1

        cons_sum(i, 1) = Cells(i, 2).Value & "" 'pulls participant
        cons_sum(i, 2) = cons_sum(i, 1) & Cells(i, 1) ' participant and gas gate concatenated

        If cons_sum(i, 1) = "BOPE" Then
             Sheets(cons_sum(i, 1)).Select

             cons_sum(i, 3) = WorksheetFunction.Match(cons_sum(i, 2), Sheets(cons_sum(i, 1)).Range("A:A")) ' find participant gas gate combo

             cons_sum(i, 4) = Application.Sum(Sheets(cons_sum(i, 1)).Range(Cells(cons_sum(i, 3), 5), Cells(cons_sum(i, 3), 16)))

             If cons_sum(i, 4) > 0 Then
                Sheets("Pre-Summary").Cells(i, 4).Value = cons_sum(i, 4)
             End If
        End If
    Next i

    On Error Resume Next
End Sub

2 个答案:

答案 0 :(得分:1)

正如Siddharth指出的那样,更改工作表会导致cons_sum(i, 1) = "BOPE"始终为负数。因此,虽然循环将运行1,848次,但它不会改变任何东西。

此外,还有一些评论:

  • 您正在使用1848x4阵列在每一行中执行多个操作 - 但仅存储每个操作的值,之后不使用该数组。因此,您不需要1848x4,但只需要1x4,因为您可以重用变量
  • 使用说话变量要好得多,而不是使用数组。这将使您的代码更容易理解
  • 您对VBA公式/语句中隐藏的工作簿结构有很多假设,例如:行数,名称“BOPE”等。最好将它们存储在宏的开头的常量中 - 甚至更好地将它们存储在设置表上的某处并用命名范围引用它们
  • 您很可能忘记FALSE(或0)作为匹配函数的第三个参数。因此,如果列未排序,则函数可能返回错误的值
  • 您可以使用Range(Cells(x1,y1),Cells(x2,y2))Range.Resize(及其组合)代替Range.Offset。这使代码更容易阅读!
  • 不要使用On Error Resume Next,除非您确切地知道您很乐意忽略哪些错误!即使您使用它,也可以在允许产生错误的操作之后立即使用另一个On Error语句。

考虑到这一点,我将您的代码重新编写为以下内容:

Sub Create_GAR080_reworked()
    Const cStrTerm As String = "BOPE"

    Dim wsData As Worksheet
    Dim lngRowCount As Long, i As Long
    Dim strParticipantGasID As String
    Dim lngParticipantGasCombo As Long
    Dim dblSum As Double

    Set wsData = Sheets(cStrTerm)

    With Sheets("Pre-Summary")
        lngRowCount = .Cells(Rows.Count, 1).End(xlUp).Row
        For i = 1 To lngRowCount

            If .Cells(i, 2) = cStrTerm Then
                strParticipantGasID = cStrTerm & .Cells(i, 1)   ' participant and gas gate concatenated

                lngParticipantGasCombo = WorksheetFunction.Match( _
                    strParticipantGasID, wsData.Range("A:A"), 0)  ' find participant gas gate combo

                dblSum = Application.Sum( _
                    wsData.Range("E1:P1").Offset(lngParticipantGasCombo - 1))

                If dblSum > 0 Then
                   .Cells(i, 4).Value = dblSum
                End If
            End If
        Next i
    End With
End Sub

由于我没有您的工作表,我无法调试它。另外,不确定我是否选择了正确的名称,因为我不知道每个变量实际上是指什么。但它应该给你一个开始。

答案 1 :(得分:0)

如果第一次出现代码Sheets(cons_sum(i, 1)).Select,则您将永远不会回到预摘要表。

尝试:

Option Explicit

Sub Create_GAR080()
    Consmonth = Sheets("GAR080").Range("B2").Value

    Sheets("Pre-Summary").Select

    LastRow_summary = Cells(Rows.Count, "A").End(xlUp).Row
    LastRow = 156
    LastCol = 16

    Dim cons_sum() As Variant
    ReDim cons_sum(LastRow_summary, 4)

    For i = 1 To LastRow_summary Step 1
        Sheets("Pre-Summary").Select

        cons_sum(i, 1) = Cells(i, 2).Value & "" 'pulls participant
        cons_sum(i, 2) = cons_sum(i, 1) & Cells(i, 1) ' participant and gas gate concatenated

        If cons_sum(i, 1) = "BOPE" Then
             Sheets(cons_sum(i, 1)).Select

             cons_sum(i, 3) = WorksheetFunction.Match(cons_sum(i, 2), Sheets(cons_sum(i, 1)).Range("A:A")) ' find participant gas gate combo

             cons_sum(i, 4) = Application.Sum(Sheets(cons_sum(i, 1)).Range(Cells(cons_sum(i, 3), 5), Cells(cons_sum(i, 3), 16)))

             If cons_sum(i, 4) > 0 Then
                Sheets("Pre-Summary").Cells(i, 4).Value = cons_sum(i, 4)
             End If
        End If
    Next i

    On Error Resume Next
End Sub