При работе с Системой компоновки данных (СКД), особенно в случаях использования внешних наборов данных, разработчики часто сталкиваются с неожиданным поведением платформы. Одна из таких проблем — некорректная типизация параметров. Рассмотрим ситуацию: в процедуре ПриКомпоновкеДанных мы пытаемся получить значение параметра, который в схеме определен как ПеречислениеСсылка, но внезапно получаем обычную строку. Это блокирует дальнейшую работу, так как внешние запросы или логика обработки таблиц значений ожидают конкретную ссылку.
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем внутренние механизмы работы СКД с типами и изучим несколько надежных способов решения проблемы.
Разберем типичный сценарий. Разработчик создает отчет на базе СКД, где данные подготавливаются программно. В модуле объекта в процедуре ПриКомпоновкеДанных происходит обращение к параметрам компоновщика настроек. Код выглядит примерно так:
ПараметрЗначение = КомпоновщикНастроек.Настройки.Parameters.FindParameterValue(New DataCompositionParameter("ИмяПараметра"));
Если ПараметрЗначение <> Неопределено Тогда
НужноеЗначение = ПараметрЗначение.Value; // Здесь ожидается ссылка, но приходит строка
КонецЕсли;
Проблема чаще всего проявляется именно с типом ПеречислениеСсылка. Выясним причину: СКД — это сложный механизм, который объединяет основную схему, настройки по умолчанию и пользовательские настройки. Когда параметр выносится в пользовательские настройки (на форму отчета), система оптимизирует хранение данных. Если в самой схеме компоновки данных тип параметра не задан максимально жестко, 1С может передать значение в виде строкового идентификатора, который визуально похож на имя значения перечисления.
Особенно остро это проявляется при использовании внешних наборов данных. В отличие от обычного запроса, где тип параметра может быть «подсказан» самой структурой SQL-запроса, во внешнем наборе данных СКД полностью полагается на описание в макете. Если описание допускает неопределенность, происходит автоматическое приведение к строке.
Одной из главных ошибок является прямое обращение к свойству КомпоновщикНастроек.Настройки. Эти настройки могут не содержать в себе всех изменений, внесенных пользователем в интерфейсе, или содержать их в «сыром» виде. Для получения актуальных и правильно типизированных данных всегда рекомендуется использовать метод ПолучитьНастройки().
Рассмотрим, как изменить подход к получению значений:
// Вместо прямого обращения к КомпоновщикНастроек.Настройки
ПолныеНастройки = КомпоновщикНастроек.GetSettings();
ПараметрОбъект = ПолныеНастройки.DataParameters.FindParameterValue(New DataCompositionParameter("ВыпускПоОперацииСтоимость"));
Если ПараметрОбъект <> Неопределено Тогда
// Теперь вероятность получить корректный тип гораздо выше
ЗначениеПараметра = ПараметрОбъект.Value;
КонецЕсли;
Метод GetSettings() (или ПолучитьНастройки()) выполняет слияние фиксированных и пользовательских настроек, при этом платформа производит дополнительную валидацию типов согласно метаданным, указанным в схеме.
Проанализируем вкладку «Параметры» в макете вашей СКД. Часто разработчики оставляют колонку «Тип» в значении по умолчанию или выбирают составной тип данных. Для перечислений это критично.
Чтобы избежать «остроения» типа, выполните следующие шаги:
ВыпускПоОперацииСтоимость).ПеречислениеСсылка.КодыОперацийПартииТоваров).Важный нюанс: если в колонке «Выражение» у вас написано что-то вроде "Перечисления.КодыОпераций.Выпуск" (в кавычках), 1С воспримет это именно как строку. Если вам нужно значение по умолчанию, пишите его без кавычек как обращение к объекту метаданных, либо выбирайте через стандартное окно выбора значения.
Если изменить схему невозможно или вышеуказанные методы не помогают (например, из-за специфического бага платформы в старых релизах), мы можем применить «силовой» метод — принудительное приведение типа в коде 1С. Это самый надежный способ для работы в процедуре ПриКомпоновкеДанных.
Разберем пример реализации:
// Получаем значение из параметров
ЗначениеИзПараметра = КомпоновщикНастроек.Настройки.DataParameters.FindParameterValue(New DataCompositionParameter("ВыпускПоОперацииСтоимость")).Value;
// Если нам вернулась строка вместо ссылки, приводим её к нужному типу
Если ТипЗнч(ЗначениеИзПараметра) = Тип("String") Тогда
// Создаем описание типа нужного перечисления
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("EnumRef.КодыОперацийПартииТоваров"));
НужныйТип = Новый TypeDescription(МассивТипов);
// Используем метод ПривестиЗначение.
// Если строка совпадает с именем значения перечисления, вернется ссылка.
// Если нет - вернется пустая ссылка данного перечисления.
КорректноеЗначение = НужныйТип.AdjustValue(ЗначениеИзПараметра);
Иначе
КорректноеЗначение = ЗначениеИзПараметра;
КонецЕсли;
Этот метод гарантирует, что в ваш запрос или таблицу внешнего набора данных попадет объект правильного типа, что исключит ошибки несоответствия типов при выполнении кода.
Иногда проблема кроется в том, что для параметра заполнен список Доступные значения в схеме СКД. Если после обновления конфигурации состав перечисления изменился, а в схеме остались «старые» привязки, СКД может не найти соответствия и вернуть строковый идентификатор. Посмотрим на список доступных значений: если он заполнен вручную, попробуйте его очистить и проверить, решило ли это проблему. В большинстве случаев автоматического выбора типа перечисления достаточно для корректной работы.
Мы выяснили, что получение строки вместо ссылки в параметрах СКД — это чаще всего следствие неоднозначности типов в настройках или особенность работы с пользовательскими расширениями компоновки. Чтобы ваш код работал стабильно, придерживайтесь следующих правил:
КомпоновщикНастроек.ПолучитьНастройки().ValueTable для внешнего набора данных) используйте TypeDescription для явного приведения типов полученных параметров.Применяя эти подходы, вы обеспечите типизацию данных и стабильную работу ваших отчетов вне зависимости от сложности настроек пользователя.