Как реализовать отбор по организации в таблице значений на форме обработки

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке сложных инструментов в среде 1С:Предприятие 8.3 часто возникает задача фильтрации данных. Если в динамических списках отборы настраиваются платформенно, то при использовании Таблицы Значений (ТЗ) на управляемой форме программисту необходимо самостоятельно реализовать механизм выбора параметров и перестроения данных. В данной статье мы подробно разберем, как организовать отбор документов по организации, когда данные загружаются в ТЗ через запрос.

Постановка задачи и анализ ситуации

Представим ситуацию: у нас есть обработка, на форме которой расположена таблица. Данные в эту таблицу попадают из сложного запроса (например, объединение счетов на оплату и реализаций). Нам необходимо добавить поле выбора организации, при изменении которого список документов будет мгновенно обновляться, показывая только записи по выбранному контрагенту. Выясним причину, почему стандартные методы КомпоновкиДанных не всегда подходят для ТЗ, и рассмотрим шаги реализации прямого запроса.

Шаг 1. Подготовка реквизитов формы

Для начала проанализируем структуру нашей формы. Нам понадобятся следующие элементы:

  1. Реквизит объекта или формы ОтборОрганизация с типом СправочникСсылка.Организации.
  2. Таблица значений (например, ДанныеСЧ), отображаемая на форме.
  3. Период (Дата начала и Дата окончания) для первичного ограничения выборки.

Важно помнить, что если мы хотим предоставить пользователю возможность выбирать сразу несколько организаций, тип реквизита ОтборОрганизация должен быть СписокЗначений.

Шаг 2. Программный вызов формы выбора

Иногда требуется переопределить стандартное поведение выбора организации, чтобы, например, сразу включить режим множественного выбора. Рассмотрим, как это сделать в обработчике события НачалоВыбора для поля отбора.

Проанализируем код на стороне клиента:


&НаКлиенте
Процедура ОтборОрганизацияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отключаем стандартное окно
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("РежимВыбора", Истина);
    ПараметрыФормы.Вставить("МножественныйВыбор", Истина); // Разрешаем подбор нескольких компаний
    
    // Создаем оповещение о закрытии формы выбора
    ОбработкаВыбора = Новый ОписаниеОповещения("ПослеВыбораОрганизаций", ЭтаФорма);
    
    ОткрытьФорму("Справочник.Организации.ФормаВыбора", ПараметрыФормы, Элемент, , , , ОбработкаВыбора);
    
КонецПроцедуры

После того как пользователь выберет одну или несколько организаций, сработает процедура оповещения. Разберем ее содержание:


&НаКлиенте
Процедура ПослеВыбораОрганизаций(Значение, ДопПараметры) Экспорт
    
    Если Значение = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Значение может быть как одиночной ссылкой, так и массивом
    ОбновитьДанныеНаСервере(Значение);
    
КонецПроцедуры

Шаг 3. Реализация серверной логики и запроса

Теперь перейдем к самому ответственному этапу — получению данных с учетом выбранного фильтра. Мы будем использовать объект Запрос. Важный нюанс: если вы используете стандартный запрос (не СКД), фигурные скобки {} для необязательных параметров не работают привычным образом. Нам нужно либо динамически менять текст запроса, либо использовать условие в самом тексте.

Рассмотрим пример построения запроса с фильтрацией по организации:


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

Шаг 4. Оптимизация работы с "необязательным" параметром

Проанализируем ситуацию, когда пользователь хочет видеть документы по всем организациям сразу. В коде выше мы применили логическое условие (&ПустойОтбор ИЛИ Организация В (&МассивОрганизаций)). Рассмотрим подробнее, как это работает:

Это позволяет избежать дублирования кода и написания нескольких вариантов текста запроса.

Шаг 5. Обработка события "При изменении"

Если на форме организации выбираются не через специальную кнопку подбора, а через обычное поле ввода, нам необходимо повесить обработчик на событие ПриИзменении этого поля.


&НаКлиенте
Процедура ОтборОрганизацияПриИзменении(Элемент)
    
    // Если реквизит формы называется ОтборОрганизация
    МассивДляЗапроса = Новый Массив;
    Если ЗначениеЗаполнено(ОтборОрганизация) Тогда
        МассивДляЗапроса.Добавить(ОтборОрганизация);
    Иначе
        МассивДляЗапроса = Неопределено;
    КонецЕсли;
    
    ОбновитьДанныеНаСервере(МассивДляЗапроса);
    
КонецПроцедуры

Полезные советы по работе с таблицами значений

При реализации подобных механизмов стоит обратить внимание на следующие моменты:

  1. Типизация колонок ТЗ: При загрузке данных из запроса методом Загрузить(), убедитесь, что имена колонок в запросе (псевдонимы через КАК) полностью совпадают с именами реквизитов вашей таблицы на форме.
  2. Использование РеквизитФормыВЗначение: Если ваша логика заполнения ТЗ находится в модуле объекта обработки, вам придется использовать ОбработкаОбъект = РеквизитФормыВЗначение("Объект"). Однако помните, что это ресурсоемкая операция. Старайтесь передавать только необходимые параметры (даты, ссылки) в серверную процедуру.
  3. Индексация: Если документов в базе очень много, убедитесь, что в запросе используются индексированные поля. В документах поле Организация индексируется платформой по умолчанию, что обеспечивает высокую скорость отбора.

Подводя итог, мы видим, что реализация отбора в таблице значений требует четкого понимания взаимодействия между клиентом и сервером. Правильное использование параметров запроса и обработка событий элементов формы позволяют создать отзывчивый и удобный интерфейс для пользователя, не уступающий стандартным спискам 1С.

← На главную