【问题标题】:How do I edit my sum formula to select a dynamic range of cells?如何编辑求和公式以选择动态范围的单元格?
【发布时间】:2018-03-06 22:49:33
【问题描述】:

我录制了一个宏,确保选择了使用相对引用,但是在运行宏时,sum 函数总是选择将出现总数的单元格上方的 8 个单元格,即使我使用 Ctrl录制了它>+Shift+向上箭头选择正上方的所有非空白单元格:

ActiveCell.FormulaR1C1 = "=SUM(R[-8]C:R[-1]C)

我查看了与我想要实现的目标相似的以下内容,但我的目标是相反的,并且无法弄清楚如何修改我的代码,它将对向上移动的每个单元格求和,直到它命中一个空白单元格。

目标是能够在工作表中的不同点输入小计,在这些点对不同单元格数量的范围求和。

如果有助于查看上下文,这就是整个宏的样子:

Sub InsertTotal()
'
' InsertTotal Macro
' Insert blank rows, bold line and total amount
'
' Keyboard Shortcut: Ctrl+y
'
    ActiveCell.Rows("1:2").EntireRow.Select
    Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    ActiveCell.Offset(0, 7).Range("A1").Select
    Selection.Font.Bold = True
    ActiveCell.FormulaR1C1 = "=SUM(R[-8]C:R[-1]C)"
    ActiveCell.Offset(-1, -7).Range("A1").Select
    Range(Selection, Selection.End(xlToRight)).Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    Selection.Borders(xlEdgeLeft).LineStyle = xlNone
    Selection.Borders(xlEdgeTop).LineStyle = xlNone
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    Selection.Borders(xlEdgeRight).LineStyle = xlNone
    Selection.Borders(xlInsideVertical).LineStyle = xlNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
    ActiveCell.Select
End Sub

任何 cmets 或建议都会有很大帮助

【问题讨论】:

  • 我感觉部分原因是您使用了.Select。尝试avoid using .Select/.Activate` 看看是否有帮助。
  • 让我直说。这里的问题是:如何制作一个公式,总结上面的所有单元格,在第一个空白单元格处停止。对吗?
  • @BruceWayne 同意,但不要忘记他使用了宏记录器。我认为 Excel 教给人们的坏习惯比其他任何东西都多。老实说,我认为.Select.ActivateActiveWorkbook等存在的唯一原因是让录制宏成为可能。

标签: vba excel excel-formula


【解决方案1】:
Public Function sumAbove(ByVal CellSelected As Range) As Double
    Dim FirstSelected As Range
    Dim TopMostNonBlankCell As Range

    Set FirstSelected = CellSelected.Cells(1) 'if user inputs more than one cell, we use only the first

    If FirstSelected.Offset(-1).Value2 = vbNullString Then 'we check, if the value above FirstSelected is blank
        Set TopMostNonBlankCell = FirstSelected
    Else 'If it is not blank, we use CTRL+SHIFT+UP
        Set TopMostNonBlankCell = FirstSelected.End(xlUp)
    End If
    'Some error handling should be put above, to handle if the sumAbove is used in first row.

    sumAbove = WorksheetFunction.Sum(Range(TopMostNonBlankCell, CellSelected).Value2)
End Function

编辑1

要将其合并到您的代码中,请尝试使用:
ActiveCell.FormulaR1C1 = "=SUM(" & ActiveCell.Offset(-1).Address(ReferenceStyle:=xlR1C1) & ":" & ActiveCell.Offset(-1).End(xlUp).Address(ReferenceStyle:=xlR1C1) & ")"

解释一下:

  • 为避免循环引用,我们需要将活动单元格偏移 -1 行。
  • 您可以简化代码以使用默认的 A1 引用符号,如下所示:ActiveCell.Formula = "=SUM(" & ActiveCell.Offset(-1).Address & ":" & ActiveCell.Offset(-1).End(xlUp).Address & ")"。结果是一样的。
  • 您将需要一些异常处理(参见我上面的函数)。
  • 为了使代码稍微更高效和可读,一些范围变量,如Set ActiveCellMinusRow = ActiveCell.Offset(-1),并在我提议的代码中使用它。

【讨论】:

  • 谢谢布拉尼斯拉夫。是否可以在原始代码行中以某种方式使用 End(xlUp) - FormulaR1C1 = "=SUM(R[-8]C:R[-1]C)" - 在这种情况下替换 "-8" ,因为它是唯一的变量,或者这不会为范围内的第一个单元格返回数值?
  • @LukeJ 嗨。是的你可以!你正在做的是给 SUM 函数一些范围。我的代码也是如此。如果您可以通过 End(xlUp) 动态确定范围,则可以使用其地址来构建 SUM 参数。查看我的编辑,即将推出。
  • 再次感谢您的回复。这是一个巨大的帮助,并引导我找到我在上面添加的答案 - 可能不是最优雅的 - 但它适用于我将遇到的所有情况。
【解决方案2】:

这是我使用的解决方案,因为它涵盖了我在将要使用的数据集中能想到的所有选项。

If ActiveCell.Offset(-2) = "" Then
    ActiveCell.Formula = "=SUM(" & ActiveCell.Offset(-1).Address & ":" & ActiveCell.Offset(-1).Address & ")"
Else
    ActiveCell.Formula = "=SUM(" & ActiveCell.Offset(-1).Address & ":" & ActiveCell.Offset(-1).End(xlUp).Address & ")"
End If

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    相关资源
    最近更新 更多