【问题标题】:Using a counter in a loop within a loop = problems in excel vba在循环中的循环中使用计数器 = excel vba 中的问题
【发布时间】:2017-06-16 00:17:56
【问题描述】:

您好,感谢您的帮助。

我在 excel 方面完全是个菜鸟,但由于我的研究需要,我一直在自学
我通过从 youtube 频道 ExcelVbaIsFun 改编它创建了这个基本代码

Sub ZipCodeSum2()

Dim dbsheet As Worksheet
Set dbsheet = ThisWorkbook.Sheets("Sheet1")
lr = dbsheet.Cells(Rows.Count, 1).End(xlUp).Row
SelRow = Selection.Row
'zip code
zip = dbsheet.Cells(SelRow, 2)

For i = 2 To lr 'change lr to 3 for testing purposes
Cells(i, 3).Select

 For x = 2 To lr 'change lr to 10 for testing purposes
    If dbsheet.Cells(x, 2) = zip Then
        counter = counter + dbsheet.Cells(x, 1)
    ActiveCell = counter
    End If

 Next x

Next i

End Sub

问题在于,对于第一个“i”,“外循环”运行良好,并且 sum 函数运行良好。但是,在下一个“i”中,它会添加第一个“i”和的结果,然后也将第二个“i”和添加到其中。因此,如果邮政编码相同,则基本上会导致第二个“i”是我想要的结果的两倍。

任何帮助将不胜感激!谢谢!

sample of my worksheet

【问题讨论】:

  • 听起来您需要在找到匹配项后包含Exit For 或切换到application.match 才能仅获得第一个匹配项。
  • SUMIF 或 SUMIFS 不是更好的解决方案是否有原因?
  • @YowE3K - 你了解我...一直在寻找简单的出路。
  • 要回答您的具体问题,请在 For x = 2 To lr 之前添加 counter = 0,但这不会使您的代码正常工作 - 您将向 C 列中的每个单元格写入相同的值时刻,因为您在For i 循环之外设置了zip。 (但有可能它会完全写入另一张工作表,因为您不限定 Cells(i, 3) 指的是哪个工作表。)
  • @Jeeped 感谢您的建议!我将如何将其添加到代码中?同样对于 SUM 函数,我进行了调查,但找不到一个好的骨架来使用“计数器”来做我能做的事情。

标签: excel vba loops counter


【解决方案1】:

如果您希望在执行内部循环之前重置counter,请在进入该循环之前对其进行初始化:

Sub ZipCodeSum2()
    Dim dbsheet As Worksheet
    Dim lr As Long
    Dim SelRow As Long
    Dim zip As String
    Dim i As Long
    Dim counter As Currency
    Dim x As Long

    Set dbsheet = ThisWorkbook.Sheets("Sheet1")
    lr = dbsheet.Cells(dbsheet.Rows.Count, 1).End(xlUp).Row

    For i = 2 To lr 'change lr to 3 for testing purposes
        'zip should be set inside the "For i" loop
        zip = dbsheet.Cells(i, "B").Value
        counter = 0
        For x = 2 To lr 'change lr to 10 for testing purposes
            If dbsheet.Cells(x, "B").Value = zip Then
                counter = counter + dbsheet.Cells(x, "A").Value
            End If
        Next 
        dbsheet.Cells(i, "C").Value = counter
    Next i
End Sub

但这可以简化为:

Sub ZipCodeSum2()
    With ThisWorkbook.Sheets("Sheet1")
        With .Range("C2:C" & .Cells(.Rows.Count, "A").End(xlUp).Row)
            .Formula = "=SUMIF(B:B,B2,A:A)"
            .Value = .Value
        End With
    End With
End Sub

或者你可以只放置公式

=SUMIF(B:B,B2,A:A)

到 Excel 中的单元格 C2 并复制下来。

【讨论】:

  • 太棒了!这段代码运行良好!我使用了您的第一个建议,因为我对您的第二个建议一无所知。我不能使用的最后一个求和公式,因为我的数据库有超过 300,000 个条目,这将花费我很长时间。谢谢!
  • 现在我要研究这段代码,直到我意识到你做了什么:)
【解决方案2】:

在 C2 中尝试,

=sumifs(a$2:a2, b$2:b2, b2)

根据需要填写。

如果您只希望某个值的最后一个实例显示总和,那么,

=IF(COUNTIF(A$2:A2, A2)=COUNTIF(A:A, A2), SUMIFS(A$2:A2, B$2:B2, B2), TEXT(,))

【讨论】:

  • 哈哈,我的数据库有时有 300,000 或更多,但谢谢!
  • 如果您认为使用工作表单元格引用的嵌套循环会比 SUMIFS 更快,那么您就错了。即使是变体内存阵列也很难击败它。但是,仅仅因为您认为 300K 行是很多数据,我会投赞成票。
  • 对不起,如果我听起来居高临下,我只是从来没有处理过这么多的数据。我也遇到了计算速度的问题,它崩溃了很多。接下来我将尝试 SUMIF,看看是否能解决问题。
  • 顺便说一句,超过 50K 行的任何内容,您都应该保存为 .XLSB(Excel 二进制)工作簿。顺便说一句,这是我的默认另存为模式。
  • 谢谢!我刚刚尝试了 SUMIF 函数,但它对我来说违反直觉,因为它给了我很多介于两者之间的值,而我宁愿只使用重复值并使用另一个宏来删除重复,使其符合邮政编码和货币数据。
猜你喜欢
  • 1970-01-01
  • 2011-09-21
  • 2023-01-12
  • 2011-10-29
  • 2012-05-30
  • 2020-06-25
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
相关资源
最近更新 更多