Как правильно выгрузить справочник по параметрам в «1С:Конвертация данных 2.1» и исправить типичные ошибки кода

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

При переносе данных между конфигурациями (например, из «1С:Документооборот 1.3» в «1С:Документооборот 2.1») разработчики часто сталкиваются с необходимостью выгрузить элементы справочников выборочно — за определенный период или по конкретным условиям. В процессе настройки правил в конфигурации «1С:Конвертация данных 2.1» (КД) могут возникнуть неочевидные логические ошибки и сбои контекста выполнения кода. В этой статье мы подробно разберем, как правильно реализовать выгрузку данных по параметрам, исправить логические нестыковки в условиях и устранить частую ошибку Значение не является значением объектного типа.

Часть 1. Исправление логической ошибки при фильтрации по периоду

Рассмотрим стандартную ситуацию. Разработчику необходимо выгрузить элементы справочника ИсходящиеДокументы за определенный период, например, за январь 2019 года. Для этого в правилах обмена создаются два параметра: ДатаНач (01.01.2019) и ДатаКон (31.01.2019). Начинающие специалисты часто пишут код фильтрации в обработчике «Перед выгрузкой» следующим образом:


Если Объект.ДатаРегистрации <= Параметры.ДатаНач И Объект.ДатаРегистрации >= Параметры.ДатаКон Тогда
    Отказ = ИСТИНА;
КонецЕсли;

Проанализируем этот код. В данном условии используется логический оператор И. Для того чтобы сработал отказ от выгрузки (Отказ = ИСТИНА), дата регистрации документа должна быть одновременно меньше или равна начальной дате (01.01.2019) И больше или равна конечной дате (31.01.2019). Физически ни одна дата не может отвечать этому условию одновременно. В результате условие никогда не выполняется, и система выгружает абсолютно все документы без фильтрации.

Для исправления этой логической ошибки нам необходимо использовать оператор ИЛИ либо применить отрицание. Рассмотрим правильные варианты написания кода:

Вариант 1. Использование логического оператора ИЛИ:


Если Объект.ДатаРегистрации < Параметры.ДатаНач ИЛИ Объект.ДатаРегистрации > Параметры.ДатаКон Тогда
    Отказ = ИСТИНА;
КонецЕсли;

Этот вариант наиболее прост для понимания: если дата документа выходит за рамки нашего диапазона (меньше начала либо больше окончания), мы отказываемся от его выгрузки.

Вариант 2. Отрицание вхождения в диапазон:


Если НЕ (Объект.ДатаРегистрации >= Параметры.ДатаНач И Объект.ДатаРегистрации <= Параметры.ДатаКон) Тогда
    Отказ = ИСТИНА;
КонецЕсли;

Здесь мы явно задаем диапазон отбора, а оператор НЕ отсекает всё, что в него не попадает.

Часть 2. Оптимизация производительности: «Стандартная выборка» против «Произвольного алгоритма»

Использование обработчика «Перед выгрузкой» в правилах выгрузки данных (ПВД) со стандартной выборкой — очень неэффективное решение для баз с большим объемом данных, таких как «1С:Документооборот».

Выясним причину низкой скорости работы. При стандартном способе выборки платформа «1С:Предприятие» сначала считывает из базы данных абсолютно все документы справочника, создает для каждого из них объект в оперативной памяти и только после этого запускает код обработчика «Перед выгрузкой». Если в вашей базе сотни тысяч документов, а выгрузить нужно всего сто за один месяц, система все равно прогонит через память терабайты информации. Это приведет к колоссальному падению скорости обмена и риску получить ошибку Недостаточно памяти.

Для оптимизации процесса мы рекомендуем перевести ПВД в режим «Произвольный алгоритм» и выбирать документы запросом на уровне СУБД. Пошагово разберем, как это сделать:

  1. Откройте настройки ПВД для нужного справочника.
  2. Установите способ выборки данных: Произвольный алгоритм.
  3. В обработчике «Перед обработкой» напишите запрос, который вернет только отфильтрованные данные:

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ИсходящиеДокументы.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.ИсходящиеДокументы КАК ИсходящиеДокументы
    |ГДЕ
    |   ИсходящиеДокументы.ДатаРегистрации МЕЖДУ &ДатаНач И &ДатаКон";

Запрос.УстановитьПараметр("ДатаНач", Параметры.ДатаНач);
// Важно использовать КонецДня для конечной даты, чтобы захватить документы, созданные в последний день периода
Запрос.УстановитьПараметр("ДатаКон", КонецДня(Параметры.ДатаКон));

ВыборкаДанных = Запрос.Выполнить().Выгрузить();

При таком подходе база данных вернет только строго подходящие под период документы, а скорость выполнения выгрузки возрастет в десятки раз.

Часть 3. Разбор ошибки «Значение не является значением объектного типа»

Вторая частая проблема возникает при попытке наложить фильтр по дополнительным реквизитам справочника. Например, нам нужно отсечь недействительные элементы:


Если Объект.Недействителен = ИСТИНА Тогда
    Отказ = ИСТИНА;
КонецЕсли;

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

Причина 1. Смешение контекстов ПВД и ПКО (Объект vs Источник)

В КД 2.1 крайне важно понимать, в каком именно обработчике выполняется код:

Если вы скопировали код из ПВД в ПКО (например, в обработчик «Перед выгрузкой» ПКО), то обращение к Объект.Недействителен вызовет указанную ошибку, так как система попытается прочитать свойство у пустого значения. Правильный код для ПКО должен выглядеть следующим образом:


Если Источник.Недействителен Тогда
    Отказ = ИСТИНА;
КонецЕсли;

Причина 2. Иерархическая структура справочника (Группы и Элементы)

Если справочник является иерархическим (содержит папки и элементы), то при выгрузке система обрабатывает в том числе и группы (папки). У групп справочника в метаданных может отсутствовать реквизит Недействителен (он назначен только для элементов). Попытка прочитать этот реквизит у папки вызовет ошибку объектного типа.

Решением является предварительная проверка на то, является ли объект группой:


// Пример для ПКО с проверкой на группу
Если Источник.ЭтоГруппа Тогда
    // Если папки выгружать не нужно, раскомментируйте строку ниже:
    // Отказ = ИСТИНА;
ИначеЕсли Источник.Недействителен Тогда
    Отказ = ИСТИНА;
КонецЕсли;

Причина 3. Битая или пустая ссылка

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


Если НЕ ЗначениеЗаполнено(Источник) Тогда
    Отказ = ИСТИНА;
ИначеЕсли Источник.Недействителен Тогда
    Отказ = ИСТИНА;
КонецЕсли;

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

← На главную