#excel #vba #function
#excel #vba #функция
Вопрос:
Я пытаюсь настроить функцию для регулярного выражения, которая возвращает a cell.address
. Он работает на 99%, за исключением того, что, похоже, возвращает значение ячейки test
по сравнению с местоположением ячейки, и я не могу понять это.
Отладка:
В нем говорится Object variable or with block variable not set
, что если я Dim celladdr As Range
но если я прокомментирую это, ошибка изменится на Object doesn't support this property or method
, и я это вижу celladdr = test
.
Затем я попробовал Set celladdr = Range(celladdr.Address)
и получил Object Required
.
Кто-нибудь может указать на ошибку?
Вот некоторый урезанный код: Обратите внимание, я жестко запрограммировал шаблон регулярных выражений, поскольку эта функция работает должным образом, проблема, похоже, в RegExSearch
функции, но я могу добавить больше кода обратно, если это необходимо.
Public Sub TESTING()
Dim celladdr As Range
celladdr = RegExFunc("TEST")
ActiveSheet.celladdr.Select
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RegExFunc(var) As Variant
RegExSearchPattern = RegExPattern(var)
RegExFunc = RegExSearch(RegExSearchPattern)
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RegExPattern(my_string) As Variant
RegExPattern = "([a-z]{4})"
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RegExSearch(strPattern) As Range
Dim regexp As Object
Dim rcell As Range, rng As Range
Dim strInput As String
Set regexp = CreateObject("vbscript.regexp")
Set rng = Range("A1:Z255")
For Each rcell In rng.Cells
If rcell <> "" Then
If strPattern <> "" Then
strInput = rcell.Value
With regexp
.Global = False
.MultiLine = False
.ignoreCase = True
.Pattern = strPattern
End With
If regexp.Test(strInput) Then
MsgBox rcell amp; " Matched in Cell" amp; rcell.Address
Set RegExSearch = Range(rcell.Address)
MsgBox RegExSearch
End If
End If
End If
Next
End Function
Ответ №1:
Были разные экземпляры, в которых вам нужен был Set
объект, и один, в котором a Dim
был необходим. Поскольку вы объявили почти все как вариант, немного сложнее определить разбивку. По моему опыту, лучше всегда специально объявлять переменные в VBA.
Я запустил следующий скорректированный код (добавил несколько наборов, как указано выше), и он работал без каких-либо ошибок декомпиляции или времени выполнения.
Public Sub TESTING()
Dim celladdr As Range
Set celladdr = RegExFunc("TEST")
celladdr.Select
End Sub
Public Function RegExFunc(var As String) As Range
Dim RegExSearchPattern As String
RegExSearchPattern = RegExPattern(var)
Set RegExFunc = RegExSearch(RegExSearchPattern)
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RegExPattern(my_string As String) As String
RegExPattern = "([a-z]{4})"
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RegExSearch(strPattern As String) As Range
Dim regexp As Object
Dim rcell As Range, rng As Range
Dim strInput As String
Set regexp = CreateObject("vbscript.regexp")
Set rng = Range("A1:Z255")
For Each rcell In rng.Cells
If rcell <> "" Then
If strPattern <> "" Then
strInput = rcell.Value
With regexp
.Global = False
.MultiLine = False
.ignoreCase = True
.Pattern = strPattern
End With
If regexp.Test(strInput) Then
MsgBox rcell amp; " Matched in Cell" amp; rcell.Address
Set RegExSearch = Range(rcell.Address)
MsgBox RegExSearch
End If
End If
End If
Next
End Function
Комментарии:
1. Я все еще получаю
Object doesn't support this property or method
при запуске. Я подозреваю, что вы не ввели слово из 4 букв ни в одной ячейке диапазона, чтобы проверить, нужно ли найти результат. Я понимаю, что мне нужно начать объявлять вещи такими, какие они есть, более конкретно, чтобы помочь избежать этого в будущем.2. Я только что попробовал ваше редактирование, и оно сработало! Я собираюсь отправиться домой, завтра мне придется читать глубже, но, спасибо, похоже, это исправлено.
3. Действительно. Я также настроил строку так, чтобы она не была
ActiveSheet
, а только возвращала диапазон.
Ответ №2:
Адрес ячейки — это просто строка; вы не задаете его, просто назначаете его =
.
RegExSearch = rcell.Address
… вернет абсолютный адрес ячейки.
Возможно, вы захотите рассмотреть возможность выхода из For Each rcell In rng.Cells
цикла, если шаблон найден. Похоже, нет смысла продолжать, если вам не нужны адреса ячеек объединения всех совпадающих ячеек.
If regexp.Test(strInput) Then
MsgBox rcell amp; " Matched in Cell" amp; rcell.Address
RegExSearch = rcell.Address
MsgBox RegExSearch
Exit For
End If
Вы устанавливаете идентичные аргументы регулярных выражений внутри цикла. Переместите назначение аргумента над For Each rcell In rng.Cells
циклом.
With regexp
.Global = False
.MultiLine = False
.ignoreCase = True
.Pattern = strPattern
End With
For Each rcell In rng.Cells
Комментарии:
1. Это выдает ошибку в этой строке
Object variable or With block variable not set
. Я пробовал это и раньше, но затем в этой строке произошла ошибка. У меня этоExit Function
было внутриIf Regex Test
инструкции, но я исправлю это после того, как оно заработает. Я не уверен, хочу ли я остановиться на 1-м или последнем результате.2. Объявите функцию правильно.
Public Function RegExSearch(strPattern) As String
илиPublic Function RegExSearch(strPattern)
(последний вариант является вариантом, поэтому он может возвращать либо значение, либо адрес).3. @user11343412 Отличное замечание о том, что диапазон не добавляется друг к другу. Я подумал то же самое, но не обратился к этому в своем ответе. 1 для этого.