Найти нужное значение в таблице по условию

Весь MS Office, программирование на Visual Basic for Applications и MS VB

Модератор: Naeel Maqsudov

SAS888
Сообщения: 156
Зарегистрирован: 16 янв 2008, 08:28

Посмотрите пример во вложении. Сделал одну общую функцию "ПБ".
Обратите внимание, что порядок аргументов в функции изменился. Теперь так:
1. Какого по счету проигравшего искать (1-го или 2-го)
2. Диапазон, из которого требуется взять фамилию для поиска.
3. Диапазон для 1-го поиска.
4. Диапазон для 2-го поиска.
5. Диапазон для 3-го поиска (Optipnal).
Причем, диапазон для 3-го поиска в коде функции задан опционально как "Nothing". Поэтому, в случае, если 3-й диапазон поиска не требуется, его можно просто не вводить. А т. к. все аргументы, задаваемые опционально должны вводиться после обязательных, пришлось изменить порядок аргументов. Так, например, сравните заданные аргументы функции в ячейках "J15:J16" и "H15:H16".
Проверяйте...
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Спасибо огромное! Это то что нужно! Я её погоняю на всякие варианты исходов, результат напишу, но поверхностная проверка дала отличный результат! Работает как надо!
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Всё работает пока правильно, значения выдаёт верные... Но проблема возникнет когда я буду формировать протокол соревнований. В конце соревнований в протокол (на отдельный лист) друг за другом копируются все первые страницы листов с сетками поединков. Диапазон этих страниц начинается и заканчивается нечётной строкой листа. В итоге в протоколе первый скопированный диапазон будет начинаться с нечётной строки, а второй - с чётной... и так далее. То есть проблема с функцией возникнет из-за чётности строк. Можно ли, чтобы в функции, чётная и не чётная строка учитывалась относительно просматриваемого диапазона, а не листа? То есть, чтобы функция, после того как нашла искомое значение в диапазоне, - определяла бы его позицию в этом диапазоне, и если позиция нечётная, то отображалось бы значение нижней строки, а если позиция чётная, то отображалось бы значение верхней строки.
SAS888
Сообщения: 156
Зарегистрирован: 16 янв 2008, 08:28

Понял. Поправил. Проверяйте...
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Спасибо огромнейшее! Самое оно! Продолжаю проверку... Пока всё замечательно!
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Работает прекрасно! Ошибок в поиске нужных значений не обнаруживалось! Пытаюсь эту же функцию применить для сеток на 16 и 32 участника, т.к. условия для поиска те же. Но там количество диапазонов для поиска и количество проигравших победителю больше. Как увеличить количество диапазонов для поиска я вроде бы разобрался... В последнем примере (Пример_6) я изменил строки (1-ю, 10-ю и 11-ю):

Код: Выделить всё

1. Function ПБ(flag As Integer, Who As Range, rng1 As Range, rng2 As Range, Optional rng3 As Range = Nothing) As String
10. For i = 1 To 3
11.         Set z = Choose(i, rng1, rng2, rng3)
на:

Код: Выделить всё

1. Function ПБ(flag As Integer, Who As Range, rng1 As Range, rng2 As Range, Optional rng3 As Range = Nothing, Optional rng4 As Range = Nothing, Optional rng5 As Range = Nothing) As String
10. For i = 1 To 5
11.         Set z = Choose(i, rng1, rng2, rng3, rng4, rng5)
Не знаю, насколько верно, но вроде работает (поправьте если я что-то не учёл)... А вот как добавить или изменить "Какого по счету проигравшего искать (1-го, 2-го, 3-го или 4-го)", - я не разобрался... Не могли бы подсказать, что для этого надо изменить или добавить?
SAS888
Сообщения: 156
Зарегистрирован: 16 янв 2008, 08:28

...как добавить или изменить "Какого по счету проигравшего искать (1-го, 2-го, 3-го или 4-го)"
Немного поясню.
В предыдущем варианте функции "ПБ", в цикле по каждому диапазону производилось сравнение "If flag = 1 Then...Else...End If". Поэтому, если аргумент "flag" = 1, то функция вернет 1-го проигравшего. Иначе (flag <>1) - второго. Не зависимо от самого значения аргумента "flag".
В предлагаемом варианте введена переменная "f", которая в цикле сравнивается с заданным аргументом "flag". И, если "f = flag", то присваиваем значению функции удовлетворяющее условиям найденное значение и выходим из цикла. Иначе - игнорируем найденное значение (очищаем строковую переменную "isk"), инкременируем переменную "f" и продолжаем поиск по следующим диапазонам.
Пример во вложении. Проверьте. На более 3-х диапазонах я не проверял...
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Спасибо за подробный ответ! Теперь я понимаю, почему у меня не получилось, сам бы я конечно не додумался бы до такого... Ещё раз спасибо! Начинаю проверку, результат сообщу!
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Всё отлично работает, причём во всех сетках! Только никак не могу понять, чем эта функция конфликтует с макросом на копирование значений диапазонов ячеек, предложенным вами в моей предыдущей теме (http://forum.developing.ru/showthread.p ... 0%BA/page2). Точнее даже не с ним, а с тем что я в него дописал. Для наглядности, пример во вложении. А дописал я строку

Код: Выделить всё

Sheets("Ход поединков").Range("B3:D482").ClearContents
До функции всё копировалось нормально, а теперь с первого копируемого диапазона, вместо значений выдаёт #ЗНАЧ. И главное, почему только с первого, а не со всех диапазонов? Я нашёл два параметра, из-за которых идёт конфликт, но так и не понял - почему?. Первый, - это моя добавленная строка. Если я её убираю, то всё нормально копируется, но приходиться вручную очищать лист перед следующим копированием. Тут, кстати тоже не понятная ситуация, почему, если я убираю строку из макроса и перед копированием очищаю лист вручную, то всё копируется нормально, а если тоже действие произвожу с помощью макроса, то выскакивает этот ляп? Ну а второй параметр, это строка функции

Код: Выделить всё

Application.Volatile
Если её убрать, то копируется нормально. Но без неё формулы функции реагируют только на изменения в диапазонах поиска, что не всегда удобно. В принципе, не обязательно, чтобы формулы реагировали на любые из на листе, но помимо изменений в диапазонах поиска нужно реагирование и на изменения в диапазоне, справа от диапазона с искомым значением.
Почему выскакивает это #ЗНАЧ, из-за чего это происходит, и можно ли это исправить не теряя функциональности, т.е. чтобы и лист очищался перед копированием и формулы реагировали на изменения описанные выше, если допустим убрать строку Application.Volatile или заменить её на другую?
VanBlack
Сообщения: 69
Зарегистрирован: 26 окт 2013, 15:28

Всё отлично работает, причём во всех сетках! Только никак не могу понять, чем эта функция конфликтует с макросом на копирование значений диапазонов ячеек, предложенным вами в моей предыдущей теме (http://forum.developing.ru/showthread.p ... 0%BA/page2). Точнее даже не с ним, а с тем что я в него дописал. Для наглядности, пример во вложении. А дописал я строку

Код: Выделить всё

Sheets("Ход поединков").Range("B3:D482").ClearContents
До функции всё копировалось нормально, а теперь с первого копируемого диапазона, вместо значений выдаёт #ЗНАЧ. И главное, почему только с первого, а не со всех диапазонов? Я нашёл два параметра, из-за которых идёт конфликт, но так и не смог понять - почему. Первый, - это моя добавленная строка. Если я её убираю, то всё нормально копируется, но приходиться вручную очищать лист перед следующим копированием. Тут, кстати тоже не понятная ситуация, почему, если я убираю строку из макроса и перед копированием очищаю лист вручную, то всё копируется нормально, а если тоже действие произвожу с помощью макроса, то выскакивает этот ляп? Ну а второй параметр, это строка функции

Код: Выделить всё

Application.Volatile
Если её убрать, то копируется нормально. Но без неё формулы функции реагируют только на изменения в диапазонах поиска, что не всегда удобно. В принципе, не обязательно, чтобы формулы реагировали на любые изменения на листе, но помимо изменений в диапазонах поиска нужно реагирование и на изменения в диапазоне справа от диапазона искомого значения.
Ответить