Почему в запросе 1С дублируются параметры и как это исправить?

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

При разработке отчетов и обработок в 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 (кириллица). Если при выполнении такого запроса заполнить только один из них методом УстановитьПараметр(), платформа выдаст исключение: «Не задано значение параметра».

Способы диагностики и устранения ошибки

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

  1. Перезапись имени параметра: Самый простой способ устранить проблему в тексте запроса — полностью удалить имя параметра во всех выражениях и заново набрать его на одном языке либо скопировать через буфер обмена из одного места в остальные.
  2. Программная диагностика методом НайтиПараметры(): При возникновении сомнений можно программно получить список всех параметров запроса. Метод Запрос.НайтиПараметры() возвращает коллекцию, по которой легко увидеть дублирующиеся названия:
    
    Запрос = Новый Запрос;
    Запрос.Текст = ТекстЗапроса;
    СписокПараметров = Запрос.НайтиПараметры();
    
    Для Каждого ИмяПараметра Из СписокПараметров Цикл
        Сообщить(ИмяПараметра.Имя);
    КонецЦикла;
    
  3. Поиск регулярными выражениями: В глобальном поиске Конфигуратора или текстовом редакторе можно включить поиск по регулярным выражениям, чтобы найти слова со смешанной раскладкой:

    [а-яА-ЯёЁ][a-zA-Z] — для поиска перехода с кириллицы на латиницу;

    [a-zA-Z][а-яА-ЯёЁ] — для поиска перехода с латиницы на кириллицу.

  4. Использование линтеров и 1C:EDT: Среда разработки 1C:EDT, а также статические анализаторы кода (BSL Language Server, SonarQube) содержат встроенные правила проверки (например, Mixed Language Identifiers), которые автоматически подчеркивают переменные и параметры с разноязычными символами.

Рекомендации по оптимизации запроса к регистру бухгалтерии

Рассмотрим структуру исходного запроса с точки зрения производительности. Конструкция СчетДт В ИЕРАРХИИ (&Счет) внутри выражения ВЫБОР КОГДА в секции ВЫБРАТЬ создает существенную нагрузку на СУБД, так как проверка иерархии для каждой строки требует дополнительных подзапросов или соединений.

Чтобы повысить быстродействие, применим следующие оптимизации:

  1. Передача массива счетов вместо иерархии: Если список субсчетов известен заранее, сформируем массив счетов на встроенном языке и передадим его в условие В (&МассивСчетов) вместо ресурсоемкого оператора В ИЕРАРХИИ.
  2. Использование специализированных виртуальных таблиц: Для получения оборотов по дебету и кредиту эффективнее обращаться к виртуальной таблице ОборотыДтКт либо разделять выборку с помощью ОБЪЕДИНИТЬ ВСЕ с наложением условий на счета непосредственно в параметрах виртуальных таблиц, а не в секции ГДЕ или ВЫБРАТЬ.

Для предотвращения подобных ошибок при повседневной разработке рекомендуется установить русскую раскладку клавиатуры по умолчанию в операционной системе и избегать переключения языков при написании названий переменных и параметров.

← На главную