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