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