Работа с внешними источниками данных (ВИД) в 1С открывает широкие возможности для интеграции с базами данных SQL, Oracle или PostgreSQL. Однако разработчики часто сталкиваются с проблемой: при написании запроса к внешней таблице поле Ссылка отсутствует в списке доступных полей. Рассмотрим подробно, от чего зависит появление этого поля, как получить ссылку программно и как использовать её для изменения данных во внешней системе.
Для того чтобы платформа 1С сформировала виртуальное поле Ссылка для таблицы внешнего источника, недостаточно просто подключить таблицу. Разберем по шагам необходимые настройки в конфигураторе:
ID типа INT) или составной ключ из нескольких колонок.Важный нюанс: Поле Ссылка в 1С для внешних источников — это не привычный нам GUID, а сериализованное представление значений ключевых полей. Если эти условия соблюдены, в конструкторе запроса мы увидим доступное поле Ссылка.
Рассмотрим ситуацию, когда нам нужно программно отобрать записи и получить их ссылки для дальнейшей обработки. Проанализируем пример запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МояВнешняяТаблица.Ссылка КАК Ссылка,
| МояВнешняяТаблица.Наименование КАК Наименование
|ИЗ
| ВнешнийИсточникДанных.МойИсточник.Таблица.МояВнешняяТаблица КАК МояВнешняяТаблица
|ГДЕ
| МояВнешняяТаблица.Статус = &Статус";
Запрос.УстановитьПараметр("Статус", "Новый");
РезультатЗапроса = Запрос.Выполнить();
Выясним, что происходит «под капотом»: платформа выполняет SQL-запрос к внешней базе, получает значения ключевых полей и на их основе формирует объекты типа ВнешнийИсточникДанныхТаблицаСсылка. Теперь мы можем использовать эти ссылки так же, как и ссылки на справочники или документы.
Часто ссылка нужна именно для того, чтобы изменить реквизиты строки внешней таблицы. Разберем, как это сделать, используя метод ПолучитьОбъект(). Предположим, мы уже получили выборку из запроса выше:
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем объект по ссылке из результата запроса
ВнешнийОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Изменяем нужные поля
ВнешнийОбъект.Статус = "Обработан";
ВнешнийОбъект.ДатаОбработки = ТекущаяДата();
// Записываем изменения во внешнюю базу
Попытка
ВнешнийОбъект.Записать();
Исключение
Сообщить("Ошибка записи во внешнюю БД: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Рассмотрим критически важный момент: метод Записать() будет работать только в том случае, если в настройках таблицы ВИД в конфигураторе не установлена галочка «Только чтение». Также у пользователя СУБД, под которым установлено соединение, должны быть права на выполнение операции UPDATE.
Проанализируем структуру ссылки. В отличие от внутренних объектов 1С, где ссылка — это случайный уникальный номер, ссылка внешнего источника жестко привязана к данным в SQL-таблице. Если во внешней базе изменится значение первичного ключа для строки, ссылка в 1С станет «битой» (объект не будет найден).
Интересная особенность: ссылки на внешние источники можно хранить в реквизитах базы 1С. Например, мы можем создать справочник Договоры и добавить в него реквизит ИД_Во_Внешней_Системе с типом ВнешнийИсточникДанныхТаблицаСсылка.ИмяИсточника.ИмяТаблицы. Это позволяет связывать данные двух систем на уровне платформенных механизмов.
Необходимо понимать, что использование объектной модели (ПолучитьОбъект()) для массовой обработки данных (тысячи строк) может значительно замедлить работу системы. Каждый вызов ПолучитьОбъект() и последующая Записать() — это отдельные сетевые транзакции к внешней СУБД.
Если нам требуется массовое изменение данных, рассмотрим альтернативный подход — прямой SQL-запрос через установленное соединение:
Соединение = ВнешниеИсточникиДанных.МойИсточник.УстановитьСоединение();
// Если СУБД позволяет, можно выполнить прямой UPDATE через объект Запрос
// или использовать механизмы ADO/ODBC напрямую через драйвер.
Для успешного получения ссылки в запросе к внешнему источнику данных мы должны:
Соблюдение этих правил позволяет полноценно использовать объектную технику 1С при работе со сторонними базами данных, обеспечивая прозрачность и типизацию кода.