При работе с двумя конфигурациями 1С, такими как 1С:Управление нашей фирмой (УНФ) и 1С:Бухгалтерия Предприятия (БП), синхронизация данных является критически важным процессом. Часто возникает вопрос, как избежать перезаписи объектов, которые уже были загружены в базу-приемник (БП 3.0) при последующих обменах, особенно если требуется “догрузить” данные за уже синхронизированный период. Давайте рассмотрим эту проблему подробнее и выясним, какие существуют решения.
Прежде всего, важно понимать, как работает типовой механизм синхронизации данных в 1С. По умолчанию он разработан для оптимизации обмена и предотвращения избыточных операций:
Если объект в базе-источнике (УНФ) не изменился, а в базе-приемнике (БП) он уже существует (и был ранее загружен), типовой механизм не должен его перезаписывать, если он не был модифицирован в УНФ после предыдущего обмена.
Рекомендуемый подход к ведению учета: Обычно, при использовании связки УНФ и БП, УНФ выступает в роли основной системы для оперативного и управленческого учета, а БП используется для формирования регламентированной бухгалтерской отчетности. При таком подходе, ввод первичных документов осуществляется в УНФ, а в БП загружаются уже обработанные данные, необходимые для бухгалтерии. Это помогает избежать дублирования информации и конфликтов.
Хотя прямого флажка «не перезаписывать уже загруженные объекты» в типовых настройках нет, существуют методы, позволяющие контролировать процесс синхронизации и косвенно влиять на перезапись:
Один из самых распространенных способов управления объемом данных — это использование ограничений по дате. Вы можете установить дату, с которой будет происходить обмен и регистрация документов:
Анализируем ситуацию: При повторной синхронизации за уже синхронизированный период, установка новой «Даты начала обмена» может не сработать так, как вы ожидаете, если цель — исключить перезапись уже существующих объектов, но добавить новые за тот же период. Если вы просто сдвинете дату обмена вперед, новые документы за прошлый период не попадут в обмен. Если вы установите дату обмена назад, объекты, которые были изменены в УНФ с момента предыдущего обмена, будут перезаписаны в БП, что не соответствует вашему требованию. Для предотвращения повторной отправки лишних данных можно использовать обработку для отмены регистрации документов в плане обмена за выбранный период.
Настройки синхронизации позволяют гибко регулировать состав передаваемой информации:
Если УНФ является единственным источником данных для БП, и из БП ничего не должно выгружаться обратно в УНФ, обязательно настройте односторонний обмен. В настройках синхронизации данных в 1С:БП установите переключатель на «Не отправлять» данные. Это предотвратит возможные конфликты и дублирование при попытке БП выгрузить свои данные.
Одной из ключевых задач при настройке синхронизации является корректное сопоставление элементов в обеих базах. Это достигается путем использования уникальных ключевых реквизитов:
УНФ- для УНФ и БП- для БП) добавляется к номерам документов и кодам списков. Это позволяет создавать уникальную нумерацию объектов в каждой базе и помогает системе однозначно идентифицировать, из какой базы пришел тот или иной объект, предотвращая коллизии при сопоставлении.При обнаружении расхождений система может выдать предупреждения. Мы рекомендуем регулярно просматривать и устранять эти предупреждения, чтобы обеспечить корректность обмена.
Форумное обсуждение справедливо указывает на то, что для специфических сценариев, когда требуется более тонкое управление, например, полное исключение перезаписи для определенных объектов, может потребоваться программная доработка. Упоминание «отладчика» намекает на необходимость вмешательства в стандартный механизм обмена данными.
Для реализации задачи «догрузить без перезаписи» на программном уровне мы можем использовать возможности механизмов обмена данными, в частности, типовые подсистемы «Обмен данными» и «Конвертация данных 2.0».
Инструмент Конвертация данных 2.0 предоставляет широкие возможности для настройки правил обмена. В нем можно создавать и модифицировать правила конвертации объектов, которые определяют, как данные из одной конфигурации преобразуются для другой. В правилах конвертации объектов (ПКО) существуют события, которые мы можем перехватить:
ПередЗагрузкойОбъекта: Это событие происходит непосредственно перед попыткой загрузки объекта в базу-приемник. Здесь мы можем написать код, который проверяет наличие объекта в базе-приемнике.ПриЗагрузкеОбъекта: Выполняется после загрузки объекта, но до его записи.Пример логики для события ПередЗагрузкойОбъекта в ПКО:
Предположим, мы хотим, чтобы документы определенного вида не перезаписывались, если они уже существуют. Мы можем:
// Примерный код в событии "ПередЗагрузкойОбъекта" для ПравилаКонвертацииОбъекта "Документ.РеализацияТоваровУслуг"
// Параметры:
// ОбъектИсточник - Объект, который загружается из файла
// ОбъектПриемник - Объект, который будет создан или найден в базе-приемнике
// Отказ - Булево, если Истина, то загрузка объекта будет отменена
// Допустим, мы хотим предотвратить перезапись, если документ с таким же номером и датой уже существует
// и не помечен на удаление.
Если ТипЗнч(ОбъектИсточник) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
// Попробуем найти существующий документ в базе-приемнике
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| РеализацияТоваровУслуг.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Номер = &Номер
| И РеализацияТоваровУслуг.Дата = &Дата
| И РеализацияТоваровУслуг.Организация = &Организация"; // Добавляем организацию для более точного поиска
Запрос.УстановитьПараметр("Номер", ОбъектИсточник.Номер);
Запрос.УстановитьПараметр("Дата", ОбъектИсточник.Дата);
// Для параметра &Организация нужно будет найти соответствующую организацию в базе-приемнике.
// Это можно сделать, используя дополнительные параметры конвертации или по ключевым реквизитам
// объекта-организации, который уже был или будет сконвертирован.
// В данном примере упростим, предполагая, что Организация уже сопоставлена.
// Получаем организацию из входящего объекта и ищем ее в базе-приемнике.
// Здесь требуется более сложная логика, т.к. ОбъектИсточник.Организация - это ссылка из базы-источника.
// Нужно найти соответствующую ссылку в базе-приемнике.
// Примерно так (это упрощение, без учета всех деталей конвертации ссылок):
// ОрганизацияПриемник = НайтиСоответствиеСсылок(ОбъектИсточник.Организация);
// Запрос.УстановитьПараметр("Организация", ОрганизацияПриемник);
// Для демонстрации предположим, что Организация уже корректно установлена в объекте-приемнике
// или мы можем ее найти каким-то другим способом.
// Если прямая ссылка недоступна, придется искать по ИНН/КПП.
// Пусть ОрганизацияУНФ = ОбъектИсточник.Организация;
// ОрганизацияБП = УправлениеОбменомДанными.НайтиОбъектПоКлючуОбъектаВДругойИБ(ОрганизацияУНФ);
// Если ОрганизацияБП = Неопределено Тогда
// ОрганизацияБП = Константы.ОсновнаяОрганизация.Получить(); // Или другая логика поиска
// КонецЕсли;
// Запрос.УстановитьПараметр("Организация", ОрганизацияБП);
// Более надежный способ получить объект "Организация" из Приемника для параметра
// Мы знаем, что ОбъектПриемник (который еще не записан) уже имеет заполненное поле Организация.
Если ОбъектПриемник.Свойство("Организация") Тогда
Запрос.УстановитьПараметр("Организация", ОбъектПриемник.Организация);
Иначе
// Если поле Организация отсутствует или не заполнено, что маловероятно для документа
Отказ = Истина; // Или обработать ошибку
Возврат;
КонецЕсли;
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
// Документ с таким номером и датой уже существует в базе-приемнике.
// Мы не хотим его перезаписывать, если он не был изменен в источнике.
// Дополнительно можно сравнить какие-либо реквизиты, чтобы убедиться,
// что это тот же самый объект и он не требует обновления.
// Например, если в ОбъектеИсточник есть какой-то хэш или дата изменения,
// можно сравнить их с существующим объектом в Приемнике.
// В простейшем случае, если нашли по номеру/дате/организации, просто отменяем загрузку.
Отказ = Истина; // Отменяем загрузку текущего объекта
Сообщить("Документ " + ОбъектИсточник.Номер + " от " + ОбъектИсточник.Дата + " уже существует. Загрузка отменена.");
КонецЕсли;
КонецЕсли;
Подобный код можно разместить в обработчиках событий правил конвертации объектов, которые открываются в конфигурации Конвертация данных.
Если требуется глубокое вмешательство, можно использовать универсальный обмен данными XML и самостоятельно модифицировать выгружаемый или загружаемый XML-файл. Однако этот путь значительно сложнее и требует детального понимания структуры обмена.
Упоминание отладчика в форумной ветке подразумевает, что для понимания процесса и поиска места для вмешательства необходимо проанализировать работу типовых механизмов. Мы рекомендуем поставить точки останова в следующих местах:
МенеджерОбменаДанными, ОбменДаннымиВызовСервера).Анализируя последовательность вызовов функций и значения переменных в отладчике, мы можем определить, в какой момент система принимает решение о перезаписи или создании нового объекта, и где можно встроить свою логику. Для упрощения этой задачи можно использовать расширение для отладки обмена через Универсальный формат.
Прежде чем приступать к любым изменениям или настройкам синхронизации, мы настоятельно рекомендуем выполнить следующие действия:
Таким образом, хотя прямого переключателя «отключить перезапись» нет, мы можем достичь желаемого результата путем комбинирования настроек ограничения по дате, выбора объектов для обмена и, при необходимости, программной доработки правил конвертации данных. Последний подход требует знаний в области программирования 1С и работы с Конвертацией данных, но предоставляет максимальную гибкость.