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