这是我能想到的一种方式。我将分两部分来解释。
PART 1
比方说,我们有一个名为范围Sid
。
这个词Sid
可以以任何一种形式出现,如下图所示。为什么它以=
开头?这已在下面的Part2
中解释。
=Sid '<~~ 1
="Sid" '<~~ 2
=XSid '<~~ 3
=SidX '<~~ 4
=_Sid '<~~ 5
=Sid_ '<~~ 6
=(Sid) '<~~ 7
任何其他情况下,我想将上述的一个子集。现在,在我们的案例中唯一有效的发现是第一个和最后一个,因为我们正在寻找我们的命名范围。
因此,这里有一个快速函数来检查单元格公式是否具有命名范围。我相信它可以在第一和最后的情况下进行更有效的
Function isNamedRangePresent(rng As Range, s As String) As Boolean
Dim sFormula As String
Dim pos1 As Long, pos2 As Long, sLen As Long, i As Long
sFormula = rng.Formula: sLen = Len(sFormula)
pos2 = 1
Do
pos1 = InStr(pos2, sFormula, s) - 1
If pos1 < 1 Then Exit Do
isNamedRangePresent = True
For i = 65 To 90
'~~> A-Z before Sid for example XSid
If UCase(Mid(sFormula, pos1, 1)) = Chr(i) Then
isNamedRangePresent = False
Exit For
End If
Next i
'~~> Check for " for example "Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos1, 1)) = Chr(34) Then isNamedRangePresent = False
'~~> Check for underscore for example _Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos1, 1)) = Chr(95) Then isNamedRangePresent = False
pos2 = pos1 + Len(s) + 1
If pos2 <= sLen Then
For i = 65 To 90
'~~> A-Z after Sid for example SidX
If UCase(Mid(sFormula, pos2, 1)) = Chr(i) Then
isNamedRangePresent = False
Exit For
End If
Next i
'~~> "Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos2, 1)) = Chr(34) Then isNamedRangePresent = False
'~~> _Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos2, 1)) = Chr(95) Then isNamedRangePresent = False
End If
Loop
End Function
所以,Debug.Print isNamedRangePresent(Range("D2"), "Sid")
会给你True
看到这个
PART 2
现在来到.Find
。我发现你在工作表中只搜索一次。由于您可以有很多Sid
字样的场景,因此您不能只有一个.Find
。您将不得不使用.FindNext
。请参阅THIS关于如何使用该链接。我已经在那里解释过了,所以我不会在这里解释这一点。
我们可以通过仅搜索具有公式的单元格来使我们的.Find
更高效。要做到这一点,我们必须使用.SpecialCells(xlCellTypeFormulas)
。这解释了为什么我们在PART1
的例子中有“=”。:)
下面是一个例子(PART1代码在底部加入)
Sub Sample()
Dim oRange As Range, aCell As Range, bCell As Range
Dim oSht As Worksheet
Dim strSearch As String, FoundAt As String
Set oSht = Worksheets("Sheet1")
'~~> Set your range where you need to find - Only Formula Cells
On Error Resume Next
Set oRange = oSht.Cells.SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
If Not oRange Is Nothing Then
strSearch = "Sid"
Set aCell = oRange.Find(What:=strSearch, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Check if the cell has named range
If isNamedRangePresent(aCell, strSearch) Then FoundAt = aCell.Address
Do
Set aCell = oRange.FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
'~~> Check if the cell has named range
If isNamedRangePresent(aCell, strSearch) Then FoundAt = FoundAt & ", " & aCell.Address
Else
Exit Do
End If
Loop
Else
MsgBox SearchString & " not Found"
Exit Sub
End If
If FoundAt = "" Then
MsgBox "The Named Range was not found"
Else
MsgBox "The Named Range has been found these locations: " & FoundAt
End If
End If
End Sub
Function isNamedRangePresent(rng As Range, s As String) As Boolean
Dim sFormula As String
Dim pos1 As Long, pos2 As Long, sLen As Long, i As Long
sFormula = rng.Formula: sLen = Len(sFormula)
pos2 = 1
Do
pos1 = InStr(pos2, sFormula, s) - 1
If pos1 < 1 Then Exit Do
isNamedRangePresent = True
For i = 65 To 90
'~~> A-Z before Sid for example XSid
If UCase(Mid(sFormula, pos1, 1)) = Chr(i) Then
isNamedRangePresent = False
Exit For
End If
Next i
'~~> Check for " for example "Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos1, 1)) = Chr(34) Then isNamedRangePresent = False
'~~> Check for underscore for example _Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos1, 1)) = Chr(95) Then isNamedRangePresent = False
pos2 = pos1 + Len(s) + 1
If pos2 <= sLen Then
For i = 65 To 90
'~~> A-Z after Sid for example SidX
If UCase(Mid(sFormula, pos2, 1)) = Chr(i) Then
isNamedRangePresent = False
Exit For
End If
Next i
'~~> "Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos2, 1)) = Chr(34) Then isNamedRangePresent = False
'~~> _Sid
If isNamedRangePresent = True Then _
If UCase(Mid(sFormula, pos2, 1)) = Chr(95) Then isNamedRangePresent = False
End If
Loop
End Function
输出
唷!!!
+ 1令人惊叹的问题。让我想了很久:) – 2014-11-01 12:27:45
@SiddharthRout,我也是! – 2014-11-01 18:00:21