【问题标题】:Remove zeros from middle of string从字符串中间删除零
【发布时间】:2019-07-25 18:59:53
【问题描述】:

我有一个带有前缀的序列号列表,然后是几个数字。所有序列号都是 8 个字符,因此根据前缀和零的数量,在前缀和数字之间添加不同数量的前导零。 (例如 ALT00001、CAT00564、AAR19470、M0000003、MISC7859、MISC0025) 如何从序列号中删除所有前导零,但保留作为实际数字一部分的任何零?

我很想创建一个执行此操作的宏,因为我必须每天无数次在多个工作簿上运行此代码。

【问题讨论】:

  • 告诉我们您期望的结果。
  • ALT1、CAT564、AAR19470、M3、MISC7859、MISC25
  • 前缀是否会包含A4BC0001等数字?
  • @TerryW 不,前缀永远不会包含数字

标签: vba excel-formula


【解决方案1】:

A 列中有数据,在 B1 中输入:

=LEFT(A1,3) & --RIGHT(A1,5)

然后向下复制。

编辑#1:

根据更新的例子,我们必须找到第一个数字在字符串中的位置,并据此进行解析。

C1中输入:

=MIN(FIND({"0","1","2","3","4","5","6","7","8","9"},UPPER(A1)&"0123456789"))

并向下复制。 (这给出了第一个数字的位置)

现在在B1输入:

=LEFT(A1,C1-1) & --RIGHT(A1,8-C1+1)

或:

=LEFT(A1,C1-1) & --RIGHT(A1,9-C1)

(如果您不想要“帮助”列,请组合公式)

编辑#2:

这里有一些代码:

Sub Deb()
    Dim Kolumn As String, rng As Range, cell As Range, s As String, L As Long
    Dim i As Long

    Kolumn = "A"
    Set rng = Intersect(Columns(Kolumn).EntireColumn, ActiveSheet.UsedRange).Offset(1, 0).Cells

    For Each cell In rng
        s = cell.Value
        If s = "" Then Exit Sub
        L = Len(s)
        For i = 1 To L
            If IsNumeric(Mid(s, i, 1)) Then
                GoTo Process
            End If
        Next i
        MsgBox "bad data " & s
        Exit Sub
Process:
        cell.Value = Left(s, i + -1) & CLng(Mid(s, i))
    Next cell

End Sub

编辑#3:

宏很容易安装和使用:

  1. ALT-F11 调出 VBE 窗口
  2. ALT-I ALT-M 打开一个新模块
  3. 粘贴内容并关闭 VBE 窗口

如果您保存工作簿,宏将与它一起保存。 如果您使用的是 2003 年以后的 Excel 版本,则必须保存 文件为 .xlsm 而不是 .xlsx

删除宏:

  1. 如上所示打开 VBE 窗口
  2. 清除代码
  3. 关闭 VBE 窗口

使用 Excel 窗口中的宏:

  1. 选择要运行宏的工作表
  2. ALT-F8
  3. 选择宏
  4. 触摸运行

要了解有关宏的更多信息,请参阅:

http://www.mvps.org/dmcritchie/excel/getstarted.htm

http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx

必须启用宏才能正常工作!

编辑#4:

此代码检查错误:

Sub Deb_2()
    Dim Kolumn As String, rng As Range, cell As Range, s As String, L As Long
    Dim i As Long

    Kolumn = "A"
    Set rng = Intersect(Columns(Kolumn).EntireColumn, ActiveSheet.UsedRange).Offset(1, 0).Cells

    For Each cell In rng
        s = cell.Value
        If s = "" Then Exit Sub
        L = Len(s)
        For i = 1 To L
            If IsNumeric(Mid(s, i, 1)) Then
                GoTo Process
            End If
        Next i
        MsgBox "bad data " & s
        Exit Sub
Process:
        If IsNumeric(Mid(s, i)) Then
            cell.Value = Left(s, i + -1) & CLng(Mid(s, i))
        End If
    Next cell

End Sub

【讨论】:

【解决方案2】:

我有两种方法,一种是使用excel数组公式查找文本字符串中的数值,另一种是使用excel幂查询转换数据只需 4 个简单的步骤。

方法 1 - 数组公式

下面的公式将首先将文本字符串转换为数组,例如。 ALT00001会变成{"A";"L";"T";"0";"0";"0";"0";"1"},然后检查数组中的每个字符是否是像{FALSE;FALSE;FALSE;TRUE;TRUE;TRUE;TRUE;TRUE}这样的数值,最后将所有的TRUE结果相加。这将为您提供文本字符串中数值的总数。

{=SUM(--ISNUMBER(--MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1)))}

请注意,这是一个数组公式,因此您需要在完成公式编辑后按CSE(Ctrl+Shift+Enter)。

在我的工作中,我在单元格B1中输入了数组公式,然后在单元格C1中我输入了以下公式得到结果。

=LEFT(A1,8-B1)&--RIGHT(A1,B1)

您可以将这两个公式结合起来,但它看起来会很长而且不容易被其他人解释。如果确实要合并,则需要按 CSE 使其工作,因为它合并了一个数组。

方法 2 - Power Query

虽然@Deb 没有要求使用 Power Query (PQ) 的解决方案,但我仍然想分享一种有效解决问题的替代方法,因为上述基于公式的解决方案不是那么直接而且有些复杂。

PQ 能够转换来自多个工作表的数据,并具有丰富的内置功能,非常用户友好。请注意,您需要有 Excel 2010 或更高版本才能使用 PQ。

以下是使用 PQ 的步骤:

1) 将数据范围加载到 PQ Editor,其中一种方法是突出显示数据范围并在 Data 选项卡中使用 From Table,如下所示:

2) 加载后,PQ 编辑器将在新窗口中打开。下一步是将值分为文本字符串和数字字符串。一种快速的方法是使用 PQ 编辑器的 Transform 选项卡中的 Split Column (By Non-digit to Digit),如下所示。

3) 现在我们在第一列中有文本,在第二列中有数字。下一步是清除数字列中值前面的“0”。一种方法是将 Data TypeText 更改为 Whole Number,然后将其更改回 Text(我将解释为什么您需要将其更改回 Text in下一步)。

4) 下一步是合并两列以获得所需的结果。一种方法是添加自定义列并使用& 组合两列中的值,如下所示。

=[Column1.1]&[Column1.2] the way of using & is same as in an excel formula

如我上一步所说,我们需要将数值改回text,原因是PQ Editor不允许将文本值与数值结合,会导致如下错误。

5) 最后一步取决于您的偏好。我所做的是删除其他列并将结果列加载到您的原始数据所在的当前工作表中。

很遗憾,PQ 无法覆盖源数据。但是,在我看来,最好将源数据保存在安全的地方而不会被覆盖,然后将编辑/转换后的数据导出到新的地方并进行处理。

这里是幕后的代码,但所有步骤都是使用内置函数执行的,您可以轻松地通过谷歌搜索每个步骤的诀窍。

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Split Column by Character Transition" = Table.SplitColumn(Source, "Column1", Splitter.SplitTextByCharacterTransition((c) => not List.Contains({"0".."9"}, c), {"0".."9"}), {"Column1.1", "Column1.2"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Character Transition",{{"Column1.2", Int64.Type}}),
    #"Changed Type2" = Table.TransformColumnTypes(#"Changed Type1",{{"Column1.2", type text}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type2", "Result", each [Column1.1]&[Column1.2]),
    #"Removed Other Columns" = Table.SelectColumns(#"Added Custom",{"Result"})
in
    #"Removed Other Columns"

干杯:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-09
    • 2021-06-15
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 2014-08-04
    相关资源
    最近更新 更多