Быстрые отборы в списках типовых конфигураций

Несмотря на растущую популярность типовых программ на основе управляемых форм, всё ещё распространены программы на основе Толстого клиента. В основе типовых программ основные объекты (Документы и Справочники) представлены в форме списков (Динамические списки). Используемые формы хоть и снабжены универсальным отбором, но оперативный доступ к поиску нужных данных несколько затруднен. Для поиска нужного документа или элемента справочника, даже в форме Списка для подбора приходится производить множество манипуляций…

Для документов чрезвычайно удобным оказывается динамический интервал даты документа (Последние x дней для Начала интервала). Одновременно самым распространенным критерием поиска документа является ввод последних трех цифр номера, подразделения документа, Склада и т.п. Для своих нужд добавил в большинство используемых списков документов дополнительные поля быстрого отбора (чего и вам советую). Поля оптимизированы для самых массовых критериев поиска. А чтобы потратить минимум труда на добавление, использовал командное добавление полей и унифицированный код для добавления. Код позволяет добавлять и прятать поля быстрого отбора.

Следует учесть несколько моментов:

  • Поиск будет более быстрым, если для отбираемого реквизита будет существовать Индекс (настройка в конфигураторе).
  • И, разумеется, Поле должно быть выведено на форму списка.
  • Попадались случаи разного наименования Поля списка на форме (следует проверять).
  • Отбор числового значения (например, СуммаДокумента) можно настроить и как поиск точного значения, и как диапазон 1% разброса (или свой алгоритм).
  • На форме умещаются от 4 до 5 полей быстрого отбора (в одну строку и на развернутой форме).
  • При первоначальном заполнении, Форма списка оказывается в промежуточном размере, как следствие могут не все элементы расположатся оптимально. Лечится сворачиваем и разворачиваем быстрого отбора.
  • Форму списка снабжают кнопкой Сворачивания/Разворачивания Быстрого отбора.
  • После редактирования значений отбора, рекомендуется переносить фокус на сам список (для ускорения выбора нужного элемента).

Данная методика применима для большинства типовых конфигураций 1С на основе Толстого клиента (УТ_10, БП_2, УНФ, и др.).

Немного о структуре доработок:

ПриОткрытии() — автозапуск добавления быстрого отбора

БыстрыйОтборДок();// Подключаем быстрыйОтбор (или выключаем)

ПБОПриИзменении(Элемент) // Отработка изменения значения отбора (одна на всех)

 

Перем мОтбора;//Признак включения Быстрого отбора
Процедура ПриОткрытии()
БыстрыйОтборДок();//НВЮ/ Подключаем быстрыйОтбор
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.тНомер;//Активируем быстрый поиск по Номеру
КонецПроцедуры
//НВЮ/ Открыть быстрый отбор.
//Процедура ПриОткрытии()
//  БыстрыйОтборДок();// Подключаем быстрыйОтбор
Процедура БыстрыйОтборДок(ВклОтбора=Истина)
//Параметры  (Начальное размещение полей)
оВысота = 19;
оВерх   = 28;
оЛево   = 6;
СпПБО   = Новый ТаблицаЗначений; //Таблица описания Быстрого отбора
СпПБО.Колонки.Добавить("Значение");//Реквизит списка для отбора
СпПБО.Колонки.Добавить("Представление");//Подпись на панели быстрого отбора
СпПБО.Колонки.Добавить("Тип");//Тип значения отбора
//Наполнение полей отбора
НовПБО = СпПБО.Добавить();
НовПБО.Значение = "Номер";  НовПБО.Представление = "№?"; НовПБО.Тип = "Строка";
НовПБО = СпПБО.Добавить();
НовПБО.Значение = "Контрагент"; НовПБО.Представление = "КА?";   НовПБО.Тип = "Контрагенты";
НовПБО = СпПБО.Добавить();
НовПБО.Значение = "Подразделение";  НовПБО.Представление = "Отд.?"; НовПБО.Тип = "Подразделения";
НовПБО = СпПБО.Добавить();
НовПБО = СпПБО.Добавить();
НовПБО.Значение = "СуммаДокумента"; НовПБО.Представление = "Сум.?"; НовПБО.Тип = "Число";
//оРазд = 10;

Если мОтбора = Неопределено Тогда
мОтбора = Истина;//Первичная Инициализация
ИначеЕсли Не ВклОтбора Тогда
Для каждого ЭлмПБО Из СпПБО Цикл
ЭлементыФормы["т"+ЭлмПБО.Значение].Высота   = 0;
ЭлементыФормы["т"+ЭлмПБО.Значение].Видимость = Ложь;
ЭлементыФормы["З"+ЭлмПБО.Значение].Высота   = 0;
ЭлементыФормы["З"+ЭлмПБО.Значение].Видимость = Ложь;
КонецЦикла;
//Все Поля Скрыты
ЭлементыФормы.ДокументСписок.Верх = 33;
ЭлементыФормы.ДокументСписок.Высота = ЭтаФорма.Высота-40;
Возврат;
КонецЕсли;
//Отработка инициализации
НПП = 1;
Для каждого ЭлмПБО Из СпПБО Цикл
Если ЭлементыФормы.ДокументСписок.Ширина<оЛево+160+СтрДлина(ЭлмПБО.Представление) Тогда
ЭлементыФормы.ДокументСписок.Ширина = ЭлементыФормы.ДокументСписок.Ширина+160+СтрДлина(ЭлмПБО.Представление);
КонецЕсли;
РазместитьПолеБО(ЭлементыФормы, ЭлмПБО.Значение, ЭлмПБО.Представление, ЭлмПБО.Тип, 19, оВерх, оЛево);
Если НПП=1 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._1, Истина); // Alt+1
ИначеЕсли НПП=2 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._2, Истина); // Alt+2
ИначеЕсли НПП=3 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._3, Истина); // Alt+3
ИначеЕсли НПП=4 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._4, Истина); // Alt+4
ИначеЕсли НПП=5 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._5, Истина); // Alt+5
ИначеЕсли НПП=6 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._6, Истина); // Alt+6
ИначеЕсли НПП=7 Тогда
ЭлементыФормы["з"+ЭлмПБО.Значение].СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша._7, Истина); // Alt+7
КонецЕсли;
НПП=НПП+1;
КонецЦикла;

//Подвинем Список
ЭлементыФормы.ДокументСписок.Высота = ЭлементыФормы.ДокументСписок.Высота - оВысота;
ЭлементыФормы.ДокументСписок.Верх = ЭлементыФормы.ДокументСписок.Верх + оВысота;
КонецПроцедуры

//НВЮ/ Отбираем ПБО
Процедура ПБОПриИзменении(Элемент)
ИскЗначение = Элемент.Значение;
Если ЗначениеЗаполнено(ИскЗначение) Тогда
Если Элемент.Ширина<75 Тогда
Элемент.Ширина=75;
КонецЕсли;
Если Лев(СокрЛП(ТипЗнч(ИскЗначение)),6)="Строка" Тогда
Отбор[Сред(Элемент.Имя,2)].Значение = ИскЗначение;
Отбор[Сред(Элемент.Имя,2)].ВидСравнения = ВидСравнения.Содержит;
ИначеЕсли Лев(СокрЛП(ТипЗнч(ИскЗначение)),5)="Число" Тогда
Отбор[Сред(Элемент.Имя,2)].ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
Отбор[Сред(Элемент.Имя,2)].ЗначениеС = ИскЗначение*0.98;
Отбор[Сред(Элемент.Имя,2)].ЗначениеПо = ИскЗначение*1.02;
Иначе
Отбор[Сред(Элемент.Имя,2)].Значение = ИскЗначение;
Отбор[Сред(Элемент.Имя,2)].ВидСравнения=ВидСравнения.Равно;
КонецЕсли;
Отбор[Сред(Элемент.Имя,2)].Использование=Истина;
Иначе
Отбор[Сред(Элемент.Имя,2)].Использование=Ложь;
КонецЕсли;
Если Отбор[Сред(Элемент.Имя,2)].Значение<>ИскЗначение Тогда
ЭтаФорма.Обновить();
КонецЕсли;
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДокументСписок;
КонецПроцедуры
//НВЮ/ Очищаем ПБО+
Процедура ПБООчистка(Элемент, СтандартнаяОбработка)
Отбор[Сред(Элемент.Имя,2)].Использование=Ложь;//По имени Элемента отключаем отбор
Если Отбор[Сред(Элемент.Имя,2)].Значение<>Элемент.Значение Тогда
ЭтаФорма.Обновить();
КонецЕсли;
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДокументСписок;
КонецПроцедуры
//НВЮ/ Универсальное Размещение Поля отбора
//Параметры:
//  ЭФ  - <ЭлементыФормы>   - Размещение Элементов Формы
//
Процедура РазместитьПолеБО(ЭФ, ИмяПБО, ПредставлениеПБО, ТипПБО, оВысота=19, оВерх, оЛево) Экспорт
тЗаг = ЭлементыФормы.Найти("т"+ИмяПБО);
Если тЗаг=Неопределено Тогда
тЗаг = ЭлементыФормы.Добавить(Тип("Надпись"),"т"+ИмяПБО,Истина);
тЗаг.Значение = ПредставлениеПБО;
Иначе
тЗаг.Видимость = Истина;
КонецЕсли;
тЗаг.Верх = оВерх;
тЗаг.Лево = оЛево;
тЗаг.Ширина = СтрДлина(ПредставлениеПБО)*8;
оЛево   = оЛево + тЗаг.Ширина;
тЗаг.Высота = оВысота;
тЗаг = ЭлементыФормы.Найти("З"+ИмяПБО);
Если тЗаг=Неопределено Тогда
тЗаг = ЭлементыФормы.Добавить(Тип("ПолеВвода"),"З"+ИмяПБО,Истина);
тЗаг.УстановитьДействие("ПриИзменении",Новый Действие("ПБОПриИзменении"));
тЗаг.УстановитьДействие("Очистка",Новый Действие("ПБООчистка"));
Иначе
тЗаг.Видимость = Истина;
КонецЕсли;
тЗаг.Верх = оВерх;
тЗаг.Лево = оЛево;
//  ТипПБО  = СокрЛП(ТипЗнч(ЭлементыФормы.ДокументСписок.Колонки[ИмяПБО].ЭлементУправления.Значение));
Если ТипПБО="Строка" Тогда
тЗаг.Ширина = 75;
тЗаг.ТипЗначения = ОбщегоНазначения.ПолучитьОписаниеТиповСтроки(10);
ИначеЕсли ТипПБО="Число" Тогда
тЗаг.Ширина = 110;
тЗаг.ТипЗначения = ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(14,2);
Иначе
тЗаг.Ширина = 130;
тЗаг.ТипЗначения = ОбщегоНазначения.ПолучитьОписаниеТиповСправочника(ТипПБО);//
КонецЕсли;
оЛево   = оЛево + тЗаг.Ширина + 10;//НВЮ/ Добавлен разделитель полей
тЗаг.Высота = оВысота;
тЗаг.КнопкаОчистки = Истина;
тЗаг.ПропускатьПриВводе = Истина;

КонецПроцедуры
//НВЮ/ Включение/Отключение Быстрого отбора
Процедура ДействияФормыБыстрыйОтбор(Кнопка)
Если мОтбора Тогда//Включен, сл. Выключаем совсем
БыстрыйОтборДок(Ложь);
мОтбора = Ложь;
ЭлементыФормы.ДокументСписок.Верх = 33 ;//Типовое Расположение
ЭлементыФормы.ДокументСписок.Высота = ЭтаФорма.Высота - 33;
Иначе   //Включаем (Отображаем) Быстрый Отбор
//      мОтбора=ТекущаяДата();
БыстрыйОтборДок(Истина);
мОтбора = Истина;
КонецЕсли;
КонецПроцедуры

 

5 Comments

  1. DrAku1a

    Осталось вынести процедуры генерации элементов и обработки событий в общий модуль,

    выгрузить файлы конфигурации и обработать тексты модулей форм.

    А вообще, идея — не нова: http://infostart.ru/public/152560/, но не особо прижилась, судя по количеству «Лайков»…

    Reply
  2. nixel

    Толстый клиент <> Обычное приложение.

    Не проще конструктором сгенерить управляемую форму списка?

    И весь компоновщик настроек с быстрыми/небыстрыми отборами дает вам сама платформа.

    Reply
  3. V.Nikonov

    Я не парясь копировал фрагмент кода… Вставлял в нужную форму подправляя Автозапуск и требуемые реквизиты отбора в Процедуре БыстрыйОтборДок()… 10 или 15 форм списков обтяпал за час.

    Идея централизованного хранения параметров панели быстрого отбора теплилась, но так и не родилась… Времени и финансирования не хватило.

    Reply
  4. Altair777

    (2) любопытно, а что Вы имеете в виду? Через «Найти»?

    Reply
  5. nixel

    (4) через «Настроить список». и вынесение установленных настроек в «Быстрый доступ»

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *