Как программно изменить строки и заполнить Объект расчетов в табличной части документа 1С

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

При разработке обработок для автоматического заполнения документов в современных конфигурациях, таких как 1С:ERP 2, Комплексная автоматизация 2 или Управление торговлей 11, программисты часто сталкиваются с ситуацией, когда прямое присваивание значения в колонку табличной части не приносит результата. Особенно это актуально для колонки ОбъектРасчетов. Разберем подробно, почему так происходит, и как правильно реализовать заполнение этих данных.

Анализируем причину проблемы: почему поле остается пустым

Рассмотрим ситуацию: у нас есть документ, в котором не заполнены колонки, отвечающие за расчеты с партнерами. Попытка просто присвоить ссылку на заказ или накладную напрямую в поле Строка.ОбъектРасчетов часто приводит к тому, что значение остается в состоянии Неопределено или очищается при записи. Проанализируем, почему это происходит.

В современных типовых решениях поле ОбъектРасчетов имеет составной тип данных, определяемый через ОпределяемыйТип.ОбъектРасчетов. Важно понимать, что в последних версиях систем (начиная с УТ 11.4/11.5 и ERP 2.4/2.5) расчеты ведутся не напрямую по документам, а через специальный вспомогательный справочник ОбъектыРасчетов. Если вы пытаетесь записать в это поле ссылку на ДокументСсылка.ЗаказКлиента, а система ожидает ссылку на СправочникСсылка.ОбъектыРасчетов, то из-за несовпадения типов данных значение не будет установлено.

Шаг 1: Проверка состава определяемого типа

Прежде чем приступать к написанию кода, откроем конфигуратор и найдем ОпределяемыйТип.ОбъектРасчетов. Нам необходимо выяснить, какие типы данных входят в его состав. Если в списке типов присутствует СправочникСсылка.ОбъектыРасчетов, значит, система использует новую архитектуру взаиморасчетов. В этом случае нам нужно не просто найти документ-основание, но и получить ссылку на соответствующий элемент этого справочника, который «завернут» вокруг нашего документа.

Шаг 2: Оптимизация работы с запросом (отказ от запроса в цикле)

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

Рассмотрим правильный подход к подготовке данных:


// 1. Собираем массив документов-оснований из ТЧ для пакетного поиска
МассивОснований = ДокументОбъект.РасчетыСПартнерами.ВыгрузитьКолонку("ЗаказКлиента");

// 2. Выполняем один запрос ко всем нужным данным
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ОбъектыРасчетов.Ссылка КАК ОбъектРасчетов,
    |	ОбъектыРасчетов.Объект КАК ДокументОснование,
    |	ОбъектыРасчетов.ТипОбъектаРасчетов КАК ТипОбъекта
    |ИЗ
    |	Справочник.ОбъектыРасчетов КАК ОбъектыРасчетов
    |ГДЕ
    |	ОбъектыРасчетов.Объект В(&МассивОснований)";

Запрос.УстановитьПараметр("МассивОснований", МассивОснований);
ТаблицаСоответствий = Запрос.Выполнить().Выгрузить();

Шаг 3: Использование системных механизмов для создания объектов расчетов

Если запрос не вернул существующий элемент справочника ОбъектыРасчетов, его необходимо создать. В типовых конфигурациях крайне не рекомендуется делать это вручную через СоздатьЭлемент(). Для этих целей существует программный интерфейс (API) в общих модулях.

Проанализируем использование функции ДенежныеСредстваСервер.НайтиИлиСоздатьОбъектРасчетов. Этот метод самостоятельно проверит наличие записи в справочнике и, если её нет, создаст новую с правильным заполнением всех реквизитов, включая ТипОбъектаРасчетов.

Шаг 4: Реализация заполнения табличной части

Теперь объединим всё вышесказанное в итоговый алгоритм. Мы будем обходить строки табличной части и устанавливать значения, используя подготовленную таблицу или обращаясь к системным функциям.


ДокументОбъект = ДокСсылка.ПолучитьОбъект();

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

// Записываем документ с проведением, чтобы обновить регистры
Если ДокументОбъект.Модифицирован() Тогда
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;

Важные моменты при записи и проведении

Разберем нюансы финального этапа работы с документом. Простого вызова метода Записать(РежимЗаписиДокумента.Запись) недостаточно. Поскольку ОбъектРасчетов напрямую влияет на движения в регистрах накопления (таких как Расчеты с клиентами или Расчеты по срокам), документ обязательно должен быть перепроведен.

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

Выводы и рекомендации

Подводя итог, выделим ключевые правила работы со строками ТЧ при заполнении расчетов:

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

Используя этот системный подход, вы сможете корректно автоматизировать заполнение любых документов, связанных с движением денежных средств и задолженностью, обеспечив корректность учета в базе данных.

← На главную