Ошибка 91 в функции, но не в подобном сабе - PullRequest
1 голос
/ 21 мая 2019

Я хочу преобразовать строку в переменную диапазона, которую я буду использовать в другом месте. Моей первой идеей было создать функцию преобразования текста в диапазон и избежать повторного использования синтаксиса. Я знаю, что это, вероятно, очень простой вопрос, но я не мог понять это.

Моя первая попытка была такая. Он печатает «косвенно», где я хочу (это был всего лишь тест), но, запуская макрос шаг за шагом, я вижу, что в то время возникает ошибка 91 для «выхода» из функции.

Dim rng As Range
rng = TXT2RNG(Range("A1").Value)

'This is the function, located in Modulo1
'Function TXT2RNG(text As String) As Range
'Set TXT2RNG = Range(text)
'TXT2RNG.Value = "indirect"
'End Function
End Sub

Я пытался сделать то же самое, но без функции, и она работает, как я ожидал.

Dim rng As Range
Set rng = Range(Range("A2").Value)
'Set rng = Range(Range("A1").Value)
rng.Value = "direct"
End Sub

Резюме: второй код работает как обходной путь, но я хочу знать, почему первый код не может извлечь из него уроки и использовать подобные структуры в будущем. Спасибо

Ответы [ 2 ]

0 голосов
/ 21 мая 2019

По сути, вы просто пропускаете Set при назначении результата функции для вашей переменной - вы делаете это правильно в вашем direct примере.
Всякий раз, когда вы имеете дело с объектами (например,рабочий лист, диапазон), вам нужно использовать Set при назначении переменной.Хорошее объяснение можно найти по адресу https://stackoverflow.com/a/18928737/7599798

. Пропуск Set приведет к ошибке 91 при назначении его переменной объекта.Однако, если вы объявите переменную rng как Variant, вы не получите ошибку времени выполнения.Вместо этого VBA будет использовать так называемое свойство по умолчанию , для Range это Value, так что в результате вы получите содержимое Range в своей переменной (" косвенный *"1018 * "в вашем примере).Это причина использовать тип данных Variant только в случае крайней необходимости.

При этом следует учитывать как минимум 2 проблемы, о которых следует позаботиться:

  • при использованииRange -функция, как и вы, относится к ActiveSheet, то есть к листу, который в данный момент имеет фокус.При кодировании это не всегда то, что вы хотите, поэтому подумайте, нужно ли вам утвердить свою функцию.Вы действительно должны уделить время, чтобы прочитать ответы Как избежать использования Select в Excel VBA для понимания.
  • Вам следует подумать о том, что должно произойти, если текст, передаваемый вашей функции, не содержит действительного диапазона адресов.В настоящее время вы получите ошибку времени выполнения (1004).Обработка ошибок в VBA выполняется с помощью On Error -статементов.Вам следует избегать On Error Resume Next.

Вы можете изменить свою функцию на:

Function TXT2RNG(ws as Worksheet, text As String) As Range
    On Error Goto InvalidRange
    Set TXT2RNG = ws.Range(text)
    ' TXT2RNG.Value = "indirect"
    Exit Function
InvalidRange:
    ' Think about what to do here, show a message, simply ignore it...
    Set TXT2RNG = Nothing
End Function

И вызов будет

Dim rng as Range, address as string
address = Range("A1").Value
Set rng = TXT2RNG(activeSheet, address)
if not rng is Nothing then
    (...)
0 голосов
/ 21 мая 2019

Добро пожаловать в переполнение стека.

Проходя по своему коду, вы не объявляете «текст» как что-либо.

Если вы используете функцию «Часы», вы увидите, что это пустая строка

enter image description here

Полагаю, вам нужна функция, которая вытягивает диапазон, а затем вторая функция, которая вытягивает строку этого. A Private Sub намного лучше Смотрите этот ответ https://stackoverflow.com/a/2913690/2463166

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