Обновление технологической платформы 1С:Предприятие 8.3 нередко сопровождается изменением внутренних алгоритмов оптимизации запросов и механизмов типизации данных. Типичный сценарий: после перехода с релиза ветки 8.3.21 на более свежие версии (8.3.24, 8.3.25 и выше) в управляемой форме перестают корректно отображаться строковые реквизиты. Вместо ожидаемой строки заданной длины (например, строкового кода сортировки длиной 20 символов) пользователь видит в колонке только один первый символ.
При этом прямое тестирование запроса через консоль запросов возвращает полноценные строки без каких-либо дефектов. Поскольку откат платформы на старые сборки часто невозможен из-за требований типовых конфигураций («1С:Бухгалтерия предприятия», «1С:Зарплата и управление персоналом»), разработчик сталкивается с необходимостью адаптировать запрос динамического списка под обновленные правила платформы.
Сбой проявляется при соблюдении следующего набора условий:
Строка определенной длины (например, 20 или 50 символов).Запрос присутствуют полные строки.ПОДСТРОКА(...) либо завершается синтаксической ошибкой, либо не меняет видимое поведение динамического списка.Чтобы понять причину аномалии, важно различать принципы функционирования обычного объекта Запрос и объекта ДинамическийСписок:
Когда поле выборки формируется из значения составного типа (каковым является поле Значение в планах видов характеристик или регистрах сведений), платформа не может однозначно определить точную длину строки на этапе компиляции структуры динамического списка. В ранних версиях платформы (до 8.3.21) механизм вывода типов мог определять длину по метаданным первой строки или по наиболее широкому типу в описании объекта. Начиная с платформы 8.3.24, правила строгости типизации изменились: если для составного поля не задано явное сужение типа, результирующий тип поля в динамическом списке может деградировать до базовой строки минимальной размерности — Строка(1).
Распространенная попытка обойти ограничение — обернуть выражение в строковую функцию:
ПОДСТРОКА(ДопСведения.Значение, 1, 20)
Однако в контексте динамического списка такой подход часто оказывается неработоспособным по следующим причинам:
ПОДСТРОКА ожидает на вход аргумент исключительно строкового типа. Если поле Значение имеет составной тип (включающий числа, даты, ссылки на справочники), вызов функции на уровне СУБД приводит к ошибке приведения типов или игнорированию операции.NULL. Обработка NULL функцией ПОДСТРОКА без предварительной проверки через ЕСТЬNULL возвращает неопределенный результат.ПОДСТРОКА является функцией обработки данных, а не оператором декларирования типа метаданных. Она не сообщает оптимизатору динамического списка явную сигнатуру типа колонки формы.Для гарантированного восстановления корректной длины поля необходимо выполнить диагностику и модификацию схемы выборки:
ЛЕВОЕ СОЕДИНЕНИЕ) значение реквизита для части записей будет неопределено. Его необходимо заменить пустой строкой с помощью конструкции ЕСТЬNULL(...).ВЫРАЗИТЬ, который на уровне синтаксического анализатора платформы декларирует результирующий тип колонки динамического списка.Канонический способ фиксации типа и размерности данных в произвольном запросе динамического списка — совместное использование функций ЕСТЬNULL и ВЫРАЗИТЬ.
В тексте запроса динамического списка проблемное поле необходимо описать следующим образом:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование,
ВЫРАЗИТЬ(ЕСТЬNULL(ДопСведенияСортКод.Значение, "") КАК СТРОКА(100)) КАК СортировочныйКод,
ВЫРАЗИТЬ(ЕСТЬNULL(ДопСведенияСортЧислом.Значение, 0) КАК ЧИСЛО(10, 0)) КАК СортировочныйКодЧислом
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСведенияСортКод
ПО ДопСведенияСортКод.Объект = Номенклатура.Ссылка
И ДопСведенияСортКод.Свойство = &СвойствоСтрока
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСведенияСортЧислом
ПО ДопСведенияСортЧислом.Объект = Номенклатура.Ссылка
И ДопСведенияСортЧислом.Свойство = &СвойствоЧисло
Обратите внимание на порядок вложенности: сначала функция ЕСТЬNULL подставляет значение по умолчанию (пустую строку "" или число 0), а затем внешняя конструкция ВЫРАЗИТЬ(... КАК СТРОКА(N)) явно задает для динамического списка размерность N. Если длина кода сортировки составляет 20 символов, рекомендуется указывать размерность с запасом (например, 50 или 100), либо точно равную максимальной длине свойства в ПВХ.
При использовании оператора ВЫРАЗИТЬ в динамических списках необходимо учитывать следующие системные ограничения платформы 1С:Предприятие:
СТРОКА без указания конкретной длины в скобках. Конструкция ВЫРАЗИТЬ(Поле КАК СТРОКА) вызовет ошибку на уровне СУБД, так как динамический список не может корректно сортировать и группировать поля неограниченной длины. Длина должна быть задана явно: СТРОКА(100).ВЫРАЗИТЬ не осуществляет конвертацию одного типа в другой (например, он не преобразует ссылку справочника в текст ее наименования). Он лишь сообщает платформе, какой именно тип из доступного состава типов следует извлечь. Если в поле фактически записана ссылка или дата, а запрос пытается выразить ее как СТРОКА(100), платформа вернет пустое значение (или значение по умолчанию).ВЫРАЗИТЬ(Поле КАК ЧИСЛО(Длина, Точность)). Пропуск разрядности может привести к аналогичной проблеме округления или отсечения дробной части.Явное декларирование типов с помощью ВЫРАЗИТЬ является стандартным требованием стандартов разработки 1С для любых вычисляемых полей и полей составного типа в динамических списках. Соблюдение этого правила гарантирует стабильную работу форм при любых последующих обновлениях платформы 1С:Предприятие.