Установка быстрых отборов в форме списка (выбора) справочника (для новичков)
Я сам новичок в 1С и знаю, как трудно поначалу разобраться в море незнакомой информации и быстро найти нужную для решения какой-либо срочной задачи. Поэтому эту статейку пишу и для себя тоже.
Иногда пользователю нужно быстро отобрать нужные строки в списке по нескольким не точным критериям.
В списках отбор может быть установлен вручную пользователем стандартным способом через контекстное меню списка «Установить отбор и сортировку списка»
Но если отборы часто используемые, то мы можем вынести поля для ввода критериев на форму и устанавливать отборы программно.
1) Рассмотрим установку такого отбора на примере списка справочника Номенклатура.
Открываем в конфигураторе форму списка справочника Номенклатура.
Уменьшим высоту табличного поля «Список».
На освободившееся место над табличным полем разместим 5 элементов:
- метку,
- два флажка
- два поля ввода.
со следующими именами:
1) Отборы
2) фНомер – Булево
3) отбНомер – Строка(20)
4) фНаименование – Булево
5) отбНаименование – Строка(150)
Результат будет выглядеть примерно так:
Сверим список реквизитов формы на закладке «Реквизиты», наши новые обведены красным:
Теперь пишем в модуле формы обработчики событий «При изменении» для флажков и полей ввода.
Для назначения обработчика события элементу формы выбираем мышкой нужный элемент, идем в панель «Свойства» , ищем в разделе «События» событие «ПриИзменении» и щелкаем мышкой по лупе:
И в созданную заготовку процедуры вписываем нужный код:
Вот код этих четырех обработчиков:
// при изменении флажка фНомер
Процедура фНомерПриИзменении(Элемент)
// если не заполнен Номер для отбора не будем понапрасну дергать Отбор
Если ЗначениеЗаполнено(отбНомер) Тогда
УстановитьОтборыФормы();
КонецЕсли;
КонецПроцедуры
// при изменении поля ввода отбНомер
Процедура отбНомерПриИзменении(Элемент)
// если не установлен флажок не будем понапрасну дергать Отбор
Если фНомер Тогда
УстановитьОтборыФормы();
КонецЕсли;
КонецПроцедуры
Процедура фНаименованиеПриИзменении(Элемент)
// если не заполнено Наименование для отбора не будем понапрасну дергать Отбор
Если ЗначениеЗаполнено(отбНаименование) Тогда
УстановитьОтборыФормы();
КонецЕсли;
КонецПроцедуры
Процедура отбНаименованиеПриИзменении(Элемент)
// если не установлен флажок не будем понапрасну дергать Отбор
Если фНаименование Тогда
УстановитьОтборыФормы();
КонецЕсли;
КонецПроцедуры
На двух наших полях ввода включим свойство «КнопкаОчистки».
При очистке поля ввода мы будем сбрасывать соответсвующий флажок и перечитывать отбор:
// при очистке поля ввода отбНомер
Процедура отбНомерОчистка(Элемент, СтандартнаяОбработка)
фНомер = Ложь;
УстановитьОтборыФормы();
КонецПроцедуры
// при очистке поля ввода отбНаименование
Процедура отбНаименованиеОчистка(Элемент, СтандартнаяОбработка)
фНаименование = Ложь;
УстановитьОтборыФормы();
КонецПроцедуры
Теперь пишем процедуру установки отбора:
Процедура УстановитьОтборыФормы()
// запомним состояние иерархии
мИерархическийПросмотр = ЭлементыФормы.Список.ИерархическийПросмотр;
Если (фНомер И НЕ ПустаяСтрока(отбНомер))
или (фНаименование И ЗначениеЗаполнено(отбНаименование))
Тогда
// сбросим иерархию
Если ЭлементыФормы.Список.ИерархическийПросмотр Тогда
ЭлементыФормы.Список.ИерархическийПросмотр = Ложь;
КонецЕсли;
// получаем запросом список с установленными критериями отбора
сз = ВернутьСписок();
// устанавливаем отбор на ссылки, входящие в возвращенный список ссылок
ЭтаФорма.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
ЭтаФорма.Отбор.Ссылка.Значение = сз;
ЭтаФорма.Отбор.Ссылка.Использование = Истина;
Иначе
// сбросим отбор
ЭтаФорма.Отбор.Ссылка.Использование = Ложь;
// вернем иерархию взад
Если НЕ мИерархическийПросмотр Тогда
ЭлементыФормы.Список.ИерархическийПросмотр = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
А теперь пишем функцию, выбирающую запросом ссылки по введенным пользователем критериям и возвращающую как результат список отобранных ссылок:
Функция ВернутьСписок()
Запрос = Новый Запрос;
// устанавливаем параметры запроса введенными критериями
Запрос.УстановитьПараметр("фНомер" , фНомер);
Запрос.УстановитьПараметр("фНаименование", фНаименование);
Запрос.УстановитьПараметр("пНомер" , "%" + СокрЛП(отбНомер) + "%");
Запрос.УстановитьПараметр("пНаименование", "%" + СокрЛП(отбНаименование) + "%");
// нам нужна только ссылка для построения списка значений
Запрос.Текст = "ВЫБРАТЬ
| Ссылка
|ИЗ
| Справочник.Номенклатура
|
|ГДЕ
| // 1-ое условие
| (&фНомер = Ложь
| или (&фНомер и НоменклатурныйНомер ПОДОБНО &пНомер)
| )
| // соединим условия союзом И
| И
|
| // 2-ое условие
| (&фНаименование = Ложь
| или (&фНаименование и Наименование ПОДОБНО &пНаименование)
| )
|";
Результат = Запрос.Выполнить();
// создаем новый список значений и выгружаем в него колонку «Ссылка» из результата запроса
сз = Новый СписокЗначений;
сз.ЗагрузитьЗначения(Результат.Выгрузить().ВыгрузитьКолонку("Ссылка"));
// возвращаем результат - полученный список зачений
Возврат сз;
КонецФункции
Вот результат отбора по двум критериям:
Взглянем на форму отборов опять для сравнения и видим на ней установленный наш отбор по ссылке:
2) Рассмотрим более сложный пример со справочником «Основные средства».
Размещаем над списком 7 элементов:
Где 1 – это просто метка, а остальные реквизиты имеют следующие типы:
Добавим в модуль списка новую процедуру ЭлементОтбораПриИзменении и впишем в нее следующий код:
Процедура ЭлементОтбораПриИзменении(Элемент)
УстановитьОтборыФормы();
КонецПроцедуры
Всем новым элементам (кроме метки, хе-хе) назначаем этот обработчик, чтобы не плодить их тучу однотипных:
Пишем процедуру установки снятия отбора:
Процедура УстановитьОтборыФормы()
мИерархияВкл = ЭлементыФормы.СправочникСписок.ИерархическийПросмотр;
Если (флПоИнвНомеру и НЕ ПустаяСтрока(отбИнвНомер))
или (флПоПодразделению и ЗначениеЗаполнено(отбПодразделение))
или (флПоМОЛ и ЗначениеЗаполнено(отбМОЛ))Тогда
Если мИерархияВкл Тогда
ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;
КонецЕсли;
СписокОС = ВернутьСписокОС();
ЭтаФорма.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
ЭтаФорма.Отбор.Ссылка.Значение = СписокОС;
ЭтаФорма.Отбор.Ссылка.Использование = Истина;
Иначе
Если ЭтаФорма.Отбор.Ссылка.Использование Тогда
ЭтаФорма.Отбор.Ссылка.Использование = Ложь;
ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = мИерархияВкл;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
И пишем еще одну процедурку получения списка ссылок запросом.
Здесь мы будем получать последние сведения по ОС из регистров сведений:
- Инвентарный Номер из РС ПервоначальныеСведения
- Подразделение и МОЛ из РС МестонахождениеОС.
Функция ВернутьСписокОС()
Запрос = Новый Запрос;
Если флПоИнвНомеру и НЕ (флПоПодразделению или флПоМОЛ) Тогда
// отбор только по инв. номерам только
Запрос.Текст = "ВЫБРАТЬ
| ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство
|ИЗ
| РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(
| &пДата,
| ИнвентарныйНомер ПОДОБНО &пИнвНомер)
|КАК ПервоначальныеСведенияОССрезПоследних";
Иначе
аргУсловие = "";
Если флПоПодразделению И ЗначениеЗаполнено(отбПодразделение) Тогда
аргУсловие = "МестонахождениеОССрезПоследних.Местонахождение = &пПодразделение"
КонецЕсли;
Если флПоМОЛ И ЗначениеЗаполнено(отбМОЛ) Тогда
стрМОЛ = "МестонахождениеОССрезПоследних.МОЛ = &пМОЛ";
аргУсловие = ?(ПустаяСтрока(аргУсловие), стрМОЛ, аргУсловие + " И " + стрМОЛ);
КонецЕсли;
Если НЕ флПоИнвНомеру Тогда
Запрос.Текст = "ВЫБРАТЬ
| МестонахождениеОССрезПоследних.ОсновноеСредство
|ИЗ
| РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&пДата, )
|КАК МестонахождениеОССрезПоследних
|ГДЕ " + аргУсловие;
Иначе
Запрос.Текст = "ВЫБРАТЬ
| ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство
|ИЗ
| РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних(
| &пДата,
| ИнвентарныйНомер ПОДОБНО &пИнвНомер)
| КАК ПервоначальныеСведенияОССрезПоследних
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&пДата, )
| КАК МестонахождениеОССрезПоследних
| ПО ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство = МестонахождениеОССрезПоследних.ОсновноеСредство
|ГДЕ " + аргУсловие;
КонецЕсли;
КонецЕсли;
Запрос.УстановитьПараметр("пИнвНомер" , "%" + СокрЛП(отбИнвНомер) + "%");
Запрос.УстановитьПараметр("пДата" , ТекущаяДата());
Запрос.УстановитьПараметр("пПодразделение", отбПодразделение);
Запрос.УстановитьПараметр("пМОЛ" , отбМОЛ);
Результат = Запрос.Выполнить();
сз = Новый СписокЗначений;
сз.ЗагрузитьЗначения(Результат.Выгрузить().ВыгрузитьКолонку("ОсновноеСредство"));
Возврат сз;
КонецФункции
Теперь добавляем в список две новых колонки МОЛ и Местонахождение без привязки к данным
Установим их свойства «Видимость» в Ложь, чтобы они не светились в списке сразу. Их заполение мы будем обрабатывать в событии ПриПолученииДанных (см. ниже)
В свойстве ЭлементУправления обоим назначаем «Поле ввода»
В обработчик ПриПолученииДанных добавляем код для отображения значений наших добавленных колонок:
Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)
…
// создаем структуру для получения сведений из регистра
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Организация" , Организация);
СтруктураОтбора.Вставить("ОсновноеСредство", ДанныеСтроки.Ссылка);
// будем запрашивать и выводить данные только при видимости наших колонок
Если ОформлениеСтроки.Ячейки.МОЛ.Видимость
или ОформлениеСтроки.Ячейки.Местонахождение.Видимость Тогда
МестонахождениеОС =
РегистрыСведений.МестонахождениеОСБухгалтерскийУчет.ПолучитьПоследнее(
ДатаСведений, СтруктураОтбора);
ОформлениеСтроки.Ячейки.МОЛ.Значение = МестонахождениеОС.МОЛ;
ОформлениеСтроки.Ячейки.Местонахождение.Значение =
МестонахождениеОС.Подразделение;
КонецЕсли;
КонецПроцедуры
Сохраняемся, запускаемся.
Открываем список ОС, устанавливаем видимость наших новых колонок МОЛ и Местонахождение, вводим критерии отбора и вуаля:
P.S.
Недостаток рассмотренного подхода в том, что если ранее был каким-либо образом установлен отбор по ссылке, то он будет затерт нашим.
А как скомбинировать старый отбор с новым я не знаю, пока.
Спасибо за внимание.
Успехов!
До встречи.