Перенос хозяйственных операций из торговых конфигураций (например, Управление торговлей 10.3) в бухгалтерские (Бухгалтерия предприятия) — одна из наиболее частых задач при интеграции систем 1С. Иногда возникает потребность переносить документы не в аналогичные документы приемника, а напрямую в ручные операции — Документ.ОперацияБух. Это актуально при сложных схемах учета, переносе специфической аналитики или свертке данных.
Однако при попытке настроить такой перенос через Конвертацию данных 2 (КД 2) разработчики часто сталкиваются с трудностями при выгрузке субконто дебета и кредита. В этой статье мы подробно разберем, почему возникает популярная ошибка «Итератор для значения не определен», как правильно сформировать коллекцию проводок в коде выгрузки и какие настройки ПКС необходимо выполнить в правилах обмена.
Перед тем как перейти к написанию кода, проанализируем структуру целевого документа. В отличие от стандартных документов конфигурации, у ОперацияБух нет табличной части для хранения проводок на уровне метаданных документа. Все движения формируются и хранятся непосредственно в регистре бухгалтерии Хозрасчетный, где данный документ выступает в роли регистратора.
При переносе данных в ОперацияБух нам необходимо передать не просто реквизиты шапки, а сгенерировать полноценный набор записей регистра бухгалтерии. В КД 2 этот набор передается через виртуальную табличную часть (коллекцию) с именем Хозрасчетный.
Ошибка возникает на этапе выгрузки данных, когда движок Конвертации данных пытается сериализовать свойства СубконтоДт и СубконтоКт в XML-файл. На уровне платформы 1С субконто в регистре бухгалтерии представляют собой специальный тип данных — СубконтоПредопределенныйНабор.
В КД 2 для передачи аналитики используется объект типа Соответствие (или Структура). Если в коде выгрузки передать в качестве субконто одиночное значение (например, напрямую ссылку на справочник Номенклатура или Контрагенты), правила конвертации выдадут ошибку итератора. Алгоритм КД ожидает коллекцию (соответствие ключей и значений), чтобы обойти ее в цикле и записать каждое субконто по порядку.
Рассмотрим по шагам, как исправить эту ошибку и настроить корректные правила выгрузки.
Для того чтобы перенести документ источника (например, Реализацию товаров и услуг) в операцию, нам нужно вручную сформировать таблицу проводок. Напишем запрос к регистру накопления или табличной части исходного документа и соберем коллекцию объектов для выгрузки.
Посмотрим на пример правильного заполнения таблицы переносимых проводок в обработчике «Перед выгрузкой» Правила выгрузки данных (ПВД):
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("НашДокумент", Объект);
Запрос.Текст =
"ВЫБРАТЬ
| ПартииОбороты.Номенклатура КАК Номенклатура,
| ПартииОбороты.КоличествоОборот КАК Количество,
| ПартииОбороты.СтоимостьОборот КАК Стоимость
|ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(,, Регистратор, Регистратор = &НашДокумент) КАК ПартииОбороты";
ТаблицаДвижений = Запрос.Выполнить().Выгрузить();
// Создаем структуру таблицы значений, которая полностью повторяет поля регистра Хозрасчетный
КоллекцияОбъектовТемп = Новый ТаблицаЗначений;
КоллекцияОбъектовТемп.Колонки.Добавить("Сумма");
КоллекцияОбъектовТемп.Колонки.Добавить("Активность");
КоллекцияОбъектовТемп.Колонки.Добавить("Период");
КоллекцияОбъектовТемп.Колонки.Добавить("КоличествоДт");
КоллекцияОбъектовТемп.Колонки.Добавить("КоличествоКт");
КоллекцияОбъектовТемп.Колонки.Добавить("Организация");
КоллекцияОбъектовТемп.Колонки.Добавить("СчетДт");
КоллекцияОбъектовТемп.Колонки.Добавить("СчетКт");
КоллекцияОбъектовТемп.Колонки.Добавить("СубконтоДт"); // Здесь будет Соответствие
КоллекцияОбъектовТемп.Колонки.Добавить("СубконтоКт"); // Здесь будет Соответствие
Для Каждого СтрТТТ Из ТаблицаДвижений Цикл
СтрКоллекция = КоллекцияОбъектовТемп.Добавить();
// Заполняем счета учета (передаем строковый код счета)
СтрКоллекция.СчетДт = "41.11";
СтрКоллекция.СчетКт = "20.01";
СтрКоллекция.КоличествоДт = СтрТТТ.Количество;
СтрКоллекция.Сумма = СтрТТТ.Стоимость;
// ВАЖНО: Инициализируем новые соответствия для субконто
СубконтоДт = Новый Соответствие;
СубконтоКт = Новый Соответствие;
// Формируем структуру поиска для Вида Субконто (План видов характеристик)
// Ключом соответствия должна выступать структура поиска или сам объект ВидСубконто
КлючСубконто = Новый Структура("Наименование", "Номенклатура");
СубконтоДт.Вставить(КлючСубконто, СтрТТТ.Номенклатура);
// Записываем полученные коллекции в строку таблицы
СтрКоллекция.СубконтоДт = СубконтоДт;
СтрКоллекция.СубконтоКт = СубконтоКт; // Передаем пустым, если по Кт нет аналитики
СтрКоллекция.Активность = Истина;
СтрКоллекция.Период = Объект.Дата;
СтрКоллекция.Организация = Объект.Организация;
КонецЦикла;
// Передаем сформированную таблицу через ИсходящиеДанные в ПКО
ИсходящиеДанные = Новый Структура("Дата, Номер, Организация, Хозрасчетный");
ИсходящиеДанные.Дата = Объект.Дата;
ИсходящиеДанные.Номер = Объект.Номер;
ИсходящиеДанные.Организация = Объект.Организация;
ИсходящиеДанные.Хозрасчетный = КоллекцияОбъектовТемп;
Обратите внимание: Для тех строк, где субконто по кредиту отсутствует, мы все равно инициализируем и передаем пустое Соответствие. Это гарантирует, что сериализатор КД 2 не споткнется на значении Неопределено.
После подготовки входящих данных нам необходимо правильно сопоставить свойства в ПКО (Правила конвертации объектов). Для документа ОперацияБух создаем ПКО и настраиваем следующие правила конвертации свойств (ПКС):
Хозрасчетный. Укажите источник данных — пусто, приемник — Движения.Хозрасчетный (или имя коллекции движений регистра). Поставьте флаг «Получить из входящих данных».Хозрасчетный сопоставьте реквизиты проводки: СчетДт, СчетКт, СубконтоДт, СубконтоКт, Сумма и др.СубконтоДт и СубконтоКт необходимо обязательно настроить ПКО. В качестве правила конвертации для них укажите ПКО для плана видов характеристик ВидыСубконтоХозрасчетные.СубконтоДт (и аналогично для СубконтоКт) и в обработчике событий «Перед выгрузкой» напишите следующий код:
ИмяПКОВидСубконто = "ВидыСубконтоХозрасчетные";
Этот код сообщает системе, по какому именно правилу нужно сопоставлять ключи соответствия (виды аналитики), которые мы передали из структуры Новый Структура("Наименование", "Номенклатура").
При переносе проводок "один в один" может возникнуть ситуация, когда состав субконто на счетах учета в источнике и приемнике различается. Например, в базе-источнике на счете 41 настроено три субконто (Номенклатура, Склады, Партии), а в базе-приемнике — только два (Номенклатура, Склады).
Если попытаться записать проводку с лишним субконто, платформа 1С выдаст ошибку при попытке записи набора записей регистра бухгалтерии. Чтобы избежать этого, добавим защитный алгоритм в обработчик «После загрузки» ПКО документа ОперацияБух:
Для Каждого Проводка Из Объект.Движения.Хозрасчетный Цикл
// Проверяем и очищаем лишние субконто по Дебету
Если Проводка.СчетДт.ДоступностьСубконто Тогда
Для Каждого Субконто Из Проводка.СубконтоДт Цикл
ФлагНайдено = Ложь;
Для Каждого ВидСубконтоСчета Из Проводка.СчетДт.ВидыСубконто Цикл
Если ВидСубконтоСчета.ВидСубконто = Субконто.Ключ Тогда
ФлагНайдено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ ФлагНайдено Тогда
Проводка.СубконтоДт.Удалить(Субконто.Ключ);
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Проверяем и очищаем лишние субконто по Кредиту
Если Проводка.СчетКт.ДоступностьСубконто Тогда
Для Каждого Субконто Из Проводка.СубконтоКт Цикл
ФлагНайдено = Ложь;
Для Каждого ВидСубконтоСчета Из Проводка.СчетКт.ВидыСубконто Цикл
Если ВидСубконтоСчета.ВидСубконто = Субконто.Ключ Тогда
ФлагНайдено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ ФлагНайдено Тогда
Проводка.СубконтоКт.Удалить(Субконто.Ключ);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Этот код гарантирует, что в движениях документа останутся только те виды субконто, которые физически настроены на счетах дебета и кредита в целевой базе данных. Программа успешно запишет операцию без аварийного завершения сеанса обмена.
Мы успешно разобрали процесс переноса документов в ручные операции ОперацияБух. Основной секрет стабильной выгрузки субконто кроется в строгом соблюдении типов данных (передача Соответствия в КД 2) и сопоставлении видов субконто через специализированное ПКО. Применение этих правил позволит вам быстро и без ошибок реализовать интеграцию любой сложности.