Синхронизация современной системы 1С:Предприятие с устаревшими программными комплексами на базе FoxPro (DBF) — это классическая задача при поэтапном переходе на новое ПО. Основная сложность заключается в том, что старые системы часто не обладают механизмами автоматической очистки связанных данных при изменении или удалении объектов в источнике. В этой статье мы подробно рассмотрим архитектурный подход к решению проблемы «адресного» удаления строк табличных частей в базе-приемнике, когда разработчик внешней системы недоступен, а связь осуществляется исключительно через «горячую папку» с файлами обмена.
Разберем ситуацию: документ в 1С при выгрузке должен трансформироваться в две таблицы DBF — docum (шапка) и list (табличная часть). При этом одна строка документа в 1С может порождать до четырех записей в DBF, каждая из которых имеет свой уникальный идентификатор (УИН). Проблема возникает, когда пользователь в 1С удаляет строку из табличной части или меняет реквизиты (например, подразделение), из-за чего данные должны «переехать» из одного узла обмена в другой. База-приемник не умеет сама сопоставлять текущий состав строк с присланным — ей нужно явно указать, какой УИН пометить на удаление (проставить символ d в специальном поле).
Для решения этой задачи мы не можем использовать стандартный механизм регистрации изменений объектов, так как он фиксирует изменение всего документа, но не «помнит», какие строки были в нем до записи. Проанализируем наиболее эффективный метод — использование независимого регистра сведений (теневой таблицы).
Рассмотрим создание независимого регистра сведений, например, УИН_ВыгруженныхСтрок. Этот регистр будет служить «памятью» системы о том, что именно было отправлено в FoxPro. В структуре регистра нам потребуются следующие измерения и ресурсы:
Такая структура позволит нам в любой момент времени узнать, какие УИНы были созданы для конкретного документа и в какой узел они ушли.
Выясним, как фиксировать факт удаления строки. Нам необходимо подписаться на событие ПередЗаписью документа. Разберем алгоритм действий по шагам:
1. Считываем текущее состояние строк из регистра УИН_ВыгруженныхСтрок по данному документу в таблицу значений (старое состояние).
2. Анализируем новую табличную часть объекта (новое состояние).
3. Сравниваем их. Те УИНы, которые присутствуют в старом состоянии, но отсутствуют в новом (или если изменилось подразделение), помечаются в регистре специальным флагом К_Удалению.
Посмотрим на пример кода в обработчике события:
// В процедуре ПередЗаписью документа
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ РегистрСведений.УИН_ВыгруженныхСтрок ГДЕ ДокументСсылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
СтарыеСтроки = Запрос.Выполнить().Выгрузить();
// Проходим по строкам ТЧ объекта
Для Каждого СтрокаТЧ Из Источник.Товары Цикл
// Ищем соответствие, обновляем или создаем записи в регистре
КонецЦикла;
// Те записи, которые не найдены в новой ТЧ, помечаем на удаление
Для Каждого ЗаписьИзРегистра Из СтарыеСтроки Цикл
Если Не СтрокаНайдена Тогда
МенеджерЗаписи = РегистрыСведений.УИН_ВыгруженныхСтрок.СоздатьМенеджерЗаписи();
// Заполняем ключевые поля и ставим статус удаления
МенеджерЗаписи.Статус = Перечисления.СтатусыВыгрузки.КУдалению;
МенеджерЗаписи.Записать();
КонецЕсли;
КонецЦикла;
Проанализируем ситуацию со сменой подразделения. Если в документе меняется подразделение, это означает, что во все базы-приемники старого подразделения нужно отправить команду на удаление всех строк документа, а в базу нового подразделения — команду на создание. Это критически важный момент.
Мы настраиваем ПланОбмена с фильтрацией по подразделениям. При изменении регистра УИН_ВыгруженныхСтрок изменения автоматически регистрируются на узлах. В регламентном задании выгрузки мы выбираем изменения по плану обмена, формируем DBF-файл и записываем в поле признака удаления букву d для тех записей, у которых в регистре стоит статус К_Удалению.
При работе с устаревшими базами FoxPro стандартного объекта XBase в 1С может быть недостаточно из-за проблем с кодировками или блокировками файлов. Рассмотрим использование ADODB для более надежной записи. Это позволит использовать SQL-команды прямо к файлам DBF.
// Пример подключения через ADO к папке с DBF
Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Provider=VFPOLEDB.1;Data Source=" + ПутьКПапке + ";";
Connection.Open(ConnectionString);
// Выполнение вставки или обновления с меткой удаления
Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "UPDATE list SET deleted_flag = 'd' WHERE uin_id = '" + ТекущийУИН + "'";
Command.Execute();
Важные рекомендации по работе с «горячими папками»:
.tmp, запишите все данные, закройте файл и только потом перемещайте (переименовывайте) его в .dbf в «горячую папку». Это гарантирует, что база-приемник не начнет читать недописанный файл.866 (OEM). При использовании XBase обязательно проверяйте кодировку создаваемого файла.Подводя итог, можно сказать, что наиболее стабильная архитектура для взаимодействия с «мертвыми» внешними системами строится на принципе событийного логирования внутри 1С. Мы не полагаемся на состояние внешней базы, а ведем собственный учет того, что было отправлено. Использование независимого регистра сведений в связке с Планом обмена позволяет гарантированно отслеживать удаление строк и корректно обрабатывать перемещение документов между подразделениями, обеспечивая целостность данных в FoxPro.