Excel·VBA选中列一键计算小计总计

76 篇文章 24 订阅

不同于《Excel·VBA一键计算每月合计》,仅对指定关键字计算合计数,而本文可以实现对选中列自动插入小计、总计行并求和

连续相同关键值自动小计

自动插入小计、总计行,对关键值列中连续相同值的行,对选中列进行小计,并最后总计

Sub 选中列一键计算小计总计_关键值()
    '对关键值列中连续相同值的行,对选中列进行小计,并最后总计
    '适用单/多列选中、单/多列部分选中;部分选中时,选中区域不得与表头行重叠,避免计算错误
    Dim key_col&, title_row&, rng As Range, i&, j&, k&
    Dim first_row&, last_row&, first_col&, last_col&, start_row&, end_row&
'--------------------参数填写:key_col、title_row都为数字
    key_col = 1    '关键值号,对连续相同的进行小计;空值不影响
    title_row = 1  '表头行数,不进行计算;0即为全部计算
    Set rng = Intersect(ActiveSheet.UsedRange, Selection)  'intersect语句避免选择整列造成无用计算
    first_row = rng.row     '选中区域开始行号
    last_row = first_row + rng.Rows.Count - 1  '选中区域结束行号
    first_col = rng.column  '选中区域开始列号
    last_col = first_col + rng.Columns.Count - 1  '选中区域结束列号
    
    With ActiveSheet
        '总计
        .Rows(last_row + 1).Insert  '选中末行插入
        .Cells(last_row + 1, key_col) = "总计": r = last_row - first_row + 1  '总行数
        For i = first_col To last_col
            If title_row >= first_row Then  '整列选中,或部分选中时包含表头
                .Cells(last_row + 1, i).FormulaR1C1 = "=SUM(R[-" & r - title_row & "]C:R[-1]C)"
            Else  '部分选中,且不包含表头
                .Cells(last_row + 1, i).FormulaR1C1 = "=SUM(R[-" & r & "]C:R[-1]C)"
            End If
        Next
        '清除公式仅保留结果,避免被后续小计的值干扰
        .Cells(last_row + 1, first_col).Resize(1, last_col - first_col + 1) = .Cells(last_row + 1, first_col).Resize(1, last_col - first_col + 1).Value
        '小计
        If first_row > title_row Then start_row = first_row Else start_row = title_row + 1
        end_row = last_row + 1  '因总计行,总行数+1
        Do
            For j = start_row + 1 To end_row
                If .Cells(start_row, key_col) <> .Cells(j, key_col) Then
                    .Rows(j).Insert
                    .Cells(j, key_col) = .Cells(j - 1, key_col).Value & "-小计"
                    For k = first_col To last_col
                        .Cells(j, k).FormulaR1C1 = "=SUM(R[-" & j - start_row & "]C:R[-1]C)"
                    Next
                    '也可清除公式仅保留结果
                    Range(.Cells(j, first_col), .Cells(j, last_col)).Value = Range(.Cells(j, first_col), .Cells(j, last_col)).Value
                    start_row = j + 1: end_row = end_row + 1  '开始、结束行号更新值
                    Exit For  '结束for循环
                End If
            Next
        Loop Until start_row >= end_row
    End With
    Debug.Print "小计、总计行插入完成"
End Sub

举例

在这里插入图片描述
参数:key_col = 1,title_row = 1,选中C列运行代码,结果:

在这里插入图片描述

固定行数分段自动小计

Sub 选中列一键计算小计总计_分段()
    '对选中列按固定行数进行小计,并最后总计
    '适用单/多列选中、单/多列部分选中;部分选中时,选中区域不得与表头行重叠,避免计算错误
    Dim key_col&, title_row&, split_row&, rng As Range, i&, j&, k&
    Dim first_row&, last_row&, first_col&, last_col&, start_row&, end_row&, split_last&
'--------------------参数填写:key_col、title_row、split_row都为数字
    key_col = 1    '小计、总计,所在列号
    title_row = 1  '表头行数,不进行计算;0即为全部计算
    split_row = 8  '按固定行数分段小计
    Set rng = Intersect(ActiveSheet.UsedRange, Selection)  'intersect语句避免选择整列造成无用计算
    first_row = rng.row     '选中区域开始行号
    last_row = first_row + rng.Rows.Count - 1  '选中区域结束行号
    first_col = rng.column  '选中区域开始列号
    last_col = first_col + rng.Columns.Count - 1  '选中区域结束列号
    
    With ActiveSheet
        '总计
        .Rows(last_row + 1).Insert  '选中末行插入
        .Cells(last_row + 1, key_col) = "总计": r = last_row - first_row + 1  '总行数
        For i = first_col To last_col
            If title_row >= first_row Then  '整列选中,或部分选中时包含表头
                .Cells(last_row + 1, i).FormulaR1C1 = "=SUM(R[-" & r - title_row & "]C:R[-1]C)"
            Else  '部分选中,且不包含表头
                .Cells(last_row + 1, i).FormulaR1C1 = "=SUM(R[-" & r & "]C:R[-1]C)"
            End If
        Next
        .Cells(last_row + 1, first_col).Resize(1, last_col - first_col + 1) = .Cells(last_row + 1, first_col).Resize(1, last_col - first_col + 1).Value
        '小计
        If first_row > title_row Then start_row = first_row Else start_row = title_row + 1
        end_row = last_row + 1  '因总计行,总行数+1
        split_last = (end_row - start_row) Mod split_row  '最后一个非完整分段行数
        Do
            If start_row + split_row <= end_row Then  '非最后一个分段,或完整分段
                j = start_row + split_row: offset_row = split_row
            Else  '最后一个非完整分段
                j = end_row: offset_row = split_last
            End If
            .Rows(j).Insert
            .Cells(j, key_col) = "小计"
            For k = first_col To last_col
                .Cells(j, k).FormulaR1C1 = "=SUM(R[-" & offset_row & "]C:R[-1]C)"
            Next
            '也可清除公式仅保留结果
            'Range(.Cells(j, first_col), .Cells(j, last_col)).Value = Range(.Cells(j, first_col), .Cells(j, last_col)).Value
            start_row = j + 1: end_row = end_row + 1  '开始、结束行号更新值
        Loop Until start_row >= end_row
    End With
    Debug.Print "小计、总计行插入完成"
End Sub

结果:
参数:key_col = 1,title_row = 1,split_row = 8,选中C列运行代码,结果与上面举例的效果一致

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
遇到一个问题是这样的:有个做采购的同事,他来找到我,让我给他设计一个execl表格,能完成它日常采购东西的流水账,要是能够自动输入当天日期和时间。 然后我开始分析这个问题,用=now()这个函数能够做到自动获得当前日期和时间,但是问题在于怎么触发它,于是我有想到if语句。然后我制作一张简单的样表,A2设置为输入序号,B2里放日期和时间,当A2输入内容后,B2自动输入当前日期和时间。那么B2里设置函数=IF(A2="","",NOW()) 开始以为就这么简单,但是发现这个表格如果重新打开后,所以B都会变为最新的日期,而且当A2被重新编辑后,B2就会变更日期为最新日期,这样完全实现不了采购同事的需。于是我查阅了资料,找到了Target更新事件和Offset获得焦点,让他们配合起来达到目的,经过不懈的努力,终于让我把代码写成功了,初步达到了采购同事的要。特此把代码写在下面。供大家参考(以下代码最好配合实际案例的execl表的环境进行阅读,这样事半功倍,execl表,我把它挂载到一个下载链接吧): Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column <> 1 And Target.Column <> 5 Or Target.Count > 1 Then Exit Sub On Error Resume Next With Target If .Column = 1 And .Offset(0, 1).Value = "" Then '判断该单元格是否已经写入时间 .Offset(0, 1) = Now() End If If .Column = 5 Then '计算合计价格 .Offset(0, 1) = .Offset(0, 0) * .Offset(0, -1) End If End With End Sub

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔_51

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值