Работа со справочниками — одна из ключевых задач при программировании в 1С:Предприятие. Без умения корректно обращаться к элементам справочников невозможно создать функциональные обработки, отчеты или автоматизировать бизнес-процессы. Эта статья охватывает все актуальные способы доступа к элементам: от базовых действий в пользовательском режиме до сложных программных конструкций на встроенном языке.
Мы разберем не только синтаксис, но и нюансы производительности, типичные ошибки новичков, а также малоизвестные приемы, которые экономят время опытным разработчикам. Особое внимание уделено различиям между управляемыми формами и обычным приложением, так как это принципиально меняет подход к работе со справочниками.
Если вы только начинаете осваивать 1С, начните с первых двух разделов — они помогут понять логику работы со справочниками без погружения в код. Разработчикам со стажем будут полезны разделы про программный доступ и оптимизацию запросов.
1. Ручной поиск элемента справочника через интерфейс 1С
Самый простой способ найти элемент справочника — использовать встроенные инструменты платформы. Этот метод не требует знания программирования и подходит для быстрых операций, когда нужно проверить данные или внести правки вручную.
Чтобы открыть справочник:
- 📂 Перейдите в главное меню программы и выберите раздел
Справочники(в зависимости от конфигурации название может отличаться, например,Номенклатура,Контрагенты,Сотрудники). - 🔍 В открывшемся окне справочника используйте поле
Поиск(обычно в верхней части формы) — введите название или часть названия элемента. - 📋 Для уточнения поиска нажмите на значок фильтра (🔧) и задайте дополнительные параметры: группа, пометка удаления, реквизиты.
- ⚡ Если справочник большой, используйте
Показать все(илиЕщё → Показать всё) для загрузки всех элементов без постраничной навигации.
Важно учитывать, что в управляемых формах (начиная с версии 8.2) интерфейс может отличаться: поиск часто реализован через поле ввода с подсказками (like-search), а фильтры вынесены в отдельную панель. В обычном приложении (8.1 и ранее) поиск работает по точному совпадению начала строки.
Если справочник не открывается через меню, проверьте права доступа вашего пользователя в Администрирование → Пользователи. Часто ограничения накладываются на уровне ролей.
Для ускорения работы с часто используемыми справочниками можно:
- 🔖 Добавить их в
Избранное(значок звездочки рядом с названием справочника). - 🔄 Настроить
Пользовательские настройкисписка (колонки, сортировка) через контекстное меню. - 📌 Использовать горячие клавиши:
Ctrl+Fдля поиска,F5для обновления списка.
2. Поиск по коду или наименованию: синтаксис и примеры
Когда ручного поиска недостаточно (например, при написании обработок или отчетов), приходится обращаться к элементам программно. Самые распространенные методы — поиск по коду или наименованию. Эти реквизиты есть у любого справочника и гарантированно уникальны в пределах одного справочника.
Базовый синтаксис для поиска по коду:
ЭлементСправочника = Справочники.ИмяСправочника.НайтиПоКоду(Код);
Если ЭлементСправочника.Пустая() Тогда
Сообщить("Элемент не найден!");
Иначе
Сообщить("Найден: " + ЭлементСправочника.Наименование);
КонецЕсли;
Аналогично работает поиск по наименованию:
ЭлементСправочника = Справочники.ИмяСправочника.НайтиПоНаименованию(Наименование);
Примеры реального использования:
| Задача | Код | Примечание |
|---|---|---|
| Поиск номенклатуры по артикулу (если артикул = код) | Номенклатура = Справочники.Номенклатура.НайтиПоКоду("ART-00123"); |
Артикул должен быть задан как код элемента |
| Поиск контрагента по полному наименованию | Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка"); |
Регистр важен! "ромашка" ≠ "Ромашка" |
| Проверка существования элемента перед созданием | Если НовыйЭлемент.Пустая() Тогда ... |
Избегает дублирования |
Обратите внимание на особенность метода НайтиПоНаименованию(): он ищет по точному совпадению строки, включая пробелы и регистр. Если нужно найти элемент по части наименования, используйте ПолучитьСписок() с фильтром или запрос.
3. Работа с элементами справочника через запросы
Запросы — самый мощный и гибкий инструмент для работы со справочниками, особенно когда нужно получить данные по сложным условиям или сразу несколько реквизитов. В отличие от прямых методов вроде НайтиПоКоду(), запросы позволяют:
- 🔗 Объединять данные из нескольких справочников.
- 📊 Фильтровать по любым реквизитам, включая пользовательские.
- 📈 Сортировать и группировать результаты.
- ⚡ Получать данные пакетно (одним запросом), что ускоряет работу с большими объемами.
Пример простого запроса для получения элемента справочника Номенклатура по части наименования:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Поиск
|УПОРЯДОЧИТЬ ПО
| Наименование";
Запрос.УстановитьПараметр("Поиск", "%телефон%"); // Ищем все с словом "телефон"
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Для работы с результатами запроса используйте цикл:
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование + " (" + Выборка.Ссылка + ")");
КонецЦикла;
Ключевые преимущества запросов:
- 🚀 Производительность: один запрос к базе вместо сотен вызовов
НайтиПоКоду(). - 🔍 Гибкость: можно использовать
ПОДОБНО,В(), подзапросы. - 📎 Агрегация: легко получить суммы, количество, средние значения по связанным данным.
Когда НЕ стоит использовать запросы?
Запросы не подходят для:
1. Единичных операций (например, поиска одного элемента по точному коду) — проще использовать прямые методы.
2. Изменения данных — запросы читают данные, но не модифицируют их (для изменений нужны объекты).
3. Работы с временными данными — если данные часто меняются, лучше использовать менеджер значения.
4. Программное создание и модификация элементов справочника
Часто требуется не только найти элемент, но и создать новый или изменить существующий. Для этого в 1С предусмотрены методы СоздатьЭлемент(), Записать() и УстановитьНовыйКод().
Пример создания нового элемента в справочнике Контрагенты:
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = "ООО Новый Партнер";
НовыйКонтрагент.ИНН = "1234567890";
НовыйКонтрагент.КПП = "123456789";
НовыйКонтрагент.ЮрЛицо = Перечисления.ТипыКонтрагентов.ЮридическоеЛицо;
НовыйКонтрагент.Записать();
Для изменения существующего элемента сначала найдите его (например, по коду), затем измените реквизиты и сохраните:
Контрагент = Справочники.Контрагенты.НайтиПоКоду("00001");
Если Не Контрагент.Пустая() Тогда
Контрагент.Телефон = "+7 (495) 123-45-67";
Контрагент.Записать();
КонецЕсли;
Важные нюансы:
- ⚠️ Проверка на пустую ссылку обязательна перед записью, иначе будет ошибка.
- 🔄 Транзакции: при пакетных изменениях оберните код в
НачатьТранзакцию()/ЗафиксироватьТранзакцию(). - 📛 Уникальность кода: если код задается вручную, проверьте его уникальность через
ПроверитьУникальностьКода().
🔹 Проверить, что элемент не пустой (метод Пустая())
🔹 Убедиться в уникальности кода (если задается вручную)
🔹 Заполнить обязательные реквизиты (помечены красным в конфигураторе)
🔹 Проверить права доступа (исключение при записи)
-->
Для работы с иерархическими справочниками (где элементы могут быть группами) используйте:
НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
НоваяГруппа.Наименование = "Электроника";
НоваяГруппа.Записать();
5. Ошибки при работе с элементами справочников и как их избежать
Даже опытные разработчики сталкиваются с ошибками при обращении к справочникам. Рассмотрим самые распространенные проблемы и способы их решения.
1. Ошибка "Объект не найден"
Возникает, когда вы пытаетесь обратиться к несуществующему элементу. Всегда проверяйте результат методов НайтиПоКоду() или ПолучитьПоНаименованию():
Элемент = Справочники.Товары.НайтиПоКоду("999");
Если Элемент.Пустая() Тогда
// Обработка отсутствия элемента
КонецЕсли;
2. Нарушение прав доступа
Если при записи элемента возникает ошибка прав, проверьте:
- 🔐 Права текущего пользователя в
Администрирование → Пользователи. - 📜 Права на уровне ролей (может быть запрет на изменение конкретного справочника).
- 🔧 Настройки RLS (ограничение доступа к данным) в конфигураторе.
3. Зависание при работе с большими справочниками
Если справочник содержит десятки тысяч элементов, прямые методы вроде ПолучитьСписок() могут тормозить. Решения:
- 🔄 Используйте
Выбрать()с ограничением количества строк (ПЕРВЫЕ 100в запросе). - 📊 Применяйте индексы для часто используемых реквизитов (настраивается в конфигураторе).
- ⚡ Для фонаовых операций используйте
ФоновоеЗадание.
Всегда проверяйте результат методов поиска на пустоту — это предотвращает 90% ошибок при работе со справочниками.
4. Проблемы с транзакциями
Если вы изменяете несколько элементов подряд, не забывайте про транзакции:
НачатьТранзакцию();
Попытка
// Код изменения элементов
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;
5. Несоответствие типов данных
При присвоении значений реквизитам следите за типами. Например, нельзя присвоить строку в реквизит типа Число:
Элемент.Цена = "100"; // Ошибка! Нужно: Элемент.Цена = 100;
6. Оптимизация работы со справочниками: советы для крупных баз
В больших базах данных (100 000+ элементов в справочнике) неоптимизированный код может приводить к зависаниям. Вот ключевые приемы для ускорения работы:
1. Используйте запросы вместо прямых методов
Запрос к базе за одну операцию может вернуть сотни строк, тогда как НайтиПоКоду() в цикле выполнит сотни отдельных обращений.
2. Кэшируйте часто используемые элементы
Если один и тот же элемент справочника используется многократно, сохраните его в переменную:
Перем мКонтрагент;
Если мКонтрагент = Неопределено Тогда
мКонтрагент = Справочники.Контрагенты.НайтиПоКоду("00001");
КонецЕсли;
3. Ограничивайте выборки
В запросах всегда используйте ПЕРВЫЕ N или условия ГДЕ, чтобы не грузить лишние данные:
"ВЫБРАТЬ ПЕРВЫЕ 100 Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура"
4. Используйте менеджеры значений
Для временного хранения данных (например, при обработке документов) используйте МенеджерЗначения вместо обращений к базе:
Менеджер = Новый МенеджерЗначения;
Менеджер.Вставить("Контрагент1", Справочники.Контрагенты.НайтиПоКоду("00001"));
5. Настраивайте индексы
В конфигураторе для часто используемых реквизитов справочников настройте индексы. Это ускорит поиск по этим полям. Например, если вы часто ищете номенклатуру по артикулу, добавьте индекс для реквизита Артикул.
| Проблема | Решение | Эффект |
|---|---|---|
| Медленный поиск по наименованию | Добавить индекс на реквизит Наименование |
Ускорение в 5-10 раз |
| Зависание при загрузке большого справочника | Использовать ПЕРВЫЕ 100 в запросе |
Мгновенный отклик |
| Частые обращения к одному элементу | Кэшировать элемент в переменной | Снижение нагрузки на базу |
Для справочников с более чем 50 000 элементов рассмотрите возможность разделения на подчиненные справочники или архивирования старых данных.
7. Особенности работы с справочниками в управляемых формах
С появлением управляемых форм (начиная с версии 8.2) логика работы со справочниками изменилась. Теперь элементы часто привязываются к формам через реквизиты, а доступ к ним осуществляется через контекст формы.
1. Получение текущего элемента справочника на форме
Если форма открыта для редактирования элемента справочника, получить его можно так:
ТекущийЭлемент = ЭлементыФормы.Объект;
2. Работа с динамическими списками
В управляемых формах справочники часто отображаются как динамические списки. Для доступа к выбранному элементу:
ВыбранныйЭлемент = ЭлементыФормы.СписокСправочника.ТекущиеДанные;
3. Открытие формы элемента программно
Чтобы открыть форму для редактирования элемента:
ПараметрыФормы = Новый Структура("Ключ", ЭлементСправочника.Ссылка);
ОткрытьФорму("Справочник.Контрагенты.ФормаЭлемента", ПараметрыФормы);
4. Обработка событий формы
В управляемых формах часто используются события ПриИзменении или ПередЗаписью для валидации данных:
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
Если Элемент.ИНН = "" Тогда
Сообщить("ИНН обязателен для заполнения!");
КонецЕсли;
КонецПроцедуры
Ключевые отличия управляемых форм от обычного приложения:
- 🎭 Трехуровневая архитектура: клиент → сервер → база данных.
- 🔄 Асинхронность: многие операции выполняются на сервере.
- 📱 Кросс-платформенность: формы адаптируются под веб и мобильные устройства.
В управляемых формах избегайте прямых обращений к базе на клиенте — используйте серверные процедуры.
8. Продвинутые приемы: работа с ссылками и коллекциями
Для опытных разработчиков полезно знать продвинутые методы работы со справочниками, которые экономят время и упрощают код.
1. Работа со ссылками
Ссылка на элемент справочника — это его уникальный идентификатор. Ссылки можно сравнивать, сохранять и передавать между формами:
СсылкаНаЭлемент = Справочники.Номенклатура.НайтиПоКоду("001").Ссылка;
Если СсылкаНаЭлемент.Сравнить(ДругаяСсылка) = 0 Тогда
// Ссылки совпадают
КонецЕсли;
2. Массовая обработка элементов
Для пакетного изменения элементов используйте Выбрать() или запросы с последующим циклом:
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Цена < 100 Тогда
Выборка.Цена = 100;
Выборка.Записать();
КонецЕсли;
КонецЦикла;
3. Использование коллекций
Для хранения наборов ссылок удобно использовать коллекции Массив, СписокЗначений или Соответствие:
СписокТоваров = Новый СписокЗначений;
СписокТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("001").Ссылка);
СписокТоваров.Добавить(Справочники.Номенклатура.НайтиПоКоду("002").Ссылка);
4. Работа с предопределенными элементами
Некоторые элементы справочников могут быть предопределенными (задаются в конфигураторе). Доступ к ним осуществляется через свойство Предопределенный:
ПредопределенныйЭлемент = Справочники.ВидыНоменклатуры.Предопределенный("Услуга");
5. Использование XDTO для обмена данными
При интеграции с внешними системами удобно использовать XDTO для сериализации элементов справочников:
ЗаписьXML = Новый ЗаписьXML;
ФабрикаXDTO = Новый ФабрикаXDTO;
ОбъектXDTO = ФабрикаXDTO.SправочникОбъект(ЭлементСправочника);
ЗаписатьXDTO(ЗаписьXML, ОбъектXDTO);
Как ускорить выборку из большого справочника?
1. Используйте отбор в запросе — например, ГДЕ Номенклатура.Группа = &Группа.
2. Применяйте виртуальные таблицы — они оптимизированы для чтения.
3. Настройте кэширование на уровне СУБД (например, в PostgreSQL).
4. Разбивайте справочники на логические части (например, по годам или регионам).
Эти приемы особенно полезны при разработке сложных отчетов, обработок для обмена данными или интеграции с другими системами.
FAQ: Частые вопросы по работе со справочниками 1С
🔹 Как найти элемент справочника, если не знаю ни кода, ни наименования?
Используйте метод ПолучитьСписок() с фильтром по известным реквизитам:
Список = Справочники.Контрагенты.ПолучитьСписок();
Фильтр = Новый Структура("ИНН", "1234567890");
Список.Фильтровать(Фильтр);
Или составьте запрос с условием по нужному реквизиту.
🔹 Почему метод НайтиПоНаименованию() не находит элемент, который точно есть в базе?
Скорее всего, проблема в регистре или пробелах. Метод чувствителен к точному совпадению. Попробуйте:
- Привести наименование к верхнему регистру:
НайтиПоНаименованию(Строка(Наименование).ВРегистр()). - Удалить лишние пробелы:
СтрЗаменить(Наименование, " ", " "). - Использовать запрос с
ПОДОБНОдля нечеткого поиска.
🔹 Можно ли получить элемент справочника по его УИД (GUID)?
Да, для этого используйте метод ПолучитьСсылку() с указанием УИД:
УИД = Новый УникальныйИдентификатор("123e4567-e89b-12d3-a456-426614174000");
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);
УИД элемента можно узнать через свойство УникальныйИдентификатор().
🔹 Как проверить, существует ли элемент справочника, не вызывая ошибку?
Используйте конструкцию с проверкой на Пустая():
Элемент = Справочники.Товары.НайтиПоКоду("999");
Если Элемент.Пустая() Тогда
Сообщить("Элемент не существует");
Иначе
Сообщить("Элемент найден");
КонецЕсли;
Или используйте запрос с проверкой ВЫБРАТЬ РАЗРЕШЕННЫЕ.
🔹 Как скопировать элемент справочника с сохранением всех реквизитов?
Создайте новый элемент и перенесите данные в цикле:
ИсходныйЭлемент = Справочники.Номенклатура.НайтиПоКоду("001");
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = ИсходныйЭлемент.Наименование + " (копия)";
// Копирование всех реквизитов
Для Каждого Реквизит Из ИсходныйЭлемент.Метаданные().Реквизиты Цикл
Если НовыйЭлемент.Метаданные().Реквизиты.Найти(Реквизит.Имя) <> Неопределено Тогда
НовыйЭлемент[Реквизит.Имя] = ИсходныйЭлемент[Реквизит.Имя];
КонецЕсли;
КонецЦикла;
НовыйЭлемент.Записать();