dot*_*t12 3 excel vba excel-formula
一些类似命名的线程,但仍然无法解决我的问题。我需要从 Excel 字符串(在我的场景中为 8 位数字)中提取一个固定长度的 NUMBER 值。为此提供了以下 Excel 公式:
=MID(A1,FIND("--------",SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"0","-"),"1","-"),"2","-"),"3","-"),"4","-"),"5","-"),"6","-"),"7","-"),"8","-"),"9","-")),8)
Run Code Online (Sandbox Code Playgroud)
它可以完成这项工作,但是我对此有两个问题:
最重要的是 - 我正在寻找完全匹配。虽然它确实提取了它找到的第一个 8 位数字序列,但我真的只需要8 位数字,这意味着应该忽略 9 位(或更长)数字(因为 7 位数字已经是)。此公式还从较长的数字中提取前 8 位数字。
不太重要,但只查找以 1 开头的数字会很好。所以,真的只是想提取这个:1??????? 作为数值。因此,像“一12891212一”或“一12891212一”应该被提取,同时12891212 0A或23456789不应该。
如果合理可行,与 VBA 相比,我更喜欢基于 Excel 公式的方法。任何帮助深表感谢!
这可以通过公式来完成,但这一切都取决于您的 Excel 版本:
1) Excel 2016,你仍然可以使用一个公式:
公式B1:
=IFERROR(MID(A1,MAX((MID(A1,ROW(A$1:INDEX(A:A,LEN(A1))),1)="1")*(ISNUMBER(--MID(A1,ROW(A$1:INDEX(A:A,LEN(A1))),8)))*(NOT(ISNUMBER(--MID(A1,ROW(A$1:INDEX(A:A,LEN(A1)))+8,1))))*(NOT(ISNUMBER(--MID(A1,ROW(A$1:INDEX(A:A,LEN(A1)))-1,1))))*(ROW(A$1:INDEX(A:A,LEN(A1))))),8),"Nothing found")
Run Code Online (Sandbox Code Playgroud)
注意:这是一个数组公式,需要通过CtrlShiftEnter
2) Excel 2019,使用CONCAT和FILTERXML:
公式B1:
=IFERROR(FILTERXML("<t><s>"&CONCAT(IF(ISNUMBER(--MID(A1,ROW(A$1:INDEX(A:A,LEN(A1))),1)),MID(A1,ROW(A$1:INDEX(A:A,LEN(A1))),1),"</s><s>"))&"</s></t>","//s[starts-with(., '1') and string-length(.) =8]"),"Nothing Found")
Run Code Online (Sandbox Code Playgroud)
注意:这是一个数组公式,需要通过CtrlShiftEnter
3) Excel 365,使用前面提到的功能,但包括SEQUENCE:
公式B1:
=IFERROR(FILTERXML("<t><s>"&CONCAT(IF(ISNUMBER(--MID(A1,SEQUENCE(LEN(A1)),1)),MID(A1,SEQUENCE(LEN(A1)),1),"</s><s>"))&"</s></t>","//s[starts-with(., '1') and string-length(.) =8]"),"Nothing Found")
Run Code Online (Sandbox Code Playgroud)
该XPATH公式的一部分,以实际查询的照顾,寻找与“1”开始,是“8”,总长度的字符串。这甚至可以处理像'abc123456789abc12345678abc29876543'这样的字符串返回'12345678'。
如果您喜欢FILTERXML和XPATH,那么您可能会发现这很有趣。
4) VBA:如果你必须使用 VBA,我想 UDF 是一个不错的选择。就像是:
Function GetStr(str As String, pat As String) As String
With CreateObject("vbscript.regexp")
.Pattern = pat
.Global = True
If .Test(str) = True Then
GetStr = .Execute(str)(0).Submatches(0)
Else
GetStr = "Nothing found"
End If
End With
End Function
Run Code Online (Sandbox Code Playgroud)
您可以B1按照=GetStr(A1,"(?:^|\D)(1\d{7})(?:\D|$)"). 这是使用正则表达式。如果您有兴趣并想了解更多信息,那么这对您来说很有趣。
我故意将模式留在 UDF 之外,您可能想要更改它。当前模式可以在这个在线Demo 中看到,引擎将从左到右寻找:
(?: - 第一个非捕获组
^|\D - 起始字符串 ancor 或数字以外的任何内容。) - 关闭第一个非捕获组。( - 第一个捕获组。
1\d{7} - 搜索文字 1 后跟 7 位数字。) - 关闭第一个捕获组。(?: - 第二非捕获组
\D|$ - 除了数字或结束字符串 ancor 以外的任何内容。) - 关闭第二个非捕获组。