Страницы: 1
RSS
Добавления номеров Видимых строк в массив, VBA
 
Добрый день!
Возникла тривиальная задача, но нет идей как решить следующее:
Необходимо получить массив из номеров строк выделенных пользователем, ячейки должны быть видимыми.
Например имеется набор из десяти строк 2 из которых скрыты пусть это будет 3 и 8 строки. Необходимо чтобы в массив попали все видимые
arr = (1,2,4,5,6,7,9,10) .
Подскажите пожалуйста как сделать у меня из идей только перебор циклом каждой строки на состояние видимая или нет, и последовательное заполнение массива, но это очень неоптимальный путь как мне кажется.  
 
Нормальный путь. Можно ещё сначала нажать F5 - Выделить - только видимые ячейки, а потом циклом перебор выделенного.
 
Код
Sub GetVisibleCells()
    Dim i As Long, rng As Range, Cell As Range, arr() As Variant
    If TypeName(Selection) = "Range" Then
        Selection.SpecialCells(xlCellTypeVisible).Select
        Set rng = Selection
        For Each Cell In Selection
            ReDim Preserve arr(0 To i)
            arr(i) = Cell.Row
            i = i + 1
        Next Cell
    End If
    Dim tmp As String
    tmp = Join(arr, ", ")
    MsgBox tmp
End Sub
'Вариант 2
Sub GetVisibleCells2()
    Dim strS As String, rng As Range, Cell As Range, arr As Variant
    If TypeName(Selection) = "Range" Then
        Selection.SpecialCells(xlCellTypeVisible).Select
        Set rng = Selection
        For Each Cell In Selection
            strS = strS & Cell.Row & " "
        Next Cell
        arr = Split(Left(strS, Len(strS) - 1), " ")
    End If
    Dim tmp As String
    tmp = Join(arr, ", ")
    MsgBox tmp
End Sub

Без цикла не придумал варианта.
 
Добрый день! Мне кажется:
  • лучше не менять выделение
  • анализировать нужно строки, а не ячейки
  • переопределение границ массива - дорогая операция

Код
Option Explicit

' Выдает список (через запятую) всех видимых строк диапазона rg.
' Если диапазон имеет несколько областей, то будут выданы номера видимых строк для каждой области (повторения возможны).
Function GetListVisibleRows(ByVal rg As Range)
  Dim i As Long, row As Range, arr()
  ReDim arr(1 To 999)
  For Each row In Selection.SpecialCells(xlCellTypeVisible).Rows
    i = i + 1
    If i > UBound(arr) Then ReDim Preserve arr(1 To UBound(arr) * 2)
    arr(i) = row.row
  Next row
  If i > 0 Then
    ReDim Preserve arr(1 To i)
    GetListVisibleRows = Join(arr, ",")
  End If
End Function

Sub Test()
  Debug.Print GetListVisibleRows(Selection)
End Sub
Владимир
 
sokol92, приветствую!
Отличный вариант, только For Each row In rg.Special… и редим можно сразу на миллион делать, но погоду это не сделает  :D
Цитата
DANIKOLA:Selection.SpecialCells(xlCellTypeVisible).Select : Set rng = Selection : For Each Cell In Selection
простите, но это вообще очень "странный" (мягко говоря) код. Выделяем из выделенного только видимые, присваиваем этот диапазон в переменную, а потом вообще эту переменную не используем. И это уже не говоря об оптимизации…

P.S.: Если вы начинающий, то вопросов нет - хорошая попытка и рабочий (не тестил) вариант  ;)
Изменено: Jack Famous - 16.08.2021 12:00:39
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх