Как в 1С:Конвертации Данных 2 подставить значение справочника в табличную часть в зависимости от реквизита перечисления шапки документа?

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

При работе с 1С:Конвертацией Данных 2 (КД 2) нередко возникает необходимость динамически заполнять реквизиты табличных частей документа-приемника. Одна из таких распространенных задач – подстановка определенного элемента справочника в табличную часть в зависимости от значения реквизита типа «Перечисление» в шапке документа-источника. Рассмотрим подробно несколько подходов к решению этой задачи на примере документа «Поступление доп. расходов» в конфигурации 1С:Комплексная автоматизация 1 (КА 1) и его реквизита шапки «СпособыРаспределенияДопРасходов».

Предположим, у нас есть документ «Поступление доп. расходов» с реквизитом шапки СпособыРаспределенияДопРасходов (тип Перечисление). В табличной части документа-приемника нам нужно заполнить реквизит СтатьяРасходов (тип Справочник.СтатьиРасходов) таким образом, чтобы при значении Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству подставлялся один элемент справочника (например, с кодом «0000001»), а при Перечисления.СпособыРаспределенияДопРасходов.ПоСумме — другой (например, с кодом «0000002»).

Решение 1: Использование ПКО «Перечисление – Справочник» с поиском по коду

Этот подход является одним из наиболее типовых и декларативных в КД 2. Он позволяет централизованно управлять логикой сопоставления типов данных и поиском элементов.

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

  2. Настраиваем ПКС для реквизита табличной части. В ПКО документа-источника находим табличную часть, в которой находится реквизит СтатьяРасходов, и создаем или редактируем ПКС для этого реквизита.

    • В качестве Источника для этого ПКС мы указываем пустые поля (если СтатьяРасходов в источнике не соответствует напрямую).
    • В качестве Приемника указываем наш реквизит СтатьяРасходов в табличной части документа-приемника.
    • Самое главное, для этого ПКС нам нужно указать Правило конвертации, которое будет использоваться для преобразования исходного значения в ссылку на элемент справочника. Мы создадим новое ПКО специально для этой цели.
  3. Создаем новое ПКО «Перечисление – Справочник».

    • В конфигурации КД 2 создаем новое Правило Конвертации Объектов (ПКО).
    • В качестве Источника для этого ПКО выбираем наше перечисление: Перечисление.СпособыРаспределенияДопРасходов.
    • В качестве Приемника выбираем справочник: Справочник.СтатьиРасходов.
    • Переходим на вкладку «Поиск» этого нового ПКО. Устанавливаем флаг «Поиск по полям» и в списке полей для поиска выбираем «Код». Это означает, что КД 2 будет искать элемент справочника СтатьиРасходов по значению, которое будет передано в качестве кода.
    • Настраиваем ПКС для поля «Код» внутри этого ПКО. На вкладке «Свойства» этого ПКО («Перечисление.СпособыРаспределенияДопРасходов» → «Справочник.СтатьиРасходов») создаем или редактируем ПКС для свойства Код приемника.
    • В событии «Перед выгрузкой» для этого ПКС (для поля Код) пишем код, который сопоставляет значение перечисления с нужным кодом справочника:
      
      Если Источник = Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству Тогда
          Значение = "0000001";
      ИначеЕсли Источник = Перечисления.СпособыРаспределенияДопРасходов.ПоСумме Тогда
          Значение = "0000002";
      Иначе
          // Если способ распределения не соответствует ни одному из известных,
          // можно установить код по умолчанию или вызвать исключение.
          Значение = "0000000"; // Пример кода по умолчанию
          // ВызватьИсключение "Неизвестный способ распределения: " + Строка(Источник);
      КонецЕсли;
      

      Здесь переменная Источник в контексте этого ПКО будет содержать значение перечисления, переданное из основного ПКС табличной части.

  4. Возвращаемся к ПКС для реквизита СтатьяРасходов в табличной части (из пункта 2) и настраиваем его окончательно.

    • В поле «Правило конвертации» для этого ПКС указываем только что созданное ПКО «Перечисление – Справочник» (например, ПеречислениеСпособыРаспределенияДопРасходов_СтатьиРасходов).
    • В событии «Перед выгрузкой» для этого ПКС (для реквизита СтатьяРасходов табличной части) нам нужно передать значение перечисления из шапки документа в созданное ПКО. Код будет выглядеть так: Значение = Источник.СпособРаспределения;

      Переменная Источник здесь относится к текущему объекту табличной части, но для получения значения из шапки мы обращаемся к свойству Источник.СпособРаспределения. Это значение (перечисление) будет передано в наше ПКО «Перечисление – Справочник», где уже будет преобразовано в код справочника для поиска.

Преимущества этого подхода: Он декларативен, логика сопоставления находится в одном месте (в ПКО «Перечисление – Справочник») и легко поддерживается. КД 2 эффективно использует свой встроенный механизм поиска.

Решение 2: Использование параметров в ПКО

Этот метод предоставляет большую гибкость, особенно если таблица соответствий между способом распределения и статьей расходов может быть сложной или динамической. Мы будем использовать коллекцию Параметры, доступную в КД 2.

  1. Заполняем параметры в ПКО документа. Мы начнем с того, что определим соответствие между значениями перечисления и кодами справочников в коллекции Параметры на уровне ПКО всего документа. Это можно сделать в событии «Перед выгрузкой» (или «После выгрузки», в зависимости от контекста, когда вам нужны эти параметры) основного ПКО документа-источника:

    
    // В событии "Перед выгрузкой" или "После выгрузки" ПКО документа-источника (например, Документ.ПоступлениеДопРасходов)
    Параметры.Вставить("КодыСтатейПоСпособу", Новый Соответствие());
    Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству, "0000001");
    Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоСумме, "0000002");
    // При необходимости можно добавить другие соответствия
    

    Мы создали соответствие, где ключом является значение перечисления, а значением — строковый код элемента справочника.

  2. Используем параметры в ПКС для реквизита табличной части. Теперь, в ПКС для реквизита СтатьяРасходов в табличной части (источник пуст, приемник — СтатьяРасходов), в событии «Перед выгрузкой», мы обращаемся к этим параметрам:

    
    // В событии "Перед выгрузкой" ПКС для реквизита "СтатьяРасходов" табличной части
    КодыСтатейПоСпособу = Параметры.Получить("КодыСтатейПоСпособу");
    КодДляПоиска = "";
    
    Если КодыСтатейПоСпособу <> Неопределено И КодыСтатейПоСпособу.ЕстьКлюч(Источник.СпособРаспределения) Тогда
        КодДляПоиска = КодыСтатейПоСпособу[Источник.СпособРаспределения];
                
        // Теперь, когда у нас есть код, мы можем найти элемент справочника
        // Используем стандартную функцию КД для поиска ссылки по строковому представлению
        Значение = ЗначениеИзСтрокиВСсылку("Справочник.СтатьиРасходов", КодДляПоиска, "Код");
                
        Если Значение = Неопределено Тогда
            // Важно предусмотреть обработку ситуации, если элемент по коду не найден
            ВызватьИсключение "Не найдена статья расходов с кодом: " + КодДляПоиска + " для способа распределения: " + Строка(Источник.СпособРаспределения);
        КонецЕсли;
    Иначе
        // Если соответствие не найдено или параметр не был задан,
        // устанавливаем неопределенное значение или значение по умолчанию
        Значение = Неопределено;
        // Можно также вызвать исключение, если такая ситуация недопустима
        // ВызватьИсключение "Не найдено соответствие для способа распределения: " + Строка(Источник.СпособРаспределения);
    КонецЕсли;
    

    Функция ЗначениеИзСтрокиВСсылку() является одной из универсальных функций КД 2, которая позволяет найти ссылку на объект по его строковому представлению (коду, наименованию или другим полям).

Преимущества этого подхода: Высокая гибкость, удобство в администрировании соответствий (они могут быть легко изменены в одном месте). Отделение логики сопоставления от непосредственного присвоения значения. Особенно полезно, когда количество сопоставляемых значений велико или правила сопоставления сложны.

Решение 3: Программный поиск элемента справочника в событии «ПередВыгрузкой» ПКС табличной части

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

  1. Создаем/редактируем ПКС для реквизита табличной части. В ПКО документа-источника, для табличной части, создаем или редактируем ПКС для реквизита СтатьяРасходов. В качестве Источника указываем пустые поля, в качестве Приемника — реквизит СтатьяРасходов.

  2. Реализуем логику поиска в событии «Перед выгрузкой». В событии «Перед выгрузкой» этого ПКС пишем код, который будет определять нужный код справочника и затем искать его в базе-приемнике:

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

Преимущества этого подхода: Простота реализации для небольшого количества условий, отсутствие необходимости в создании дополнительных ПКО. Вся логика находится непосредственно там, где присваивается значение. Недостатки: Менее декларативный подход. При большом количестве условий код может стать громоздким и сложным для поддержки. Логика сопоставления «размазывается» по коду.

Общие рекомендации и важные моменты

  1. Место размещения кода: Все предложенные решения используют событие «Перед выгрузкой» Правила Конвертации Свойств (ПКС) для реквизита табличной части. Это гарантирует, что значение будет определено до того, как КД 2 попытается его выгрузить и записать в документ-приемник.

  2. Типы значений: Убедитесь, что переменная Значение в коде всегда получает ссылку на элемент справочника (тип СправочникСсылка.<ИмяСправочника>), а не просто строковый код или наименование. Функции типа ЗначениеИзСтрокиВСсылку() или механизмы ПКО «Источник – Приемник» с поиском автоматически преобразуют строковые или перечислимые значения в ссылки.

  3. Обработка ошибок: Всегда предусматривайте ситуации, когда элемент справочника не может быть найден по заданным критериям. Используйте ВызватьИсключение, чтобы прекратить обмен с подробным сообщением об ошибке, или устанавливайте значение по умолчанию (если это допустимо бизнес-логикой).

  4. Отладка: Активно используйте режим отладки в КД 2. Вы можете установить точки останова в коде событий «Перед выгрузкой», чтобы пошагово просмотреть выполнение и убедиться, что значения присваиваются правильно. Также полезно изучать «Протокол обмена» после выполнения обмена, чтобы видеть, какие данные были конвертированы и какие ошибки возникли.

  5. Оптимизация: При большом количестве строк в табличной части и сложном сопоставлении, если вы используете программный поиск (Решение 3) или поиск через параметры (Решение 2) с функцией ЗначениеИзСтрокиВСсылку(), подумайте о предварительной загрузке всех необходимых статей расходов в Соответствие или ТаблицуЗначений в событии «Перед выгрузкой» основного ПКО документа. Это позволит избежать многократных обращений к базе данных для поиска одного и того же элемента и ускорит обмен.

    
    // Пример оптимизации: загрузка статей расходов в соответствие в ПКО документа
    // В событии "Перед выгрузкой" ПКО документа-источника
    
    // Создаем соответствие для кеширования найденных статей расходов
    Параметры.Вставить("КешСтатейРасходов", Новый Соответствие()); 
    
    // Заполняем соответствие кодов из перечисления
    Параметры.Вставить("КодыСтатейПоСпособу", Новый Соответствие());
    Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоКоличеству, "0000001");
    Параметры.КодыСтатейПоСпособу.Вставить(Перечисления.СпособыРаспределенияДопРасходов.ПоСумме, "0000002");
    
    // В ПКС табличной части, в ПередВыгрузке:
    КодыСтатейПоСпособу = Параметры.Получить("КодыСтатейПоСпособу");
    КешСтатейРасходов = Параметры.Получить("КешСтатейРасходов");
    
    Если КодыСтатейПоСпособу.ЕстьКлюч(Источник.СпособРаспределения) Тогда
        КодДляПоиска = КодыСтатейПоСпособу[Источник.СпособРаспределения];
        Если КешСтатейРасходов.ЕстьКлюч(КодДляПоиска) Тогда
            Значение = КешСтатейРасходов[КодДляПоиска];
        Иначе
            ОбъектСсылка = ЗначениеИзСтрокиВСсылку("Справочник.СтатьиРасходов", КодДляПоиска, "Код");
            Если ОбъектСсылка <> Неопределено Тогда
                Значение = ОбъектСсылка;
                КешСтатейРасходов.Вставить(КодДляПоиска, Значение); // Кешируем найденное значение
            Иначе
                ВызватьИсключение "Не найдена статья расходов с кодом: " + КодДляПоиска;
            КонецЕсли;
        КонецЕсли;
    Иначе
        Значение = Неопределено;
    КонецЕсли;
    

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

← На главную