Как сравнить оборотно-сальдовые ведомости в двух базах 1С после переноса данных?

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

Перенос данных между информационными базами — процедура ответственная, и завершающим этапом всегда должна быть сверка итогов. Самый распространенный способ контроля — сравнение оборотно-сальдовых ведомостей (ОСВ). Однако, когда данных много, ручная сверка становится невозможной. Рассмотрим, как автоматизировать этот процесс с помощью программирования, разберем типичные ошибки при использовании COM-соединения и выясним, какие инструменты помогут справиться с большими объемами информации.

Анализ исходной проблемы и типичных ошибок в запросах

Разберем ситуацию: у нас есть база-источник и база-приемник. Мы хотим получить данные из обеих баз, объединить их в одну таблицу, где суммы из источника будут с обратным знаком (минусом), сгруппировать по аналитике и вывести только те строки, где итог не равен нулю. Это отличная стратегия, но на практике программисты часто сталкиваются с тем, что запрос «не работает».

Проанализируем основную ошибку в подходе через COM-соединение. В языке запросов 1С невозможно передать результат внешнего запроса напрямую в предложение ИЗ, как это пытался сделать автор темы: ИЗ &ВнешнийЗапрос. Параметр запроса может быть только значением (числом, строкой, ссылкой) или таблицей значений, но для использования таблицы значений её необходимо предварительно загрузить в Менеджер временных таблиц.

Важный нюанс: при работе через COM-соединение таблица значений, полученная из внешней базы, является COM-объектом. Ее нельзя просто передать в локальный запрос. Сначала ее нужно «переложить» в родную таблицу значений текущей базы.

Решение 1: Программная обработка данных через таблицы значений

Рассмотрим алгоритм правильной организации сравнения. Мы выполним запрос в каждой базе отдельно, выгрузим результаты в локальные таблицы и объединим их для анализа.

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


ТЗ_Сравнение = Новый ТаблицаЗначений;
ТЗ_Сравнение.Колонки.Добавить("Счет", Новый ОписаниеТипов("Строка"));
ТЗ_Сравнение.Колонки.Добавить("Организация", Новый ОписаниеТипов("Строка"));
ТЗ_Сравнение.Колонки.Добавить("Субконто1", Новый ОписаниеТипов("Строка"));
ТЗ_Сравнение.Колонки.Добавить("Субконто2", Новый ОписаниеТипов("Строка"));
ТЗ_Сравнение.Колонки.Добавить("СуммаНачальныйОстаток", Новый ОписаниеТипов("Число"));
ТЗ_Сравнение.Колонки.Добавить("СуммаОборотДт", Новый ОписаниеТипов("Число"));
ТЗ_Сравнение.Колонки.Добавить("СуммаОборотКт", Новый ОписаниеТипов("Число"));
ТЗ_Сравнение.Колонки.Добавить("СуммаКонечныйОстаток", Новый ОписаниеТипов("Число"));

Затем мы подключаемся к внешней базе через V83.COMConnector, выполняем там запрос по регистру бухгалтерии и в цикле переносим данные в нашу ТЗ_Сравнение, умножая числовые показатели на -1. После этого аналогичным образом добавляем данные из текущей базы (уже с положительными знаками).

Рассмотрим, почему важно использовать строковые представления: При переносе данных ссылки на объекты (счета, справочники) в разных базах могут отличаться. Чтобы сопоставление прошло успешно, лучше использовать Код для счетов и Наименование (или УникальныйИдентификатор) для объектов субконто. Выражение ПРЕДСТАВЛЕНИЕ() в запросе поможет получить готовые строки для сравнения.

Решение 2: Использование уникальных идентификаторов (GUID)

Если перенос данных осуществлялся с сохранением идентификаторов (например, через Конвертацию данных), то самым надежным способом будет сравнение по GUID. Разберем, как вытащить GUID из внешней базы через COM-соединение:


// Во внешней базе в запросе получаем Ссылку
Выборка = ВнешнийЗапрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    УникальныйИдентификаторСтрокой = Соединение.String(Выборка.Ссылка.UUID());
    // Далее используем эту строку для поиска объекта в текущей базе
КонецЦикла;

Использование GUID позволяет избежать проблем, когда в разных базах есть объекты с одинаковыми наименованиями, но разным смыслом. Проанализируем ситуацию: если мы сравниваем ОСВ по счету 01 «Основные средства», то сравнение по наименованию может выдать ошибку, если в одной базе объект называется «Компьютер», а в другой — «Компьютер в сборе».

Решение 3: Сравнение табличных документов (MXL)

Для небольших баз или экспресс-проверки можно воспользоваться стандартным механизмом 1С. Сохраните оборотно-сальдовую ведомость из базы-источника и базы-приемника в файлы формата .mxl. Далее воспользуйтесь меню Файл — Сравнить файлы.

Однако, как было отмечено в обсуждении, этот метод имеет существенный недостаток — ограничение памяти. При сравнении файлов большого объема (десятки тысяч строк) 32-разрядное клиентское приложение может выдать ошибку «Недостаточно оперативной памяти». Это связано с тем, что механизм сравнения .mxl пытается построить графическую карту различий, что крайне ресурсозатратно.

Решение 4: Профессиональные инструменты сравнения (Консоль ИР)

Если задача сверки стоит часто или объемы данных колоссальны, рекомендуется использовать специализированные инструменты, такие как «Сравнитель таблиц» из состава Инструментов Разработчика (ИР). Посмотрим, в чем преимущество такого подхода:

  1. Минимальное потребление памяти: Данные сравниваются в виде чистых таблиц значений, а не графических макетов.
  2. Гибкая настройка ключей: Вы можете указать, по каким колонкам считать строки идентичными (например, «Счет» + «Организация» + «Субконто1»).
  3. Подсветка разницы: Инструмент автоматически выделит ячейки, в которых суммы не совпали.

Методика работы проста: выгружаем результат запроса из базы 1 в файл, затем из базы 2 в другой файл, и открываем их в сравнителе. Это намного эффективнее, чем пытаться написать сложный универсальный запрос «на все случаи жизни».

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

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

  1. Получите две таблицы значений.
  2. В каждой таблице создайте одну колонку КлючСвязи, в которую запишите конкатенацию строковых представлений всей аналитики.
  3. Отсортируйте обе таблицы по колонке КлючСвязи.
  4. Используйте один цикл для обхода обеих таблиц, сравнивая текущие ключи. Если ключи равны — вычисляйте разницу сумм. Если ключ в первой таблице «меньше», значит этой записи нет во второй, и наоборот.

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

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

← На главную