2008-11-11 3 views
5

скажем, у меня есть распространение листов Excel, как показано ниже:Как вернуть диапазон ячеек в VBA без использования цикла?

 
col1 col2 
------------ 
dog1 dog 
dog2 dog 
dog3 dog 
dog4 dog 
cat1 cat 
cat2 cat 
cat3 cat 

Я хочу вернуть диапазон ячеек (dog1, dog2, dog3, dog4) или (cat1, cat2, Cat3) на основе либо «собаки "или" cat "

Я знаю, что я могу сделать цикл, чтобы проверять один за другим, но есть ли какой-либо другой метод в VBA, чтобы я мог« фильтровать »результат одним выстрелом?

Возможно, Range.Find (XXX) может помочь, но я вижу только примеры только для одной ячейки, а не для диапазона ячеек.

Пожалуйста, советы

С уважением

+0

Пример, который вы опубликовали, выглядит очень странно, пожалуйста, измените его, чтобы он был читабельным. – schnaader 2008-11-11 19:36:09

+0

Это не проблема с пробелом. Он использует странный набор символов или что-то в этом роде. – 2008-11-11 19:41:22

ответ

0

Благодаря DJ.

Это решение FindAll по-прежнему использует цикл VBA для выполнения действий.

Я пытаюсь найти способ без использования петли пользовательского уровня для фильтрации диапазона в excel VBA.

Здесь я нашел решение. он использует превосходный встроенный движок для выполнения этой работы.

(1) использовать worksheetfunction.CountIf ("Кошка"), чтобы получить отсчет "кошки" клеток

(2) использовать .find ("кошки"), чтобы получить первую строку «кошки "

с подсчетом строк и первого ряда, я могу получить диапазон« кот ».

Хорошая часть этого решения: отсутствие петли пользовательского уровня, это может улучшить производительность, если диапазон большой.

0

Excel поддерживает протокол ODBC. Я знаю, что вы можете подключиться к электронной таблице Excel из базы данных Access и запросить ее. Я этого не делал, но, возможно, есть способ запросить электронную таблицу, используя ODBC изнутри Excel.

0

Если вы используете старую машину veeeery или у вас есть рабочий лист XL2007 с базиллионными рядами, цикл будет достаточно быстрым. Честное слово!

Не доверяйте мне? Посмотри на это. Я заполнил ряд миллиона строк со случайными буквами, используя это:

=CHAR(RANDBETWEEN(65,90)) 

Тогда я написал эту функцию, и назвал его из диапазона с 26 ячейками с помощью Control-Shift-Enter:

=TRANSPOSE(UniqueChars(A1:A1000000)) 

Вот не-очень-оптимизировал функции VBA Я взломан в течение нескольких минут:

Option Explicit 

Public Function UniqueChars(rng As Range) 

Dim dict As New Dictionary 
Dim vals 
Dim row As Long 
Dim started As Single 

    started = Timer 

    vals = rng.Value2 

    For row = LBound(vals, 1) To UBound(vals, 1) 
     If dict.Exists(vals(row, 1)) Then 
     Else 
      dict.Add vals(row, 1), vals(row, 1) 
     End If 
    Next 

    UniqueChars = dict.Items 

    Debug.Print Timer - started 

End Function 

на моем годовалого Core 2 Duo T7300 (2 ГГц) ноутбук потребовалось 0,58 сек.

1

Забыл еще одну особенность XL2007: расширенная фильтрация.Если вы хотите его в VBA, я получил это из записанного макроса:

Range("A1:A1000000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:= Range("F1"), Unique:=True 

Я засек около 0,35 сек ...

Правда, не так много пользы, если вы не имеете 2007.

2

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

Sub GetRange() 
Dim cn As Object 
Dim rs As Object 
Dim strcn, strFile, strPos1, strPos2 

    Set cn = CreateObject("ADODB.Connection") 
    Set rs = CreateObject("ADODB.Recordset") 

    strFile = ActiveWorkbook.FullName 

    strcn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ 
    & strFile & ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';" 

    cn.Open strcn 

    rs.Open "SELECT * FROM [Sheet1$]", cn, 3 'adOpenStatic' 

    rs.Find "Col2='cat'" 
    strPos1 = rs.AbsolutePosition + 1 
    rs.MoveLast 
    If Trim(rs!Col2 & "") <> "cat" Then 
     rs.Find "Col2='cat'", , -1 'adSearchBackward' 
     strPos2 = rs.AbsolutePosition + 1 
    Else 
     strPos2 = rs.AbsolutePosition + 1 
    End If 
    Range("A" & strPos1, "B" & strPos2).Select 
End Sub 
Смежные вопросы