MS Excel VBA: поиск ячеек с определенным типом формулы - PullRequest
1 голос
/ 22 сентября 2019

Я хочу автоматически найти ячейки, содержащие формулы, являющиеся простой ссылкой.Например:

=D20 или ='Sheet1'!D20.

Цель состоит в том, чтобы я хотел автоматически раскрасить эти ячейки цветом.

Есть ли способ в VBA для поиска типов формул?

Ответы [ 3 ]

2 голосов
/ 22 сентября 2019

Через некоторое время, чтобы позволить этому утонуть, я думаю, что это не так просто.Прямые ссылки на ячейки могут включать простые ссылки, такие как:

=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Вы должны установить ссылку на него:

    enter image description here

  • Код затем использует .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, чтобы убедиться, что второй символ не является числовым.

1 голос
/ 22 сентября 2019

Используйте функцию FORMULATEXT() в Conditional Formatting для автоматического выделения ячеек, содержащих вашу формулу.См. Ниже формулу для Conditional Formatting

=OR(FORMULATEXT(A1)="=Sheet1!D20",FORMULATEXT(A1)="=D20")

enter image description here

1 голос
/ 22 сентября 2019

Создать цикл для прохождения всех ячеек с формулами (.HasFormula), получить текст формулы ячейки в виде строки, взять весь текст формула, кроме первого символа (RIGHT (text, (LEN (text) - 1))), а затем проверьте, является ли эта строка допустимым диапазоном.Если это не так, то в ячейке есть больше, чем «просто ссылка».Удачи в выяснении кода :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...