При разработке сложных инструментов в среде 1С:Предприятие 8.3 часто возникает задача фильтрации данных. Если в динамических списках отборы настраиваются платформенно, то при использовании Таблицы Значений (ТЗ) на управляемой форме программисту необходимо самостоятельно реализовать механизм выбора параметров и перестроения данных. В данной статье мы подробно разберем, как организовать отбор документов по организации, когда данные загружаются в ТЗ через запрос.
Представим ситуацию: у нас есть обработка, на форме которой расположена таблица. Данные в эту таблицу попадают из сложного запроса (например, объединение счетов на оплату и реализаций). Нам необходимо добавить поле выбора организации, при изменении которого список документов будет мгновенно обновляться, показывая только записи по выбранному контрагенту. Выясним причину, почему стандартные методы КомпоновкиДанных не всегда подходят для ТЗ, и рассмотрим шаги реализации прямого запроса.
Для начала проанализируем структуру нашей формы. Нам понадобятся следующие элементы:
ОтборОрганизация с типом СправочникСсылка.Организации.ДанныеСЧ), отображаемая на форме.Важно помнить, что если мы хотим предоставить пользователю возможность выбирать сразу несколько организаций, тип реквизита ОтборОрганизация должен быть СписокЗначений.
Иногда требуется переопределить стандартное поведение выбора организации, чтобы, например, сразу включить режим множественного выбора. Рассмотрим, как это сделать в обработчике события НачалоВыбора для поля отбора.
Проанализируем код на стороне клиента:
&НаКлиенте
Процедура ОтборОрганизацияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отключаем стандартное окно
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("РежимВыбора", Истина);
ПараметрыФормы.Вставить("МножественныйВыбор", Истина); // Разрешаем подбор нескольких компаний
// Создаем оповещение о закрытии формы выбора
ОбработкаВыбора = Новый ОписаниеОповещения("ПослеВыбораОрганизаций", ЭтаФорма);
ОткрытьФорму("Справочник.Организации.ФормаВыбора", ПараметрыФормы, Элемент, , , , ОбработкаВыбора);
КонецПроцедуры
После того как пользователь выберет одну или несколько организаций, сработает процедура оповещения. Разберем ее содержание:
&НаКлиенте
Процедура ПослеВыбораОрганизаций(Значение, ДопПараметры) Экспорт
Если Значение = Неопределено Тогда
Возврат;
КонецЕсли;
// Значение может быть как одиночной ссылкой, так и массивом
ОбновитьДанныеНаСервере(Значение);
КонецПроцедуры
Теперь перейдем к самому ответственному этапу — получению данных с учетом выбранного фильтра. Мы будем использовать объект Запрос. Важный нюанс: если вы используете стандартный запрос (не СКД), фигурные скобки {} для необязательных параметров не работают привычным образом. Нам нужно либо динамически менять текст запроса, либо использовать условие в самом тексте.
Рассмотрим пример построения запроса с фильтрацией по организации:
&НаСервере
Процедура ОбновитьДанныеНаСервере(МассивОрганизаций)
// Очищаем текущую таблицу на форме
ДанныеСЧ.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Счет.Ссылка КАК ДокументСчета,
| Счет.Дата КАК Дата,
| Счет.Организация КАК Организация,
| Счет.Контрагент КАК Контрагент
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК Счет
|ГДЕ
| Счет.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И (&ПустойОтбор ИЛИ Счет.Организация В (&МассивОрганизаций))";
// Установка параметров периода
Запрос.УстановитьПараметр("НачалоПериода", Объект.НачПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецДня(Объект.КонПериода));
// Проверяем, задан ли отбор
ПустойОтбор = (МассивОрганизаций = Неопределено);
Запрос.УстановитьПараметр("ПустойОтбор", ПустойОтбор);
Запрос.УстановитьПараметр("МассивОрганизаций", МассивОрганизаций);
// Выгружаем результат напрямую в таблицу формы
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
ДанныеСЧ.Загрузить(РезультатЗапроса.Выгрузить());
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию, когда пользователь хочет видеть документы по всем организациям сразу. В коде выше мы применили логическое условие (&ПустойОтбор ИЛИ Организация В (&МассивОрганизаций)). Рассмотрим подробнее, как это работает:
МассивОрганизаций не заполнен, параметр ПустойОтбор равен Истина. Условие Истина ИЛИ ... всегда возвращает истину, и фильтр по организации игнорируется.ПустойОтбор равен Ложь, и запрос начинает учитывать вторую часть условия — наличие организации в переданном списке.Это позволяет избежать дублирования кода и написания нескольких вариантов текста запроса.
Если на форме организации выбираются не через специальную кнопку подбора, а через обычное поле ввода, нам необходимо повесить обработчик на событие ПриИзменении этого поля.
&НаКлиенте
Процедура ОтборОрганизацияПриИзменении(Элемент)
// Если реквизит формы называется ОтборОрганизация
МассивДляЗапроса = Новый Массив;
Если ЗначениеЗаполнено(ОтборОрганизация) Тогда
МассивДляЗапроса.Добавить(ОтборОрганизация);
Иначе
МассивДляЗапроса = Неопределено;
КонецЕсли;
ОбновитьДанныеНаСервере(МассивДляЗапроса);
КонецПроцедуры
При реализации подобных механизмов стоит обратить внимание на следующие моменты:
Загрузить(), убедитесь, что имена колонок в запросе (псевдонимы через КАК) полностью совпадают с именами реквизитов вашей таблицы на форме.ОбработкаОбъект = РеквизитФормыВЗначение("Объект"). Однако помните, что это ресурсоемкая операция. Старайтесь передавать только необходимые параметры (даты, ссылки) в серверную процедуру.Организация индексируется платформой по умолчанию, что обеспечивает высокую скорость отбора.Подводя итог, мы видим, что реализация отбора в таблице значений требует четкого понимания взаимодействия между клиентом и сервером. Правильное использование параметров запроса и обработка событий элементов формы позволяют создать отзывчивый и удобный интерфейс для пользователя, не уступающий стандартным спискам 1С.