如何在Excel

时间:2017-12-01 12:54:03

标签: excel excel-formula substring

我有这样的记录

A                          Result
Hello AP#12/22 Welcome     AP#12
Thanks AP#123-21           AP#123
No problem AP#111          AP#111

因此,您可以看到我需要字符串中的AP代码。它不得包含 - 或/ part。

  

注意:

     

AP代码可以是任意数量的数字

     

它可以出现在最后或开始

     

AP代码后面可以跟/或 - 或任何其他特殊符号,例如   :或任何其他。

所以我需要一个通用公式,而不是检查每个特殊字符(/, - ,:)来获取AP代码。

我想在不使用VB的情况下实现这一目标。

2 个答案:

答案 0 :(得分:3)

可能不是最有效的解决方案......但是这里没有VBA的方式:(为了可读性添加了换行符)

= "AP#"&MID(MID(A1,FIND("AP#",A1)+3,999),1,
  MAX((ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,999),{1,2,3},1)+0)+0)*{1,2,3}))

修改

稍微好一点的解决方案:

= MID(A1,FIND("AP#",A1),
  MAX(ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,999),{1,2,3},1)+0)*{1,2,3})+3)

编辑(再次)

正如评论中所指出的,这并未考虑AP#1-1之类的内容。以下是将此考虑在内的更新公式:

= MID(A1,FIND("AP#",A1),IFERROR(MATCH(FALSE,
  ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,3),{1,2,3},1)+0),0),4)+2)

根据要求,以下是此公式的工作原理。我会一步一步地分解它。这是一个很长的解释,但如果你只是一步一步,我认为你应该能够理解整个公式。我将从内到外解释发生了什么。

FIND("AP#",A1)返回A1AP#的第一个A1实例出现在FIND("AP#",A1)中的字符索引号。

为简单起见,我会在下一步中将<x1>称为MID(A1,<x1>+3,3)

A1会返回AP#后面AP#后面的3个字符。它只返回3个字符,因为从原始问题开始,您说在MID(A1,<x1>+3,999)之后最多可以显示3个数字。

(快速说明:最初我将公式的这一部分作为999,但在做出此解释之后,我意识到3可以缩减为9993仍然可以工作,只是MID(A1,<x1>+3,3)更简单,使公式更有效。)

我将在下一步中将此值<x2>称为MID(<x2>,{1,2,3},1)

<x2>实质上将<x2>(一个3个字符的字符串)转换为3个字符串的数组,每个字符串长1个字符。换句话说,如果"1-2"是{例},MID(<x2>,{1,2,3},1),则表示{"1","-","2"}MID(<x2>,{1,2,3},1)。有必要将3个字符的字符串转换为1x3个单个字符数组,以便单独分析每个字符。

我将在下一步中将<x3>称为<x3>+0

<x3>似乎只是一个简单的步骤,但这里有很多事情要做。请注意,+0仍然是字符串的数组,而不是数字(即使它们看起来像数字)。 #VALUE!会将所有看起来像数字的字符串转换为数字,并将 don&#t; 看起来像数字的所有字符串转换为错误值。 (在这种情况下,{"1","-","2"}+0。)

坚持使用相同的示例,{1,#VALUE!,2}将等于<x3>+0

我将在下一步中将<x4>称为MATCH(FALSE,ISNUMBER(<x4>),0)

<x4>返回MATCH(FALSE,ISNUMBER({1,#VALUE!,2}),0)的第一个索引,其中不是一个数字。这里的想法是找到第一个非数字的索引,然后包括该索引的所有内容(减一)。

坚持使用我们的相同示例,2将返回{1,#VALUE!,2},因为MATCH(FALSE,ISNUMBER(<x4>),0)中的第二个索引是第一个不是数字的索引。

我将在下一步中将<x5>称为<x4>

<x5>中的所有值都可能是数字,在这种情况下IFERROR(<x5>,4)会返回错误,因为它无法找到非数字的匹配项。 4解决了这个问题。如果<x5>中的所有值都是数字,则返回值4。返回AP#的原因是因为我们基本上是说AP#之后的所有3个字符都是数字,所以我们之后的第一个字符 考虑之后IFERROR(<x5>,4)是第四个索引。

我将在下一步中将<x6>称为<x6>+2

(<x6>-1)+3似乎是一个奇怪的计算,它是,所以我会以不同的方式编写它会更有意义:<x6>

请记住AP#在此处所代表的内容: {{1}之后的第一个非数字的索引,显示在3个字符的字符串中}。因此,<x6>-1AP#之后要包含的字符数。

现在,为什么要加3?在(<x6>-1)+3本身中包含3个字符需要AP#。这将在下一步有意义。

我将在下一步中将<x6>+2称为<x7>

MID(A1,FIND(AP#,A1),<x7>)返回字符串A1的一部分,从A中的AP#开头,以及<x7>个字符。 <x7>有多大?但是,AP#代码中有许多数字加上3.(同样,我们必须添加3以在计算中包含3个AP#个字符。)

这是整个计算。

考虑到这一点,您可能希望在整个计算周围包含IFERROR,以处理在字符串中找不到AP#的情况,例如类似的东西:

= IFERROR(MID(A1,FIND("AP#",A1),IFERROR(MATCH(FALSE,
  ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,3),{1,2,3},1)+0),0),4)+2),"no match")

但真的是你的电话。我不确定这是否有必要。

答案 1 :(得分:2)

考虑以下用户定义函数:

Public Function FindAPcode(s As String) As String
    Dim L As Long, CH As String, i As Long, j As Long

    FindAPcode = ""
    L = Len(s)
    If L = 0 Then Exit Function
    j = InStr(1, s, "AP#") + 3
    If j = 3 Then Exit Function
    FindAPcode = "AP#"

    For i = j To L
        CH = Mid(s, i, 1)
        If IsNumeric(CH) Then
            FindAPcode = FindAPcode & CH
        Else
            Exit Function
        End If
     Next i
End Function

enter image description here

用户定义函数(UDF)非常易于安装和使用:

  1. ALT-F11调出VBE窗口
  2. ALT-I ALT-M打开了一个新模块
  3. 粘贴内容并关闭VBE窗口
  4. 如果保存工作簿,UDF将随之保存。 如果您在2003年之后使用的是Excel版本,则必须保存 该文件为.xlsm而不是.xlsx

    删除UDF:

    1. 按上述方式调出VBE窗口
    2. 清除代码
    3. 关闭VBE窗口
    4. 从Excel使用UDF:

      = myfunction的(A1)

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

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

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

      有关UDF的详细信息,请参阅:

      http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx

      必须启用宏才能使其生效!