【问题标题】:VBA and regexp - identify numbers stored as textVBA 和正则表达式 - 识别存储为文本的数字
【发布时间】:2022-01-27 00:32:24
【问题描述】:

我有一些看起来像这样的数据(超过 400 列):

year ID fake_num1 fake_num2 text1
2019 11 36 000 10'000 text, 1
2020 12 -1 275 1 000,00 text 2

列 fake_num1 和 fake_num2 存储为文本。我想要实现的是

  1. 识别那些假数字列
  2. 使用 for 循环清理数据(例如,删除空格、列、用点替换逗号)

我在第 1 步需要一些帮助。我必须识别列 fake_num1 和 fake_num2,同时避免使用 text1 等列。我正在考虑使用正则表达式,但也许还有另一种解决方案。

我在这里使用了部分代码:SO regexp,但是我不确定如何从那里继续。

Dim strPattern as String: strPattern = "^[0-9]$"

会找到任何以数字开头和结尾的东西,并且只有数字(如果我的理解是正确的)。管理上表所列案例的最佳方法是什么?

【问题讨论】:

  • 数据存储在哪里,在应用程序(word,Excel?)一个文本文件中?。如果您使用的是 VBA,那么一个测试字符串以查看它是否仅包含“数字字符”的函数(即字符 0 到 9 以及任何数字格式字符(如“.,-+”字符)可能是一种方法跨度>
  • 如果列中的cel值不是数字,这是否意味着该列都是假的?如果是这样,您应该枚举情况以使该值成为数字。哪个是小数分隔符?一个点? 1 000,00 应该变成 1000.00 吗?
  • @freeflow 它存储在我导入 Excel 的 csv 文件中。
  • @FaneDuru 小数点分隔符是逗号。千位分隔符有时是空格,有时是撇号。上表列出了这些可能性。
  • @freeflow 你将如何编写正则表达式来处理你提到的内容?

标签: regex vba


【解决方案1】:

请尝试下一个代码,它将“假数字列”视为替换必要字符使字符串变为数字的列:

Sub testMakeNumbers()
 Dim sh As Worksheet, lastR As Long, lastCol As Long, i As Long, rngCol As Range
 
 Set sh = ActiveSheet 'you can use here the necessary sheet
 lastR = sh.Range("A" & sh.rows.Count).End(xlUp).row
 lastCol = sh.cells(1, Columns.Count).End(xlToLeft).Column
 
 'determine the problematic columns:
 For i = 1 To lastCol
    If Not IsNumeric(sh.cells(2, i).Value) And _
            IsNumeric(Replace(Replace(Replace(sh.cells(2, i).Value, " ", ""), "'", ""), ",", ".")) Then
        If rngCol Is Nothing Then
            Set rngCol = sh.cells(2, i)
        Else
            Set rngCol = Union(rngCol, sh.cells(2, i))
        End If
    End If
 Next
 'replace the characters making the string as number:
 With Intersect(rngCol.EntireColumn, sh.Range("A2", sh.cells(lastR, lastCol)))
       .Replace ",", "."
       .Replace Chr(160), ""
       .Replace " ", ""
       .Replace "'", ""
  End With
End Sub

【讨论】:

  • 它似乎应该可以工作,但我不知道为什么它不能替换空间。如果我使用上表并应用代码,Replace(Replace(Replace(sh.Cells(2, i).Value, " ", ""), "'", ""), ",", ".") 方法不起作用。这意味着如果条件IsNumeric() 不满足,因为它返回False
  • @DanielMc 我不这么认为...请创建一个包含三行的测试 Sub:Dim x As Stringx = "36 '000,00"Debug.Print Replace(Replace(Replace(x, " ", ""), "'", ""), ",", ".")。它在Immediate Window 中返回什么?尝试制作 x = "whatever you want testing" 。您上面的数据示例没有行和列的标题。第二行是要分析以确定有问题的列吗?上面的代码处理第二行...
  • 我没有测试你的提议,但是我找到了解决方案。如果我将" " 替换为Chr(160) 它可以工作:) 非常感谢您的帮助我将您的解决方案标记为答案,您可以补充一下" " 在某些情况下应该由Chr(160) 替换吗?我用excel的`Code()`函数找到了。
  • 回答您关于第二行的问题:并非针对所有列。有些列只有第 3400 行的数据...有没有比遍历行更有效的方法?
  • @DanielMc 我不知道空格不是空格... :) 空格的 ASCI 代码是 32。160 是通过 Excel 转换解释为空格的不同内容...好的,我会调整代码来做到这一点。
猜你喜欢
  • 1970-01-01
  • 2019-01-06
  • 2017-10-22
  • 2018-09-30
  • 1970-01-01
  • 2018-05-05
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多