Разработка конфигураций в платформе 1С:Предприятие часто требует хранения справочных данных, которые меняются редко и не зависят от конкретных дат или моментов времени. Для этих целей идеально подходят непериодические регистры сведений. В отличие от периодических аналогов, они не имеют измерений времени, что упрощает работу с ними, но накладывает свои ограничения на логику выборки данных.

Программистам необходимо четко понимать разницу между ключом записи и просто набором полей. Ошибка в определении уникальности записи может привести к дублированию данных или невозможности найти нужную информацию программным способом. Далее мы подробно разберем методы получения записей через объекты метаданных и язык запросов.

Основная сложность для начинающих разработчиков заключается в том, что структура запроса к непериодическому регистру выглядит иначе, чем к табличной части документа или обычному справочнику. Неправильное использование срезов или условий отбора может привести к ошибкам выполнения или получению пустого набора данных.

Архитектура и особенности непериодических регистров

Непериодический регистр сведений предназначен для хранения информации, актуальной «здесь и сейчас». Ключевой особенностью является отсутствие псевдоизмерения Период. Это означает, что в таблице базы данных физически отсутствует колонка, отвечающая за время действия записи.

Уникальность записи в таком регистре определяется исключительно комбинацией измерений. Если вы попытаетесь записать вторую запись с теми же значениями измерений, платформа выдаст ошибку или перезапишет данные, в зависимости от режима записи. Это фундаментальное отличие от периодических регистров, где одна и та же сущность может существовать в разные моменты времени.

При проектировании структуры важно правильно выбрать типы данных для измерений. Использование слишком объемных строк или составных типов может негативно сказаться на производительности выборки. Всегда стремитесь к минимизации ключа записи.

⚠️ Внимание: Непериодические регистры не поддерживают ведение истории изменений «из коробки». Если вам нужно хранить архив состояний, используйте периодический регистр с режимом периодичности «Непериодический» (в старых версиях) или просто включайте измерение даты в ключ.

💡

Используйте индексацию по всем измерениям для ускорения поиска записей по полному ключу. Это критично для регистров с большим объемом данных.

Получение данных через объект менеджера регистра

Самый простой способ получить конкретную запись — использовать объект менеджера регистра сведений. Этот подход удобен, когда вам известны все значения измерений, составляющих ключ записи. Метод Получить() возвращает объект записи или неопределенность.

Для работы с объектом записи необходимо сначала создать его через менеджер. Синтаксис вызова строго типизирован: вы должны передать значения измерений в том порядке, в котором они объявлены в конфигураторе, либо использовать именованные параметры.

КлючЗаписи = РегистрыСведений.КурсВалют.СоздатьКлючЗаписи();

КлючЗаписи.Валюта = Справочники.Валюты.НайтиПоНаименованию("Доллар США");

Запись = РегистрыСведений.КурсВалют.Получить(КлючЗаписи);

Если Запись = Неопределено Тогда

Сообщить("Запись не найдена");

Иначе

Сообщить("Текущий курс: " + Запись.Курс);

КонецЕсли;

Обратите внимание, что метод Получить() работает только с полным ключом. Если вы попытаетесь получить запись, не заполнив все обязательные измерения, система не сможет идентифицировать строку в таблице базы данных. Это ограничение следует учитывать при написании алгоритмов поиска.

☑️ Проверка перед получением записи

Выполнено: 0 / 4

Выборка данных с помощью языка запросов

Когда требуется получить не одну конкретную запись, а набор данных по условию (например, все курсы валют или список настроек для определенного пользователя), язык запросов 1С становится незаменимым инструментом. Синтаксис запроса к непериодическому регистру предельно прост.

В отличие от периодических регистров, здесь не нужно использовать срезы последних или первых записей. Вы обращаетесь к виртуальной таблице регистра напрямую. Это упрощает код и делает его более читаемым для других разработчиков.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РегистрСведений.НастройкиПользователей.Пользователь,

| РегистрСведений.НастройкиПользователей.ИспользоватьПодсказки,

| РегистрСведений.НастройкиПользователей.ЦветТемы

|ИЗ

| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей

|ГДЕ

| НастройкиПользователей.Пользователь = &Пользователь";

Запрос.УстановитьПараметр("Пользователь", ТекущийПользователь());

Результат = Запрос.Выполнить();

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

// Обработка полученной записи

КонецЦикла;

Использование параметризированных запросов, как показано в примере выше, является лучшей практикой. Это защищает базу данных от SQL-инъекций (хотя в 1С риск минимален) и позволяет переиспользовать текст запроса при изменении входных данных.

📊 Какой способ выборки вы используете чаще?
Объект менеджера (Получить)
Язык запросов
Консоль запросов
Произвольный запрос через СКД

Особенности работы с ресурсами и реквизитами

При получении записи важно различать измерения и ресурсы. Измерения формируют ключ, по которому происходит поиск, а ресурсы содержат полезные данные, которые мы хотим извлечь. В запросе можно выбирать как те, так и другие поля.

Если в регистре определены дополнительные реквизиты (не являющиеся ресурсами или измерениями), они также доступны для выборки. Однако стоит помнить, что реквизиты хранятся в отдельной таблице расширений, что может потребовать дополнительного соединения (JOIN) при сложных запросах, хотя платформа 1С часто оптимизирует это автоматически.

Тип поля Назначение Участие в ключе Пример
Измерение Идентификация записи Да Контрагент, Организация
Ресурс Хранение значения Нет СтавкаНДС, Комментарий
Реквизит Доп. информация Нет Ответственный, ДатаИзменения

При записи данных в регистр через объект записи, значения ресурсов обновляются, если запись уже существует. Если же вы используете запрос на вставку, необходимо контролировать уникальность ключа вручную, чтобы избежать конфликтов.

⚠️ Внимание: При выборке больших объемов данных из непериодического регистра убедитесь, что в условии ГДЕ задействованы индексные поля (измерения). Полный перебор таблицы (Table Scan) может заблокировать работу базы в многопользовательском режиме.

Обработка отсутствия записей и создание новых

Частая задача в программировании 1С — получить запись, а если её нет, то создать. Паттерн «Get or Create» реализуется достаточно просто. Сначала мы пытаемся получить объект через менеджер. Если возвращается Неопределено, создаем новую запись.

Важно использовать транзакционность при таких операциях, если есть риск параллельного доступа нескольких пользователей к одному и тому же ключу записи. Блокировка данных предотвратит ситуацию, когда два пользователя одновременно создадут дублирующиеся записи.

Транзакция = НачатьТранзакцию();

Попытка

Запись = Регистр.Получить(Ключ);

Если Запись = Неопределено Тогда

Запись = Регистр.СоздатьЗапись();

Запись.Заполнить(Ключ);

Запись.Значение = 100;

Запись.Записать();

КонецЕсли;

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение;

КонецПопытки;

Использование блока Попытка...Исключение в сочетании с транзакцией гарантирует целостность данных. В высоконагруженных системах также рекомендуется использовать механизмы блокировок на уровне регистра.

Оптимизация блокировок

Для снижения конкуренции за блокировки можно использовать режим управляемых блокировок, явно указывая объекты блокировки в запросе.

Удаление и очистка регистров сведений

Удаление записей из непериодического регистра выполняется методом Удалить() у объекта записи или через запрос на удаление. При удалении через объект необходимо сначала получить эту запись, так как метод вызывается у экземпляра.

Массовое удаление лучше выполнять запросом. Это значительно быстрее, чем перебор в цикле. Синтаксис запроса на удаление аналогичен запросу на выборку, но вместо таблицы результатов формируется команда модификации данных.

Запрос = Новый Запрос;

Запрос.Текст =

"УДАЛИТЬ

| РегистрСведений.ВременныеДанные.Запись

|ИЗ

| РегистрСведений.ВременныеДанные КАК ВременныеДанные

|ГДЕ

| ВременныеДанные.ДатаСоздания < &Граница";

Запрос.УстановитьПараметр("Граница", ТекущаяДата() - 30);

Запрос.Выполнить();

При удалении записей следует помнить о ссылочной целостности, если она настроена. Хотя регистры сведений обычно не имеют жестких связей как документы, логическая связь с удаляемыми справочниками должна обрабатываться в коде приложения.

💡

Массовое удаление через запрос выполняется на стороне СУБД и работает в сотни раз быстрее цикла перебора объектов 1С.

Часто задаваемые вопросы (FAQ)

В чем главная разница между периодическим и непериодическим регистром при выборке?

Главное отличие — наличие измерения «Период». В непериодическом регистре запись уникальна по измерениям, и в запросе не нужно использовать срезы (СрезПоследних, СрезПервых). Вы обращаетесь к таблице напрямую.

Можно ли изменить измерения у уже созданной записи регистра?

Нет, измерения являются ключом записи. Чтобы изменить значение измерения, необходимо удалить старую запись и создать новую с обновленными значениями ключа. Попытка изменить измерение у объекта записи приведет к ошибке.

Как получить все записи регистра без условий?

Просто не указывайте блок ГДЕ в тексте запроса. Однако будьте осторожны: если регистр содержит миллионы строк, такая выборка может замедлить работу системы. Всегда старайтесь фильтровать данные.

Что будет, если записать запись с существующим ключом?

Если вы используете метод Записать() у объекта записи, данные будут обновлены (перезаписаны). Если используется запрос на вставку, возникнет ошибка нарушения уникальности ключа.

Где физически хранятся данные непериодического регистра?

Данные хранятся в таблице базы данных (SQL), имя которой формируется по шаблону _RgS<код регистра>. Структура таблицы соответствует объявленным измерениям и ресурсам в конфигураторе.