Почему я не должен превращать определенные ссылки на объекты в переменную объекта?Каковы руководящие принципы? - PullRequest
0 голосов
/ 21 ноября 2018

Внутри моего цикла (см. Код ниже), почему я НЕ должен превращать ссылку ws.Cells.SpecialCells(xlCellTypeFormulas) в переменную объекта Range?(Основываясь на хороших привычках кодирования, разве мы не должны превращать все ссылки на объекты Range, Worksheet и Workbook в переменные объекта? Независимо от того, используются ли они один или несколько раз?)

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

Sub FormatAllFormulas()
    Dim ws As Worksheet
    Dim wsc As Sheets

    Set wsc = ActiveWorkbook.Worksheets

    For Each ws In wsc
        With ws.Cells.SpecialCells(xlCellTypeFormulas) 
            .Style = "Currency"
            .Font.Bold = True
            .Interior.Color = 4908260
        End With
    Next ws
End Sub

1 Ответ

0 голосов
/ 21 ноября 2018

Вы получаете ссылку на переменную Range - она ​​просто удерживается самим блоком With. 5.4.2.21 спецификации языка объясняет:

Переменная блока With классифицируется как переменная и имеет тот же объявленный тип, что и .

Во время выполнения это происходит следующим образом:

Если типом значения вычисляемого выражения является класс, оно Устанавливает - назначается анонимному С блочная переменная.Затем,выполнен.Послевыполняется, Ничего назначается анонимному С переменной блока .

Функционально этот код из вашего примера ...

For Each ws In wsc
    With ws.Cells.SpecialCells(xlCellTypeFormulas) 
        .Style = "Currency"
        .Font.Bold = True
        .Interior.Color = 4908260
    End With
Next ws

... точно так же, как это:

For Each ws In wsc
    Dim WithBlockVariable As Range
    Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
    WithBlockVariable.Style = "Currency"
    WithBlockVariable.Font.Bold = True
    WithBlockVariable.Interior.Color = 4908260
    Set WithBlockVariable = Nothing
Next ws

Что касается того, что вы должны использовать, это в значительной степени суждение.Как отмечено в комментариях, блок With может быть гораздо более читабельным, чем локальная переменная.Другое соображение заключается в том, что, поскольку ссылка неявная, вы не можете случайно использовать ее после выхода из блока With.Это может быть особенно важно в вашем примере, потому что объявленные переменные всегда имеют область действия процедуры.Это означает, что в расширенном примере вы можете использовать WithBlockVariable вне цикла .Поэтому, если вы не намереваетесь использовать его вне блока, вы также можете сделать его невозможным для использования вне блока.


Последнее, на что следует обратить внимание (и именно здесь люди могут столкнуться с проблемами производительности), это то, что блоки With могут сохранять операции разыменования, если вы неоднократно используете более одного . в выражениях.Например, если вы устанавливаете более одного из свойств в Font:

With ws.Cells(1, 1)
    .Font.Bold = True
    .Font.Color = vbRed
    .Font.Italic = True
End With

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

With ws.Cells(1, 1).Font
    .Bold = True
    .Color = vbRed
    .Italic = True
End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...