Обмен данными через формат DBF — это классический, но зачастую проблемный способ интеграции 1С со сторонними системами. Одной из самых сложных ситуаций является отсутствие в структуре файла GUID (уникального идентификатора). Если при этом пользователи в сторонней программе имеют возможность изменять номер и дату документа уже после того, как он был загружен в 1С, возникает дублирование данных. Алгоритм загрузки просто не находит документ по старым реквизитам и создает новый.
В этой статье мы разберем, как построить надежную систему идентификации объектов, даже если входные данные крайне нестабильны. Рассмотрим несколько подходов: от административных мер до продвинутых алгоритмов нечеткого поиска.
Самый надежный способ, который упоминается в обсуждении, — это добавление в структуру DBF-файла дополнительного поля для хранения уникального идентификатора. Программисты часто называют его ГНОМ (Глобальный Номер Обмена) или просто пользовательский GUID.
Разберем, как это работает. В сторонней программе при создании документа один раз генерируется уникальная строка (например, через NewId() в SQL или встроенные средства языка). Этот идентификатор записывается в поле DBF и никогда не меняется, даже если пользователь правит номер, дату или контрагента.
На стороне 1С нам необходимо:
ИдентификаторСтороннейСистемы (тип: Строка, длина 36-50 символов).Проанализируем пример кода для поиска документа:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.ИдентификаторСтороннейСистемы = &Идентификатор";
Запрос.УстановитьПараметр("Идентификатор", СтрокаИзDBF.EXT_ID);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
Иначе
ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
ДокументОбъект.ИдентификаторСтороннейСистемы = СтрокаИзDBF.EXT_ID;
КонецЕсли;
Если изменить структуру DBF невозможно, нам придется использовать логику "похожести". Мы можем предположить, что хотя номер и дата изменились, другие важные параметры (сумма, контрагент, состав товаров) остались прежними. Разберем, как реализовать механизм сопоставления по весам.
Каждому совпадению полей мы присваиваем определенный балл. Например:
Если итоговая сумма баллов превышает порог (например, 80), мы считаем, что это тот же самый документ. Рассмотрим логику функции сопоставления:
Функция НайтиПохожийДокумент(ДанныеФайла)
// Ищем документы контрагента за период +/- 5 дней
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка, СуммаДокумента, Дата ИЗ Документ.Продажа ГДЕ Контрагент = &Контрагент";
// ... установка параметров периода ...
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Вес = 0;
Если Выборка.СуммаДокумента = ДанныеФайла.Сумма Тогда
Вес = Вес + 50;
КонецЕсли;
Если НачалоДня(Выборка.Дата) = НачалоДня(ДанныеФайла.Дата) Тогда
Вес = Вес + 30;
КонецЕсли;
Если Вес >= 80 Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
В технологии DBF каждая строка имеет свой порядковый физический номер — RECNO. Если программа-источник не создает файл каждый раз "с нуля", а обновляет существующий, то запись о документе №369852147 будет всегда находиться на одной и той же позиции в файле.
Важный нюанс: Этот метод рискован, так как после процедуры сжатия (Pack) или пересоздания файла индексы сместятся. Однако в стабильных системах это может стать временным решением. Мы можем сохранять номер строки из файла в 1С и при следующей загрузке проверять именно эту позицию.
Чтобы контролировать изменения, проанализируем ситуацию через промежуточное звено. Создадим в 1С РегистрСведений, который будет хранить "слепки" (хэши) строк из последнего успешно загруженного файла.
Алгоритм действий следующий:
Такой подход позволяет избежать автоматического создания дублей и перекладывает принятие окончательного решения на оператора, предоставляя ему удобный интерфейс для сравнения старых и новых данных.
Как отмечалось в обсуждении, существуют реквизиты, которые подтверждены первичными документами и меняются крайне редко. Это могут быть Номер входящего документа или Номер БСО (бланка строгой отчетности). Если в вашей предметной области есть такие данные, они должны стать первичным ключом поиска.
Проанализируем преимущества этого метода:
Выясним причину, по которой "специалисты" так часто меняют данные. Если это неизбежное зло, то лучшей стратегией будет комбинированный метод:
Шаг 1: Попытка поиска по жесткому идентификатору (если его удалось внедрить).
Шаг 2: Поиск по входящим номерам документов (БСО).
Шаг 3: Сверка итоговых оборотов за день. Если в 1С и в файле итоговая сумма за день совпадает, но состав документов разный — это явный признак того, что какой-то документ был переименован. В этом случае стоит реализовать механизм "Сторно": помечать на удаление все загруженные за этот день документы и загружать их заново из файла целиком.
Рассмотрим пример реализации метода "перезагрузки периода":
Процедура ЗагрузитьПериодСПолнымОбновлением(ДатаНачала, ДатаОкончания, ДанныеФайла)
// 1. Находим все документы, ранее загруженные за этот период
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.Продажа ГДЕ Дата МЕЖДУ &Д1 И &Д2 И ЗагруженИзВнешнейСистемы = ИСТИНА";
// ...
// 2. Помечаем их на удаление, чтобы не создавать дублей
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
ДокОбъект.УстановитьПометкуУдаления(Истина);
ДокОбъект.Записать();
КонецЦикла;
// 3. Создаем новые документы на основе текущих данных из DBF
Для Каждого СтрокаДанных Из ДанныеФайла Цикл
СоздатьНовыйДокумент(СтрокаДанных);
КонецЦикла;
КонецПроцедуры
В заключение отметим, что работа с DBF без уникальных ключей — это всегда поиск компромисса между автоматизацией и ручным контролем. Использование промежуточных регистров истории и алгоритмов нечеткого поиска позволяет свести количество ошибок к минимуму, сохраняя при этом актуальность данных в учетной системе.