Работа с внешними базами данных через COM-соединение — это стандартная задача при интеграции различных конфигураций 1С. Одной из наиболее часто встречающихся операций является поиск конкретного документа по его уникальному идентификатору (GUID) с целью последующего редактирования или удаления. В этой статье мы подробно разберем, как правильно реализовать этот механизм, избежав типичных ошибок, связанных с "фантомными" ссылками и блокировками объектов.
Прежде чем приступать к манипуляциям с документами, нам необходимо инициировать само соединение с базой. Мы будем использовать V83.COMConnector, так как он работает быстрее и потребляет меньше ресурсов по сравнению с V83.Application.
Рассмотрим пример инициализации соединения:
// Создаем объект коннектора
ComConnector = Новый COMОбъект("V83.Comconnector");
// Формируем строку подключения (для серверного варианта)
СтрПодключение = "Srvr='ИмяСервера';Ref='ИмяБазы';Usr='Логин';Pwd='Пароль';";
// Устанавливаем соединение
Попытка
Соединение = ComConnector.Connect(СтрПодключение);
Исключение
Сообщить("Ошибка подключения: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Многие начинающие разработчики совершают ошибку, пытаясь найти документ через поиск по коду или номеру. Однако, если у вас есть GUID (строковое представление уникального идентификатора), это самый надежный способ идентифицировать объект.
Разберем, как правильно получить ссылку на документ во внешней базе. Важно помнить, что объект УникальныйИдентификатор должен быть создан именно в контексте внешнего соединения.
// Наш GUID документа
СтрокаGUID = "5accfd89-3247-4862-ab79-e9aced2515";
// Создаем объект UUID в COM-базе
ВнешнийGUID = Соединение.NewObject("УникальныйИдентификатор", СтрокаGUID);
// Получаем ссылку через менеджер конкретного документа
// Замените "ВнутреннееПотреблениеТоваров" на имя вашего документа
СсылкаНаДок = Соединение.Документы.ВнутреннееПотреблениеТоваров.ПолучитьСсылку(ВнешнийGUID);
Важный нюанс: Метод ПолучитьСсылку() всегда возвращает ссылку, даже если объекта с таким GUID в базе не существует. Это так называемая "битая" или "фантомная" ссылка. Чтобы проверить, реальный ли это документ, необходимо попытаться получить его объект или проверить метаданные.
Изменение данных (в том числе установка пометки удаления) возможно только для объекта документа, а не для его ссылки. Рассмотрим, как правильно перейти от ссылки к объекту и выполнить удаление.
Проанализируем следующий алгоритм:
// Пытаемся получить объект
ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
Если ДокОбъект = Неопределено Тогда
Сообщить("Документ с указанным GUID не найден в базе.");
Иначе
Попытка
// Метод УстановитьПометкуУдаления(Истина) сразу записывает объект
ДокОбъект.УстановитьПометкуУдаления(Истина);
Сообщить("Документ успешно помечен на удаление.");
Исключение
Сообщить("Не удалось пометить документ: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Обратите внимание, что при работе через COM рекомендуется использовать англоязычные аналоги методов для повышения стабильности кода. Например, вместо ПолучитьОбъект() можно вызвать GetObject(), а вместо УстановитьПометкуУдаления() — SetDeletionMark().
Во время выполнения этого кода вы можете столкнуться с ошибками. Выясним основные причины:
ПолучитьОбъект() выдаст ошибку. Всегда используйте конструкцию Попытка...Исключение.УстановитьПометкуУдаления(Истина) инициирует выполнение кода в модуле объекта и подписках на события. Если в базе прописаны жесткие условия (например, нельзя удалять документы прошлых периодов), COM-вызов вернет ошибку.Если вам нужно обойти часть интерактивных проверок, можно использовать прямой способ изменения признака пометки удаления:
ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
Если ДокОбъект <> Неопределено Тогда
ДокОбъект.ПометкаУдаления = Истина;
// Используем РежимЗаписиДокумента.Запись для пропуска лишних проверок проведения
ДокОбъект.Записать(Соединение.РежимЗаписиДокумента.Запись);
КонецЕсли;
Если вам необходимо проверить существование множества объектов, использование метода ПолучитьОбъект() для каждого из них будет крайне медленным. В таких случаях лучше использовать механизм запросов через COM-соединение.
Посмотрим на пример реализации запроса:
Запрос = Соединение.NewObject("Запрос");
Запрос.Текст =
"ВЫБРАТЬ
| Т.Ссылка
|ИЗ
| Документ.ВнутреннееПотреблениеТоваров КАК Т
|ГДЕ
| Т.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДок);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Сообщить("Документа не существует в БД");
КонецЕсли;
Не забывайте, что COM-соединения удерживают лицензии и память. После завершения всех операций обязательно освобождайте переменные, содержащие COM-объекты.
// Освобождаем объекты
ДокОбъект = Неопределено;
Соединение = Неопределено;
Подведем итог: для успешного удаления документа по GUID через COM нужно четко соблюдать последовательность: Подключение -> Создание UUID -> Получение Ссылки -> Получение Объекта -> Запись с пометкой удаления. Использование английских имен методов (GetObject, Write) и обязательная обработка исключений сделают ваш код надежным и устойчивым к внешним факторам.