Отработка Selection
предполагает наличие выбора.Если ничего не выбрано, Selection
равно Nothing
, и доступ к его членам выдает ошибку 91, как вы получаете.
Отработка Selection.Style
требует, чтобы текущий выбор имел свойство Style
, ноSelection
может быть Shape
или Chart
, необязательно Range
ячеек.
Единственный способ убедиться в этом - проверить тип данных Selection
-добавьте это защитное предложение в начало вашего кода, должно исправить это:
If Not TypeOf Selection Is Excel.Range Then Exit Sub
Теперь, когда мы знаем, что мы смотрим на Range
, можно безопасно привести его к этому интерфейсу и покончить скод с поздней привязкой, который разрешается только во время выполнения (и риск ошибки 438 для любой опечатки ... которую Option Explicit
не сможет подобрать):
Dim selectedCells As Range
Set selectedCells = Selection
Теперь я знаюмы обычно предпочитаем положительные условные выражения, но создание пустого условного блока со всей логикой в части Else
не имеет смысла.Инвертируйте это условие и удалите пустой блок - и если вы собираетесь записать значение только для того, чтобы перезаписать его следующим оператором, перейдите сразу ко второму назначению:
If selectedCells.Style <> "Percent" Then
selectedCells.NumberFormat = "_($* #,##0_);_($* (#,##0);_($* ""-""??_);_(@_)"
End If
Тем не менее, поскольку макросс именем «remove decimals» было бы неплохо сначала проверить, что мы смотрим на числовое значение - но мы не можем сделать это для диапазона selectedCells
, нам нужно проверять каждую отдельную ячейку отдельно (потому что selectedCells.Value
- это двумерный вариант массива с любым диапазоном из нескольких ячеек.
Итак, резюмируем:
Public Sub RemoveDecimals()
'bail out if no cells are selected:
If Not TypeOf Selection Is Excel.Range Then Exit Sub
Dim cell As Range
For Each cell In selectedCells
'ignore non-numeric and percentage cells:
If IsNumeric(cell.Value) And cell.Style <> "Percent" Then
cell.NumberFormat = "_($* #,##0_);_($* (#,##0);_($* ""-""??_);_(@_)"
End If
Next
End Sub