Сравнение данных — одна из самых частых задач при разработке в платформе 1С:Предприятие. Часто возникает необходимость найти расхождения между двумя наборами данных, например, сверить остатки на разных складах, выявить изменения в справочниках после выгрузки или проверить корректность миграции данных. Простое визуальное сравнение неэффективно, когда речь идет о тысячах строк.

Язык запросов 1С предоставляет мощный инструментарий для решения этой проблемы без написания сложного кода на встроенном языке. Правильное использование операторов соединения и временных таблиц позволяет получить разницу между наборами данных за доли секунды. В этой статье мы разберем основные сценарии и нюансы реализации.

Использование оператора ПОДОБНО для текстовых полей

Самый простой способ найти различия в строковых данных — использовать оператор ПОДОБНО. Он позволяет сравнивать значения по маске, что особенно полезно при поиске частичных совпадений или игнорировании регистра. Однако для точного сравнения целых таблиц этот метод применяется редко.

Чаще всего ПОДОБНО используют в сочетании с другими условиями для фильтрации. Например, если нужно найти документы, номера которых отличаются только наличием префикса.

Для точного побитового сравнения строк лучше использовать стандартное условие НЕ РАВНО или функцию СТРОКА для явного приведения типов. Это гарантирует, что сравнение пройдет корректно даже при различиях в типах данных исходных колонок.

⚠️ Внимание: Оператор ПОДОБНО может работать медленнее обычного сравнения на больших объемах данных, так как он часто требует полного сканирования таблицы вместо использования индексов.

Рассмотрим пример, где мы ищем номенклатуру с похожими названиями, но разными артикулами. Это помогает выявить дубли в базе:

ВЫБРАТЬ

Номенклатура.Наименование КАК Имя,

Номенклатура.Артикул КАК Код

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.Наименование ПОДОБНО "%Телевизор%"

И Номенклатура.Артикул НЕ ПОДОБНО "TV-%"

Сравнение через ВНЕШНЕЕ СОЕДИНЕНИЕ

Наиболее универсальный метод сравнения двух таблиц — использование конструкции ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ (или ПРАВОЕ, в зависимости от того, какая таблица эталонная). Суть метода заключается в том, чтобы соединить таблицу-источник и таблицу-приемник по ключевым полям.

Если после соединения поле из правой таблицы оказывается ЕСТЬ NULL, это означает, что запись присутствует в левой таблице, но отсутствует в правой. И наоборот, если мы ищем записи, которые есть только во второй таблице, мы проверяем на NULL поля первой.

Этот подход идеально подходит для сверки списков сотрудников, контрагентов или элементов справочников. Он позволяет сразу увидеть, кто был добавлен, а кто удален, в одном результирующем наборе данных.

  • 🔍 Используйте ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, чтобы найти записи, удаленные из правой таблицы.
  • 🔄 Используйте ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, чтобы увидеть все различия в обоих направлениях сразу.
  • ⚡ Обязательно индексируйте поля, по которым происходит соединение, для ускорения выборки.

Пример запроса для поиска отсутствующих элементов:

ВЫБРАТЬ

ЛеваяТаблица.Код,

ЛеваяТаблица.Наименование

ИЗ

Справочник.Контрагенты КАК ЛеваяТаблица

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КонтрагентыАрхив КАК ПраваяТаблица

ПО ЛеваяТаблица.Ссылка = ПраваяТаблица.Ссылка

ГДЕ

ПраваяТаблица.Ссылка ЕСТЬ NULL

💡

Если вы сравниваете большие регистры сведений, предварительно отберите нужные периоды в подзапросах, чтобы не грузить память лишними данными.

Работа с временными таблицами для сложных сравнений

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

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

Синтаксис создания временной таблицы начинается с символа #. После выполнения запроса данные помещаются в эту таблицу и доступны для последующих запросов в рамках той же сессии. Это позволяет разбить сложный алгоритм сравнения на понятные этапы.

Важно следить за объемом данных во временных таблицах. Если вы поместите туда миллионы строк, это может привести к исчерпанию памяти сервера 1С. Всегда фильтруйте данные перед помещением во временное хранилище.

⚠️ Внимание: Временные таблицы существуют только в рамках одной сессии пользователя. При разрыве соединения или завершении работы клиента данные будут безвозвратно утеряны.

Пример последовательности действий с временными таблицами:

// Шаг 1: Получаем данные из первого источника

ВЫБРАТЬ

РегистрНакопления.ТоварыНаСкладах.Товар,

СУММА(РегистрНакопления.ТоварыНаСкладах.Количество) КАК Остаток1

ПОМЕСТИТЬ ВТ_Склад1

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

ГДЕ

ТоварыНаСкладах.Склад = &Склад1

СГРУППИРОВАТЬ ПО

ТоварыНаСкладах.Товар

;

📊 Какой метод сравнения вы используете чаще всего?
Внешнее соединение
Временные таблицы
Обход в цикле
Консоль запросов

Сравнение количественных показателей и итогов

Часто требуется сравнить не наличие записей, а их числовые значения. Например, сверить суммы документов или остатки товаров. В таких случаях простого соединения недостаточно, необходимо использовать агрегатные функции.

Ключевым моментом здесь является группировка данных. Вы должны сгруппировать записи по уникальным ключам (например, по ссылке на документ или элемент справочника) и посчитать суммы, количества или средние значения. Затем сравниваются уже эти итоговые показатели.

Для выявления расхождений используется условие в блоке ИМЕЮЩИЕ или фильтрация в основном запросе после группировки. Это позволяет отсечь идеально совпадающие записи и оставить только проблемные.

Метод Когда использовать Производительность
Внешнее соединение Поиск отсутствующих записей Высокая (при индексах)
Временные таблицы Сложная логика, несколько источников Средняя (зависит от памяти)
Агрегатные функции Сверка сумм и остатков Высокая
Оператор ПОДОБНО Поиск по маске в тексте Низкая на больших данных

При сравнении денежных сумм всегда учитывайте возможную погрешность округления. Прямое сравнение Сумма1 = Сумма2 может дать ложный результат из-за особенностей хранения чисел с плавающей точкой. Лучше использовать проверку на диапазон или округление до копеек перед сравнением.

💡

При сравнении денег используйте функцию ОКРУГЛИТЬ() до 2 знаков после запятой, чтобы избежать ошибок из-за микро-различий в вычислениях.

Оптимизация производительности при сравнении

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

Использование индексов — второй критический фактор. Убедитесь, что поля, по которым вы делаете СОЕДИНЕНИЕ или ГДЕ, проиндексированы в конфигурации. В противном случае 1С будет вынуждена выполнять полное сканирование таблиц, что экспоненциально замедляет работу.

Также стоит избегать вложенных запросов там, где можно использовать временные таблицы. Хотя оптимизатор 1С умеет работать с вложенными запросами, явное разделение этапов часто дает более предсказуемый план выполнения.

  • 🚀 Отключите автоматическое упорядочивание (УПОРЯДОЧИТЬ ПО), если порядок строк не важен для логики — это ускорит выборку.
  • 🛑 Не используйте функции в условиях соединения, например ГОД(Дата) = 2023, это отключает использование индексов по дате.
  • 📉 Разбивайте сравнение на пакеты по периодам, если объем данных превышает сотни тысяч записей.

⚠️ Внимание: Интерфейсы и механизмы работы с/query могут меняться в новых версиях платформы 1С. Всегда проверяйте синтаксис в справке по вашей конкретной версии конфигурации.

Секрет быстрой работы

Использование пакета запросов позволяет отправить несколько связанных запросов на сервер одним вызовом, снижая сетевые задержки.

Практические примеры кода для разработчиков

Рассмотрим готовый пример сравнения двух регистров накопления для выявления расхождений в остатках. Этот код можно адаптировать под любые табличные части или справочники.

В данном примере мы создаем две временные таблицы с остатками на разные даты, а затем соединяем их, вычисляя разницу. Такой подход позволяет получить отчет "План-Факт" или "Остаток на начало - Остаток на конец" одним запросом.

ВЫБРАТЬ

ОстаткиНачало.Номенклатура,

ОстаткиНачало.Количество КАК Начало,

ОстаткиКонец.Количество КАК Конец,

(ОстаткиКонец.Количество - ОстаткиНачало.Количество) КАК Разница

ИЗ

ВТ_Начало КАК ОстаткиНачало

ПОЛНОЕ СОЕДИНЕНИЕ ВТ_Конец КАК ОстаткиКонец

ПО ОстаткиНачало.Номенклатура = ОстаткиКонец.Номенклатура

ГДЕ

(ОстаткиНачало.Количество <> ОстаткиКонец.Количество)

ИЛИ (ОстаткиНачало.Номенклатура ЕСТЬ NULL)

ИЛИ (ОстаткиКонец.Номенклатура ЕСТЬ NULL)

Обратите внимание на условие в блоке ГДЕ. Оно отфильтровывает строки, где данные полностью совпадают, оставляя только те, где есть изменения или расхождения. Это значительно уменьшает объем итогового отчета.

☑️ Чек-лист перед запуском сравнения

Выполнено: 0 / 4
Можно ли сравнивать таблицы из разных информационных баз в одном запросе?

Нет, язык запросов 1С работает только в контексте текущей подключенной базы данных. Для сравнения данных из разных баз необходимо сначала выгрузить данные из внешней базы (например, через COM-соединение или HTTP-сервис) во временную таблицу текущей сессии, и уже затем выполнять сравнение.

Почему запрос с ВНЕШНИМ СОЕДИНЕНИЕМ работает медленно?

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

Как сравнить табличные части документов?

Необходимо делать соединение не только по ссылке на документ (Родитель), но и по номеру строки или уникальному идентификатору строки табличной части. Часто используют конструкцию СОЕДИНЕНИЕ ПО Документ.Ссылка = ТабЧасть.Ссылка И Документ.НомерСтроки = ТабЧасть.НомерСтроки.

Что делать, если при сравнении теряются данные из-за дублей?

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

Есть ли ограничение на размер временных таблиц?

Жесткого ограничения в строках нет, но есть ограничение по объему оперативной памяти, выделенной процессу rphost. При попытке поместить слишком большой объем данных сервер может завершить сессию с ошибкой превышения лимита памяти. Для больших данных используйте файловые таблицы или разбиение на периоды.