При разработке правил обмена в конфигурации «Конвертация данных 2.0» (или 2.1) нередко требуется сформировать вспомогательную коллекцию (например, таблицу соответствий или список услуг) в одном обработчике и повторно использовать ее в других обработчиках событий — таких как правила конвертации объектов (ПКО) или правила конвертации свойств (ПКС).
Попытка использовать для этих целей стандартный механизм платформы ПоместитьВоВременноеХранилище часто приводит к тому, что при последующем вызове ПолучитьИзВременногоХранилища возвращается Неопределено или пустая коллекция. Разберем по шагам, почему так происходит и как правильно организовать кэширование данных в рамках сеанса загрузки.
Проанализируем механику работы временного хранилища платформы «1С:Предприятие 8». Когда мы вызываем метод:
Адрес = ПоместитьВоВременноеХранилище(ТаблицаУслуг, Новый УникальныйИдентификатор);
платформа создает запись во временном хранилище, привязанную к вновь созданному идентификатору. Однако время жизни такого объекта ограничено:
ПослеЗагрузкиПараметров к обработчикам ПКО (например, ПослеЗагрузкиОбъекта) может разделяться серверными контекстами, из-за чего данные, помещенные по сгенерированному идентификатору, просто удаляются сборщиком мусора платформы.В «Конвертации данных» механизм обмена предоставляет встроенный глобальный контекст — объект Параметры. На стороне базы-приемника это обычная структура 1С, которая существует на протяжении всего процесса загрузки данных и доступна во всех обработчиках событий.
Нам нет необходимости использовать временное хранилище — достаточно поместить саму ТаблицаЗначений напрямую в структуру Параметры.
Рассмотрим пошаговую реализацию правильного подхода:
В глобальном обработчике конвертации ПослеЗагрузкиПараметров (или ПередЗагрузкойДанных) формируем таблицу и записываем ее в структуру параметров.
// Создаем и заполняем нужную таблицу
ТаблицаУслуг = Новый ТаблицаЗначений;
ТаблицаУслуг.Колонки.Добавить("Номенклатура");
ТаблицаУслуг.Колонки.Добавить("Количество");
ТаблицаУслуг.Колонки.Добавить("СтавкаНДС");
// Добавляем строки по логике обмена
Строка = ТаблицаУслуг.Добавить();
Строка.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Услуга доставки");
Строка.Количество = 1;
// Помещаем таблицу напрямую в глобальную структуру Параметры
Параметры.Вставить("ТаблицаУслуг", ТаблицаУслуг);
Обратите внимание: если параметр используется только внутри базы-приемника как временный кэш или алгоритмическая таблица, объявлять его заранее в дереве параметров конвертации необязательно — метод Вставить() добавит новое свойство динамически.
В обработчике правила конвертации объекта (например, в ПКО документа ПоступлениеТоваровУслуг в событии ПослеЗагрузки) получаем сохраненную таблицу и выполняем требуемую обработку.
// Проверяем наличие параметра перед обращением к нему
Если Параметры.Свойство("ТаблицаУслуг") И ЗначениеЗаполнено(Параметры.ТаблицаУслуг) Тогда
ТЗ = Параметры.ТаблицаУслуг;
// Выполняем действия над загруженным объектом
Для Каждого Стр Из ТЗ Цикл
СтрокаТЧ = Объект.Услуги.Добавить();
СтрокаТЧ.Номенклатура = Стр.Номенклатура;
СтрокаТЧ.Количество = Стр.Количество;
КонецЦикла;
КонецЕсли;
Посмотрим на практические приемы, которые помогают оптимизировать работу с коллекциями в конвертации данных:
НайтиСтроки(), обязательно индексируйте ключевые колонки перед сохранением в Параметры:
ТаблицаУслуг.Индексы.Добавить("Номенклатура");
Соответствие вместо ТаблицаЗначений. Доступ по ключу в Соответствие работает значительно быстрее поиска по колонкам таблицы.ТаблицаЗначений напрямую через XML-параметры не сериализуется. В таком случае в источнике упаковываем ее через ЗначениеВСтрокуВнутр(Таблица), а в приемнике в обработчике ПослеЗагрузкиПараметров восстанавливаем через ЗначениеИзСтрокиВнутр(Параметры.ИмяПараметра).