-
本技巧的目的:掌握单元格合并,拆分,求和的方法。
- 用代码合并单元格后的效果
- 用代码拆分单元格后的效果
如果需要在拆分后将原有的文字全部保留,在单元格中实现是很麻烦的一件事,但使用VBA代码形式很简单。
代码助手实现代码快速输入
- 只要在代码区输入中文:合并+空格 就会弹出相应的代码 以供选择
- 使用代码助手还能够随时收录自己需要的代码:
-
如何判断单元格区域是否存在合并单元格
代码如下:
- 注释:
- 使用 Range.MergeCells 属性 检查 单元格中是否包含合并单元格
- 可以使用立即窗口来测试一下三个不同的结果:
- 当有合并单元格时,返回的结果为 True
- 当没有合并单元格时,返回的结果为 False
- 当混合二个不同类型的单元格时,返回的结果为 Null
- 代码的书写就是根据三种不同的返回值来书写
- Selection.MergeCells = True ‘有合并单元格
- IsNull(Selection.MergeCells) ‘检查变量值是否为 Null ,即是否混合二种格式的单元格
- Else ‘最后为无合并的单元格
- IsNull 函数的 示例 1:
- Dim 值, 检查结果
- 检查结果 = IsNull(值)
- ‘因为值是空值,则: 检查结果 = False。
- 示例 2:
- 值 = “”
- 检查结果 = IsNull(值)
- ‘因为值设置为空值,则: 检查结果= False。
- 示例 3:
- 值 = Null
- 检查结果 = IsNull(值)
- ‘值设置为:Null 则:检查结果 = True。
- 将上面的代码修改一下就变成通用的函数了,这样可以方便随时调用
- 注释:
- 一般子函数, 只要不需要外部调用, 无论是否有返回值, 都可以使用 function 语句
- 括号内的 r 为外部传入的参数,外部传入时可以不使用 r 这个变量, 可以任意名称, 只要类型与当前子函数相符即可
- 参数传入后, 无论外部是什么名称, 当前过程会自动转换为 r 。 参数 r 可以直接在当前过程中使用,不需要声明
- 如果要返回结果, 函数名称需要写上等于哪个值, 即: 判断合并单元格 = s
- 子函数写好后,直接调用就可以出来结果:
-
合并单元格时能够连接每个单元格的文本的方法
合并前:
- 合并单元格的代码:
- 注释:
- 先将原单元格的内容全部用连接的方式记录下来
- 合并单元格: rng.Merge
- s = s & “,” & r ‘第1次连接时 s 为空值, 结果变成 ,453, 后面的连接是正常的: ,453,189…. 如上图
- rng = Mid(s, 2) ‘使用 Mid 去掉第1个 , 逗号
- WrapText 属性:所有单元格中的文本都自动换行,返回 True;都不自动换行,返回 False;有些单元格中的文本自动换行,有些不自动换行,返回 Null
- 同样的,修改成子函数,方便后续调用:
- 执行前:
- 执行后:
- 注释:
- 把三个地址放入数组: “A1:A4”, “C3:C5”, “E6:E8”
- 调用子函数—合并单元格所有内容, 执行合并单元格的操作
- Function 合并单元格所有内容(rng As Range),括号内的 rng 是外部传入的参数
- 子函数的优点:主函数不需要每次都写一大段代码,可以通过传参数的方法在子函数中完成,子函数可以被多个过程调用。 变量也可以相对减少很多。
- rng = “‘“ & Mid(s, 2)
‘加上”‘“代表是以文本写入,因为有数字,可以防止写入到单元格中出错
合并内容相同的连续单元格
合并前的格式:
- 合并后的格式及代码:
- 注释:
- 加速语句,有关必须有开, 都是成对的。 Application.DisplayAlerts = False Application.DisplayAlerts = True
- 位置语句开始后面,所有需要使用该位置的地址前面都要加上 .
- ★★★ 注意:合并单元格,删除单元格,为了防止单元格的位置混乱,都必须是从下到上的循环, step 是 -1
.Range(.Cells(i - 1, “A”), .Cells(i, “A”)).Merge ‘二个单元格合并,range(最上面单元格,最下面单元格)
拆分单元格时仍然保留每个单元格中的内容
拆分前面已合并的单元格,代码如下:
- 注释:
- 取消合并单元格,从上到下即可
- 先记录原值,再写入的过程
- 循环行号需要变化:i = i + rng.Rows.Count - 1 即:循环行号(本行) + 包含本行内的单元格的行数 - 1 本行
- MergeArea 属性:返回单元格对象。如果在合并区域,返回单元格的合并区域。如果不在合并区域内,返回该单元格
- n = .Range(“A1048576”).End(xlUp).Row + _
- .Range(“A1048576”).End(xlUp).MergeArea.Rows.Count - 1
‘为了防止最后行为合并的单元格, 出现计算不准确情况。使用这个公式计算最大行: 最大行 + 最大行的合并区域的行数 - 1
合并单元格对应同行区域求和
代码:
- 注释:
- Application.ThisCell: 返回当前单元格, 如图为: C2 它的 MergeArea 合并区域: C2:C4
- r.Resize(e.Rows.Count) ‘传入的参数 r 为: A2,它扩展 (C2:C4 的行数:3),即: A2:A4
- Application.WorksheetFunction.Sum(e) ‘对该区域调用工作表函数执行求和
- 在选定区域中写入公式的代码:
- 选定区域为: B2:B9
- 注释:
- 打断点逐步调试看结果, 方便理解
- 第一次取出的 e 是 B2单元格
- Set s = e.MergeArea ‘当前 B2 单元格 的合并区域地址为: $B$2:$B$4
- If e.Address = s.Range(“a1”).Address Then ‘因为 B2 是 合并区域: $B$2:$B$4 中的第1个地址,则执行后面的代码
- Split(s.Address, “$”) ‘用 $ 拆分合并区域地址, 拆分后:
- 求和区 = Replace(s.Address, 拆分(1), 替换列)
- ‘原来的地址: $B$2:$B$4, 拆分(1)的值: B 见上图, 替换成之前输入的列号: A
- 替换后的结果: $A$2:$A$4
- e.Formula = “=sum(“ & 求和区 & “)” ‘e 即B2单元格 写入公式 =sum($a$2:$a$4)
- 第二次取出的 e 是 B3单元格
- If e.Address = s.Range(“a1”).Address Then ‘因为 B3 不是 合并区域: $B$2:$B$4 中的第1个地址,则不执行后面的代码
- 就是通过这样一个循环,完成所有原生公式的写入,完成求和的目的
更多作品请百度搜索 郑广学
VBA代码助手 懒人神器 在 EXCEL880.COM 官网下载