Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.10.2010, 21:05   #1
Rimida
 
Регистрация: 26.10.2010
Сообщений: 5
Вопрос VBA: как определить содержится ли в массиве данное значение

Коллеги, помогите оптимизировать макрос.
Использую часто повторяющуюся операцию: ищу среди ячеек одной колонки листа совпадающее значение. Сейчас использую цикл Do While или комбинацию While Wend + If Then с перебором всех ячеек с помощью Cells (i, k):

While i <= dataRows
If CLng(.Cells(i, 9).Value) = EDR Then
Worksheets("Customers").Cells(k, 2).Value = .Cells(i, 11).Value
i = dataRows
End If
i = i + 1
Wend

Но подозреваю, что существует более оптимальный путь. Например, сформировать одномерный массив из значений колонки и затем с помощью какой-то функции (какой?) определить номер ячейки, совпадающей с заданным значением. Есть идеи?

Последний раз редактировалось Rimida; 26.10.2010 в 21:13.
Rimida вне форума Ответить с цитированием
Старый 26.10.2010, 23:56   #2
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

В массиве можно найти соответствие с помощью Match, но совсем недавно, вроде даже на этом форуме, мы выяснили, что простым перебором массива не только быстрее, но и надёжнее получить результат.

Вот, нашёл: http://www.programmersforum.ru/showt...F1%F2%F0%E5%E5

Вообще поиск по листу можно делать с помощью Find - это быстрее, чем перебор ячеек.
Код:
Sub test()
    ' если значение ячейки "А1" не содержится в массиве "B1:B10"
    If [B1:B10].Find([A1], , , xlWhole) Is Nothing Then
        MsgBox """А1"" НЕ содержится в массиве ""B1:B10"""
    Else
        MsgBox """А1"" содержится в массиве ""B1:B10"""
    End If
End Sub
Или такой вариант, вроде как без поиска:
Код:
Sub test1()
    ' если значение ячейки "А1" содержится в массиве "B1:B10"
    If [or(B1:B10=A1)] Then
        MsgBox """А1"" содержится в массиве ""B1:B10"""
    Else
        MsgBox """А1"" НЕ содержится в массиве ""B1:B10"""
    End If
End Sub
Но если перебирать массив, то скорость уже сравнима, а удобств больше - можно легко дополнительные условия отбора добавить.
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 27.10.2010 в 00:10.
Hugo121 вне форума Ответить с цитированием
Старый 27.10.2010, 14:28   #3
Rimida
 
Регистрация: 26.10.2010
Сообщений: 5
По умолчанию

Супер! За метод Find спасибо. Действительно получается быстрее. Ищу ячейку с нужными данными, определяю номер ее строки и провожу необходимые действия с другими ячейками данной строки.
Rimida вне форума Ответить с цитированием
Старый 27.10.2010, 18:21   #4
Rimida
 
Регистрация: 26.10.2010
Сообщений: 5
По умолчанию

Блин, Find не работает :-(
Не могу понять причину.

Цитата:
Dim b
Dim FindCell As Range
Dim Bus As String

b = 5784437
Set FindCell = Worksheets("Checklist").Columns(1). Find(b, LookIn:=xlValues)
If Not FindCell Is Nothing Then
Bus = Worksheets("Checklist").Cells(FindC ell.row, 6).Value
MsgBox FindCell.row & " - " & Bus & " - " & Worksheets("Checklist").Cells(FindC ell.row, 2).Value
Else
Bus = "?"
MsgBox Bus
End If
Заданное значение не находит, хотя оно там точно есть!
Rimida вне форума Ответить с цитированием
Старый 27.10.2010, 18:29   #5
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Добавьте в параметры частичный поиск xlPart - может пробелы мешают.
Вручную через поиск находит это значение?
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 27.10.2010, 19:13   #6
Rimida
 
Регистрация: 26.10.2010
Сообщений: 5
По умолчанию

xlPart не помогает
вручную - находит!
что обидно - сначала в режиме тестирования все заработало, а потом вдруг перестало, причину найти не могу

Последний раз редактировалось Rimida; 27.10.2010 в 19:17.
Rimida вне форума Ответить с цитированием
Старый 27.10.2010, 21:48   #7
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Код рабочий (если убрать два закравшихся пробела), я проверил.
Без примера с ошибкой больше сказать нечего.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 28.10.2010, 14:06   #8
Rimida
 
Регистрация: 26.10.2010
Сообщений: 5
По умолчанию

Может быть проблема в формате данных? На текстовых данных все работает. С числовыми - нет.
ОК, если можно еще вопрос по оптимизации. Теоретически работа с массивом данных проходит быстрее, чем постоянное обращение к ячейкам листа. Соответственно, можно скопировать нужный мне диапазон листа в массив, обработать его, а затем записать обратно. Вопрос: как это сделать эффективнее? Что-то я не могу найти нужный оператор/функцию.
Rimida вне форума Ответить с цитированием
Старый 28.10.2010, 14:19   #9
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

В А1:А3 цифры.
Код:
Option Explicit

Sub test()
Dim a(), i As Long
a = [a1:a3].Value
For i = 1 To UBound(a)
a(i, 1) = a(i, 1) + 1
Next
[b1].Resize(UBound(a, 1), UBound(a, 2)) = a
End Sub
или выгрузка
[b1:b3].Value = a
или
[b1:b3] = a
или, чтоб понять суть:
[b1].Resize(3, 1) = a
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 28.10.2010 в 14:22.
Hugo121 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выборка записей в поле которых содержится значение nuul Lokos БД в Delphi 1 05.08.2010 08:23
Значение содержится в массиве kipish_lp Microsoft Office Excel 4 19.06.2010 11:31
проверить, содержится ли строка в массиве aurora_87 Общие вопросы C/C++ 6 28.12.2008 01:25
Определить является ли данное число совершенным.. Паскаль. Karabas Помощь студентам 6 23.12.2008 21:53
Как определить значение по графику? leonid Microsoft Office Excel 4 27.05.2008 08:48