英文:
VBA code to find last rows and calculate multiple subtotals in the same column
问题
我正在尝试编写VBA代码来自动化一个月度报告。以下问题是报告中许多流程自动化的一个小部分。我需要找到每个子程序(在B列中的SUB_PGM)的小计。需要求和的值位于H列中。需要注意的是,程序或交易在子程序中的数量不会始终一致,因此求和范围永远不会一致。我的当前VBA代码通过引用包含程序的小计值的查找表来解决此问题,而不是尝试对所需数据集中的行进行求和。供参考,“Do Until ActiveCell = ''”是因为在最后一行数据下面有一个'。这是由于一些其他格式原因造成的,但我将其用作循环中的停止点。
虽然我的当前宏成功运行并创建了这些小计,但在运行后出现以下错误:“运行时错误 '1004':应用程序定义或对象定义的错误。调试器突出显示了“If IsEmpty(ActiveCell.Offset(1)) Then”。然后,这个错误会阻止下一个宏运行,运行后的活动单元格变为Excel文件中最后可能的行(1048576)。
以下是我的当前代码以及所需结果的屏幕截图。感谢您的帮助!
英文:
I am trying to write VBA code to automate a monthly report. The below problem is one small part in a much larger macro automating many processes in the report. I need to find the subtotal for every sub program (SUB_PGM in column B). The values that need to be summed are in column H. It is important to note that there will not always be a consistent number of programs or transactions within the programs so sum ranges will never be consistent. My current VBA code works around this issue by referencing a lookup table containing the subtotaled values for the programs instead of trying to sum the rows in the desired set of data. For reference, the "Do Until ActiveCell = "'" " is because there is a ' underneath the last row with data in it. This is due to some other formatting reasons but I was using it as a stopping point in the loop.
While my current macro does successfully run and create these subtotals, it comes with the following error after running "Run-time error '1004': Application-defined or object-defined error. The debugger highlights the "If IsEmpty(ActiveCell.Offset(1)) Then". This error then prevents the next macro from running and the active cell after running becomes the last possible row in an excel file (1048576).
Below you will find my current code as well as a screenshot of the desired outcome. Thank you for your help!
Range("H4").Select
Selection.End(xlDown).Offset(1).Select
ActiveCell.FormulaR1C1 = _
"=IFERROR(VLOOKUP('Current Subpgm'!R[-1]C[-6],Table3,2,FALSE), "" "")"
Do Until ActiveCell = "'"
Selection.End(xlDown).Select
If IsEmpty(ActiveCell.Offset(1)) Then
ActiveCell.Offset(1).Select
ActiveCell.FormulaR1C1 = _
"=IFERROR(VLOOKUP('Current Subpgm'!R[-1]C[-6],Table3,2,FALSE), "" "")"
Else
Selection.End(xlDown).Offset(1).Select
ActiveCell.FormulaR1C1 = _
"=IFERROR(VLOOKUP('Current Subpgm'!R[-1]C[-6],Table3,2,FALSE), "" "")"
End If
Loop
答案1
得分: 0
你可以使用代码来实现这一点,但你是否知道你可以轻松地在不使用代码的情况下通过插入数据透视表来完成?而且数据透视表还提供了其他几个好处...
英文:
While you can do this using code, are you aware that you can easily do this without code by simply inserting a Pivot Table? And a Pivot Table provides several other benefits...
答案2
得分: 0
来自cybernetic.nomad的建议是100%正确的,然而,没有看到您的源数据,无法帮助重新编写代码以避免使用select/active。
从您描述的错误来看,问题似乎是ActiveCell已经到达工作表的最后一行,然后执行.Offset(1)
意味着代码尝试访问超出那一行的行。
在不尝试修复任何潜在问题(比如代码为什么找不到带有撇号的单元格)的情况下,明显的“修复”是在If IsEmpty(ActiveCell.Offset(1)) Then
行之前立即添加以下内容:
如果 ActiveCell.Row = ActiveCell.Parent.Rows.Count Then
退出 Do
结束 If
这只是在ActiveCell到达工作表的最后一行时退出循环...根据您的数据,这可能会解决您的问题...或者可能不会?
英文:
The advice from cybernetic.nomad is 100% correct, however, without seeing your source data it isn't possible to help re-write your code to avoid using select/active.
From the error you describe, the problem sounds like the ActiveCell has reached the last row of the Worksheet, then doing .Offset(1)
means the code tries to access a row beyond that.
Without trying to fix any underlying issue (like why didn't the code find the cell with an apostrophe), the obvious 'fix' would be to add this immediately before the If IsEmpty(ActiveCell.Offset(1)) Then
line:
If ActiveCell.Row = ActiveCell.Parent.Rows.Count Then
Exit Do
End If
... this just causes the loop to be exited if the ActiveCell has reached the last row of the Worksheet ... depending on your data, this may fix your problem ... or may not?!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论