2015-02-11 2 views
0

Когда я ввожу следующую функцию в качестве UDF в клетке:Считать видимые пробелы с помощью VBA?

Function VisibleBlankCells(r As Range) As Long 
    On Error Resume Next 
    VisibleBlankCells = Intersect(r.SpecialCells(xlCellTypeVisible), r.SpecialCells(xlCellTypeBlanks)).Count 
    On Error GoTo 0 
End Function 

r.SpecialCells(xlCellTypeBlanks) оценивает все клетки в r, как пустой, независимо от того, содержат ли они текст или нет. Что может быть причиной этого и альтернативного решения?

+0

Вы пытались удалить инструкцию 'On Error Resume Next' (shudder), чтобы узнать, есть ли на самом деле ошибка? –

ответ

1

Избавьтесь от On Error Resume Next для начала - вы всегда должны предполагать, что ваш код не удастся и учтет его соответственно, просто игнорируя ошибки, просто усложнит ситуацию.

Во-вторых, нет необходимости использовать Intersect - просто идентифицируйте видимые ячейки напрямую, а затем используйте дополнительный метод SpecialCells() для идентификации пустых дочерних ячеек.

Function VisibleBlankCells(r As Range) As Long 
    VisibleBlankCells = r.SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeBlanks).Count 
End Function 

протестированы с этим:

Sub test_code() 
    Dim r As Range: Set r = Selection 
    Debug.Print CountBlanks(r) 
End Sub 

Function CountBlanks(r As Range) As Long 
    CountBlanks = r.SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeBlanks).Count 
End Function 
+0

Какую версию Excel вы используете? –

+0

2010 ... еще слова bla – EngJon

+0

OP использует Excel 2013. xlCellTypeBlanks возвращает «правильный» адрес и подсчитывает, когда я его выполняю при выборе. Но неправильно, когда я использую его как UDF и выполняю его на r как диапазон – user1283776

0

Этот вид механизма фильтра не будет работать в формате UDF (см this для получения информации о том, что). Я предлагаю зацикливание внутри ОДС:

Public Function VisibleBlankCells(rng As Range) As Long 
    Dim i As Integer 
    Dim cell As Range 
    i = 0 
    For Each cell In rng 
     If cell.Rows.Hidden = False And _ 
     cell.Columns.Hidden = False And _ 
     cell.Value = "" Then 
      i = i + 1 
     End If 
    Next 
    VisibleBlankCells = i 
End Function 

Однако, могут возникнуть некоторые проблемы, связанные с обновлением и функциональности:

  1. Значение ОДС только обновления после редактирования ссылочный диапазона или вызова других пользовательских функций , Поэтому, если вы скрываете столбец или строку в этом диапазоне, он не будет иметь мгновенного эффекта
  2. В (рабочем) выполнении вашего кода в Sub видимые ячейки (также) относятся к еще неиспользуемым ячейкам на вашем листе быть «невидимым». Однако в моем решении все ячейки, которые не содержатся в скрытой строке/столбце, считаются видимыми.
Смежные вопросы