excel学习库

excel表格_excel函数公式大全_execl从入门到精通

Excel VBA 按数字加特定字符关键字汇总/正则表达式/字典

本文于2023年8月12日首发于本人同名其他平台,更多文章案例请搜索关注!

内容提要

  • 正则表达式提取数字加指定字符

  • 字典方法汇总数据

大家好,我是冷水泡茶,今天在论坛上看到一个求助贴:

他的明细表数据是这样的:

他要在同一张表的B29、C29列写入数据:

他的具体需求是:把B列包含“??芯"项目,对应的G列数据进行汇总,并且用进一法舍入到10位,并且要把29行以下,C列为0的行删除。

其实,在实际工作中碰到类似问题,添加辅助列或者对照表都是不错的选择,但楼主不想添加辅助列,只想用VBA代码来解决,那么,从研究VBA代码的角度,还是值得探讨探讨的,我们一起来看一看吧:

基本思路

1、首先,我们分析关键字特征,它是不确定的几位数字加上一个“芯”。

2、然后,我又发现,它的项目字段中,只有一段连续的数字,没有其他数字。

3、我突然想起我们前面分享过的文章,正则表达式提取数字【Excel VBA 提取数字/自定义工作表函数/正则表达式/批量提取电话号码】,还有一篇【Excel VBA 提取单元格字符串中的数字并求和/兼聊原始数据的问题】。

4、我们用前文中分享过的函数GetNum把所有数字提取出来,再加上一个“芯”字,不就成了?试了一下,确实可行。但是感觉直接用这种方法,有点偷机取巧的意思,不算正解。

5、正确的思路应该是,用正则表达式把“芯”前面的数字及“芯”字提取出来。

程序代码

1、自定义函数ExtractKey,提取汇总关键字:

Function ExtractKey(str As String)    Dim regex As Object    Dim matches As Object    Dim strResult As String    ' 创建正则表达式对象    Set regex = CreateObject("VBScript.RegExp")    regex.Global = True    regex.IgnoreCase = True    regex.Pattern = "\d+芯"    ' 执行正则匹配    Set matches = regex.Execute(str)    ' 提取第一个匹配结果    If matches.Count > 0 Then        strResult = matches.Item(0).Value    Else        strResult = ""    End If    ExtractKey = strResult    ' 清除对象引用    Set regex = Nothing    Set matches = NothingEnd Function

代码解析:

(1)创建正则表达式对象regex

(2)定义模式:regex.Pattern = "\d+芯",表示匹配“芯”及其前面的所有连续的数字。

(3)执行匹配Set matches = regex.Execute(str)

(4)提取匹配结果给自定义函数赋值

2、Sum过程,按提取关键字汇总数据:

Sub Sum()    Dim arr()    Dim ws As Worksheet    Dim lastRow As Integer    Dim Dic As Object    Dim dKey As String    Dim iCol As Integer    Dim arrTem()    ThisWorkbook.Activate    Set ws = Sheets("线路定额")    Set Dic = CreateObject("Scripting.dictionary")    ws.Activate    lastRow = 28    arr = ws.Range(Cells(2, 2), Cells(lastRow, 7)).Value    iCol = UBound(arr, 2)    For i = 1 To UBound(arr, 1)        If InStr(arr(i, 1), "芯") > 0 Then            dKey = arr(i, 1)            dKey = ExtractKey(dKey)            Dic(dKey) = Dic(dKey) + arr(i, iCol)        End If    Next    lastRow = ws.UsedRange.Rows.Count    ws.Range("B29:C" & lastRow).ClearContents    arrTem = Dic.keys    ws.Range("B29").Resize(UBound(arrTem) + 1, 1) = Application.WorksheetFunction.Transpose(arrTem)    arrTem = Dic.items    '取整    For i = LBound(arrTem) To UBound(arrTem)        arrTem(i) = Application.WorksheetFunction.Ceiling(arrTem(i), 10)    Next    ws.Range("C29").Resize(UBound(arrTem) + 1, 1) = Application.WorksheetFunction.Transpose(arrTem)    '删除C列单元格为0的行    lastRow = ws.UsedRange.Rows.Count    For i = lastRow To 29 Step -1        If Cells(i, 3) = 0 Then            Rows(i).Delete        End If    NextEnd Sub

代码解析:

(1)定义字典Dic。

(2)把原始数据读入数组,他要求在第29行写入数据,所以把lastRow定为28。(我想不出原因为什么要在同一张表上进行汇总,要是我做的话,肯定是把汇总数据放到另外一张表上。)

(3)循环数组,提取汇总关键字“?芯”,这里用同一个变量dkey,逐步取得结果。

(4)把关键字装入字典,顺带进行汇总,把汇总结果存在字典的Item里。

(5)把字典的keys赋值给数组arrTem,再把arrTem存入工作表B列。

(6)把字典的items赋值给数组arrTem,用工作表函数ceiling把数组的值取整到10位后,再存入工作表C列。

(7)删除第29行以下,C列为0的记录。删除行要从下往上删除。

总结

1、字符提取,用正则表达式,非常方便。

2、字段汇总,用字典,可以在向字典添加键值的同时进行汇总。

---End---

喜欢就点个、点在看留个言呗!分享一下更给力!感谢!

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2024年12月    »
1
2345678
9101112131415
16171819202122
23242526272829
3031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
    文章归档
      友情链接