我有这样的记录
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的情况下实现这一目标。
答案 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)
返回A1
中AP#
的第一个A1
实例出现在FIND("AP#",A1)
中的字符索引号。
为简单起见,我会在下一步中将<x1>
称为MID(A1,<x1>+3,3)
。
A1
会返回AP#
后面AP#
后面的3个字符。它只返回3个字符,因为从原始问题开始,您说在MID(A1,<x1>+3,999)
之后最多可以显示3个数字。
(快速说明:最初我将公式的这一部分作为999
,但在做出此解释之后,我意识到3
可以缩减为999
。3
仍然可以工作,只是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>-1
是AP#
之后要包含的字符数。
现在,为什么要加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
用户定义函数(UDF)非常易于安装和使用:
如果保存工作簿,UDF将随之保存。 如果您在2003年之后使用的是Excel版本,则必须保存 该文件为.xlsm而不是.xlsx
删除UDF:
从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
必须启用宏才能使其生效!