При обновлении платформы или изменении конфигурации (например, Управление Торговлей + CRM) пользователи могут столкнуться с неприятной визуальной ошибкой: в форме списка (например, справочника "Партнеры" или "Контрагенты") в колонке ИНН отображается только одна первая цифра. Остальная часть номера обрезается. Очистка кэша, как правило, не помогает.
В этой статье мы подробно разберем причины такого поведения платформы и рассмотрим несколько способов решения проблемы — от пользовательских настроек до программной доработки через расширения.
Прежде чем переходить к исправлению, давайте проанализируем, почему это происходит. Проблема кроется в механизме работы объекта ДинамическийСписок и взаимодействия платформы с СУБД (SQL).
Часто поле "ИНН" в современных конфигурациях имеет Определяемый тип (Defined Type). Это означает, что поле теоретически может хранить значения разных типов (Строка, Число, Ссылка и т.д.). Когда платформа строит запрос для динамического списка, она пытается оптимизировать выборку данных.
Если в базе данных (в таблице SQL) в первых попавшихся записях поле ИНН не заполнено (имеет значение NULL) или содержит пустую строку, планировщик запросов может ошибочно определить тип выходного поля как строку длиной 1 символ (аналог varchar(1)). В результате, когда в выборку попадает реальный длинный ИНН, он обрезается под эту маску.
Иногда проблему можно решить, не прибегая к конфигуратору. Если колонка ИНН выводится в списке не напрямую из реквизита списка, а через сложные связи, попробуем вывести данные "напрямую" через ссылку.
Выполним следующие действия в режиме "1С:Предприятие":
Суть метода: Мы заставляем платформу получать данные не из кэшированного или вычисляемого поля динамического списка, а напрямую через разыменование ссылки (механизм чтения данных объекта). Это часто помогает, если ошибка была именно в тексте запроса динамического списка.
Если первый способ не помог или неприемлем по соображениям производительности (разыменование ссылок в списках может работать медленно), необходимо скорректировать запрос динамического списка. Это самое надежное решение.
Нам нужно явно указать платформе, какую длину строки мы ожидаем. Для этого используем конструкцию ВЫРАЗИТЬ ... КАК ....
Рассмотрим, как изменить запрос. В свойствах динамического списка нужно включить флаг Произвольный запрос и отредактировать текст запроса.
Было:
ВЫБРАТЬ
Партнеры.Ссылка,
Партнеры.Наименование,
Партнеры.ИНН
ИЗ
Справочник.Партнеры КАК Партнеры
Стало (правильный вариант):
ВЫБРАТЬ
Партнеры.Ссылка,
Партнеры.Наименование,
ВЫРАЗИТЬ(Партнеры.ИНН КАК СТРОКА(12)) КАК ИНН
ИЗ
Справочник.Партнеры КАК Партнеры
Важные нюансы:
ВЫРАЗИТЬ с указанием типа СТРОКА и конкретной длины (например, 12 или 20 символов).NULL (например, при левом соединении таблиц), конструкция ВЫРАЗИТЬ может не сработать ожидаемо. В этом случае используйте комбинацию с ЕСТЬNULL.Пример безопасного запроса с обработкой NULL:
ВЫРАЗИТЬ(ЕСТЬNULL(Партнеры.ИНН, "") КАК СТРОКА(20)) КАК ИНН
В исходной проблеме указано, что конфигурация находится на поддержке, и менять основную форму нельзя. В этом случае мы воспользуемся механизмом Расширений конфигурации. Это позволит исправить ошибку, сохранив возможность автоматического обновления типовой конфигурации.
Разберем алгоритм действий пошагово:
Справочник.Партнеры.Форма.ФормаСписка) и добавим её в расширение.ПриСозданииНаСервере (используем аннотацию &НаСервере и тип перехвата После).В модуле формы расширения напишем код, который программно подменит текст запроса динамического списка. Обратите внимание, что нам нужно не просто изменить текст запроса, но и убедиться, что поле на форме связано с правильными данными.
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Получаем текущий текст запроса динамического списка
ТекстЗапроса = Список.ТекстЗапроса;
// Находим фрагмент, отвечающий за выборку ИНН.
// Важно знать точное имя поля в исходном запросе.
// Предположим, оно называется просто "ИНН" или "Партнеры.ИНН".
// Вариант замены подстрокой (нужно быть аккуратным)
// Лучше полностью переопределить текст запроса, скопировав его из типовой,
// но мы рассмотрим точечную замену для примера:
Если СтрНайти(ТекстЗапроса, "ВЫРАЗИТЬ(") = 0 Тогда
// Заменяем простое поле на типизированное
// Меняем "Партнеры.ИНН" на конструкцию с ВЫРАЗИТЬ
НовыйФрагмент = "ВЫРАЗИТЬ(ЕСТЬNULL(Партнеры.ИНН, """") КАК СТРОКА(20))";
// Обратите внимание: просто замена строки может быть ненадежной,
// если в запросе поле встречается несколько раз.
// Надежнее полностью скопировать типовой запрос и вставить его с правками:
// Список.ТекстЗапроса = "... полная версия исправленного запроса ...";
// Для демонстрации идеи:
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "Партнеры.ИНН,", НовыйФрагмент + " КАК ИНН,");
Список.ТекстЗапроса = ТекстЗапроса;
КонецЕсли;
КонецПроцедуры
Критически важный момент: Псевдонимы полей
Если вы меняете запрос, обязательно сохраняйте псевдоним поля (КАК ИНН). Элемент формы (колонка таблицы), который отображает данные, "привязан" к определенному имени поля в данных списка (ПутьКДанным). Если вы назовете поле в запросе по-другому (например, ИНН_Испр), а в настройках элемента формы останется старый путь Список.ИНН, то колонка станет пустой или ошибка не уйдет.
Если вы добавляете новое поле в запрос:
... ВЫРАЗИТЬ(Партнеры.ИНН КАК СТРОКА(20)) КАК ИНН_Нормальный ...
Тогда вам нужно программно изменить путь к данным у элемента формы:
ЭлементИНН = Элементы.Найти("ИНН"); // Имя элемента на форме
Если ЭлементИНН <> Неопределено Тогда
ЭлементИНН.ПутьКДанным = "Список.ИНН_Нормальный";
КонецЕсли;
Если вы столкнулись с тем, что в динамическом списке обрезается строка:
ВЫРАЗИТЬ(Поле КАК СТРОКА(N)) в тексте запроса динамического списка.