Через некоторое время, чтобы позволить этому утонуть, я думаю, что это не так просто.Прямые ссылки на ячейки могут включать простые ссылки, такие как:
=A1
Но есть случаи, когда вы можете ссылаться на другую ячейку на другом листе, другую открытую книгу и даже другую закрытую книгу.Хотя это затрудняет использование RIGHT
, LEFT
функций или даже FORMULATEXT
для лайков, единственное, что вы можете сделать, это проверить шаблоны.
Любая прямая ссылка на ячейку не может включать какие-либодругие вычисления, означающие, что они должны исключать любого нежелательного оператора (/, *, -, +).Насколько мне известно, это означает, что если мы проверяем ячейку, в которой есть только ОДИН Precedent
, формула НЕ может начинаться с цифры NOR, может ли она заканчиваться цифрами после любого из вышеупомянутых операторов.
Наша лучшая ставка здесь - поместить эти критерии в регулярное выражение.Я ни в коем случае не эксперт по RegEx, но я думаю, что сработает следующее:
"^=.*[A-Z]+\$*\d+$"
- Начало строки -
=
- С последующим любым словом /несловесный символ, 0-n раз
- Конец строки должен состоять из цифр, 1-n раз, перед которыми должны стоять либо буквенные символы верхнего регистра, либо комбинация со знаком доллара (для абсолютных ссылок на ячейки)
Вышеприведенное работает, пока мы включаем проверку только для одного .Precedent
и проверку, не является ли второй символ формулы числовым.Например, пример кода будет выглядеть следующим образом:
Sub FindFormualaType()
Dim rng1 As Range, rng2 As Range, cl As Range
Dim regex As New RegExp
Dim matches As Object
Dim tststr As String
With regex
.Global = True
.Pattern = "^=.*[A-Z]+\$*\d+$"
End With
With Sheet1 'Change to your sheet's codename
Set rng1 = Intersect(.Cells, .Cells.SpecialCells(-4123))
For Each cl In rng1
On Error Resume Next
If cl.Precedents.Count = 1 Then
If Left(cl.Formula, 2) Like "=#" = False Then
Set matches = regex.Execute(cl.Formula)
If matches.Count = 1 Then
If Not rng2 Is Nothing Then
Set rng2 = Union(rng2, cl)
Else
Set rng2 = cl
End If
End If
End If
End If
On Error GoTo 0
Next cl
End With
rng2.Interior.Color = vbGreen
End Sub
Чтобы объяснить некоторые шаги в приведенном выше коде:
Для использования RegExp
Вы должны установить ссылку на него:
Код затем использует .SpecialCells
с xlCellTypeFormulas
(-4123
) и создает объект .Range
через .Intersect
.Поэтому нам не нужно зацикливать все ячейки, чтобы проверить с помощью .HasFormula
(возможно, сэкономить время).
Далее следует цикл по всем ячейкам вэтот недавно созданный объект .Range
и проверьте, если Precendents.Count = 1
.Нам нужно заключить это в On Error Resume Next
, потому что это приведет к ошибке, если прецеденты не найдены, например: формула наподобие ="Hello"
.
Когда счет равен 1, мы проверяемс помощью оператора Like
, если мы можем безопасно выполнить регулярное выражение и проверить соответствие на используемом шаблоне.
Поскольку я бы предпочел выполнить операцию заполнения вОдин раз, я предлагаю создать еще один .Range
объект (rng2) и использовать Union
для установки этого объекта.
Наконец, мы можем использовать что-то вроде rng2.Interior.Color = vbGreen
для окраски всех ячеек, которые имеют прямую ссылку только на одну ячейку.
Надеюсь, что это помогло.Я ни в коем случае не эксперт по RegEx, и, вероятно, это можно сделать проще.
Некоторая справочная информация о том, почему я использовал оператор Like
.Поскольку я хотел быть уверенным, что для ссылки на ячейку вычисления не выполняются, первый символ в уравнении НЕ может быть числовым.В RegEx у вас есть то, что называется "lookahead".Хотя, к сожалению, я не смог заставить выражение работать с VBA (не поддерживается?) И поэтому использовал оператор Like
, чтобы убедиться, что второй символ не является числовым.