Если вы работаете с платформой 1С:Предприятие, то рано или поздно столкнётесь с загадочным термином REF. Он появляется в коде, конфигураторе, отчётах и даже в ошибках — но что он означает? Для новичков это часто становится источником путаницы, а опытные разработчики иногда используют его не совсем корректно.
На самом деле REF — это не просто аббревиатура, а фундаментальное понятие в архитектуре 1С, связанное с идентификацией объектов. Без понимания его механизмов сложно разобраться в ссылках на документы, справочники или регистры. В этой статье мы разберём REF с нуля: от базового определения до практических примеров и типичных ошибок. Вы узнаете, как он формируется, где хранится, и почему его нельзя путать с другими типами данных.
Особое внимание уделим разнице между REF и УникальнымИдентификатором (УИД) — это критично для интеграций и обмена данными между базами. Также рассмотрим, как работа с REF влияет на производительность запросов и почему некоторые операции с ним могут замедлять систему.
Что такое REF в 1С: определение и суть
REF (от англ. reference — "ссылка") — это внутренний механизм платформы 1С:Предприятие, который используется для однозначной идентификации объектов метаданных и их экземпляров. Проще говоря, это "адрес" элемента в базе данных, по которому система может его найти.
Каждый объект в 1С — будь то элемент справочника, документ или запись регистра — имеет свой REF. Он состоит из двух частей:
- Тип объекта (например,
Справочник.Номенклатура), - Уникальный идентификатор (внутренний номер записи в таблице базы данных).
Например, ссылка на товар в справочнике номенклатуры может выглядеть так:
Справочник.Номенклатура.Наименование=Молоко_3.2%_1л,
но её внутреннее представление в коде — это именно REF, а не строка.
Важно понимать, что REF — это не то же самое, что УникальныйИдентификатор (УИД). Последний генерируется системой как глобальный идентификатор (GUID) и не меняется при переносе данных между базами, тогда как REF привязан к конкретной базе и может отличаться в разных информационных системах.
Где и как используется REF в 1С
REF применяется практически во всех сценариях работы с объектами 1С. Вот ключевые области:
- 📄 Работа с документами: ссылки на документы (например,
Документ.ПоступлениеТоваров.Номер=ПТ-000001) хранятся как REF. - 📋 Справочники: элементы справочников (контрагенты, номенклатура, сотрудники) идентифицируются через REF.
- 🔄 Регистры: записи в регистрах накопления, бухгалтерии или сведений ссылаются на объекты через REF.
- 🔍 Запросы: в языке запросов 1С ссылки возвращаются как значения типа REF.
- 📊 Отчёты и обработки: при передаче параметров часто используются ссылки.
Пример из кода:
Товар = Справочники.Номенклатура.НайтиПоНаименованию("Молоко 3.2% 1л");
Если Товар.Ссылка.Тип() = Тип("СправочникСсылка.Номенклатура") Тогда
Сообщить("Ссылка на товар: " + Товар.Ссылка); // Здесь Товар.Ссылка - это REF
КонецЕсли;
В конфигураторе REF можно увидеть:
- В окне свойств объекта (вкладка
Ссылка), - При отладке в переменных (типы
СправочникСсылка,ДокументСсылкаи др.), - В результатах выполнения запросов.
Чтобы быстро получить REF объекта в отладчике, наведите курсор на переменную-ссылку и посмотрите её значение в подсказке.
REF vs УИД: в чём разница и когда что использовать
Многие путают REF и УникальныйИдентификатор (УИД), но это принципиально разные вещи. Разберём ключевые отличия:
| Характеристика | REF | УИД (УникальныйИдентификатор) |
|---|---|---|
| Назначение | Внутренняя ссылка на объект в конкретной базе | Глобальный идентификатор объекта, не зависящий от базы |
| Формат | Составной (тип объекта + внутренний ID) | GUID (32-значный шестнадцатеричный код) |
| Изменяемость | Может измениться при переносе данных | Не изменяется никогда |
| Применение | Работа внутри одной базы | Обмен данными между базами, интеграции |
Когда использовать что:
- 🔹 REF — для внутренних операций в одной базе (поиск, модификация, запросы).
- 🔹 УИД — для обмена данными между базами, резервного копирования, интеграций с внешними системами.
Пример ошибки: если вы сохраняете REF товара в внешней системе, а затем пытаетесь по нему найти товар в другой базе 1С, это не сработает — нужно использовать УИД.
Почему УИД надёжнее для обмена данными?
УИД генерируется один раз при создании объекта и остаётся неизменным даже при переносе между базами. В то время как REF зависит от внутренней структуры таблиц конкретной базы и может "сломаться" при выгрузке/загрузке данных.
Как получить REF объекта: практические примеры
Получить REF объекта в 1С можно несколькими способами. Рассмотрим самые распространённые:
1. Через метод Ссылка
Любой объект в 1С имеет свойство Ссылка, которое возвращает его REF:
Док = Документы.ПоступлениеТоваров.СоздатьДокумент();
Сообщить(Док.Ссылка); // Выведет REF нового документа
2. Через функции поиска
Функции вроде НайтиПоНаименованию() или НайтиПоРеквизиту() возвращают объекты, у которых можно взять ссылку:
Товар = Справочники.Номенклатура.НайтиПоНаименованию("Хлеб Бородинский");
Если Товар <> Неопределено Тогда
Сообщить(Товар.Ссылка);
КонецЕсли;
3. В языке запросов
В запросах ссылки возвращаются автоматически. Например:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товар.Ссылка КАК СсылкаНаТовар
|ИЗ
| Справочник.Номенклатура КАК Товар
|ГДЕ
| Товар.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", "Молоко");
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.СсылкаНаТовар); // REF товара
КонецЦикла;
4. Через прямой доступ к базе (для опытных)
В некоторых случаях (например, при отладке) можно получить REF через прямой SQL-запрос к таблицам 1С, но это не рекомендуется для производственного кода.
🔹 Убедитесь, что ссылка не равна Неопределено
🔹 Проверьте тип ссылки (СправочникСсылка, ДокументСсылка и др.)
🔹 Если нужно, преобразуйте в строку через .УникальныйИдентификатор()
🔹 Для запросов используйте параметры, а не конкатенацию строк-->
Типичные ошибки при работе с REF и как их избежать
Даже опытные разработчики иногда допускают ошибки при работе с REF. Вот самые распространённые:
⚠️ Внимание: Сравнение ссылок через = может давать неожиданные результаты, если объекты из разных баз. Всегда проверяйте контекст!
1. Сравнение ссылок из разных баз
Если вы сравниваете REF объекта из одной базы с REF такого же объекта из другой базы, они будут разными, даже если это один и тот же элемент. Решение: используйте УИД.
// Неверно:
Если СсылкаИзБазы1 = СсылкаИзБазы2 Тогда
// Это сработает только если ссылки из одной базы!
КонецЕсли;
// Правильно:
Если СсылкаИзБазы1.УникальныйИдентификатор() = СсылкаИзБазы2.УникальныйИдентификатор() Тогда
// Теперь сравнение корректно
КонецЕсли;
2. Хранение REF в внешних системах
Соохранять REF в файлах, других базах или API опасно — при восстановлении базы из резервной копии внутренние идентификаторы могут измениться. Используйте УникальныйИдентификатор().
3. Непроверенные ссылки в запросах
Если в запрос передаётся REF, убедитесь, что он не равен Неопределено, иначе получите ошибку:
Запрос.УстановитьПараметр("Ссылка", Неопределено); // Ошибка!
4. Путаница с типами ссылок
Не все ссылки одинаковы. Например, СправочникСсылка.Номенклатура и ДокументСсылка.ПоступлениеТоваров — разные типы. Проверяйте тип перед использованием:
Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Номенклатура") Тогда
// Работаем со справочником
ИначеЕсли ТипЗнч(Ссылка) = Тип("ДокументСсылка.ПоступлениеТоваров") Тогда
// Работаем с документом
КонецЕсли;
Всегда проверяйте ссылки на Неопределено и корректность типа перед использованием в коде. Это предотвратит majority ошибок выполнения.
REF в обмене данными и интеграциях
При обмене данными между базами 1С или интеграции с внешними системами REF может стать источником проблем. Вот что нужно учитывать:
1. Обмен между базами 1С
Если вы настраиваете обмен через Универсальный формат обмена или Конвертацию данных, убедитесь, что:
- 🔄 Для сопоставления объектов используется УИД, а не REF.
- 📌 В правилах обмена настроено корректное преобразование ссылок.
- 🔍 Перед обменом проверяется целостность ссылок (нет "битых" связей).
2. Интеграция с внешними системами
При передаче данных в API или файлы:
- 🚫 Не передавайте REF напрямую — внешняя система не сможет его интерпретировать.
- ✅ Используйте
УникальныйИдентификатор()или текстовые идентификаторы (коды, артикулы). - 🔄 Для обратной загрузки данных реализуйте механизм поиска объектов по УИД.
Пример корректной передачи данных в JSON:
ДанныеДляAPI = Новый Структура;
ДанныеДляAPI.Вставить("УИД", Товар.УникальныйИдентификатор());
ДанныеДляAPI.Вставить("Код", Товар.Код);
ДанныеДляAPI.Вставить("Наименование", Товар.Наименование);
// Не передаём REF!
3. Резервное копирование и восстановление
При восстановлении базы из резервной копии REF объектов могут измениться, если структура базы была модифицирована. Это может привести к:
- 🔴 "Битым" ссылкам в документах,
- 🔴 Ошибкам в отчётах,
- 🔴 Проблемам с целостностью данных.
⚠️ Внимание: После восстановления базы из резервной копии проверьте целостность ссылок с помощью обработки ТестированиеИИсправлениеИБ.epf (входит в стандартную поставку 1С).
Производительность и оптимизация работы с REF
Неправильная работа с REF может значительно замедлить выполнение кода, особенно в больших базах. Вот как оптимизировать операции:
1. Избегайте лишних преобразований
Каждое преобразование ссылки в строку (например, через Строка(Ссылка)) или обратное действие требует ресурсов. Если можно работать со ссылкой напрямую — делайте это.
2. Используйте запросы вместо циклов
Если вам нужно получить данные по множеству ссылок, лучше сделать один запрос, чем перебирать ссылки в цикле:
// Медленно (особенно для больших массивов):
Для Каждого Ссылка Из МассивСсылок Цикл
Объект = Ссылка.ПолучитьОбъект();
// Обработка объекта
КонецЦикла;
// Быстро:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Объект.Ссылка КАК Ссылка,
| Объект.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Объект
|ГДЕ
| Объект.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Результат = Запрос.Выполнить();
3. Кэшируйте часто используемые ссылки
Если в коде многократно используется одна и та же ссылка (например, ссылка на организацию), сохраните её в переменную, чтобы не искать повторно:
Организация = Справочники.Организации.НайтиПоНаименованию("ООО Ромашка");
Если Организация <> Неопределено Тогда
// Далее используем переменную Организация, а не ищем заново
КонецЕсли;
4. Остерегайтесь "тяжёлых" ссылок
Некоторые объекты (например, документы с большим количеством табличных частей) при получении через Ссылка.ПолучитьОбъект() могут подгружать много данных. Если нужны только отдельные реквизиты, берите их через точку:
ДатаДокумента = Документ.Ссылка.Дата; // Быстрее, чем получать весь объект
| Действие | Быстро | Медленно |
|---|---|---|
| Получение даты документа | Документ.Ссылка.Дата |
Документ.ПолучитьОбъект().Дата |
| Поиск по массиву ссылок | Запрос с ГДЕ Ссылка В(&Массив) |
Цикл с Объект = Ссылка.ПолучитьОбъект() |
| Сравнение ссылок | Ссылка1 = Ссылка2 |
Строка(Ссылка1) = Строка(Ссылка2) |
FAQ: Частые вопросы о REF в 1С
Можно ли преобразовать REF в строку и обратно?
Да, но с оговорками. Преобразование REF в строку возможно через Строка(Ссылка), но обратное преобразование (ЗначениеИзСтрокиВнутр()) сработает только в той же базе данных, где был получен REF. Для переноса между базами используйте УИД.
Почему после обновления 1С некоторые REF перестали работать?
Это может произойти, если:
- Изменилась структура метаданных (например, переименован справочник),
- Была выполнена реорганизация базы (например, сжатие таблиц),
- Обновление затрагивало системные таблицы ссылок.
Решение: проверьте целостность базы через Тестирование и исправление.
Как найти объект в базе, если известен только его REF из другой базы?
Невозможно напрямую. Вам нужно:
- Получить УИД объекта в исходной базе.
- В целевой базе выполнить запрос по УИД:
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ УникальныйИдентификатор = &УИД";
Можно ли создать REF вручную?
Технически да, но это крайне не рекомендуется. REF создаётся платформой автоматически при добавлении объекта. Ручное создание может привести к:
- Нарушению целостности данных,
- Ошибкам при записях в базу,
- Проблемам с блокировками.
Если нужно создать объект программно, используйте методы вроде Справочники.Номенклатура.СоздатьЭлемент().
Как узнать, какой объект скрывается за REF?
Есть несколько способов:
- В отладчике наведите курсор на переменную-ссылку — появится подсказка с типом.
- Используйте
ТипЗнч(Ссылка)для определения типа. - Для документов можно посмотреть
Ссылка.Вид().
Пример:
Сообщить(ТипЗнч(Ссылка)); // Выведет, например, "СправочникСсылка.Номенклатура"