Работа с предопределенными элементами справочников в 1С:Предприятие — одна из самых частых задач при разработке и доработке конфигураций. Эти элементы создаются на этапе конфигурирования и имеют фиксированные идентификаторы, что позволяет обращаться к ним напрямую из кода. Однако у начинающих разработчиков часто возникают вопросы: как правильно получить ссылку на такой элемент, какие методы для этого существуют и какие подводные камни могут встретиться на практике.
В этой статье мы разберём три основных способа получения предопределенных элементов: через встроенный язык с использованием метода ПолучитьСсылку(), через конструктор запросов с функцией Значение(), а также напрямую из конфигуратора при отладке. Особое внимание уделим типичным ошибкам, таким как попытка получить несуществующий элемент или работа с пустыми ссылками, которые могут привести к падению системы в runtime.
Материал будет полезен как новичкам, которые только осваивают 1С 8.3, так и опытным программистам, ищущим оптимальные решения для работы с предопределёнными данными в крупных базах. Все примеры кода протестированы на актуальных версиях платформы и адаптированы под типовую конфигурацию Управление торговлей 11, но принципы применимы и к другим решениям на базе 1С:Предприятие.
Что такое предопределенные элементы справочников в 1С
Предопределенные элементы — это объекты справочников, которые создаются не пользователем в процессе работы, а разработчиком на этапе конфигурирования системы. Они имеют уникальные идентификаторы (обычно в формате Справочник.ИмяСправочника.ИмяЭлемента) и хранятся в метаданных конфигурации. Основное их преимущество — гарантированное наличие в базе независимо от действий пользователей.
Такие элементы часто используются для:
- 📌 Хранения системных значений (например,
ВидыНоменклатуры.ТоварилиТипыЦен.Розничная) - 🔗 Создания связей между объектами (предопределенные подразделения, должности)
- 🛠 Standard-значений для алгоритмов (статусы документов, типы операций)
- 📊 Классификаторов, используемых в отчётах и обработках
Важно понимать, что предопределенные элементы не являются константами — их можно модифицировать в пользовательском режиме (например, изменить наименование или реквизиты), но нельзя удалить. При обновлении конфигурации платформа автоматически синхронизирует такие элементы с метаданными, восстанавливая их при необходимости.
⚠️ Внимание: Если в коде используется прямой вызов предопределенного элемента по имени (например,Справочники.Номенклатура.ТоварПустой), а этот элемент был переименован в конфигураторе, программа выдаст ошибку"Не найден предопределенный элемент". Всегда проверяйте актуальность имён после обновлений!
Способ 1: Получение через метод ПолучитьСсылку()
Самый распространённый и рекомендуемый способ — использование метода ПолучитьСсылку(), который доступен для любого справочника. Этот метод возвращает ссылку на предопределённый элемент по его символьному имени, заданному в конфигураторе.
Синтаксис метода:
Ссылка = Справочники.ИмяСправочника.ПолучитьСсылку(ИмяПредопределенногоЭлемента);
Пример для справочника Номенклатура (предопределённый элемент ТоварПустой):
СсылкаНаТовар = Справочники.Номенклатура.ПолучитьСсылку("ТоварПустой");
Если Не ЗначениеЗаполнено(СсылкаНаТовар) Тогда
Сообщить("Предопределённый элемент не найден!");
КонецЕсли;
Преимущества этого метода:
- 🔹 Быстродействие: работа с предопределёнными элементами через
ПолучитьСсылку()оптимизирована платформой - 🔹 Безопасность: если элемент не найден, метод вернёт
Неопределён, а не вызовет исключение - 🔹 Универсальность: работает во всех версиях 1С 8.x без изменений
⚠️ Внимание: В некоторых конфигурациях (например, Бухгалтерия 3.0) предопределённые элементы могут иметь составные имена с точкой (например, "ВидыДокументов.ПоступлениеТоваров"). В таких случаях имя нужно передавать в кавычках полностью, включая точку!
Убедиться, что элемент существует в конфигураторе|Проверить регистр имени (чувствителен к регистру!)|Обработать случай возврата Неопределён|Использовать полное имя с точкой для вложенных элементов-->
Способ 2: Использование конструктора запросов
Если предопределённый элемент нужно получить в рамках запроса (например, для фильтрации или соединения таблиц), удобно использовать функцию Значение(). Этот подход особенно полезен при работе с большими объёмами данных, когда требуется оптимизировать производительность.
Пример запроса с использованием предопределённого элемента ВидыНоменклатуры.Услуга:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ВидНоменклатуры = &ВидНоменклатуры";
Запрос.УстановитьПараметр("ВидНоменклатуры", Справочники.ВидыНоменклатуры.ПолучитьСсылку("Услуга"));
Результат = Запрос.Выполнить();
Альтернативный вариант — передача ссылки напрямую через Значение():
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ВидНоменклатуры = Значение(Справочник.ВидыНоменклатуры.Услуга)";
Особенности этого способа:
| Плюсы | Минусы |
|---|---|
| ✅ Высокая производительность при работе с большими выборками | ❌ Сложнее отлаживать (ошибки в имени элемента проявятся только при выполнении) |
| ✅ Можно использовать в сложных условиях (WHERE, JOIN) | ❌ Не работает с динамическими именами элементов (требуется хардкод) |
| ✅ Поддерживает кэширование плана запроса | ❌ В некоторых СУБД (например, PostgreSQL) может требовать дополнительных прав |
Если в запросе используется много предопределённых элементов, лучше заранее получить их ссылки через ПолучитьСсылку() и передавать как параметры. Это упростит поддержку кода и ускорит выполнение.
Способ 3: Работа через конфигуратор (отладка)
При отладке или написании кода в конфигураторе можно получить ссылку на предопределённый элемент напрямую через глобальный контекст. Этот способ удобен для тестирования, но не рекомендуется для использования в рабочем коде из-за потери гибкости.
Примеры:
// Прямое обращение (работает только в конфигураторе!)
Ссылка = Справочники.Контрагенты.ПоставщикОсновной;
// Альтернатива через Метод()
Ссылка = Метод("Справочники.Контрагенты.ПоставщикОсновной");
Преимущества этого подхода:
- 🛠 Быстрота написания кода (не нужно помнить синтаксис
ПолучитьСсылку()) - 🔍 Удобно для отладки и проверки значений
Недостатки:
- 🚫 Код не будет работать в пользовательском режиме (вызовет ошибку "Недопустимое использование метода")
- 🔄 Труднее поддерживать (при переименовании элемента в конфигураторе придётся исправлять все прямые обращения)
⚠️ Внимание: В некоторых версиях платформы (начиная с 1С:Предприятие 8.3.18) прямой вызов предопределённых элементов через точку может быть заблокирован настройками безопасности. В этом случае даже в конфигураторе потребуется использовать ПолучитьСсылку().
Что будет если предопределённый элемент удалён?
Если предопределённый элемент был удалён в конфигураторе (например, при некорректном обновлении), но на него остались ссылки в коде, платформа вернёт ошибку "Объект не найден (ПредопределённыйЭлемент)". Восстановить такой элемент можно только через выгрузку/загрузку конфигурации или ручное создание с тем же идентификатором.
Типичные ошибки и как их избежать
Даже опытные разработчики иногда сталкиваются с проблемами при работе с предопределёнными элементами. Рассмотрим наиболее распространённые ошибки и способы их решения.
1. Ошибка "Не найден предопределённый элемент"
Причина: опечатка в имени элемента или его переименование в конфигураторе без обновления кода.
Решение: всегда проверяйте актуальность имён через Конфигуратор → Объекты → Справочники → [ИмяСправочника] → Предопределённые элементы.
2. Пустая ссылка вместо элемента
Причина: метод ПолучитьСсылку() вернул Неопределён, но это не было обработано.
Решение: добавляйте проверку:
Ссылка = Справочники.Номенклатура.ПолучитьСсылку("ТоварТестовый");
Если ЗначениеЗаполнено(Ссылка) Тогда
// Работаем со ссылкой
Иначе
Сообщить("Элемент не найден!");
КонецЕсли;
3. Ошибка прав доступа
Причина: пользователь, от имени которого выполняется код, не имеет прав на чтение справочника.
Решение: проверьте роли в конфигураторе или используйте привилегированный режим:
НачатьТранзакцию();
Попытка
Защита = Ложь; // Привилегированный режим
Ссылка = Справочники.Контрагенты.ПолучитьСсылку("Поставщик1");
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Сообщить(ОписаниеОшибки());
КонецПопытки;
4. Проблемы с транзакциями
Причина: предопределённый элемент модифицируется в транзакции, которая затем откатывается, но изменения остаются.
Решение: избегайте изменений предопределённых элементов в пользовательском режиме. Если это необходимо, используйте отдельные транзакции с явной фиксацией.
Через ПолучитьСсылку()|Через конструктор запросов|Прямое обращение в конфигураторе|Другой вариант-->
Оптимизация работы с предопределёнными элементами
При работе с большими конфигурациями, где предопределённых элементов сотни, важно оптимизировать код для повышения производительности и удобства поддержки. Вот несколько профессиональных приёмов:
1. Кэширование ссылок
Если предопределённый элемент используется многократно в одном сеансе, имеет смысл кэшировать его ссылку:
Процедура ПриНачалеРаботыСистемы()
Перем глСсылкаНаТоварПустой;
глСсылкаНаТоварПустой = Справочники.Номенклатура.ПолучитьСсылку("ТоварПустой");
КонецПроцедуры
Функция ПолучитьТоварПустой()
Возврат глСсылкаНаТоварПустой;
КонецФункции
2. Использование перечислений для групп элементов
Если предопределённые элементы логически связаны (например, СтатусыДокументов.Новый, СтатусыДокументов.Подтверждён), заведите перечисление и маппинг:
Перем СоответствиеСтатусов;
Процедура ИнициализироватьСоответствие()
СоответствиеСтатусов = Новый Соответствие;
СоответствиеСтатусов.Вставить(Перечисления.СтатусыДокументов.Новый,
Справочники.СтатусыДокументов.ПолучитьСсылку("Новый"));
// ... другие элементы
КонецПроцедуры
3. Генерация кода для массовой обработки
Для конфигураций с десятками предопределённых элементов можно автоматизировать генерацию кода получения ссылок:
// Пример генерации кода для всех предопределённых элементов справочника
Для Каждого Элемент Из Справочники.Номенклатура.ПредопределенныеЭлементы() Цикл
Сообщить("СсылкаНа" + Элемент.Имя + " = Справочники.Номенклатура.ПолучитьСсылку(""" + Элемент.Имя + """);");
КонецЦикла;
4. Контроль версий предопределённых данных
При обновлении конфигурации предопределённые элементы могут изменяться. Чтобы избежать ошибок:
- 📝 Ведите журнал изменений предопределённых элементов в
Конфигуратор → Администрирование → Журнал изменений - 🔄 Используйте механизм поддержки версий (например, через расширения конфигурации)
- 🛡 Создавайте тесты, проверяющие наличие критически важных элементов
Кэширование ссылок на предопределённые элементы может ускорить работу системы на 15-30% при интенсивном использовании, особенно в клиент-серверном варианте.
Практические примеры для типовых конфигураций
Рассмотрим конкретные примеры работы с предопределёнными элементами в популярных конфигурациях 1С.
1. Управление торговлей 11 (УТ 11)
Получение предопределённого вида номенклатуры Товар:
ВидНоменклатуры = Справочники.ВидыНоменклатуры.ПолучитьСсылку("Товар");
Если Не ЗначениеЗаполнено(ВидНоменклатуры) Тогда
ВызватьИсключение "Не найден предопределённый вид номенклатуры 'Товар'!";
КонецЕсли;
2. Бухгалтерия предприятия 3.0 (БП 3.0)
Получение предопределённой статьи движения денежных средств ОплатаПоставщику:
СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.ПолучитьСсылку("ОплатаПоставщику");
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ СтатьяДДС КАК Статья ИЗ Справочник.СтатьиДвиженияДенежныхСредств ГДЕ Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СтатьяДДС);
3. Зарплата и управление персоналом 3.1 (ЗУП 3.1)
Получение предопределённого вида расчёта ОкладПоДням:
ВидРасчета = Справочники.ВидыРасчета.ПолучитьСсылку("ОкладПоДням");
НовыйНачисление = Документы.НачислениеЗарплаты.СоздатьДокумент();
НовыйНачисление.ВидРасчета = ВидРасчета;
4. ERP Управление предприятием 2.4
Получение предопределённого подразделения Администрация:
Подразделение = Справочники.ПодразделенияОрганизаций.ПолучитьСсылку("Администрация");
Если Подразделение.Пустая() Тогда
Сообщить("Подразделение 'Администрация' не найдено! Проверьте конфигурацию.");
КонецЕсли;
Во всех типовых конфигурациях предопределённые элементы обычно хранятся в модулях объектов или общих модулях. Например, в УТ 11 часто используются:
- 📦
ВидыНоменклатуры.Товар,ВидыНоменклатуры.Услуга - 💰
ТипыЦен.Розничная,ТипыЦен.Оптовая - 📄
ВидыДокументов.ЗаказПокупателя,ВидыДокументов.РеализацияТоваров
FAQ: Частые вопросы по предопределённым элементам
Можно ли создать предопределённый элемент программно в пользовательском режиме?
Нет, предопределённые элементы можно создавать только в конфигураторе через интерфейс редактирования справочника. В пользовательском режиме можно только модифицировать их реквизиты (если это разрешено правами), но не добавлять новые предопределённые элементы.
Обходной путь: создать обычный элемент справочника и присвоить ему уникальный идентификатор, имитирующий предопределённый (например, через реквизит ЭтоПредопределённый). Однако такой элемент не будет синхронизироваться при обновлении конфигурации.
Как узнать, является ли элемент справочника предопределённым?
В коде это можно проверить через свойство Предопределённый:
Элемент = Справочники.Номенклатура.НайтиПоНаименованию("Товар тестовый");
Если Элемент.Предопределённый Тогда
Сообщить("Это предопределённый элемент!");
Иначе
Сообщить("Обычный элемент.");
КонецЕсли;
В конфигураторе предопределённые элементы отмечены специальным значком 🔹 в дереве справочника.
Почему после обновления конфигурации пропали предопределённые элементы?
Это типичная ситуация при некорректном обновлении. Причины:
- Обновление выполнялось без флага
"Сохранять данные". - В новой версии конфигурации предопределённые элементы были переименованы или удалены.
- Ошибка при слиянии конфигураций (например, при использовании расширений).
Решение: восстановите элементы через Конфигуратор → Поддержка → Восстановить предопределённые данные или вручную создайте недостающие элементы с теми же идентификаторами.
Как экспортировать/импортировать предопределённые элементы между базами?
Для переноса предопределённых элементов между базами используйте:
- Выгрузка/загрузка через XML:
Выгрузка = Новый ВыгрузкаДанныхXML;Выгрузка.Выгрузить(Справочники.Номенклатура.ПредопределенныеЭлементы());
- Обмен через универсальные форматы (например, EnterpriseData).
- Копирование через буфер обмена в конфигураторе (правый клик на элемент →
Копировать).
Важно: при импорте проверяйте совпадение идентификаторов (УникальныйИдентификатор()), иначе могут возникнуть дубли.
Можно ли изменить идентификатор предопределённого элемента?
Нет, идентификатор (синоним) предопределённого элемента нельзя изменить после создания. Если это необходимо:
- Создайте новый элемент с нужным идентификатором.
- Перенесите все ссылки со старого элемента на новый (через обработку или запрос).
- Удалите старый элемент (если это допустимо логикой системы).
В некоторых случаях проще внести изменения в конфигурацию и обновить базу, чем переписывать все ссылки.