Работа со ссылками (Ссылка) — это фундаментальный аспект программирования на платформе 1С:Предприятие 8. Ссылка представляет собой уникальный идентификатор объекта информационной базы (элемента справочника‚ документа‚ записи регистра и т.д.)‚ который позволяет оперировать объектом как единым целым‚ не загружая все его данные в память. В данной статье подробно разберем‚ как получить ссылку на объект с помощью языка запросов‚ а также рассмотрим связанные нюансы и лучшие практики.
Теоретические основы: что такое Ссылка в 1С
В платформе 1С существует два основных представления данных:
- Ссылка (Ref) — легковесный идентификатор. Содержит тип метаданных и уникальный идентификатор (UUID). Используется для навигации‚ сравнения‚ передачи в качестве параметров и внешних ключей.
- Объект (Object/Data) — полноценная структура данных в памяти (рекурсивная для справочников/документов‚ табличная для наборов записей). Содержит все реквизиты‚ табличные части и методы записи/удаления.
Важно: Запрос (Запрос) по своей природе работает с ссылками и примитивными типами. Он не возвращает полноценные управляемые объекты (типа СправочникОбъект.Номенклатура)‚ а возвращает значения типа СправочникСсылка.Номенклатура.
Основные способы получения ссылки в тексте запроса
Прямое выборка поля-ссылки (Самый частый сценарий)
Большинство таблиц БД (Справочники‚ Документы‚ Регистры накопления/сведений‚ Бизнес-процессы‚ Задачи) имеют системное поле Ссылка. При выборке из главной таблицы это поле возвращается автоматически‚ если указано * или явно перечислено.
ВЫБРАТЬ
Номенклатура.Ссылка КАК НоменклатураСсылка‚
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.ПометкаУдаления = ЛОЖЬ Результат: колонка НоменклатураСсылка будет иметь тип СправочникСсылка.Номенклатура.
Получение ссылки через JOIN (Соединение)
Часто ссылку нужно получить‚ «подтянув» её из связанной таблицы по внешнему ключу.
ВЫБРАТЬ
Товары.Номенклатура КАК НоменклатураСсылка‚ // Это и есть ссылка из регистра
Товары.Количество‚
Номенклатура.Наименование
ИЗ
РегистрНакопления.ТоварыНаСкладах;Остатки КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
ПО Товары.Номенклатура = Номенклатура.Ссылка Здесь Товары.Номенклатура — это уже готовая ссылка (внешний ключ)‚ а Номенклатура.Ссылка, то же самое поле из таблицы справочника.
Функция ЗНАЧЕНИЕ (VALUE) — создание ссылки из константы/параметра
Если вам нужно в запросе сравнить поле со конкретной заранее известной ссылкой (например‚ найти документ по конкретному контрагенту)‚ используется функция ЗНАЧЕНИЕ.
ВЫБРАТЬ
РеализацияТоваров.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваров
ГДЕ
РеализацияТоваров.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.НайтиПоНаименованию("Ромашка")) Синтаксис: ЗНАЧЕНИЕ(ПолноеИмяМетаданных.ИмяЭлемента) или ЗНАЧЕНИЕ(Метаданные.УникальныйИдентификатор).
Функция ССЫЛКА (REF) — получение ссылки по набору полей (Редко используется)
Позволяет построить ссылку‚ зная реквизиты‚ входящие в уникальный ключ (обычно это ID или код/наименование для справочников с уникальностью по коду). В современных версиях платформы (8.3+) используется крайне редко‚ так как почти всегда удобнее использовать ЗНАЧЕНИЕ или параметры запроса.
// Пример для справочника с уникальностью по Коду
ВЫБРАТЬ
ССЫЛКА(Справочник.Номенклатура‚ Код = "000001") КАК НайденнаяСсылка Работа с параметрами запроса (Best Practice)
Наиболее правильный и производительный способ передать ссылку в запрос, использовать параметры. Это позволяет платформе кэшировать план запроса и защищает от инъекций кода.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Заказ.Ссылка‚
| Заказ.Дата
|ИЗ
| Документ.ЗаказПокупателя КАК Заказ
|ГДЕ
| Заказ.Контрагент = &Контрагент
| И Заказ.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("Контрагент"‚ СсылкаНаКонтрагента); // Передаем объект типа СправочникСсылка.Контрагенты
Запрос.УстановитьПараметр("НачалоПериода"‚ НачалоДня(ТекущаяДата));
Запрос.УстановитьПараметр("КонецПериода"‚ КонецДня(ТекущаяДата));
Результат = Запрос.Выполнить; Особенности для разных типов метаданных
| Тип метаданных | Имя системного поля ссылки | Особенности |
|---|---|---|
| Справочник | Ссылка | Всегда доступно. Для иерархических справочников есть Родитель (тоже ссылка). |
| Документ | Ссылка | Доступно в виртуальных таблицах (Обороты‚ Остатки) как измерение. |
| Регистр накопления / сведений | Ссылка (только для регистров с измерением «Регистратор») | В остатках/оборотах ссылки нет (это агрегаты). В таблице записей (Выбрать) есть Ссылка на набор записей. |
| План видов характеристик / обмена | Ссылка | Аналогично справочникам. |
| Бизнес-процесс / Задача | Ссылка | Имеют специфические виртуальные таблицы (Стадии‚ Адресаты). |
| Перечисление | Нет (примитивный тип) | Значения перечислений — это не ссылки‚ а значения типа ПеречислениеСсылка.Имя. Получаются через ЗНАЧЕНИЕ(Перечисление.Имя.Значение). |
Виртуальные таблицы и ссылки
При работе с виртуальными таблицами регистров (Остатки‚ Обороты‚ Выборка) важно понимать структуру полей:
- Измерения типа Ссылка: Возвращают ссылку напрямую (например‚
Остатки.Номенклатура, этоСправочникСсылка.Номенклатура). - Регистратор: В виртуальных таблицах регистров накопления поле
Регистраторсодержит ссылку на документ (ДокументСсылка;Имя). - Набор записей: В таблице записей регистра (
РегистрНакопления.Имя.Выбратьили выборка из таблицы записей в запросе) полеСсылкассылается на Набор записей (РегистрНакопленияНаборЗаписей.Имя)‚ а не на отдельную строку.
Типичные ошибки и нюансы
Сравнение ссылки со строкой или числом
Ошибка: ГДЕ Номенклатура.Ссылка = "000001" или ГДЕ Номенклатура.Ссылка = 123.
Правильно: Сравнивать ссылку можно только со ссылкой того же типа или с NULL; Используйте ЗНАЧЕНИЕ или параметры.
Попытка получить реквизиты ссылки в запросе без JOIN
Если в запросе выбрана только ссылка (ВЫБРАТЬ Номенклатура.Ссылка)‚ то в результате запроса (Выборка) будет доступно только поле Ссылка. Обращение к Выборка.Наименование вызовет ошибку «Поле не найдено».
Решение: Либо добавить нужные поля в ВЫБРАТЬ‚ либо сделать ЛЕВОЕ СОЕДИНЕНИЕ со справочником.
Null-ссылки (Пустые ссылки)
Пустая ссылка в запросе записывается как NULL (или через функцию ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)‚ но NULL предпочтительнее).
ГДЕ Номенклатура.Родитель = NULL // Поиск элементов верхнего уровня
// или
ГДЕ НЕ Номенклатура.Родитель ЕСТЬ NULL // Элементы‚ у которых есть родитель От ссылки к Объекту: как получить полные данные
Запрос вернул ссылку. Как получить сам объект (реквизиты‚ табличные части) для записи или чтения?
В коде 1С (не в запросе):
// 1. Получаем ссылку из результата запроса
Выборка = Результат.Выбрать;
Пока Выборка.Следующий Цикл
СсылкаНаДок = Выборка.Ссылка; // Тип: ДокументСсылка.РеализацияТоваровУслуг
// 2; Получаем ОБЪЕКТ (для чтения реквизитов или записи)
ОбъектДок = СсылкаНаДок.ПолучитьОбъект;
// Теперь доступны все реквизиты и ТЧ
Сообщить(ОбъектДок;Номер);
ОбъектДок.Комментарий = "Обработано скриптом";
ОбъектДок.Записать;
КонецЦикла; Методы ссылки:
ПолучитьОбъект— загружает полный объект в память (для чтения/записи).ПолучитьОбъект(Истина)— загружает объект для интерактивного редактирования (открывает форму‚ блокирует запись).Наименование(свойство) — получает представление ссылки (строку) без загрузки полного объекта. Быстро.УникальныйИдентификатор— возвращает UUID (GUID) ссылки.
Производительность: Ссылка vs Объект в запросах
Никогда не пытайтесь «обойти» систему и получить объект в запросе. Запрос — это SQL. Он работает с наборами данных (таблицами).
- Хорошо: Запрос отбирает 10 000 ссылок за 0.1 сек. Далее в цикле по 10 штукам вызываете
ПолучитьОбъект(пакетная обработка). - Плохо: Пытаетесь в запросе собрать все реквизиты объекта в плоскую таблицу (огромный SELECT с 50 JOIN’ами)‚ чтобы «не вызывать ПолучитьОбъект». Это убьет производительность СУБД.
Золотое правило: Запрос, для отбора и агрегации (получить список ссылок/сумм). Код 1С — для бизнес-логики над конкретными объектами (ПолучитьОбъект).
Практический пример: Универсальная функция поиска ссылок
Функция НайтиСсылкиПоНаименованию(ИмяМетаданных‚ ЧастьНаименования‚ ДопУсловия = "") Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| " + ИмяМетаданных + " КАК Объект
|ГДЕ
| Объект.Наименование ПОДОБНО &Маска
| " + ?(ДопУсловия = ""‚ ""‚ "И " + ДопУсловия);
Запрос.УстановитьПараметр("Маска"‚ "%" + ЧастьНаименования + "%");
Возврат Запрос.Выполнить.ВыгрузитьКолонку("Ссылка"); // Возвращает Массив ссылок
КонецФункции
// Использование:
МассивСсылок = НайтиСсылкиПоНаименованию("Справочник.Номенклатура"‚ "Болт"‚ "Объект.ПометкаУдаления = ЛОЖЬ"); Резюме
- Ссылка в запросе — это значение системного поля
Ссылкаглавной таблицы метаданных или значение измерения/регистратора в регистрах. - Используйте параметры запроса (
&ИмяПараметра) для передачи ссылок из кода — это безопасно и быстро. - Для константных ссылок в тексте запроса применяйте
ЗНАЧЕНИЕ(Метаданные.Имя). - Запрос не возвращает Объект‚ только Ссылку. Преобразование происходит в коде через
Ссылка.ПолучитьОбъект. - Избегайте сравнения ссылок со строками/числами и выборки лишних полей «на всякий случай».
Понимание механики работы со ссылками в запросах позволяет писать эффективный‚ читаемый и надежный код на платформе 1С:Предприятие 8.