汤姆的工作表包含约20,000个充满文本数据的单元格。他需要从这些单元格中提取特定的文本模式。模式是#,其中每个#是一个数字。该图案不会出现在每个单元格的固定位置。汤姆想知道是否有一种方法可以提取所需的信息。

有几种方法可以解决此问题,而您所需的正确解决方案将取决于正在使用的数据的特征。如果您知道数据中唯一会出现破折号的位置是在模式内,则可以使用以下公式来消除破折号的存在:

=MID(A1,FIND("-",A1)-2,8)

这会找到破折号,然后从破折号左侧的两个字符开始抓取八个字符。如果文本中其他地方有破折号,或者有可能包含非数字的“模式”(例如12-34B32),并且您希望将其排除在外,则这显然不起作用。在这种情况下,您将需要一个更复杂的公式:

=IF(ISERROR(INT(MID(A1, FIND("-", A1, 1)-2, 2)) & INT(MID( A1, FIND("-", A1, 1)+1, 5))), "", MID(A1, FIND("-", A1)-2, 8))

这包括一个错误检查组件,该组件可查找破折号之前和破折号之后的字符是否包含数字以外的任何字符。如果他们这样做,则什么也不返回。

这些公式化方法不做的一件事是处理在同一单元格中可能出现多个模式的情况。在这种情况下,宏是最好的方法。下面将提取有效的模式,并将其放置在名为“结果”的新工作表中。

Sub ExtractPattern()

On Error Resume Next     Set SourceSheet = ActiveSheet     Set TargetSheet = ActiveWorkbook.Sheets("Results")

If Err = 0 Then         Worksheets("Results").Delete     End If     Worksheets.Add     ActiveSheet.Name = "Results"

Set TargetSheet = ActiveSheet     Cells(1, 1).Value = "Found Codes"

Cells(1, 1).Font.Bold = True     iTargetRow = 2

SourceSheet.Select     Selection.SpecialCells(xlCellTypeLastCell).Select     Range(Selection, Cells(1)).Select

For Each c In Selection.Cells         If c.Value Like "##-#####" Then             sRaw = c.Value             iPos = InStr(sRaw, "-")

Do While iPos > 0                 If iPos < 3 Then                     sRaw = "  " & sRaw                     iPos = iPos + 2                 End If                 sTemp = Mid(sRaw, iPos - 2, 8)

sRaw = Mid(sRaw, iPos + 6, Len(sRaw))

If sTemp Like "##-#####" Then                     TargetSheet.Cells(iTargetRow, 1) = sTemp                     iTargetRow = iTargetRow + 1                 Else                     sRaw = Mid(sTemp, 4, 5) & sRaw                 End If                 iPos = InStr(sRaw, "-")

Loop         End If     Next c End Sub

请注意,宏在两个地方使用了Like函数。第一个实例确定模式是否出现在单元中的任何位置,第二个实例用于确定提取的字符是否与所需的模式完全匹配。

注意:

如果您想知道如何使用此页面(或_ExcelTips_网站上的任何其他页面)中描述的宏,我准备了一个特殊页面,其中包含有用的信息。

_ExcelTips_是您进行经济高效的Microsoft Excel培训的来源。

本技巧(7348)适用于Microsoft Excel 97、2000、2002和2003。可以在以下功能区中为Excel的功能区界面(Excel 2007及更高版本)找到本技巧的版本: