Разработка и Конфигурация · 13 мин
Как сравнить два текста запроса 1С
Как сравнить два текста запроса 1С: встроенное сравнение конфигуратором, консоль запросов, программное сравнение строк, внешние diff-инструменты и типичные ошибки.
Сравнение двух текстов запросов — типовая задача разработчика 1С: она возникает при рефакторинге, при поиске расхождений между запросом в коде и запросом в СКД, при анализе изменений после обновления конфигурации или при проверке того, что «оптимизированный» запрос не потерял нужные поля и отборы. Встроенного инструмента «сравнить два запроса» в платформе нет, поэтому задачу решают комбинацией штатных механизмов и внешних утилит.
Важно разделять две разные задачи. Первая — сравнить тексты запросов как строки: найти отличия в синтаксисе, полях, соединениях и условиях. Вторая — сравнить результаты выполнения запросов: убедиться, что оба варианта возвращают одинаковые данные. Эти задачи решаются разными инструментами, и путать их — частая причина ошибочных выводов: тексты могут отличаться, а результат быть идентичным, и наоборот.
Что именно нужно сравнить: текст или результат
Перед выбором инструмента определите цель. Если нужно понять, чем отличается новая редакция запроса от старой (какие поля добавлены, как изменены соединения и условия), достаточно текстового сравнения. Оно быстрое и не требует доступа к базе данных.
Если же задача — доказать, что переписанный запрос возвращает те же данные, текстовое сравнение не поможет: два синтаксически разных запроса могут давать идентичный результат. Здесь нужно выполнить оба запроса на одних и тех же данных и сравнить полученные таблицы значений — по составу колонок, количеству строк и содержимому.
Третий сценарий — сравнение планов и производительности: два запроса с одинаковым результатом могут существенно различаться по скорости. Это уже задача технологического журнала и анализа плана запроса в СУБД, а не текстового сравнения.
Как выбрать подход
Сравнение текстов запросов штатными средствами конфигуратора
Конфигуратор 1С умеет сравнивать текстовые файлы. Порядок действий прост: скопируйте первый запрос в новый текстовый документ (меню «Файл → Новый → Текстовый документ»), сохраните его под именем, например, query_old.txt. Аналогично сохраните второй запрос. Затем откройте «Файл → Сравнить файлы», укажите оба файла — конфигуратор покажет построчные различия в привычном виде.
Этот способ удобен тем, что не требует никаких дополнительных инструментов и работает на любой установке. Недостаток — сравнение построчное, без понимания структуры запроса: перестановка полей в списке выборки или иное форматирование даст массу «ложных» отличий, хотя по смыслу запрос не изменился.
Если запросы находятся в разных версиях конфигурации, используйте штатное сравнение конфигураций («Конфигурация → Сравнить, объединить с конфигурацией из файла»): в отчёте о различиях по модулю будут видны изменённые строки кода, включая текст запроса, если он задан строковым литералом в модуле.
- 1Скопируйте первый текст запроса в новый текстовый документ и сохраните в файл
- 2Сохраните второй запрос во второй файл
- 3Откройте «Файл → Сравнить файлы» и выберите оба файла
- 4Просмотрите построчные различия, игнорируя чисто форматирующие изменения
- 5Проверьте осмысленные отличия: поля, таблицы, соединения, условия ГДЕ и параметры
Сравнение во внешних diff-инструментах
Для объёмных запросов удобнее специализированные утилиты сравнения: WinMerge, KDiff3, встроенное сравнение файлов в VS Code, Notepad++ с плагином Compare или онлайн-сервисы diff. Они показывают различия нагляднее, умеют игнорировать пробелы и регистр, подсвечивают изменения внутри строки.
Перед сравнением приведите оба текста к единому формату: одинаковые переносы строк, единый регистр ключевых слов, одинаковые отступы. Иначе инструмент покажет сотни отличий там, где реально изменилась одна строка. Полезный приём — прогнать оба запроса через конструктор запроса в конфигураторе: он переформатирует текст по своим правилам, и после этого сравнение станет чистым.
Не используйте онлайн-сервисы для запросов, содержащих чувствительные данные в литералах (конкретные ИНН, персональные данные в условиях отбора) — текст уходит на сторонний сервер. Для таких случаев оставайтесь на локальных инструментах.
Программное сравнение текстов запросов
Иногда сравнить тексты нужно из кода — например, при автоматической проверке того, что запрос не был изменён, или при поиске дублирующихся запросов в модулях. Простейший вариант — прямое сравнение строк:
Если СокрЛП(ТекстЗапроса1) = СокрЛП(ТекстЗапроса2) Тогда
// тексты идентичны
КонецЕсли;
Такое сравнение строгое: различие в одном пробеле или регистре даст «не равно». Для мягкого сравнения нормализуйте строки перед проверкой: приведите к одному регистру через ВРег(), удалите лишние пробелы и переводы строк, например регулярной заменой через СтрЗаменить() последовательностей пробелов на один.
Для поиска дубликатов в большом объёме кода удобен подсчёт хеш-суммы текста (например, через объект ХешированиеДанных с алгоритмом MD5 или CRC32): нормализованный текст хешируется, и совпадение хешей означает идентичность запросов. Это быстрее попарного сравнения строк при сотнях запросов.
Функция НормализоватьТекстЗапроса(Текст)
Результат = ВРег(Текст);
Результат = СтрЗаменить(Результат, Символы.ПС, " ");
Результат = СтрЗаменить(Результат, Символы.Таб, " ");
Пока СтрНайти(Результат, " ") > 0 Цикл
Результат = СтрЗаменить(Результат, " ", " ");
КонецЦикла;
Возврат СокрЛП(Результат);
КонецФункцииСравнение результатов выполнения запросов
Когда важно не «как написано», а «что возвращает», выполните оба запроса и сравните таблицы значений. Практический способ без программирования — консоль запросов (типовая для управляемых форм или популярные внешние обработки): выполните первый запрос, сохраните результат, выполните второй и сопоставьте количество строк итоговых выборок, затем выборочно сверьте данные по ключевым полям.
Программно сравнение делается так: оба запроса выполняются с одинаковыми параметрами, результаты выгружаются в таблицы значений методом Выгрузить(). Дальше проверяются: совпадение количества колонок и их имён, количество строк, а затем построчное содержимое. Для надёжности таблицы стоит отсортировать по набору ключевых колонок, так как порядок строк в результате запроса без предложения УПОРЯДОЧИТЬ не гарантирован.
ТЗ1 = Запрос1.Выполнить().Выгрузить();
ТЗ2 = Запрос2.Выполнить().Выгрузить();
ТЗ1.Сортировать("Номенклатура, Период");
ТЗ2.Сортировать("Номенклатура, Период");
Если ТЗ1.Количество() <> ТЗ2.Количество() Тогда
// результаты различаются по составу строк
КонецЕсли;
Для больших выборок построчное сравнение в цикле медленное. Быстрее свернуть контрольные суммы: например, посчитать сумму числовых полей и количество строк по каждому запросу через агрегатный запрос — расхождение агрегатов сразу покажет, что результаты не эквивалентны, а детальную сверку можно делать уже точечно.
Сравнение запросов в СКД и динамических списках
Текст запроса в схеме компоновки данных хранится внутри XML-структуры схемы, поэтому построчное сравнение модулей его не покажет. Чтобы сравнить два варианта запроса СКД, откройте схему в конструкторе, скопируйте текст запроса из набора данных в текстовый файл и далее сравнивайте как обычный текст.
Альтернатива — сохранить обе схемы в XML-файлы и сравнить файлы целиком: помимо текста запроса вы увидите различия в настройках, ресурсах и вычисляемых полях. Минус — XML многословен, и смысловые отличия тонут в служебных тегах, поэтому для анализа именно запроса лучше вырезать текст отдельно.
Для динамических списков с произвольным запросом действуйте аналогично: скопируйте текст из свойства списка в обеих версиях конфигурации и сравните как текст. Учитывайте, что платформа может неявно модифицировать запрос динамического списка (добавлять поля ключей, переупорядочивать), поэтому при расхождениях в поведении списка сравнивайте ещё и фактически исполняемый запрос — его видно в технологическом журнале.
Сравнение инструментов
Всегда под рукой, не требует установки. Минусы — только построчное сравнение, слабо подсвечивает изменения внутри строки
Наглядная подсветка, игнорирование пробелов и регистра. Требуют установки и выгрузки текстов в файлы
Подходит для автоматических проверок и поиска дублей. Не показывает, в чём именно различие
Единственный способ проверить эквивалентность результатов. Требует доступа к базе с актуальными данными
Типичные ошибки при сравнении запросов
Самая распространённая ошибка — вывод о неэквивалентности запросов по различию текста. Запросы с разным порядком полей, алиасами и форматированием могут возвращать идентичные данные. Обратное тоже верно: тексты почти совпадают, но одно лишнее ЛЕВОЕ СОЕДИНЕНИЕ задваивает строки результата.
Вторая ошибка — сравнение результатов без фиксации параметров. Если в первом запросе параметр «Период» задан датой, а во втором — границей, или виртуальные таблицы получают разные отборы, расхождение результатов говорит о разных параметрах, а не о различии логики.
Третья группа ошибок — игнорирование контекста выполнения: RLS (ограничение доступа на уровне записей) меняет фактический текст и результат запроса в зависимости от пользователя. Сравнивайте запросы под одной учётной записью, иначе вы сравниваете не запросы, а права доступа.
Как проверить, что сравнение выполнено корректно
После текстового сравнения пройдитесь по контрольному списку: совпадает ли набор выбираемых полей, источники данных (таблицы и виртуальные таблицы), типы соединений, условия в ГДЕ и параметры виртуальных таблиц, группировки и итоги. Именно эти элементы определяют семантику запроса; отступы и регистр ключевых слов — нет.
После сравнения результатов убедитесь, что совпали: число строк, набор колонок, агрегатные суммы по числовым полям. Если все три признака сошлись на репрезентативном наборе данных, запросы с высокой вероятностью эквивалентны. Для критичных доработок дополнительно прогоните сравнение на граничных случаях: пустой результат, одна строка, данные с NULL в соединяемых полях.
Как проверить результат
Поля, таблицы и типы соединений совпадают
Разные источники или лишнее ЛЕВОЕ СОЕДИНЕНИЕ — возможны дубли строк
Одинаковое при одинаковых параметрах
Разное число строк — запросы не эквивалентны
Суммы совпадают
Расхождение сумм даже при равном числе строк — различается логика вычислений
Результаты по-прежнему совпадают
Расхождение появилось — сравнение зависит от меняющихся данных или RLS
Частые вопросы
Можно ли сравнить два запроса прямо в консоли запросов?
Типовые консоли запросов выполняют запросы по одному и не имеют встроенного режима сравнения текстов. Практика такая: выполните оба запроса по очереди, зафиксируйте количество строк и контрольные суммы, а тексты сравните отдельно через конфигуратор или diff-утилиту. Некоторые сторонние консоли позволяют открыть два запроса в соседних вкладках, что упрощает визуальное сопоставление.
Как сравнить запросы, если один из них формируется программно в коде?
Добавьте в код временный вывод итогового текста (например, через Сообщить() или запись в журнал регистрации) непосредственно перед выполнением запроса — вы получите реальный текст с подставленными частями. Скопируйте его в файл и сравните со вторым вариантом. Не забудьте удалить отладочный вывод после проверки.
Тексты запросов совпадают, но результаты разные — в чём причина?
Проверьте параметры, пользователя (влияет RLS), момент времени выполнения и, для виртуальных таблиц, — параметры отборов. Также убедитесь, что оба запроса выполняются в одной базе: одинаковый запрос в рабочей и тестовой базах закономерно даст разные результаты.
Как сравнить запросы между двумя версиями конфигурации из хранилища?
Используйте сравнение версий конфигурации с версией из хранилища: в отчёте о различиях по конкретному объекту и модулю будут показаны изменённые строки кода, включая строковый литерал запроса. Если запрос находится в макете СКД, сравнивайте XML-представление схемы или выгрузите тексты запросов из обеих версий вручную.
Есть ли способ автоматически найти дубли запросов во всей конфигурации?
Штатного инструмента нет. Практический путь: выгрузить конфигурацию в файлы, найти все вхождения ключевого слова «ВЫБРАТЬ» в модулях, извлечь тексты запросов, нормализовать их (регистр, пробелы) и сравнить хеши — совпадение хешей укажет на дубли. Это делается внешней обработкой или скриптом по файлам выгрузки.
Что важно запомнить
Сравнение текстов и сравнение результатов — разные задачи. Тексты сравнивайте через «Сравнить файлы» конфигуратора или diff-утилиту, предварительно нормализовав форматирование. Эквивалентность результатов проверяйте выполнением обоих запросов с одинаковыми параметрами и сверкой таблиц значений по числу строк и агрегатным суммам.