При работе с 1С:Конвертацией Данных 2 (КД 2) нередко возникает необходимость динамически заполнять реквизиты табличных частей документа-приемника. Одна из таких распространенных задач – подстановка определенного элемента справочника в табличную часть в зависимости от значения реквизита типа «Перечисление» в шапке документа-источника. Рассмотрим подробно несколько подходов к решению этой задачи на примере документа «Поступление доп. расходов» в конфигурации 1С:Комплексная автоматизация 1 (КА 1) и его реквизита шапки «СпособыРаспределенияДопРасходов».
Предположим, у нас есть документ «Поступление доп. расходов» с реквизитом шапки СпособыРаспределенияДопРасходов (тип Перечисление). В табличной части документа-приемника нам нужно заполнить реквизит СтатьяРасходов (тип Справочник.СтатьиРасходов) таким образом, чтобы при значении Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству подставлялся один элемент справочника (например, с кодом «0000001»), а при Перечисления.СпособыРаспределенияДопРасходов.ПоСумме — другой (например, с кодом «0000002»).
Этот подход является одним из наиболее типовых и декларативных в КД 2. Он позволяет централизованно управлять логикой сопоставления типов данных и поиском элементов.
Создаем ПКО для документа-источника и документа-приемника. Для этого мы открываем Правило Конвертации Объектов (ПКО) нашего документа-источника (например, Документ.ПоступлениеДопРасходов) и указываем соответствующий документ-приемник. В этом ПКО нам необходимо будет настроить Правило Конвертации Свойств (ПКС) для табличной части.
Настраиваем ПКС для реквизита табличной части. В ПКО документа-источника находим табличную часть, в которой находится реквизит СтатьяРасходов, и создаем или редактируем ПКС для этого реквизита.
СтатьяРасходов в источнике не соответствует напрямую).СтатьяРасходов в табличной части документа-приемника.Создаем новое ПКО «Перечисление – Справочник».
Перечисление.СпособыРаспределенияДопРасходов.Справочник.СтатьиРасходов.СтатьиРасходов по значению, которое будет передано в качестве кода.Код приемника.Код) пишем код, который сопоставляет значение перечисления с нужным кодом справочника:
Если Источник = Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству Тогда
Значение = "0000001";
ИначеЕсли Источник = Перечисления.СпособыРаспределенияДопРасходов.ПоСумме Тогда
Значение = "0000002";
Иначе
// Если способ распределения не соответствует ни одному из известных,
// можно установить код по умолчанию или вызвать исключение.
Значение = "0000000"; // Пример кода по умолчанию
// ВызватьИсключение "Неизвестный способ распределения: " + Строка(Источник);
КонецЕсли;
Здесь переменная Источник в контексте этого ПКО будет содержать значение перечисления, переданное из основного ПКС табличной части.
Возвращаемся к ПКС для реквизита СтатьяРасходов в табличной части (из пункта 2) и настраиваем его окончательно.
ПеречислениеСпособыРаспределенияДопРасходов_СтатьиРасходов).СтатьяРасходов табличной части) нам нужно передать значение перечисления из шапки документа в созданное ПКО. Код будет выглядеть так:
Значение = Источник.СпособРаспределения;
Переменная Источник здесь относится к текущему объекту табличной части, но для получения значения из шапки мы обращаемся к свойству Источник.СпособРаспределения. Это значение (перечисление) будет передано в наше ПКО «Перечисление – Справочник», где уже будет преобразовано в код справочника для поиска.
Преимущества этого подхода: Он декларативен, логика сопоставления находится в одном месте (в ПКО «Перечисление – Справочник») и легко поддерживается. КД 2 эффективно использует свой встроенный механизм поиска.
Этот метод предоставляет большую гибкость, особенно если таблица соответствий между способом распределения и статьей расходов может быть сложной или динамической. Мы будем использовать коллекцию Параметры, доступную в КД 2.
Заполняем параметры в ПКО документа. Мы начнем с того, что определим соответствие между значениями перечисления и кодами справочников в коллекции Параметры на уровне ПКО всего документа. Это можно сделать в событии «Перед выгрузкой» (или «После выгрузки», в зависимости от контекста, когда вам нужны эти параметры) основного ПКО документа-источника:
// В событии "Перед выгрузкой" или "После выгрузки" ПКО документа-источника (например, Документ.ПоступлениеДопРасходов)
Параметры.Вставить("КодыСтатейПоСпособу", Новый Соответствие());
Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству, "0000001");
Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоСумме, "0000002");
// При необходимости можно добавить другие соответствия
Мы создали соответствие, где ключом является значение перечисления, а значением — строковый код элемента справочника.
Используем параметры в ПКС для реквизита табличной части. Теперь, в ПКС для реквизита СтатьяРасходов в табличной части (источник пуст, приемник — СтатьяРасходов), в событии «Перед выгрузкой», мы обращаемся к этим параметрам:
// В событии "Перед выгрузкой" ПКС для реквизита "СтатьяРасходов" табличной части
КодыСтатейПоСпособу = Параметры.Получить("КодыСтатейПоСпособу");
КодДляПоиска = "";
Если КодыСтатейПоСпособу <> Неопределено И КодыСтатейПоСпособу.ЕстьКлюч(Источник.СпособРаспределения) Тогда
КодДляПоиска = КодыСтатейПоСпособу[Источник.СпособРаспределения];
// Теперь, когда у нас есть код, мы можем найти элемент справочника
// Используем стандартную функцию КД для поиска ссылки по строковому представлению
Значение = ЗначениеИзСтрокиВСсылку("Справочник.СтатьиРасходов", КодДляПоиска, "Код");
Если Значение = Неопределено Тогда
// Важно предусмотреть обработку ситуации, если элемент по коду не найден
ВызватьИсключение "Не найдена статья расходов с кодом: " + КодДляПоиска + " для способа распределения: " + Строка(Источник.СпособРаспределения);
КонецЕсли;
Иначе
// Если соответствие не найдено или параметр не был задан,
// устанавливаем неопределенное значение или значение по умолчанию
Значение = Неопределено;
// Можно также вызвать исключение, если такая ситуация недопустима
// ВызватьИсключение "Не найдено соответствие для способа распределения: " + Строка(Источник.СпособРаспределения);
КонецЕсли;
Функция ЗначениеИзСтрокиВСсылку() является одной из универсальных функций КД 2, которая позволяет найти ссылку на объект по его строковому представлению (коду, наименованию или другим полям).
Преимущества этого подхода: Высокая гибкость, удобство в администрировании соответствий (они могут быть легко изменены в одном месте). Отделение логики сопоставления от непосредственного присвоения значения. Особенно полезно, когда количество сопоставляемых значений велико или правила сопоставления сложны.
Этот метод является наиболее прямым и подходит, если количество условий невелико и нет необходимости в создании дополнительных ПКО для перечислений. Вся логика реализуется непосредственно в одном ПКС.
Создаем/редактируем ПКС для реквизита табличной части. В ПКО документа-источника, для табличной части, создаем или редактируем ПКС для реквизита СтатьяРасходов. В качестве Источника указываем пустые поля, в качестве Приемника — реквизит СтатьяРасходов.
Реализуем логику поиска в событии «Перед выгрузкой». В событии «Перед выгрузкой» этого ПКС пишем код, который будет определять нужный код справочника и затем искать его в базе-приемнике:
// В событии "Перед выгрузкой" ПКС для реквизита "СтатьяРасходов" табличной части
ИмяСправочника = "Справочник.СтатьиРасходов"; // Указываем полное имя справочника-приемника
КодДляПоиска = "";
Если Источник.СпособРаспределения = Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству Тогда
КодДляПоиска = "0000001";
ИначеЕсли Источник.СпособРаспределения = Перечисления.СпособыРаспределенияДопРасходов.ПоСумме Тогда
КодДляПоиска = "0000002";
Иначе
// Обработка случая, если способ распределения не соответствует ни одному из известных
// Можно установить значение по умолчанию, если оно допустимо
// Или вызвать исключение, чтобы сигнализировать об ошибке
Значение = Неопределено;
// ВызватьИсключение "Неизвестный способ распределения в документе: " + Строка(Источник.СпособРаспределения);
КонецЕсли;
Если Не ПустаяСтрока(КодДляПоиска) Тогда
// Используем стандартную функцию КД для поиска ссылки по коду
ОбъектСсылка = ЗначениеИзСтрокиВСсылку(ИмяСправочника, КодДляПоиска, "Код");
Если ОбъектСсылка <> Неопределено Тогда
Значение = ОбъектСсылка;
Иначе
// Важно предусмотреть обработку ситуации, если элемент по коду не найден
ВызватьИсключение "Не найден элемент справочника " + ИмяСправочника + " по коду " + КодДляПоиска + " для способа распределения: " + Строка(Источник.СпособРаспределения);
КонецЕсли;
Иначе
Значение = Неопределено; // Если код для поиска не определен, значение не устанавливается
КонецЕсли;
Преимущества этого подхода: Простота реализации для небольшого количества условий, отсутствие необходимости в создании дополнительных ПКО. Вся логика находится непосредственно там, где присваивается значение. Недостатки: Менее декларативный подход. При большом количестве условий код может стать громоздким и сложным для поддержки. Логика сопоставления «размазывается» по коду.
Место размещения кода: Все предложенные решения используют событие «Перед выгрузкой» Правила Конвертации Свойств (ПКС) для реквизита табличной части. Это гарантирует, что значение будет определено до того, как КД 2 попытается его выгрузить и записать в документ-приемник.
Типы значений: Убедитесь, что переменная Значение в коде всегда получает ссылку на элемент справочника (тип СправочникСсылка.<ИмяСправочника>), а не просто строковый код или наименование. Функции типа ЗначениеИзСтрокиВСсылку() или механизмы ПКО «Источник – Приемник» с поиском автоматически преобразуют строковые или перечислимые значения в ссылки.
Обработка ошибок: Всегда предусматривайте ситуации, когда элемент справочника не может быть найден по заданным критериям. Используйте ВызватьИсключение, чтобы прекратить обмен с подробным сообщением об ошибке, или устанавливайте значение по умолчанию (если это допустимо бизнес-логикой).
Отладка: Активно используйте режим отладки в КД 2. Вы можете установить точки останова в коде событий «Перед выгрузкой», чтобы пошагово просмотреть выполнение и убедиться, что значения присваиваются правильно. Также полезно изучать «Протокол обмена» после выполнения обмена, чтобы видеть, какие данные были конвертированы и какие ошибки возникли.
Оптимизация: При большом количестве строк в табличной части и сложном сопоставлении, если вы используете программный поиск (Решение 3) или поиск через параметры (Решение 2) с функцией ЗначениеИзСтрокиВСсылку(), подумайте о предварительной загрузке всех необходимых статей расходов в Соответствие или ТаблицуЗначений в событии «Перед выгрузкой» основного ПКО документа. Это позволит избежать многократных обращений к базе данных для поиска одного и того же элемента и ускорит обмен.
// Пример оптимизации: загрузка статей расходов в соответствие в ПКО документа
// В событии "Перед выгрузкой" ПКО документа-источника
// Создаем соответствие для кеширования найденных статей расходов
Параметры.Вставить("КешСтатейРасходов", Новый Соответствие());
// Заполняем соответствие кодов из перечисления
Параметры.Вставить("КодыСтатейПоСпособу", Новый Соответствие());
Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству, "0000001");
Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоСумме, "0000002");
// В ПКС табличной части, в ПередВыгрузке:
КодыСтатейПоСпособу = Параметры.Получить("КодыСтатейПоСпособу");
КешСтатейРасходов = Параметры.Получить("КешСтатейРасходов");
Если КодыСтатейПоСпособу.ЕстьКлюч(Источник.СпособРаспределения) Тогда
КодДляПоиска = КодыСтатейПоСпособу[Источник.СпособРаспределения];
Если КешСтатейРасходов.ЕстьКлюч(КодДляПоиска) Тогда
Значение = КешСтатейРасходов[КодДляПоиска];
Иначе
ОбъектСсылка = ЗначениеИзСтрокиВСсылку("Справочник.СтатьиРасходов", КодДляПоиска, "Код");
Если ОбъектСсылка <> Неопределено Тогда
Значение = ОбъектСсылка;
КешСтатейРасходов.Вставить(КодДляПоиска, Значение); // Кешируем найденное значение
Иначе
ВызватьИсключение "Не найдена статья расходов с кодом: " + КодДляПоиска;
КонецЕсли;
КонецЕсли;
Иначе
Значение = Неопределено;
КонецЕсли;
Выбрав один из предложенных подходов, вы сможете эффективно настроить правила обмена в 1С:Конвертации Данных 2 для динамической подстановки значений справочников в табличные части документов, основываясь на логике, определенной реквизитами шапки документа-источника.