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