Как программно заполнить составной реквизит Контрагент в табличной части документа УТ 11?

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

При разработке внешних обработок для конфигурации «Управление торговлей 11» программисты часто сталкиваются со следующей проблемой: при заполнении табличной части документа из внешнего файла (например, Excel) численные и строковые реквизиты записываются без проблем, а ссылка на справочник в составной реквизит (например, Контрагент) не проставляется вовсе или сбрасывается сразу после выполнения кода.

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

Почему не заполняется реквизит с составным типом данных

Проанализируем основные причины, по которым ссылка на контрагента не записывается в строку табличной части:

  1. Работа с объектом на клиенте вместо сервера. В управляемых формах переменная Объект на клиенте представляет собой структуру данных формы (ДанныеФормыСтруктура), а не сам объект базы данных (ДокументОбъект). Программная установка значений на клиенте напрямую в коллекцию формы не вызывает типовые обработчики событий и может приводить к некорректному сбросу данных.
  2. Взаимосвязь реквизитов «Партнер» и «Контрагент» в УТ 11. В конфигурации «Управление торговлей» управленческий учет ведется по партнерам, а юридический — по контрагентам. В табличных частях большинства документов эти два реквизита жестко связаны. Если заполнить только реквизит Контрагент, оставив реквизит Партнер пустым, механизмы конфигурации автоматически очистят несогласованное значение.
  3. Передача пустой ссылки в составной тип. Если алгоритм поиска по ИНН возвращает пустую ссылку справочника (СправочникСсылка.Контрагенты.ПустаяСсылка()), то при попытке присвоить ее в реквизит составного типа платформа 1С преобразует данное значение в Неопределено.

Ошибочные подходы к решению

Часто разработчики пытаются решить проблему ограничениями типов на уровне элементов формы или принудительным приведением типа. Рассмотрим, почему эти способы не работают:

Использование свойства ОграничениеТипа применяется к элементам формы (например, Элементы.ИмяПоля.ОграничениеТипа) и влияет исключительно на интерактивный выбор значения пользователем в интерфейсе. Оно не меняет тип данных в реквизитах табличной части и не помогает при программной установке значения.

Также не требуется создавать объект ОписаниеТипов или использовать метод ПривестиЗначение(). Если в реквизит составного типа записывается реальная (непустая) ссылка на объект, платформа 1С автоматически определяет и фиксирует нужный тип.

Правильный алгоритм заполнения реквизитов на сервере

Для корректного заполнения табличной части документа необходимо выполнить следующие шаги:

  1. Прочитать данные из внешнего файла на клиенте и сформировать массив простых структур (содержащих примитивные типы данных: строки, числа).
  2. Передать этот массив в серверную процедуру.
  3. На сервере преобразовать данные формы в объект базы данных с помощью функции РеквизитФормыВЗначение().
  4. Выполнить поиск контрагента на сервере и заполнить табличную часть объекта, обязательно установив значения для обоих взаимосвязанных реквизитов: Контрагент и Партнер.
  5. Обновить данные формы, вызвав процедуру ЗначениеВРеквизитФормы().

Пример программного кода

Рассмотрим практическую реализацию загрузки строк в табличную часть РасчетыСПартнерами документа на сервере:


&НаКлиенте
Процедура ЗагрузитьДанныеИзФайлаНаКлиенте()
    
    // Формируем массив структур с примитивными типами данных
    МассивСтрок = Новый Массив;
    
    Для НС = 10 По ФайлСтрок Цикл
        
        СтрокаДанных = Новый Структура;
        СтрокаДанных.Вставить("ИНН", СокрЛП(Excel.Cells(НС, 1).Text));
        СтрокаДанных.Вставить("Сумма", Число(Excel.Cells(НС, 7).Text));
        
        МассивСтрок.Добавить(СтрокаДанных);
        
    КонецЦикла;
    
    // Передаем данные на сервер для обработки
    ЗаполнитьТабличнуюЧастьНаСервере(МассивСтрок);

КонецПроцедуры

&НаСервере
Процедура ЗаполнитьТабличнуюЧастьНаСервере(МассивСтрок)
    
    // Получаем прикладной объект из данных формы
    ДокументОбъект = РеквизитФормыВЗначение("Объект");
    
    ДокументОбъект.РасчетыСПартнерами.Очистить();
    
    Для Каждого СтрИзФайла Из МассивСтрок Цикл
        
        // Ищем контрагента по ИНН
        НайденныйКонтрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", СтрИзФайла.ИНН);
        
        Если НЕ ЗначениеЗаполнено(НайденныйКонтрагент) Тогда
            Продолжить;
        КонецЕсли;
        
        НоваяСтрока = ДокументОбъект.РасчетыСПартнерами.Добавить();
        
        // Устанавливаем ссылку в составной реквизит
        НоваяСтрока.Контрагент = НайденныйКонтрагент;
        
        // Обязательно заполняем связанного партнера для УТ 11
        НоваяСтрока.Партнер = НайденныйКонтрагент.Партнер;
        
        НоваяСтрока.Сумма = СтрИзФайла.Сумма;
        
    КонецЦикла;
    
    // Возвращаем измененный объект обратно в данные формы
    ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

КонецПроцедуры

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

← На главную