Как реализовать выбор периода во внешней обработке для заполнения табличной части?

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

При разработке дополнительных обработок заполнения табличных частей (ТЧ) часто возникает задача: прежде чем заполнить данные, необходимо получить от пользователя параметры, например, период (даты начала и окончания). По умолчанию стандартные команды заполнения выполняются мгновенно, не открывая окон. Разберем подробно, как изменить это поведение, настроить форму для ввода дат и правильно передать данные в документ.

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

Этот метод считается наиболее гибким и наглядным. Вместо того чтобы сразу запускать серверный код, система открывает форму вашей внешней обработки, где пользователь может выбрать период, настроить фильтры, а уже затем нажать кнопку «Заполнить».

Шаг 1. Регистрация обработки

Проанализируем структуру функции СведенияОВнешнейОбработке в модуле объекта. Чтобы форма открывалась, для параметра Использование команды необходимо указать значение ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы() (или просто строку "ОткрытиеФормы").


Функция СведенияОВнешнейОбработке() Экспорт
    РегистрационныеДанные = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    
    РегистрационныеДанные.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    РегистрационныеДанные.Назначение.Добавить("Документ.ПриемНаРаботу"); // Укажите ваш документ
    РегистрационныеДанные.Наименование = "Заполнение сотрудников по графику";
    
    НоваяКоманда = РегистрационныеДанные.Команды.Добавить();
    НоваяКоманда.Представление = "Заполнить по графику (с выбором периода)";
    НоваяКоманда.Идентификатор = "ЗаполнитьПоГрафику";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
    
    Возврат РегистрационныеДанные;
КонецФункции

Шаг 2. Создание формы и получение контекста документа

Рассмотрим, как форма обработки узнает, в каком именно документе она была вызвана. При использовании ОткрытиеФормы, БСП передает в форму параметр ОбъектыНазначения. Однако в случае заполнения ТЧ нам важнее свойство ВладелецФормы. Проанализируем код инициализации в модуле формы:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Проверяем, что обработка открыта из формы документа
    Если ВладелецФормы = Неопределено Тогда
        Сообщить("Обработка предназначена для вызова из документа!");
        Отказ = Истина;
        Возврат;
    КонецЕсли;
КонецПроцедуры

Шаг 3. Обработка нажатия кнопки «Заполнить»

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


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

    // Вызываем серверную процедуру
    ЗаполнитьТаблицуНаСервере();
    
    // Сообщаем форме владельца, что данные изменены
    ВладелецФормы.Модифицированность = Истина;
    Закрыть();
КонецПроцедуры

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

Способ 2. Использование асинхронного ввода периода (без формы обработки)

Если вам не нужна сложная форма с кучей настроек, а требуется только спросить у пользователя даты, можно использовать встроенные средства платформы в процедуре ВыполнитьКоманду. Рассмотрим этот вариант для типа команды ВызовКлиентскогоМетода.

Реализация через диалог ввода периода:


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

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

Проанализируем важные нюансы

При реализации заполнения ТЧ стоит придерживаться следующих правил:

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

Выбор конкретного метода зависит от ваших навыков: создание формы (Способ 1) более трудоемко в плане визуального проектирования, но привычнее пользователю. Использование асинхронных методов (Способ 2) позволяет обойтись минимальным количеством кода и объектов.

← На главную