При разработке отчетов и обработок в 1С:Предприятии разработчики нередко сталкиваются с ситуацией, когда Конструктор запроса или форма заполнения параметров требует ввести одно и то же значение дважды для параметров с визуально одинаковыми именами. Разберем, почему возникает такое поведение платформы, как быстро найти скрытую ошибку и как предотвратить подобные проблемы в будущем.
Проанализируем фрагмент запроса к регистру бухгалтерии, в котором возникла данная неполадка:
ВЫБРАТЬ
ХозрасчетныйДвиженияССубконто.Период,
ХозрасчетныйДвиженияССубконто.Регистратор,
ХозрасчетныйДвиженияССубконто.СчетДт,
ХозрасчетныйДвиженияССубконто.СубконтоДт1,
ХозрасчетныйДвиженияССубконто.СчетКт,
ХозрасчетныйДвиженияССубконто.СубконтоКт1,
ВЫБОР
КОГДА ХозрасчетныйДвиженияССубконто.СчетДт В ИЕРАРХИИ (&Cчет2)
ТОГДА ХозрасчетныйДвиженияССубконто.Сумма
ИНАЧЕ 0
КОНЕЦ КАК СуммаДт,
ВЫБОР
КОГДА ХозрасчетныйДвиженияССубконто.СчетКт В ИЕРАРХИИ (&Cчет2)
ТОГДА ХозрасчетныйДвиженияССубконто.Сумма
ИНАЧЕ 0
КОНЕЦ КАК СуммаКт
ИЗ
РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
,
,
Счет В ИЕРАРХИИ (&Счет2)
И Активность,
,
) КАК ХозрасчетныйДвиженияССубконто
С первого взгляда во всех трех местах используется один и тот же параметр &Счет2. Однако для компилятора запросов 1С это совершенно разные идентификаторы. Платформа сравнивает имена параметров строго по кодам символов в таблице Unicode, не выполняя нормализацию букв с одинаковым начертанием (омоглифов).
Выясним причину через проверку кодов символов с помощью встроенного языка 1С:
// Английская "C" (код 67):
КодСимвола(Сред("СчетДт В ИЕРАРХИИ (&Cчет2)", 21, 1)); // Результат: 67
// Русская "С" (код 1057):
КодСимвола(Сред("Счет В ИЕРАРХИИ (&Счет2)", 19, 1)); // Результат: 1057
В секциях ВЫБОР первая буква С была случайно набрана на латинице (код 67), а в параметрах виртуальной таблицы — на кириллице (код 1057). В результате платформа создала два независимых параметра: &Cчет2 (латиница) и &Счет2 (кириллица). Если при выполнении такого запроса заполнить только один из них методом УстановитьПараметр(), платформа выдаст исключение: «Не задано значение параметра».
Разберем по шагам, какими инструментами можно оперативно обнаружить и исправить смешение раскладок:
НайтиПараметры(): При возникновении сомнений можно программно получить список всех параметров запроса. Метод Запрос.НайтиПараметры() возвращает коллекцию, по которой легко увидеть дублирующиеся названия:
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
СписокПараметров = Запрос.НайтиПараметры();
Для Каждого ИмяПараметра Из СписокПараметров Цикл
Сообщить(ИмяПараметра.Имя);
КонецЦикла;
[а-яА-ЯёЁ][a-zA-Z] — для поиска перехода с кириллицы на латиницу;
[a-zA-Z][а-яА-ЯёЁ] — для поиска перехода с латиницы на кириллицу.
Рассмотрим структуру исходного запроса с точки зрения производительности. Конструкция СчетДт В ИЕРАРХИИ (&Счет) внутри выражения ВЫБОР КОГДА в секции ВЫБРАТЬ создает существенную нагрузку на СУБД, так как проверка иерархии для каждой строки требует дополнительных подзапросов или соединений.
Чтобы повысить быстродействие, применим следующие оптимизации:
В (&МассивСчетов) вместо ресурсоемкого оператора В ИЕРАРХИИ.ОборотыДтКт либо разделять выборку с помощью ОБЪЕДИНИТЬ ВСЕ с наложением условий на счета непосредственно в параметрах виртуальных таблиц, а не в секции ГДЕ или ВЫБРАТЬ.Для предотвращения подобных ошибок при повседневной разработке рекомендуется установить русскую раскладку клавиатуры по умолчанию в операционной системе и избегать переключения языков при написании названий переменных и параметров.