【问题标题】:Using VB on excel, sum of column is only one cell在excel上使用VB,列的总和只有一个单元格
【发布时间】:2014-09-13 00:46:06
【问题描述】:
    Dim lastrow As Integer
    Dim lastcol As Integer, thiscol As Integer

    xlWorkbook = xlApp.Workbooks.Open(Filename:="C:\Users\d3p823\Desktop\test data.xlsx") 'opens workbook'
    xlWsheet2 = xlWorkbook.Sheets("Sheet4") 'set active sheet'
    xlApp.Visible = True

    With xlWsheet2
        lastrow = xlWsheet2.Cells(xlWsheet2.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
        lastcol = xlWsheet2.Cells(1, xlWsheet2.Columns.Count).End(Excel.XlDirection.xlToLeft).Column
        For thiscol = 2 To lastcol
            xlWsheet2.Cells(lastrow + 1, thiscol).Select()
            xlApp.ActiveCell.Value = xlApp.WorksheetFunction.Sum(xlWsheet2.Cells(2, xlApp.ActiveCell.Column), xlApp.ActiveCell)
        Next
    End With

好的,所以我在电子表格中有一个矩形数据块,其中第 1 行和第 1 列作为标签(文本和数字),以及来自单元格 (2,2) 的数据。数据文件的行数和列数是可变的,但所有数据都是连续的:没有空单元格。 @Clif 和我想出了上面的代码来查找最后一行和最后一列数据,然后在每列下方的第一个空单元格中总结每一列。

谢天谢地,我不再遇到错误了,但是添加到第一个空行的总和并不是整个列的总和,只是第一个单元格的总和。这让我认为 FOR-NEXT 循环在第一次迭代之后没有进展,但我不明白为什么会发生这种情况。

【问题讨论】:

  • 您将两个单独的单元格传递给您的Sum,而不是一个范围。其他几点:您创建一个 With 块然后不要使用它,使用 Select/ActiveCell 既没有必要也不可取
  • @chrisneilsen,我尝试在没有SelectActiveCell 的情况下运行代码,只使用Cells(lastrow + 1, thiscol).Value = WorksheetFunction.Sum(Range(Cells(1, ActiveCell.Column), ActiveCell)),但它不起作用。你能告诉我我做错了什么吗?
  • @Clif 为演示添加了答案

标签: vb.net excel sum


【解决方案1】:
  • 通过将变量声明为整数,可以将它们限制为 32,768。因此,如果您对低于该级别的行求和,您的宏将失败。

  • 由于您指出您的数据区域是连续的、矩形的,并且从 A1 开始,您可以只使用 CurrentRegion 来获取对您的数据区域的范围引用。

  • 出于速度目的,这样的操作在 vba 数组中执行时会比在工作表上执行得更快。

  • 一些有限的测试表明循环到 ADD 比使用 SUM 工作表函数执行得更快(数量级),至少在有限的数据集上是这样。是否会 你的真实数据是否如此,只能通过测试来解决。

  • 我建议如下(您需要添加代码以打开工作簿,并更改代码设置相应的工作表)

-

Option Explicit
Sub AddColumns()
    Dim WS As Worksheet
    Dim RNG As Range
    Dim V As Variant
    Dim I As Long, J As Long
    Dim dTemp As Double

Set WS = Worksheets("sheet1")

'with offset, we will skip the labels row, and leave
'  one blank at the end for the total
Set RNG = Cells(1, 1).CurrentRegion.Offset(rowoffset:=1)
V = RNG

For I = 2 To UBound(V, 2) 'The "2" to skip the first column
    dTemp = 0
    For J = 1 To UBound(V, 1) - 1
        dTemp = dTemp + V(J, I)
    Next J
    V(UBound(V), I) = dTemp
Next I

RNG = V

End Sub

【讨论】:

    【解决方案2】:

    您的代码中有几个问题:

    • 您将两个单独的单元格传递给 Sum,而不是 Range。
    • 你创建了一个 With 块然后不要使用它,
    • 使用 Select/ActiveCell 既没必要也不可取
    • 使用Integer 而不是long

    With xlWsheet2
        lastrow = .Cells(.Rows.Count, 1).End(Excel.XlDirection.xlUp).Row
        lastcol = .Cells(1, .Columns.Count).End(Excel.XlDirection.xlToLeft).Column
        For thiscol = 2 To lastcol
            .Cells(lastrow + 1, thiscol).Value = _
              xlApp.Sum(.Range(.Cells(2, thiscol), .Cells(lastrow, thiscol)))
        Next
    End With
    

    【讨论】:

    • 谢谢!这很好用。我一直在与“.Cells”语法作斗争。 VS Express 只是没有给我足够的提示。我还陷入了为未定义的变量生成属性/方法存根的问题,我最终解决了这个问题。我的代码中总是有一个 WITH 块,在这里,但有一次,我尝试专门定义所有内容以查看会产生什么效果(并且一旦不起作用就忘记清理)。对于“A1”Excel 参考样式有很多帮助;对于“.cell”语法而言,这并不多。
    • 我确信只是我对代码应该如何工作的了解不够,尤其是With,但是当我运行它时,它停在第二行,lastrow =... ,带有“需要运行时错误'424'对象”。我还注意到,当我调试时,本地窗口显示xlSheet1xlApp 作为变量,输入Variant。我使用的是 Excel 2010,我的数据位于第一个选项卡上,所以我将 xlWsheet2 更改为 xlWsheet1,如果这有影响的话。
    • @Clif 不太适合劫持别人的 Q,但请注意,这是标记为 vb.net,而不是 vba。如果这是在vba 中完成的,一些细节会有所不同,但总体流程是相同的。听起来您需要将 Option Explicit 添加到您的模块中以强制声明 all 您的变量!
    • @chrisneilsen,我很抱歉。
    【解决方案3】:

    您需要第二个 For 循环才能从第 2 行转到 lastrow

    或者将Next 语句之前的语句替换为此

    ActiveCell.FormulaR1C1 = "=SUM(R[" & -lastrow + 1 & "]C:R[-1]C)"

    这使用了SUM 函数并消除了对第二个 For 循环的需要。

    【讨论】:

      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多