请教电子表格数字批量修改问题

山水无言 2018-03-13 05:54:00
加精
电子表格一些单元格有类似这样的数据:
小朱100/小刘200/小海800
小马400/小张200/大海300
......

请问,怎么用vba+正则表达式批量修改这些单元格的数字?例如,每个数字加上200,变成:
小朱300/小刘400/小海1000
小马600/小张400/大海500
......
...全文
4737 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxp8051fans 2018-03-28
  • 打赏
  • 举报
回复
vba是好东西,我复制,粘贴
山水无言 2018-03-23
  • 打赏
  • 举报
回复
最近很忙,没空上网,很感谢大家!我要好好学习一下你们的代码
of123 2018-03-22
  • 打赏
  • 举报
回复
实际上是为非线性数据库表擦屁股,尽管有很多精妙的处理方法。 最好的方式,就是重新设计成线性数据库表,便于更新处理。例如,每一行只有一个数据记录,姓名和其他数字项分在不同的列。需要附加信息的在增加列。 如果最后需要输出楼主所列的格式,也完全可以通过查询合并来实现。
line_us 2018-03-21
  • 打赏
  • 举报
回复
录个查找替换宏大概可以解决吧
zxh_33 2018-03-21
  • 打赏
  • 举报
回复
所以为什么把名字和数字写在一个单元格里,先分开不就行了
舉杯邀明月 2018-03-20
  • 打赏
  • 举报
回复
呵呵………… 刚才突然发现,“吃屎都难”居然舍得把你们的MVP图标弄得这么小了啊……
dsd999 2018-03-20
  • 打赏
  • 举报
回复
很有质量的一个帖子。。。。
赵4老师 2018-03-19
  • 打赏
  • 举报
回复
提醒:在字符串扫描问题域中,正则表达式不是万能的;而有限状态自动机是万能的。
X-i-n 2018-03-19
  • 打赏
  • 举报
回复
引用 12 楼 chewinggum 的回复:
[quote=引用 11 楼 Runnerchin 的回复:] [quote=引用 10 楼 kyong 的回复:] 谢谢各位!我是想用vba+正则表达式的方法解决,正则表达式可以对Pattern设置分组(如前面答复的regx.Pattern = "-*\d+(\.\d+){0,}"),我想是不是用分组比较好,因为每个单元格这种类型的数据(小朱100.2/小刘-200/小海800/小混蛋-1312.312)个数是不确定的
大雪糕和我的代码都是先用 "/" 分割,再遍历分割的结果,不管你的数据源里有多少数据都是一样处理,数据个数对结果没有影响。 [/quote] 纠正一下,我的代码里并没有根据“/”分组,只是简单粗暴的识别数字进行处理。对小数及负数的判断是比较流氓的办法,但流氓的办法简单有效。 提醒一下楼主,执行一下大家答复的代码试试,用自己的测试用例确定有没有问题。不知道你强调数据个数不确定是怀疑代码不支持数据扩展么?改改样例试一试嘛。 另外,不要纠结是不是用正则,正则只能让你的代码量看上去少一点,但并没有实质上的简化和高效。[/quote] 有点眼花了,扫到一眼你引用代码里的斜杠,当成你也是用的分割。
脆皮大雪糕 2018-03-17
  • 打赏
  • 举报
回复
引用 11 楼 Runnerchin 的回复:
[quote=引用 10 楼 kyong 的回复:] 谢谢各位!我是想用vba+正则表达式的方法解决,正则表达式可以对Pattern设置分组(如前面答复的regx.Pattern = "-*\d+(\.\d+){0,}"),我想是不是用分组比较好,因为每个单元格这种类型的数据(小朱100.2/小刘-200/小海800/小混蛋-1312.312)个数是不确定的
大雪糕和我的代码都是先用 "/" 分割,再遍历分割的结果,不管你的数据源里有多少数据都是一样处理,数据个数对结果没有影响。 [/quote] 纠正一下,我的代码里并没有根据“/”分组,只是简单粗暴的识别数字进行处理。对小数及负数的判断是比较流氓的办法,但流氓的办法简单有效。 提醒一下楼主,执行一下大家答复的代码试试,用自己的测试用例确定有没有问题。不知道你强调数据个数不确定是怀疑代码不支持数据扩展么?改改样例试一试嘛。 另外,不要纠结是不是用正则,正则只能让你的代码量看上去少一点,但并没有实质上的简化和高效。
X-i-n 2018-03-13
  • 打赏
  • 举报
回复
引用 8 楼 chewinggum 的回复:
[quote=引用 6 楼 Runnerchin 的回复:] [quote=引用 5 楼 chewinggum 的回复:] [quote=引用 3 楼 Runnerchin 的回复:] 遍历每个需要替换的单元格,将单元格内容按"/"切成数组,为每个数组成员执行一次正则替换,替换好了再拼回去。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "\d+"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
这个也是负数和小数有问题。[/quote] 不要在意这些细节嘛,这个一看就是用来记红包用的。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "-*\d+\.*\d+?"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
[/quote] 负小数用例还是不对 比如-1312.312 执行结果是 -11212.3212[/quote]
regx.Pattern = "-*\d+(\.\d+){0,}"
脆皮大雪糕 2018-03-13
  • 打赏
  • 举报
回复
引用 6 楼 Runnerchin 的回复:
[quote=引用 5 楼 chewinggum 的回复:] [quote=引用 3 楼 Runnerchin 的回复:] 遍历每个需要替换的单元格,将单元格内容按"/"切成数组,为每个数组成员执行一次正则替换,替换好了再拼回去。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "\d+"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
这个也是负数和小数有问题。[/quote] 不要在意这些细节嘛,这个一看就是用来记红包用的。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "-*\d+\.*\d+?"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
[/quote] 负小数用例还是不对 比如-1312.312 执行结果是 -11212.3212
赵4老师 2018-03-13
  • 打赏
  • 举报
回复
X-i-n 2018-03-13
  • 打赏
  • 举报
回复
引用 5 楼 chewinggum 的回复:
[quote=引用 3 楼 Runnerchin 的回复:] 遍历每个需要替换的单元格,将单元格内容按"/"切成数组,为每个数组成员执行一次正则替换,替换好了再拼回去。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "\d+"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
这个也是负数和小数有问题。[/quote] 不要在意这些细节嘛,这个一看就是用来记红包用的。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "-*\d+\.*\d+?"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
X-i-n 2018-03-13
  • 打赏
  • 举报
回复
引用 10 楼 kyong 的回复:
谢谢各位!我是想用vba+正则表达式的方法解决,正则表达式可以对Pattern设置分组(如前面答复的regx.Pattern = "-*\d+(\.\d+){0,}"),我想是不是用分组比较好,因为每个单元格这种类型的数据(小朱100.2/小刘-200/小海800/小混蛋-1312.312)个数是不确定的
大雪糕和我的代码都是先用 "/" 分割,再遍历分割的结果,不管你的数据源里有多少数据都是一样处理,数据个数对结果没有影响。 另外,在这个场景里只需要普通的匹配就可以了,使用分组不会带来更便捷的处理流程。一般分组用于针对特定的结构进行匹配,分组捕获的结果里各个部分都是有不同含义的,比如
Regex.Match(@"<a href='abc' target='_blank'", "href='(.+)'.+target='(.+)'")
,匹配的结果里就有两个分组,分别是abc和_blank(也就是href部分和target部分)。而你的数据要匹配的是“不确定数量的数字”,每个匹配结果地位相等,没有结构位置上的差别,这只是普通的匹配(当然用分组也能做,将同一个分组做重复匹配,但是这其实是将分组当成普通匹配来用)。 VBA的正则有一个比较坑的地方就是不支持匿名函数,Regex.Replace没有办法像高级语言里直接对分组的匹配进行计算再替换结果(比如:Regex.Replace("Ab12C12D", @"\d+",match=> (Convert.ToInt32(match.Value) + 200).ToString()),在Replace里,将Match结果处理一下直接就能赋给“替换到”参数实现一句话替换),所以这儿先split再针对最小切割单元进行替换(也可能它确实支持,但我不懂)。 正则虽然写起来方便,但是如果是对大量数据进行处理,字符串遍历的性能要比正则高很多,所以不要一味迷信某一种特定的算法。
脆皮大雪糕 2018-03-13
  • 打赏
  • 举报
回复
稍作修改,解决小数和负数的问题

Public Sub Test()
    Dim strTest As String
    strTest = "小朱100.2/小刘-200/小海800/小混蛋-1312.312"
    Debug.Print strTest
    Debug.Print TranTest(strTest)
End Sub
Private Function TranTest(strinput As String) As String
    Dim i As Long, j As Long
    Dim strOutPut As String, strTmp As String
    
    i = 1
    Do While i <= Len(strinput)
        If IsNumeric(Mid(strinput, i, 1) & "0") Then
            j = i
            strTmp = ""
            Do While j <= Len(strinput) And IsNumeric(Mid(strinput, j, 1) & "0")
                strTmp = strTmp & Mid(strinput, j, 1)
                j = j + 1
            DoEvents
            Loop
            strOutPut = strOutPut & Trim(Str(Val(strTmp) + 200))
            i = j - 1
        Else
            strOutPut = strOutPut & Mid(strinput, i, 1)
        End If
        i = i + 1
        DoEvents
    Loop
    TranTest = strOutPut
End Function

输出 小朱100.2/小刘-200/小海800/小混蛋-1312.312 小朱300.2/小刘0/小海1000/小混蛋-1112.312
脆皮大雪糕 2018-03-13
  • 打赏
  • 举报
回复
引用 3 楼 Runnerchin 的回复:
遍历每个需要替换的单元格,将单元格内容按"/"切成数组,为每个数组成员执行一次正则替换,替换好了再拼回去。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "\d+"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
这个也是负数和小数有问题。
X-i-n 2018-03-13
  • 打赏
  • 举报
回复
遍历每个需要替换的单元格,将单元格内容按"/"切成数组,为每个数组成员执行一次正则替换,替换好了再拼回去。
Sub abc()
    Dim c() As String
    For i = 2 To 4
        c = Split(Sheet1.Cells(i, 1).value, "/")
        For j = 0 To UBound(c)
            c(j) = RegReplace(c(j))
        Next j
        Sheet1.Cells(i, 2) = Join(c, "/")
    Next
End Sub

Function RegReplace(plain As String)
    Dim value As String, regx
    value = plain
    Set regx = CreateObject("VBSCRIPT.REGEXP")
    regx.Pattern = "\d+"
    regx.Global = True
    For Each Match In regx.Execute(value)
        value = Replace(value, Match.value, (Match.value + 200))
    Next
    RegReplace = value
End Function
脆皮大雪糕 2018-03-13
  • 打赏
  • 举报
回复
花十分钟写一段,其他单元格你自己去循环处理

Public Sub Test()
    Dim strTest As String
    strTest = "小朱100/小刘200/小海800"
    Debug.Print strTest
    Debug.Print TranTest(strTest)
End Sub
Private Function TranTest(strinput As String) As String
    Dim i As Long, j As Long
    Dim strOutPut As String, strTmp As String
    
    i = 1
    Do While i <= Len(strinput)
        If IsNumeric(Mid(strinput, i, 1)) Then
            j = i
            strTmp = ""
            Do While j <= Len(strinput) And IsNumeric(Mid(strinput, j, 1))
                strTmp = strTmp & Mid(strinput, j, 1)
                j = j + 1
            Loop
            strOutPut = strOutPut & Trim(Str(Val(strTmp) + 200)) '识别出数字加200
            i = j - 1
        Else
            strOutPut = strOutPut & Mid(strinput, i, 1)
        End If
        i = i + 1
        'DoEvents
    Loop
    TranTest = strOutPut
End Function

输出结果: 小朱100/小刘200/小海800 小朱300/小刘400/小海1000 这段代码目前对负数和小数的处理不对,看楼主需求,有需求再改。 如果输入全是正整数,就OK了。
舉杯邀明月 2018-03-13
  • 打赏
  • 举报
回复
难道不用正则表达式,就不可以解决这个问题吗!
加载更多回复(1)

2,461

社区成员

发帖
与我相关
我的任务
社区描述
VBA(Visual Basic for Applications)是Visual Basic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。
社区管理员
  • VBA
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧