当前位置: 首页 > news >正文

VBA之正则表达式(46)-- 解析业务逻辑公式

实例需求:某业务系统的逻辑公式如下所示(单行文本),保存在活动工作表的A1单元格中。

"DSO_90Day"->"FA_NoFunc"->"FCCS_No Intercompany"->"FCCS_Data Input"->"FCCS_No Movement"->"NoCC"->"FCCS_YTD_Input" = (("TradeAR"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" - "TradeARTooling"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" + "AllowDbtflAcc"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" ) / ("NetSalesTwoMthsPrior"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" + "NetSalesCurrent"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" + "NetSalesPrior"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic")) * 90;

为了便于大家理解数据提取需求,将逻辑公式格式化为缩进格式。

"DSO_90Day"->"FA_NoFunc"->"FCCS_No Intercompany"->"FCCS_Data Input"->"FCCS_No Movement"->"NoCC"->"FCCS_YTD_Input"  = 
(("TradeAR"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" - "TradeARTooling"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic"  + "AllowDbtflAcc"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" ) / ("NetSalesTwoMthsPrior"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" + "NetSalesCurrent"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic" + "NetSalesPrior"->"Total Functional Area"->"FCCS_Intercompany Top"->"FCCS_Total Data Source"->"FCCS_Movements"->"Total Business Unit"->"FCCS_Periodic")) * 90;

现在需要按如下规则提取数据,结果如下所示。

  • 提取引号之间的的关键字,可能包含空格
  • 提取相应的操作符合: + - * / =
  • 提取最后的数字

在这里插入图片描述

示例代码如下。

Sub ParseRule()Dim ruleSheet As WorksheetDim smartViewSheet As WorksheetDim rule As String, res()Dim i As Long, j As Long, iR As LongDim aTxt, strMatch As String, arrResDim objRegExp As Object, objMatch As ObjectSet ruleSheet = ThisWorkbook.Sheets(1)Set smartViewSheet = ThisWorkbook.Sheets(2)smartViewSheet.Cells.Clearrule = ruleSheet.Range("A1").ValueSet objRegExp = CreateObject("vbscript.regexp")objRegExp.Pattern = "((?:[\w ]+->){6}[\w]+)[\s)]*([=+\-*\/])\s([\d]*)"objRegExp.Global = TrueobjRegExp.IgnoreCase = TrueobjRegExp.MultiLine = FalseSet objMatch = objRegExp.Execute(Replace(rule, Chr(34), ""))If objMatch.Count > 0 ThenReDim arrRes(1 To objMatch.Count + 1, UBound(Split(objMatch(0).submatches(0), "->")) + 2)For j = 0 To objMatch.Count - 1strMatch = objMatch(j).submatches(0)aTxt = Split(strMatch, "->")iR = iR + 1For i = 0 To UBound(aTxt)arrRes(iR, i) = Trim(aTxt(i))NextarrRes(iR, i + 1) = objMatch(j).submatches(1)If Len(objMatch(j).submatches(2)) > 0 ThenarrRes(iR + 1, i + 1) = objMatch(j).submatches(2)End IfNextEnd IfsmartViewSheet.Range("A1").Resize(UBound(arrRes, 1), UBound(arrRes, 2) + 1).Value = arrRes
End Sub

【代码解析】
第9~10行代码获取工作表对象。
第11行代码清空工作表用于保存结果。
第12行代码由A1单元格读取字符串。
第13行代码创建正则对象。
第14行代码设置正则匹配模式。

正则表达式说明
[\w ]非提取组用于匹配数字、字母和空格
(?:[\w ]±>){6}非提取组,用于6匹配关键字(单个或者多个)->
((?:[\w ]±>){6}[\w]+)之后匹配一个或者多个字符,作为第一个提取组
[\s)]*匹配任意个数的白字符或者右括号
([=+-*/])第二个匹配组,用于提取符号
\s匹配单个白字符
([\d]*)第3个匹配组,用于匹配任意数量的数字

第15行代码设置正则全局匹配。
第16行代码设置正则匹配忽略大小写。
第16行代码设置正则匹配使用单行模式。
第17行代码执行正则匹配,注意此处使用Replace函数去除了字符串中的双引号。
第19行代码判断匹配成功。
第20行代码创建数组用于保存结果。
第21~32行代码循环提取每个匹配数据。
第22行代码获取第一个匹配组字符串内容。
第23行代码使用->作为分界符拆分字符串。
第25~27行代码将拆分后的内容保存在数组中。
第28行代码获取第2个匹配组字符串内容。
第29行代码判断是否成功匹配第3个匹配组,如果存在,那么第30行代码将其保存在结果数组中。
第34行代码将结果写入工作表。


http://www.mrgr.cn/news/9001.html

相关文章:

  • 【观察】亚信科技:“三新”业务交替领涨对冲压力,“四个转变”延展韧性增强活力...
  • 【Node】【1】node和nvm安装
  • 第135天:内网安全-横向移动非约束委派约束委派数据库攻防
  • 3b1b自注意力机制讲解记录
  • 每天一道C语言精选编程题之求字符串长度
  • 【内网渗透】ICMP隧道技术,ICMP封装穿透防火墙上线MSF/CS
  • 攻破:重定向 缓冲区
  • DataFrame中各个列的数据类型,修改数据类型
  • RPC(Remote Procedure Call,远程过程调用)实现跨进程级别调用的原理
  • 云计算产业链图谱_产业链全景图_云计算行业市场分析
  • CSS文本【关于文本看这一篇就够了!!!】
  • 分享一个基于python的内蒙古旅游景点数据分析与采集系统(源码、调试、LW、开题、PPT)
  • 【Docker】Docker学习04 | dockerfile的编写
  • Programmatically add website content to OpenAI with C#
  • 8.20 pre day bug
  • 在windows项目中如何设计TCP网络单例模式
  • C++ //练习 19.18 编写一个函数,使用count_if统计在给定的vector中有多少个空string。
  • eureka原理实践
  • 鸿蒙卡片传值app到卡片
  • 具有手势识别的动捕设备——mHand Pro VR数据手套