Диапазон ограничения загадки - PullRequest
5 голосов
/ 02 ноября 2009

Есть ли какой-то предел для того, что я могу выбрать в диапазоне через VBA? По сути, я обнаружил, что если мне нужно скрыть всю строку в цикле, потребуется много времени, если будет скрыто много строк.

ex) - Скрыть любую строку, которая не имеет значения в столбце A

For i = 1 to 600
    With Range("A" & i)
        If .value = vbEmpty then .EntireRow.Hidden = True
    End With
Next

Более быстрый способ сделать это - создать один диапазон, который ссылается на каждую из этих строк, а затем выполнить один оператор ".entirerow.hidden = true". И да, у меня уже есть application.screenupdating = false.

Проблема, с которой я сталкиваюсь, заключается в том, что, если ссылка на строку для диапазона слишком длинная, она просто не работает.

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

Function GetRows(argsArray() As Long, ParamArray args() As Variant) As Range

    Dim rngs As String
    Dim r

    For Each r In argsArray
        rngs = rngs & "," & r & ":" & r
    Next
    For Each r In args
        rngs = rngs & "," & r & ":" & r
    Next

    rngs = Right(rngs, Len(rngs) - 1)
    Set GetRows = Range(rngs)

End Function
Function dfdfd()

    Dim selList(50) As Long, j As Long
    For i = 1 To 100
        If i Mod 2 = 1 Then
            selList(j) = i
            j = j + 1
        End If
    Next
    selList(50) = 101
    GetRows(selList).Select

End Function

2-я функция "dfdfd" просто используется, чтобы привести пример, когда она выходит из строя. Чтобы увидеть, когда это работает, просто создайте новый массив, скажем, с 5 элементами, и попробуйте это. Это работает.

Окончательное (?) Обновление:

Option Explicit

Public Sub test()
    Dim i As Integer
    Dim t As Long
    Dim nRng As Range

    t = Timer()
    Application.ScreenUpdating = False
    Set nRng = [A1]
    For i = 1 To 6000
        Set nRng = Union(nRng, Range("A" & i))
    Next
    nRng.RowHeight = 0
    'nRng.EntireRow.Hidden = true
    Application.ScreenUpdating = True
    Debug.Print "Union (RowHeight): " & Timer() - t & " seconds"
    'Debug.Print "Union (EntireRow.Hidden): " & Timer() - t & " seconds"
End Sub

Результаты:

Union (высота строки: 0,109375 секунд
Союз (скрытый ряд): 0,625 секунд

Ответы [ 4 ]

6 голосов
/ 02 ноября 2009

Я думаю, что магическая функция, которую вы ищете здесь - это Union (). Он встроен в Excel VBA, так что посмотрите на помощь для этого. Это именно то, что вы ожидаете.

Перебирайте ваши диапазоны, но вместо построения строки создайте многоуровневый диапазон. Затем вы можете выбрать или установить свойства всего объекта одновременно.

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

2 голосов
/ 06 ноября 2009

Небольшое ускорение можно получить, если установить для свойства RowHeight значение 0. В моей системе это происходит вдвое быстрее (на 6000 итераций около 1,17 секунды против 2,09 секунды)

Вы не упомянули, что такое "довольно давно" и какую версию XL вы используете ...

Возможно, ваша проблема частично в том, что ваш код обнаружения строк проверяет строку, которую вы хотите скрыть (?).

Вот мой тестовый код в XL 2003 (закомментируйте одну версию, затем другую):

Option Explicit

Public Sub test()
  Dim i As Integer
  Dim t As Long

  t = Timer()
  Application.ScreenUpdating = False
  For i = 1 To 6000
    With Range("A" & i)
        'If .Value = vbEmpty Then .EntireRow.Hidden = True
        If .Value = vbEmpty Then .RowHeight = 0
    End With
    Next
  Application.ScreenUpdating = True
  Debug.Print Timer() - t & " seconds"
  End Sub
2 голосов
/ 03 ноября 2009

Более быстрый вариант может заключаться в использовании свойства SpecialCells для поиска пробелов и последующего скрытия строк:

Sub HideRows()

    Dim rng As Range

    Set rng = ActiveSheet.Range("A1:A600")
    Set rng = rng.SpecialCells(xlCellTypeBlanks)
    rng.EntireRow.Hidden = True

End Sub

Я думаю, это будет работать только для ячеек в пределах UsedRange.

1 голос
/ 13 октября 2014

Существует ограничение на длину строки. Я только что столкнулся с подобной проблемой и обнаружил, что если текст строки из Диапазон (Txt) больше, чем 255 символов, мой VBA выдает Error.eg. код:

Debug.Print sheet1.Range("R2300,T2300,V2300,R2261,T2261,V2261,R1958,T1958,V1958,R1751,T1751,V1751,R1544,T1544,V1544,R1285,T1285,V1285,R1225,T1225,V1225,R1193,T1193,V1193,R1089,T1089,V1089,R802,T802,V802,R535,T535,V535,R264,T264,V264,R205,T205,V205,R168,T168,V168,R135,T135,V135,R101").Areas.count

выдает ошибку (256 символов в строке), тогда как код

Debug.Print sheet1.Range("R230,T2300,V2300,R2261,T2261,V2261,R1958,T1958,V1958,R1751,T1751,V1751,R1544,T1544,V1544,R1285,T1285,V1285,R1225,T1225,V1225,R1193,T1193,V1193,R1089,T1089,V1089,R802,T802,V802,R535,T535,V535,R264,T264,V264,R205,T205,V205,R168,T168,V168,R135,T135,V135,R101").Areas.count

имеет 255 символов и печатает «46» без ошибок. Количество областей в обоих случаях одинаковое.

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