Почему работает только один из этих двух смайловых макросов для создания бордюр? - PullRequest
0 голосов
/ 16 января 2020

У меня есть таблица без границ. Я хочу создать границы для всех ячеек, в которых заголовки строк.

Я делаю это с помощью макроса.

Sub BorderTable()
    Dim r As Range
    Set r = RangeTitelsAxisX
    r.Borders.LineStyle = xlContinuous 'a1
    r.Borders.Weight = xlMedium        'a2
End sub   

Этот макрос работает. Но следующий макрос завершается с ошибкой

«Ошибка выполнения 424« Требуется объект »»

Sub BorderTable()
    Dim r As Range
    Set r = RangeTitelsAxisX
    BoldBorderAllCellOfRAnge (r) 'b
End Sub

И для меня эти 2 макроса эквивалентны. (Я заменяю только 21, a2 на b, и вы можете видеть выше, что b = a1, a2

Private Sub BoldBorderAllCellOfRAnge(r As Range)
    r.Borders.LineStyle = xlContinuous
    r.Borders.Weight = xlMedium 'xlThick
End Sub



Function RangeTitelsAxisX() As Range
    Range("B3").Select
    Range(Selection, Selection.End(xlDown)).Select
    Set RangeTitelsAxisX = Selection
End Function  

Почему не работает второй способ сделать макрос?

1 Ответ

3 голосов
/ 16 января 2020
 BoldBorderAllCellOfRAnge (r)

Это вызывает BoldBorderAllCellOfRAnge, но передаваемый аргумент не является объектом.

(r) в качестве аргумента означает "let-coerce r в значение, затем передайте это значение к вызываемой процедуре "- не оказывает никакого влияния в данном конкретном случае, но обратите внимание, что это фактически устанавливает значение ByVal, поскольку вызывающий код не содержит ссылку (локальную переменную) на результат этого выражения.

Обратите внимание на пробел между BoldBorderAllCellOfRAnge и (r): это VBE, сообщающий вам, что скобки являются частью аргумента , а не вызовом процедуры (т.е. они не разделяют запятый список аргументов)

Это будет синтаксическая ошибка времени компиляции:

BoldBorderAllCellOfRAnge (r, 42)

Поскольку выражение (r, 42) не может быть оценено, оно ничего не значит для VBA.

r, являющийся Range объектом, let-принуждение неявно вызывает его скрытый [_Default] член, который в этом случае возвращает 2D-вариантный массив - BoldBorderAllCellOfRAnge получает этот 2D-вариантный массив и говорит "чувак, я спросил для объекта reference », следовательно,« объект требуется ».

Итак, чтобы исправить ошибку, просто удалите скобки:

 BoldBorderAllCellOfRAnge r

В качестве альтернативы введите ключевое слово Call (Rubberduck будет пометить его как устаревший и предлагают полностью удалить его ):

 Call BoldBorderAllCellOfRAnge(r)

Обратите внимание, что VBE больше не будет принудительно заполнять пробел между именем процедуры и ( открывающая теперь скобка, и это означает, что (...) теперь разграничивает список аргументов, а не заставляет вычислять выражение.


Об этой функции:

Function RangeTitelsAxisX() As Range
    Range("B3").Select
    Range(Selection, Selection.End(xlDown)).Select
    Set RangeTitelsAxisX = Selection
End Function

Попробуйте по возможности избегать Range.Select. Это должно быть эквивалентно и гораздо более эффективно - обратите внимание, что функция неявно опубликована c, но должна быть закрытой, если она когда-либо вызывается другими процедурами в том же модуле.

Кроме того, неквалифицированный вызов Range равен , неявно ссылаясь на ActiveSheet, если этот код записан где-либо, кроме кода кода модуля рабочего листа:

Private Function RangeTitelsAxisX() As Range
    Set RangeTitelsAxisX = ActiveSheet.Range("B3").End(xlDown)
End Function

Если код записанный в модуле рабочего листа, вы захотите это так:

Private Function RangeTitelsAxisX() As Range
    Set RangeTitelsAxisX = Me.Range("B3").End(xlDown)
End Function

Всегда квалифицируйте Range вызовы с правильным Worksheet объектом: вы избежите множества ошибок.

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