К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как сравнить два текста запроса 1С

Как сравнить два текста запроса 1С: встроенное сравнение конфигуратором, консоль запросов, программное сравнение строк, внешние diff-инструменты и типичные ошибки.

Сравнение двух текстов запросов — типовая задача разработчика 1С: она возникает при рефакторинге, при поиске расхождений между запросом в коде и запросом в СКД, при анализе изменений после обновления конфигурации или при проверке того, что «оптимизированный» запрос не потерял нужные поля и отборы. Встроенного инструмента «сравнить два запроса» в платформе нет, поэтому задачу решают комбинацией штатных механизмов и внешних утилит.

Важно разделять две разные задачи. Первая — сравнить тексты запросов как строки: найти отличия в синтаксисе, полях, соединениях и условиях. Вторая — сравнить результаты выполнения запросов: убедиться, что оба варианта возвращают одинаковые данные. Эти задачи решаются разными инструментами, и путать их — частая причина ошибочных выводов: тексты могут отличаться, а результат быть идентичным, и наоборот.

Что именно нужно сравнить: текст или результат

Перед выбором инструмента определите цель. Если нужно понять, чем отличается новая редакция запроса от старой (какие поля добавлены, как изменены соединения и условия), достаточно текстового сравнения. Оно быстрое и не требует доступа к базе данных.

Если же задача — доказать, что переписанный запрос возвращает те же данные, текстовое сравнение не поможет: два синтаксически разных запроса могут давать идентичный результат. Здесь нужно выполнить оба запроса на одних и тех же данных и сравнить полученные таблицы значений — по составу колонок, количеству строк и содержимому.

Третий сценарий — сравнение планов и производительности: два запроса с одинаковым результатом могут существенно различаться по скорости. Это уже задача технологического журнала и анализа плана запроса в СУБД, а не текстового сравнения.

Маршрут решения

Как выбрать подход

Нужно найти отличия в синтаксисе, полях, отборахСравнивайте тексты: конфигуратор или внешняя diff-утилита
Нужно убедиться, что запросы возвращают одинаковые данныеВыполните оба в консоли запросов и сравните таблицы значений
Нужно понять, какой запрос быстрееЗамеряйте время выполнения и анализируйте план запроса, текстовое сравнение не подходит

Сравнение текстов запросов штатными средствами конфигуратора

Конфигуратор 1С умеет сравнивать текстовые файлы. Порядок действий прост: скопируйте первый запрос в новый текстовый документ (меню «Файл → Новый → Текстовый документ»), сохраните его под именем, например, query_old.txt. Аналогично сохраните второй запрос. Затем откройте «Файл → Сравнить файлы», укажите оба файла — конфигуратор покажет построчные различия в привычном виде.

Этот способ удобен тем, что не требует никаких дополнительных инструментов и работает на любой установке. Недостаток — сравнение построчное, без понимания структуры запроса: перестановка полей в списке выборки или иное форматирование даст массу «ложных» отличий, хотя по смыслу запрос не изменился.

Если запросы находятся в разных версиях конфигурации, используйте штатное сравнение конфигураций («Конфигурация → Сравнить, объединить с конфигурацией из файла»): в отчёте о различиях по модулю будут видны изменённые строки кода, включая текст запроса, если он задан строковым литералом в модуле.

Сравнение через конфигуратор
  1. 1
    Скопируйте первый текст запроса в новый текстовый документ и сохраните в файл
  2. 2
    Сохраните второй запрос во второй файл
  3. 3
    Откройте «Файл → Сравнить файлы» и выберите оба файла
  4. 4
    Просмотрите построчные различия, игнорируя чисто форматирующие изменения
  5. 5
    Проверьте осмысленные отличия: поля, таблицы, соединения, условия ГДЕ и параметры

Сравнение во внешних diff-инструментах

Для объёмных запросов удобнее специализированные утилиты сравнения: WinMerge, KDiff3, встроенное сравнение файлов в VS Code, Notepad++ с плагином Compare или онлайн-сервисы diff. Они показывают различия нагляднее, умеют игнорировать пробелы и регистр, подсвечивают изменения внутри строки.

Перед сравнением приведите оба текста к единому формату: одинаковые переносы строк, единый регистр ключевых слов, одинаковые отступы. Иначе инструмент покажет сотни отличий там, где реально изменилась одна строка. Полезный приём — прогнать оба запроса через конструктор запроса в конфигураторе: он переформатирует текст по своим правилам, и после этого сравнение станет чистым.

Не используйте онлайн-сервисы для запросов, содержащих чувствительные данные в литералах (конкретные ИНН, персональные данные в условиях отбора) — текст уходит на сторонний сервер. Для таких случаев оставайтесь на локальных инструментах.

Программное сравнение текстов запросов

Иногда сравнить тексты нужно из кода — например, при автоматической проверке того, что запрос не был изменён, или при поиске дублирующихся запросов в модулях. Простейший вариант — прямое сравнение строк:

Если СокрЛП(ТекстЗапроса1) = СокрЛП(ТекстЗапроса2) Тогда

// тексты идентичны

КонецЕсли;

Такое сравнение строгое: различие в одном пробеле или регистре даст «не равно». Для мягкого сравнения нормализуйте строки перед проверкой: приведите к одному регистру через ВРег(), удалите лишние пробелы и переводы строк, например регулярной заменой через СтрЗаменить() последовательностей пробелов на один.

Для поиска дубликатов в большом объёме кода удобен подсчёт хеш-суммы текста (например, через объект ХешированиеДанных с алгоритмом MD5 или CRC32): нормализованный текст хешируется, и совпадение хешей означает идентичность запросов. Это быстрее попарного сравнения строк при сотнях запросов.

bsl
Функция НормализоватьТекстЗапроса(Текст)
    Результат = ВРег(Текст);
    Результат = СтрЗаменить(Результат, Символы.ПС, " ");
    Результат = СтрЗаменить(Результат, Символы.Таб, " ");
    Пока СтрНайти(Результат, "  ") > 0 Цикл
        Результат = СтрЗаменить(Результат, "  ", " ");
    КонецЦикла;
    Возврат СокрЛП(Результат);
КонецФункции

Сравнение результатов выполнения запросов

Когда важно не «как написано», а «что возвращает», выполните оба запроса и сравните таблицы значений. Практический способ без программирования — консоль запросов (типовая для управляемых форм или популярные внешние обработки): выполните первый запрос, сохраните результат, выполните второй и сопоставьте количество строк итоговых выборок, затем выборочно сверьте данные по ключевым полям.

Программно сравнение делается так: оба запроса выполняются с одинаковыми параметрами, результаты выгружаются в таблицы значений методом Выгрузить(). Дальше проверяются: совпадение количества колонок и их имён, количество строк, а затем построчное содержимое. Для надёжности таблицы стоит отсортировать по набору ключевых колонок, так как порядок строк в результате запроса без предложения УПОРЯДОЧИТЬ не гарантирован.

ТЗ1 = Запрос1.Выполнить().Выгрузить();

ТЗ2 = Запрос2.Выполнить().Выгрузить();

ТЗ1.Сортировать("Номенклатура, Период");

ТЗ2.Сортировать("Номенклатура, Период");

Если ТЗ1.Количество() <> ТЗ2.Количество() Тогда

// результаты различаются по составу строк

КонецЕсли;

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

Сравнение запросов в СКД и динамических списках

Текст запроса в схеме компоновки данных хранится внутри XML-структуры схемы, поэтому построчное сравнение модулей его не покажет. Чтобы сравнить два варианта запроса СКД, откройте схему в конструкторе, скопируйте текст запроса из набора данных в текстовый файл и далее сравнивайте как обычный текст.

Альтернатива — сохранить обе схемы в XML-файлы и сравнить файлы целиком: помимо текста запроса вы увидите различия в настройках, ресурсах и вычисляемых полях. Минус — XML многословен, и смысловые отличия тонут в служебных тегах, поэтому для анализа именно запроса лучше вырезать текст отдельно.

Для динамических списков с произвольным запросом действуйте аналогично: скопируйте текст из свойства списка в обеих версиях конфигурации и сравните как текст. Учитывайте, что платформа может неявно модифицировать запрос динамического списка (добавлять поля ключей, переупорядочивать), поэтому при расхождениях в поведении списка сравнивайте ещё и фактически исполняемый запрос — его видно в технологическом журнале.

Сравнение инструментов

Конфигуратор «Сравнить файлы»

Всегда под рукой, не требует установки. Минусы — только построчное сравнение, слабо подсвечивает изменения внутри строки

Внешние diff-утилиты (WinMerge, VS Code)

Наглядная подсветка, игнорирование пробелов и регистра. Требуют установки и выгрузки текстов в файлы

Программное сравнение строк/хешей

Подходит для автоматических проверок и поиска дублей. Не показывает, в чём именно различие

Консоль запросов + сравнение ТЗ

Единственный способ проверить эквивалентность результатов. Требует доступа к базе с актуальными данными

Типичные ошибки при сравнении запросов

Самая распространённая ошибка — вывод о неэквивалентности запросов по различию текста. Запросы с разным порядком полей, алиасами и форматированием могут возвращать идентичные данные. Обратное тоже верно: тексты почти совпадают, но одно лишнее ЛЕВОЕ СОЕДИНЕНИЕ задваивает строки результата.

Вторая ошибка — сравнение результатов без фиксации параметров. Если в первом запросе параметр «Период» задан датой, а во втором — границей, или виртуальные таблицы получают разные отборы, расхождение результатов говорит о разных параметрах, а не о различии логики.

Третья группа ошибок — игнорирование контекста выполнения: RLS (ограничение доступа на уровне записей) меняет фактический текст и результат запроса в зависимости от пользователя. Сравнивайте запросы под одной учётной записью, иначе вы сравниваете не запросы, а права доступа.

Типичные ошибки
01
Сравнивать тексты «как есть» без нормализации форматирования — сотни ложных отличий скрывают реальные изменения
02
Делать вывод об эквивалентности по похожести текста — разные тексты могут давать одинаковый результат и наоборот
03
Выполнять запросы с разными параметрами или под разными пользователями — расхождения вызваны контекстом, а не логикой
04
Сравнивать результаты без сортировки таблиц — разный порядок строк даёт ложное «не совпадает»
05
Забыть, что запрос СКД лежит внутри XML схемы, и искать его в тексте модуля

Как проверить, что сравнение выполнено корректно

После текстового сравнения пройдитесь по контрольному списку: совпадает ли набор выбираемых полей, источники данных (таблицы и виртуальные таблицы), типы соединений, условия в ГДЕ и параметры виртуальных таблиц, группировки и итоги. Именно эти элементы определяют семантику запроса; отступы и регистр ключевых слов — нет.

После сравнения результатов убедитесь, что совпали: число строк, набор колонок, агрегатные суммы по числовым полям. Если все три признака сошлись на репрезентативном наборе данных, запросы с высокой вероятностью эквивалентны. Для критичных доработок дополнительно прогоните сравнение на граничных случаях: пустой результат, одна строка, данные с NULL в соединяемых полях.

Контрольные точки

Как проверить результат

Набор полей и источников в обоих текстах
Норма

Поля, таблицы и типы соединений совпадают

Тревожный признак

Разные источники или лишнее ЛЕВОЕ СОЕДИНЕНИЕ — возможны дубли строк

Количество строк результата
Норма

Одинаковое при одинаковых параметрах

Тревожный признак

Разное число строк — запросы не эквивалентны

Агрегатные суммы числовых полей
Норма

Суммы совпадают

Тревожный признак

Расхождение сумм даже при равном числе строк — различается логика вычислений

Повторный прогон через время
Норма

Результаты по-прежнему совпадают

Тревожный признак

Расхождение появилось — сравнение зависит от меняющихся данных или RLS

Частые вопросы

Можно ли сравнить два запроса прямо в консоли запросов?

Типовые консоли запросов выполняют запросы по одному и не имеют встроенного режима сравнения текстов. Практика такая: выполните оба запроса по очереди, зафиксируйте количество строк и контрольные суммы, а тексты сравните отдельно через конфигуратор или diff-утилиту. Некоторые сторонние консоли позволяют открыть два запроса в соседних вкладках, что упрощает визуальное сопоставление.

Как сравнить запросы, если один из них формируется программно в коде?

Добавьте в код временный вывод итогового текста (например, через Сообщить() или запись в журнал регистрации) непосредственно перед выполнением запроса — вы получите реальный текст с подставленными частями. Скопируйте его в файл и сравните со вторым вариантом. Не забудьте удалить отладочный вывод после проверки.

Тексты запросов совпадают, но результаты разные — в чём причина?

Проверьте параметры, пользователя (влияет RLS), момент времени выполнения и, для виртуальных таблиц, — параметры отборов. Также убедитесь, что оба запроса выполняются в одной базе: одинаковый запрос в рабочей и тестовой базах закономерно даст разные результаты.

Как сравнить запросы между двумя версиями конфигурации из хранилища?

Используйте сравнение версий конфигурации с версией из хранилища: в отчёте о различиях по конкретному объекту и модулю будут показаны изменённые строки кода, включая строковый литерал запроса. Если запрос находится в макете СКД, сравнивайте XML-представление схемы или выгрузите тексты запросов из обеих версий вручную.

Есть ли способ автоматически найти дубли запросов во всей конфигурации?

Штатного инструмента нет. Практический путь: выгрузить конфигурацию в файлы, найти все вхождения ключевого слова «ВЫБРАТЬ» в модулях, извлечь тексты запросов, нормализовать их (регистр, пробелы) и сравнить хеши — совпадение хешей укажет на дубли. Это делается внешней обработкой или скриптом по файлам выгрузки.

Итог

Что важно запомнить

Сравнение текстов и сравнение результатов — разные задачи. Тексты сравнивайте через «Сравнить файлы» конфигуратора или diff-утилиту, предварительно нормализовав форматирование. Эквивалентность результатов проверяйте выполнением обоих запросов с одинаковыми параметрами и сверкой таблиц значений по числу строк и агрегатным суммам.