При разработке обработок для автоматического заполнения документов в современных конфигурациях, таких как 1С:ERP 2, Комплексная автоматизация 2 или Управление торговлей 11, программисты часто сталкиваются с ситуацией, когда прямое присваивание значения в колонку табличной части не приносит результата. Особенно это актуально для колонки ОбъектРасчетов. Разберем подробно, почему так происходит, и как правильно реализовать заполнение этих данных.
Рассмотрим ситуацию: у нас есть документ, в котором не заполнены колонки, отвечающие за расчеты с партнерами. Попытка просто присвоить ссылку на заказ или накладную напрямую в поле Строка.ОбъектРасчетов часто приводит к тому, что значение остается в состоянии Неопределено или очищается при записи. Проанализируем, почему это происходит.
В современных типовых решениях поле ОбъектРасчетов имеет составной тип данных, определяемый через ОпределяемыйТип.ОбъектРасчетов. Важно понимать, что в последних версиях систем (начиная с УТ 11.4/11.5 и ERP 2.4/2.5) расчеты ведутся не напрямую по документам, а через специальный вспомогательный справочник ОбъектыРасчетов. Если вы пытаетесь записать в это поле ссылку на ДокументСсылка.ЗаказКлиента, а система ожидает ссылку на СправочникСсылка.ОбъектыРасчетов, то из-за несовпадения типов данных значение не будет установлено.
Прежде чем приступать к написанию кода, откроем конфигуратор и найдем ОпределяемыйТип.ОбъектРасчетов. Нам необходимо выяснить, какие типы данных входят в его состав. Если в списке типов присутствует СправочникСсылка.ОбъектыРасчетов, значит, система использует новую архитектуру взаиморасчетов. В этом случае нам нужно не просто найти документ-основание, но и получить ссылку на соответствующий элемент этого справочника, который «завернут» вокруг нашего документа.
В исходном примере кода запрос выполнялся внутри цикла по строкам табличной части. Это является серьезной ошибкой проектирования, так как многократно увеличивает нагрузку на сервер базы данных. Переработаем алгоритм: сначала соберем все необходимые данные одним запросом, а затем распределим их по строкам.
Рассмотрим правильный подход к подготовке данных:
// 1. Собираем массив документов-оснований из ТЧ для пакетного поиска
МассивОснований = ДокументОбъект.РасчетыСПартнерами.ВыгрузитьКолонку("ЗаказКлиента");
// 2. Выполняем один запрос ко всем нужным данным
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОбъектыРасчетов.Ссылка КАК ОбъектРасчетов,
| ОбъектыРасчетов.Объект КАК ДокументОснование,
| ОбъектыРасчетов.ТипОбъектаРасчетов КАК ТипОбъекта
|ИЗ
| Справочник.ОбъектыРасчетов КАК ОбъектыРасчетов
|ГДЕ
| ОбъектыРасчетов.Объект В(&МассивОснований)";
Запрос.УстановитьПараметр("МассивОснований", МассивОснований);
ТаблицаСоответствий = Запрос.Выполнить().Выгрузить();
Если запрос не вернул существующий элемент справочника ОбъектыРасчетов, его необходимо создать. В типовых конфигурациях крайне не рекомендуется делать это вручную через СоздатьЭлемент(). Для этих целей существует программный интерфейс (API) в общих модулях.
Проанализируем использование функции ДенежныеСредстваСервер.НайтиИлиСоздатьОбъектРасчетов. Этот метод самостоятельно проверит наличие записи в справочнике и, если её нет, создаст новую с правильным заполнением всех реквизитов, включая ТипОбъектаРасчетов.
Теперь объединим всё вышесказанное в итоговый алгоритм. Мы будем обходить строки табличной части и устанавливать значения, используя подготовленную таблицу или обращаясь к системным функциям.
ДокументОбъект = ДокСсылка.ПолучитьОбъект();
Для каждого СтрокаТЧ из ДокументОбъект.РасчетыСПартнерами Цикл
// Если объект расчетов уже заполнен, пропускаем
Если ЗначениеЗаполнено(СтрокаТЧ.ОбъектРасчетов) Тогда
Продолжить;
КонецЕсли;
// Пытаемся найти объект расчетов через типизированный поиск
// В параметрах передаем документ-основание, партнера, контрагента и договор
ПараметрыОбъекта = Новый Структура;
ПараметрыОбъекта.Вставить("Объект", СтрокаТЧ.ЗаказКлиента);
ПараметрыОбъекта.Вставить("Партнер", ДокументОбъект.Партнер);
ПараметрыОбъекта.Вставить("Контрагент", ДокументОбъект.Контрагент);
ПараметрыОбъекта.Вставить("Договор", ДокументОбъект.Договор);
// Используем типовой метод конфигурации (имя модуля может зависеть от версии ERP/УТ)
ОбъектРасчетовСсылка = ДенежныеСредстваСервер.НайтиИлиСоздатьОбъектРасчетов(
ПараметрыОбъекта.Объект,
ПараметрыОбъекта
);
Если ЗначениеЗаполнено(ОбъектРасчетовСсылка) Тогда
СтрокаТЧ.ОбъектРасчетов = ОбъектРасчетовСсылка;
// Не забываем заполнить тип объекта расчетов, если это отдельная колонка
// Обычно это перечисление: Перечисления.ТипыОбъектовРасчетов.Заказ
Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ТипОбъектаРасчетов", "РасчетыСПартнерами", ДокументОбъект.Метаданные()) Тогда
СтрокаТЧ.ТипОбъектаРасчетов = ОбъектРасчетовСсылка.ТипОбъектаРасчетов;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Записываем документ с проведением, чтобы обновить регистры
Если ДокументОбъект.Модифицирован() Тогда
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
Разберем нюансы финального этапа работы с документом. Простого вызова метода Записать(РежимЗаписиДокумента.Запись) недостаточно. Поскольку ОбъектРасчетов напрямую влияет на движения в регистрах накопления (таких как Расчеты с клиентами или Расчеты по срокам), документ обязательно должен быть перепроведен.
Обратите внимание: в некоторых случаях типовой механизм проведения может попытаться пересчитать и перезаполнить объекты расчетов автоматически. Если после работы вашей обработки данные снова «слетают», следует выяснить, не включена ли в документе настройка, заставляющая систему игнорировать ручное заполнение аналитики расчетов.
Подводя итог, выделим ключевые правила работы со строками ТЧ при заполнении расчетов:
ОбъектРасчетов — это чаще всего ссылка на справочник, а не на документ.НайтиИлиСоздатьОбъектРасчетов гарантирует целостность данных в системе и корректную работу отчетов по дебиторской задолженности.ТипОбъектаРасчетов, чтобы избежать логических ошибок при проведении.Используя этот системный подход, вы сможете корректно автоматизировать заполнение любых документов, связанных с движением денежных средств и задолженностью, обеспечив корректность учета в базе данных.