Форум программистов, компьютерный форум, киберфорум
Наши страницы
VBA
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/10: Рейтинг темы: голосов - 10, средняя оценка - 5.00
Babylizard
0 / 0 / 0
Регистрация: 12.12.2012
Сообщений: 4
1

Не срабатывает метод FindNext

12.12.2012, 13:42. Просмотров 1833. Ответов 7
Метки нет (Все метки)

Добрый!
возникла задача создать функцию наподобие ВПР, но для множества критериев. Функция СУММЕСЛИМН не подходит, т.к. подставлять должно текстовые значения.
я написал функцию, но в ней не срабатывает метод FindNext. Если строку с FindNext закомментировать, то функция найдет первое значение и успокоится. Если оставить этот метод, то функция выдает "#ЗНАЧ!"

FindArray - вся область поиска
ResultC - столбец с данными к выводу
Условия вписываются в ParamArray в порядке условие1, столбец_для_поиска1, условие2 и т.п.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Public Function ВПРДЛЯМН(ByVal FindArray As Range, ResultC As Integer, ParamArray Conds() As Variant)
 
Dim iFndRng As Range
Dim iFndRw As Long
Dim Condn As Integer
Dim Str1, Str2 As String
Dim Check As Boolean
Dim firstAddress As String
Dim TextToFind As String
 
TextToFind = Trim(Conds(0)) 
Set iFndRng = FindArray.Columns(Conds(1)).Find(TextToFind)
If Not iFndRng Is Nothing Then
    If UBound(Conds) > 1 Then 
        firstAddress = iFndRng.Address
        Do
            iFndRw = iFndRng.Row
                For Condn = 2 To UBound(Conds) Step 2
                Check = True
                    Str1 = Conds(Condn)
                    Str2 = FindArray.Cells(iFndRw, Conds(Condn + 1))
                    If StrComp(Str1, Str2, 1) <> 0 Then
                        Check = False
                        Exit For
                    End If
                Next Condn
            Set iFndRng = FindArray.Columns(Conds(1)).FindNext(iFndRng)
        Loop While iFndRng.Address <> firstAddress And Not Check
        If Check = False Then
           ВПРДЛЯМН = Nothing
        Else
           ВПРДЛЯМН = FindArray.Cells(iFndRng.Row, ResultC)
        End If
    End If
End If
End Function
подскажите, плз, как сделать, чтобы заработало?
Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.12.2012, 13:42
Ответы с готовыми решениями:

Использование метода FindNext
Всем доброго времени суток! Помогите с одной проблемой в Excel-е. На странице...

.FindNext находит значение по условию другого Find
Использую .Find дважды в цикл, каждый раз ищу разную переменную. Sub...

Как сделать, чтобы FindNext заканчивал поиск на последнем элементе?
Есть столбец, в котором некоторое значение повторяются, нужно выбрать по...

Как корректно работает FindNext (ищется только первое совпадение)
Доброе время суток. Подскажите, пожалуйста. Есть два листа с данными. На...

Не срабатывает метод
Есть класс public class barrier { public int position =...

7
SlavaRus
1091 / 205 / 29
Регистрация: 15.03.2010
Сообщений: 641
12.12.2012, 14:35 2
ResultC - столбец с данными к выводу
То есть функция возвращает массив значений? Если так, то ее надо вносить в лист массивом.
0
Babylizard
0 / 0 / 0
Регистрация: 12.12.2012
Сообщений: 4
12.12.2012, 14:42  [ТС] 3
Нет, столбец ResultC задается просто в виде цифры как в ВПР. Используется для того, чтобы функция подставляла значение из ячейки(строка_совпадения, столбец_ResultC)е
0
SlavaRus
1091 / 205 / 29
Регистрация: 15.03.2010
Сообщений: 641
12.12.2012, 15:06 4
Из справки
Continues a search that was begun with the Find method.
FindNext продолжает искать, что начато Find.
0
Babylizard
0 / 0 / 0
Регистрация: 12.12.2012
Сообщений: 4
12.12.2012, 15:20  [ТС] 5
Цитата Сообщение от Babylizard Посмотреть сообщение
Visual Basic
1
Set iFndRng = FindArray.Columns(Conds(1)).Find(TextToFind)
Спасибо!
на строке 13 первый вызов метода Find с поиском первого условия.
больше этот метод не используется.
на строке 28 используется метод FindNext. Он используется в цикле до тех пор, пока не наткнется на полное совпадение всех условий или на самую первую найденную ячейку. И на этом методе функция спотыкается.
0
Казанский
14135 / 5839 / 1530
Регистрация: 24.09.2011
Сообщений: 9,163
12.12.2012, 19:13 6
Цитирую себя с другого форума
Казанский
18.04.2012, 14:32
Проверил в 2007 - действительно, в UDF работает Find, но не работает FindNext
То есть если эту функцию вызывать из Sub (макроса) - она будет работать, а как функция листа - нет.
(такой финт - из функции листа вызвать Sub, а из Sub эту функцию - не проходит )
Используйте Find - по сравнению с FindNext надо всего лишь один аргумент дописать:
Visual Basic
1
            Set iFndRng = FindArray.Columns(Conds(1)).Find(TextToFind, iFndRng)
Между прочим, в Excel 2000 (совместимость с которым я стараюсь сохранять в своих проектах) в функциях листа не работает и метод Find. Но выход есть - использовать Application.Match (ПОИСКПОЗ) или перебирать ячейки в цикле.
2
Babylizard
0 / 0 / 0
Регистрация: 12.12.2012
Сообщений: 4
13.12.2012, 13:06  [ТС] 7
Да, помогло, Спасибо!
Если кому нужно, выкладываю работающий код функции ВПР для множества аргументов
Кликните здесь для просмотра всего текста

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Public Function ВПРДЛЯМН(ByVal FindArray As Range, ResultC As Integer, ParamArray Conds() As Variant)
 
' функция поиска значения по нескольким условиям. Аргументы функции:
' ВПРДЛЯМН(Область_поиска, номер_столбца_с_возвращаемыми_данными, Условие1, номер_столбца_для_сравнения1, Условие2, номер_столбца_для_сравнения2 ... и т.п.)
 
Dim iFndRng As Range
Dim iFndRw As Long
Dim Condn As Integer
Dim TextToFind, Str1, Str2, firstAddress As String
Dim Check As Boolean
 
TextToFind = Trim(Conds(0)) 'убираем лишние пробелы
Set iFndRng = FindArray.Columns(Conds(1)).Find(TextToFind) 'ищем первое совпадение для первого условия
If Not iFndRng Is Nothing Then 'если нашли
    If UBound(Conds) > 1 Then 'если есть другие условия
        firstAddress = iFndRng.Address
        Do
            iFndRw = iFndRng.Row
                For Condn = 2 To UBound(Conds) Step 2 'проверяем каждое условие
                Check = True
                    Str1 = Conds(Condn)
                    Str2 = FindArray.Cells(iFndRw, Conds(Condn + 1))
                    If StrComp(Str1, Str2, 1) <> 0 Then 'проверка техстовых значений на совпадение
                        Check = False
                        Exit For
                    End If
                Next Condn
            Set iFndRng = FindArray.Columns(Conds(1)).Find(TextToFind, iFndRng) 'ищем следующее совпадение
        Loop While iFndRng.Address <> firstAddress And Not Check 'продолжаем, пока не найдем строку удовлетворяющую всем условиям или уверяемся, что такой строки нет
        If Check = False Then 'если так и не нашли ничего, то возвращаем 0
            ВПРДЛЯМН = "Нет совпадения"
        Else
            ВПРДЛЯМН = FindArray.Cells(iFndRw, ResultC)
        End If
    End If
End If
End Function
0
Скрипт
5444 / 1125 / 49
Регистрация: 15.09.2012
Сообщений: 3,416
13.12.2012, 14:07 8
Babylizard, в VBA нужно указывать тип данных для каждой переменной.

В этому коде:
Visual Basic
1
Dim TextToFind, Str1, Str2, firstAddress As String
у первых трёх переменных тип данных Variant.
0
13.12.2012, 14:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.12.2012, 14:07

Не срабатывает метод .hide()
Здравствуйте друзья.Объясните почему не срабатывает метод .hide(), методом...

Не срабатывает метод nextLine();
Для практики решил написать программу приготовления чая. И всё бы хорошо но...

Не срабатывает метод css
Всем привет, только начинаю осваивать jQuery. Не могу понять, почему не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru