Как передать данные из первого документа в третий при создании на основании в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки на платформе 1С часто возникает задача передачи специфических данных, таких как реквизит Источник, из самого первого документа цепочки в самый последний. Когда документов в цепочке несколько, важно понимать, как правильно обращаться к данным оснований, чтобы не допустить ошибок типизации и обеспечить корректное заполнение реквизитов.

Разбор основной ошибки при доступе к данным

Одной из самых частых причин возникновения ошибки Значение не является значением объектного типа является попытка обратиться к реквизиту объекта через переменную, которая содержит Тип данных, а не саму ссылку на объект. В 1С важно четко разграничивать понятия: тип (например, Тип("ДокументСсылка.ТелефонныйЗвонок")) и экземпляр объекта (ссылка, хранящаяся в параметре ДанныеЗаполнения).

Если в коде вы видите, что программа не находит поле ВзаимодействиеОснование, скорее всего, вы обращаетесь к нему через описание типа. Рассмотрим, как правильно реализовать заполнение в процедуре ОбработкаЗаполнения вашего документа.

Реализация передачи данных через цепочку оснований

Когда вы создаете новый документ на основании существующего, платформа передает в процедуру ОбработкаЗаполнения параметр ДанныеЗаполнения. Этот параметр содержит ссылку на документ-основание. Чтобы получить данные из «прародителя» (справочника или другого документа), необходимо использовать эту ссылку как объект.

Рассмотрим пример кода, который позволит нам «дотянуться» до реквизита Источник, находящегося в справочнике Запросы, через документ ТелефонныйЗвонок:


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

Почему важно проверять типы данных?

В современных конфигурациях 1С, таких как 1С:Управление торговлей, поля типа ВзаимодействиеОснование являются составными. Это означает, что в одном и том же реквизите могут храниться ссылки на разные объекты: документы, справочники и т.д. Если вы попытаетесь обратиться к реквизиту Источник, не проверив предварительно тип ссылки, вы можете получить ошибку, если в основании окажется объект, у которого нет такого реквизита.

Поэтому всегда следуйте правилу «безопасного доступа»:

  1. Проверяйте тип самого основания через ТипЗнч().
  2. Проверяйте тип ссылки, хранящейся внутри составного реквизита.
  3. Используйте прямое обращение к реквизиту объекта только после подтверждения того, что тип данных совпадает с ожидаемым.

Что делать, если цепочка документов очень длинная?

Если количество документов в цепочке превышает 2-3 звена, логика последовательного обращения Основание.Основание.Основание становится громоздкой. В таких случаях мы рекомендуем рассмотреть альтернативные подходы:

Использование рекурсии для поиска корня

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

Регистры сведений как хранилище связей

Для высоконагруженных систем или систем с запутанной структурой документов наиболее правильным архитектурным решением является создание отдельного РегистраСведений (например, СвязиДокументов).

При каждой записи документа вы можете автоматически фиксировать в этом регистре запись вида: ТекущийДокумент — ДокументИсток. В этом случае для получения реквизита Источник вам не нужно будет перебирать всю цепочку — достаточно будет выполнить один простой запрос к РегиструСведений по текущему документу.

Заключение

Рассмотренный метод прямого обращения через ДанныеЗаполнения отлично подходит для простых цепочек документов. Главное — помнить, что ДанныеЗаполнения — это не просто переменная, а объект, с которым можно работать через точку, если вы уверены в его типе. Используйте отладчик 1С для анализа содержимого ДанныеЗаполнения в момент выполнения процедуры, чтобы точно видеть, какие реквизиты доступны для обращения в конкретной ситуации.

← На главную