В этой статье мы подробно рассмотрим процесс создания внешней обработки в 1С:Предприятии 8.3 с управляемой формой. Наша задача — реализовать функциональность, позволяющую пользователю выбрать период (дату начала и дату окончания), а затем динамически заполнить табличное поле на форме строками, где каждая строка будет соответствовать одному дню из выбранного периода. Мы разберем основные понятия, такие как реквизиты формы, табличные поля и таблицы значений, и предоставим пошаговую инструкцию с примерами кода.
Прежде чем перейти к практической реализации, давайте проясним ключевые термины, которые часто вызывают вопросы, особенно у начинающих разработчиков 1С. Корректное понимание этих понятий является фундаментом для успешной работы с управляемыми формами.
ТаблицаЗначений, ДеревоЗначений или ДинамическийСписок. В нашем случае, даты начала и окончания периода будут представлены как реквизиты формы.ТаблицаЗначений или ТабличнаяЧастьОбъекта.ТаблицаЗначений, либо могут быть добавлены программно уже в процессе работы.Изначально в постановке задачи могло возникнуть предположение о необходимости динамического создания *колонок* для каждого дня (например, "День 1", "День 2" и т.д.). Однако, уточнение показало, что требуется отобразить каждый день как отдельную *строку* в таблице. Для эффективной реализации такого подхода в 1С наиболее подходящим инструментом является использование объекта ТаблицаЗначений.
Для динамического формирования строк в табличном поле на управляемой форме мы будем использовать реквизит формы типа ТаблицаЗначений. Это мощный и гибкий программный объект, который позволяет нам полностью контролировать как структуру (колонки), так и содержимое (строки) таблицы непосредственно из кода. Когда ТабличноеПоле на форме привязано к такому реквизиту, любые программные изменения в ТаблицеЗначений автоматически отображаются на форме, обеспечивая динамическое обновление пользовательского интерфейса.
Давайте пошагово разберем процесс создания внешней обработки и ее функционала.
Начнем с базовой подготовки в конфигураторе.
Файл -> Новый -> Внешняя обработка
.epf
ФормаОсновная
Нам потребуется два реквизита для того, чтобы пользователь мог указать интересующий его временной интервал.
Insert
ДатаНачала
Дата
ДатаОкончания
Дата
Теперь создадим реквизит, который будет служить источником данных для нашего динамически заполняемого табличного поля.
ДанныеПериода
СписокДней
ТаблицаЗначений
ТаблицаЗначений
ДанныеПериода
День
Дата
ТаблицаЗначений
На этом шаге мы разместим визуальные элементы на форме, чтобы пользователь мог взаимодействовать с нашей обработкой.
ДанныеПериода
ТабличноеПоле
Заполнить
&НаКлиенте
&НаСервере
Перейдем к написанию основной логики, которая будет заполнять нашу таблицу. Откроем модуль формы (обычно двойным щелчком по названию формы или через контекстное меню "Открыть модуль"). Мы увидим, что автоматически были созданы процедуры
Заполнить
ЗаполнитьНаСервере
ТаблицуЗначений, должна выполняться на сервере.
Рассмотрим код, который будет получать даты начала и окончания с формы, очищать нашу ТаблицуЗначений и затем заполнять ее новыми строками, представляющими каждый день в выбранном периоде.
&НаСервере
Процедура ЗаполнитьНаСервере()
// Получаем значения дат с реквизитов формы.
// В серверном контексте к реквизитам формы можно обращаться напрямую по их именам.
ДатаНачалаПериода = ДатаНачала;
ДатаОкончанияПериода = ДатаОкончания;
// Выполняем предварительные проверки, чтобы избежать ошибок и некорректного поведения.
// Проверяем, что обе даты были указаны пользователем.
Если ДатаНачалаПериода = Неопределено ИЛИ ДатаОкончанияПериода = Неопределено Тогда
Сообщить("Пожалуйста, укажите и дату начала, и дату окончания периода.", СтатусСообщения.Важное);
Возврат; // Выходим из процедуры, так как данные некорректны.
КонецЕсли;
// Проверяем, что дата начала не позднее даты окончания.
Если ДатаНачалаПериода > ДатаОкончанияПериода Тогда
Сообщить("Дата начала не может быть позднее даты окончания.", СтатусСообщения.Важное);
Возврат; // Выходим из процедуры.
КонецЕсли;
// Очищаем существующую ТаблицуЗначений перед новым заполнением.
// Это гарантирует, что старые данные не будут смешиваться с новыми.
ДанныеПериода.Очистить();
// Инициализируем переменную для итерации по дням.
// Используем НачалоДня() для стандартизации времени до 00:00:00,
// что важно для корректного сравнения и инкрементации дат.
ТекущаяДата = НачалоДня(ДатаНачалаПериода);
// Цикл для добавления каждой даты в таблицу.
// Цикл продолжается, пока текущая дата меньше или равна дате окончания периода.
Пока ТекущаяДата <= НачалоДня(ДатаОкончанияПериода) Цикл
// Добавляем новую строку в реквизит формы типа ТаблицаЗначений (ДанныеПериода).
// Метод Добавить() возвращает ссылку на вновь созданную строку.
НоваяСтрока = ДанныеПериода.Добавить();
// Заполняем колонку "День" новой строки значением текущей даты.
// "День" - это имя колонки, которую мы определили ранее для ТаблицыЗначений.
НоваяСтрока.День = ТекущаяДата;
// Переходим к следующему дню.
// Функция ДобавитьМесяц(Дата, СмещениеМесяцев, СмещениеДней, СмещениеСекунд)
// является удобным и надежным способом для выполнения операций с датами.
// В данном случае, мы прибавляем 1 день, оставляя месяцы и секунды без изменений.
ТекущаяДата = ДобавитьМесяц(ТекущаяДата, 0, 1);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура Заполнить(Команда)
// Эта процедура выполняется на клиенте (в пользовательском интерфейсе).
// Она просто вызывает серверную процедуру ЗаполнитьНаСервере(),
// где происходит вся основная логика работы с данными.
ЗаполнитьНаСервере();
КонецПроцедуры
Разберем ключевые моменты представленного кода:
ДатаНачала
ДатаОкончания
Элементы.
ДанныеПериода.Очистить()
ТекущаяДата = НачалоДня(ДатаНачалаПериода)
НачалоДня()
Пока ТекущаяДата <= НачалоДня(ДатаОкончанияПериода) Цикл
НоваяСтрока = ДанныеПериода.Добавить()
ТаблицуЗначений. Он создает новую пустую строку и возвращает на нее ссылку, которую мы сохраняем в переменной
НоваяСтрока
НоваяСтрока.День = ТекущаяДата
ТекущаяДата
День
День
ДанныеПериода
ТекущаяДата = ДобавитьМесяц(ТекущаяДата, 0, 1)
ДобавитьМесяц
Хотя в нашей основной задаче требуется динамическое формирование строк в таблице с заранее определенными колонками, стоит упомянуть о возможности более сложного сценария, когда необходимо динамически создавать сами колонки ТаблицыЗначений или даже реквизиты формы в процессе выполнения программы. Такой подход может быть актуален, если, например, количество и имена колонок должны зависеть от выбранных пользователем параметров, периода или других динамических условий.
Для программного добавления колонок в уже существующий реквизит формы типа ТаблицаЗначений используется метод Колонки.Добавить(). Если же нам требуется создать сам реквизит формы "на лету" (что бывает реже для ТаблицаЗначений, но возможно для других типов), то применяется метод ИзменитьРеквизиты().
Рассмотрим пример программного добавления колонки в ТаблицуЗначений, если бы она не была определена в конфигураторе:
&НаСервере
Процедура ДинамическоеСозданиеКолонокНаСервере()
// Предположим, что реквизит формы "ДанныеПериода" уже существует,
// но его колонки еще не определены или нужно добавить новую.
// Проверяем, существует ли уже колонка "День".
// Если нет, то создаем ее программно.
Если ДанныеПериода.Колонки.Найти("День") = Неопределено Тогда
// Добавляем новую колонку с именем "День" и типом "Дата"
ДанныеПериода.Колонки.Добавить("День", Новый ОписаниеТипов("Дата"));
Сообщить("Колонка 'День' была добавлена в ТаблицуЗначений программно.");
Иначе
Сообщить("Колонка 'День' уже существует в ТаблицеЗначений.");
КонецЕсли;
// После добавления колонок можно приступать к заполнению строк,
// как это было описано в основной задаче.
// ...
КонецПроцедуры
Этот код позволяет гибко настроить структуру таблицы в зависимости от потребностей. Метод
ОписаниеТипов()
ИзменитьРеквизиты
ТаблицыЗначений с уникальными именами. Однако, как мы выяснили, это не является целью нашей текущей задачи, которая сфокусирована на динамическом формировании строк.
Мы успешно рассмотрели и реализовали создание внешней обработки в 1С:Предприятии 8.3 с управляемой формой, которая динамически формирует табличное поле. Наша обработка позволяет пользователю выбрать период и затем выводит каждый день этого периода как отдельную строку в таблице.
Использование реквизита формы типа ТаблицаЗначений, привязанного к ТабличномуПолю, является стандартным, гибким и наиболее эффективным подходом для решения подобных задач в 1С. Этот метод позволяет нам полностью контролировать данные, отображаемые в таблице, изменять их структуру и содержимое программно, что делает его незаменимым инструментом для разработки интерактивных и динамичных пользовательских интерфейсов.
Применяя описанные шаги и принципы, вы сможете создавать разнообразные отчеты и обработки, которые будут эффективно обрабатывать и представлять табличные данные в системе 1С:Предприятие.