Регистр сведений в конфигураторе 1С 8.3: от пустого объекта до среза последних
Содержание
Регистр сведений
создают в конфигураторе: откройте дерево конфигурации, щёлкните правой кнопкой по ветке Регистры сведений и выберите Добавить. Дальше задайте имя, периодичность и режим записи, опишите измерения и ресурсы, выдайте права в роли и выполните Конфигурация → Обновить конфигурацию базы данных (F7). После этого регистр готов к работе в режиме 1С:Предприятие.
Перед стартом решите два вопроса. Первый — нужна ли история значений (цены, курсы, тарифы) или хватит «последнего слова» (настройки, соответствия). Второй — кто пишет данные: пользователь руками или документ при проведении. От ответов зависят периодичность и режим записи, а их потом дорого менять.
Что подготовить перед созданием регистра сведений
Создание любого объекта метаданных меняет конфигурацию. Поэтому сначала убедитесь, что её вообще можно править.
- Откройте базу в режиме
Конфигуратори выполнитеКонфигурация → Открыть конфигурацию. - Если конфигурация типовая и стоит на поддержке, объекты в дереве помечены замочком. Добавить новый регистр в такую конфигурацию нельзя, пока не включена возможность изменения:
Конфигурация → Поддержка → Настройка поддержки → Включить возможность изменения. - Сделайте выгрузку базы:
Администрирование → Выгрузить информационную базу(файл .dt).
Включение возможности изменения в типовой конфигурации усложняет все будущие обновления: каждый релиз придётся сравнивать и объединять вручную. Для доработок типовых решений лучше использовать расширение конфигурации — в актуальных версиях платформы оно может содержать собственные регистры сведений, а основная конфигурация остаётся на поддержке.
Для расширения путь почти тот же: Конфигурация → Расширения конфигурации, откройте нужное расширение и добавьте регистр в его дереве. Разница одна: в конце обновляют уже расширение, а не основную конфигурацию.
Продумайте структуру на бумаге. Удобный приём — сформулировать, на какой вопрос регистр отвечает. Например: «Какой тариф доставки у перевозчика X в зоне Y на дату Z?». Всё, что стоит после «у» и «в», — измерения. То, что спрашиваем («тариф»), — ресурс. «На дату» — признак периодического регистра.
Создание регистра сведений: имя, периодичность и режим записи
После команды Добавить откроется окно редактирования объекта с вкладками слева. На вкладке Основные заполните:
- 🏷️ Имя — по-русски, без пробелов, слова с заглавной буквы:
ТарифыДоставки. Имя используется в коде и запросах, менять его потом неудобно. - 📝 Синоним — то, что увидит пользователь: «Тарифы доставки».
- 💬 Комментарий — для коллег, по желанию.
Ключевые настройки находятся на вкладке Данные: свойства Периодичность и Режим записи.
Периодичность
Свойство определяет, хранит ли регистр историю и с какой точностью.
| Значение | Что хранит | Пример |
|---|---|---|
| Непериодический | Одно значение на набор измерений | Ответственный за склад, настройка обмена |
| В пределах секунды | Историю с точностью до секунды | Котировки, частые изменения |
| В пределах дня | Одно значение в день | Курсы валют, цены |
| В пределах месяца / квартала / года | Одно значение на период | Плановые нормы, лимиты |
| По позиции регистратора | Период привязан к моменту документа | Только при подчинении регистратору |
У периодического регистра появляется стандартное поле Период. Оно входит в ключ записи: две записи с одинаковыми измерениями на один период быть не могут. Если выбрать «в пределах дня», то запись на 10:00 и на 15:00 одного числа платформа приведёт к началу дня, и вторая запись заменит первую.
💡 Берите самую грубую периодичность, которой хватает задаче. Тариф, который меняют раз в месяц, не нужно хранить с точностью до секунды.
Режим записи
- ✍️ Независимый — записи добавляют руками в форме списка или программно. Подходит для справочной информации: цены, курсы, настройки.
- 📄 Подчинение регистратору — записи создаёт документ при проведении (движения). Записи без документа не существуют; при отмене проведения или удалении документа они пропадают.
Подсказка для выбора — в интерактивном помощнике.
Измерения, ресурсы и реквизиты регистра сведений
На вкладке Данные три списка. Кнопкой Добавить над каждым из них создаются поля.
Измерения
Измерения — разрезы, по которым ищут значение. Вместе с периодом (и регистратором) они образуют уникальный ключ записи. Для нашего примера:
Перевозчик— типСправочникСсылка.Контрагенты;ЗонаДоставки— типСправочникСсылка.ЗоныДоставки(или строка фиксированной длины).
Свойства измерения, которые стоит выставить осознанно:
| Свойство | Что даёт |
|---|---|
Основной отбор | Поле появляется в отборе списка и ускоряет выборку. В независимых регистрах его ставят хотя бы на одно ключевое измерение |
Запрет незаполненных значений | Не даст записать строку с пустым измерением |
Ведущее | Связывает запись с объектом: при удалении элемента справочника записи удаляются, а в его форме появляется команда перехода к регистру |
Индексировать | Создаёт индекс по полю. Нужно, если по измерению часто фильтруют, а оно не стоит первым |
Порядок измерений важен: платформа строит основной индекс в порядке их следования. Первым ставьте то поле, по которому чаще всего отбирают.
Ресурсы
Ресурсы — сами значения: Тариф (число 15,2), Валюта, МинимальнаяСумма. Ресурс может быть любого типа, включая ссылку и строку неограниченной длины. В ключ записи ресурсы не входят.
Реквизиты
Реквизиты — вспомогательная информация, которая не участвует в поиске: Комментарий, Автор, ДатаИзменения. Их можно не заводить вовсе.
Когда сомневаетесь, измерение это или ресурс, задайте вопрос: «Может ли на одну дату у одного перевозчика быть два разных значения этого поля?». Если да — это измерение. Если нет — ресурс или реквизит.
Подчинение регистратору и итоги срезов
Если выбран режим Подчинение регистратору, в окне объекта активируется вкладка Регистраторы. Отметьте там документы, которые будут писать в регистр, например УстановкаТарифов.
Дальше нужен код проведения. Проще всего получить его конструктором: откройте документ, вкладка Движения, отметьте регистр и нажмите Конструктор движений. Конструктор сопоставит поля документа с измерениями и ресурсами и сформирует обработчик ОбработкаПроведения. Его результат выглядит так:
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ТарифыДоставки.Записывать = Истина;
Для Каждого СтрокаТЧ Из Тарифы Цикл
Движение = Движения.ТарифыДоставки.Добавить();
Движение.Период = Дата;
Движение.Перевозчик = Перевозчик;
Движение.ЗонаДоставки = СтрокаТЧ.ЗонаДоставки;
Движение.Тариф = СтрокаТЧ.Тариф;
КонецЦикла;
КонецПроцедуры
У подчинённого регистра в ключ записи входят регистратор и номер строки. Поэтому один документ может записать несколько строк с одинаковыми измерениями — уникальность по измерениям здесь не контролируется. Следите за этим в коде проведения.
Итоги срезов
У периодического регистра на вкладке Данные есть флажки Разрешить итоги среза последних и Разрешить итоги среза первых. Включённые итоги — это отдельная таблица с готовыми актуальными значениями. Срез последних по ней читается быстрее, но каждая запись в регистр становится немного дороже.
Включайте итоги, когда регистр большой (сотни тысяч записей и больше), а срез последних запрашивают постоянно. Для небольшого регистра с тарифами выигрыша не будет. Пересчитать и выключить итоги можно в режиме 1С:Предприятие через стандартную обработку Управление итогами.
Как заполнить регистр сведений: права, формы и запись из кода
Объект создан, но пользователь его пока не увидит. Осталось три шага.
1. Подсистема. На вкладке Подсистемы отметьте раздел, в котором должен появиться регистр. Тогда команда открытия списка попадёт в панель навигации раздела.
2. Права. Откройте роль (Общие → Роли), найдите регистр в списке объектов и отметьте права: Чтение и Просмотр для всех, кто смотрит; Изменение и Редактирование для тех, кто вводит данные. Без прав пользователь получит ошибку «Нарушение прав доступа».
3. Обновление. Нажмите F7 или Конфигурация → Обновить конфигурацию базы данных. Платформа покажет, какие таблицы будут созданы, и попросит подтверждение. Если в базе работают другие пользователи и изменение затрагивает структуру, понадобится монопольный доступ — планируйте обновление на нерабочее время.
При обновлении структуры с монопольным доступом сеансы остальных пользователей придётся завершить. Предупредите коллег заранее.
Формы
Отдельно рисовать формы не обязательно: платформа сгенерирует форму списка и форму записи автоматически. Свою форму создают на вкладке Формы кнопкой с лупой (конструктор форм), если нужны подсказки, проверка заполнения или особый порядок полей.
Ручной ввод
В режиме 1С:Предприятие откройте раздел, куда добавили регистр, и выберите его в панели навигации. Если подсистему не указывали, найдите регистр через главное меню: Все функции → Регистры сведений (в новых версиях платформы команда называется Функции для технического специалиста; её показ включают в Сервис и настройки → Параметры).
В списке нажмите Создать, заполните период, измерения и ресурс и запишите. Подчинённый регистр руками не заполняют: записи появляются только при проведении документа.
Запись из кода
Для независимого регистра есть два инструмента.
Менеджер записи — одна строка:
Запись = РегистрыСведений.ТарифыДоставки.СоздатьМенеджерЗаписи();
Запись.Период = НачалоДня(ТекущаяДатаСеанса());
Запись.Перевозчик = Перевозчик;
Запись.ЗонаДоставки = Зона;
Запись.Тариф = 350;
Запись.Записать();
Метод Записать() по умолчанию замещает запись с тем же ключом. Если такая уже есть, значение тарифа просто обновится.
Набор записей — много строк за раз в рамках одного отбора:
Набор = РегистрыСведений.ТарифыДоставки.СоздатьНаборЗаписей();
Набор.Отбор.Период.Установить(ДатаТарифа);
Набор.Отбор.Перевозчик.Установить(Перевозчик);
Для Каждого Строка Из ТаблицаТарифов Цикл
НоваяЗапись = Набор.Добавить();
НоваяЗапись.Период = ДатаТарифа;
НоваяЗапись.Перевозчик = Перевозчик;
НоваяЗапись.ЗонаДоставки = Строка.Зона;
НоваяЗапись.Тариф = Строка.Тариф;
КонецЦикла;
Набор.Записать();
Набор с установленным отбором при записи удаляет все старые строки, попавшие под этот отбор. Если забыть отбор по измерению, можно стереть чужие данные. Проверяйте отбор на копии базы.
Как получить данные: срезы последних и первых в запросах
Главная ценность периодического регистра — виртуальная таблица СрезПоследних. Она возвращает по каждому набору измерений последнюю запись на дату не позже указанной.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Тарифы.ЗонаДоставки,
| Тарифы.Тариф
|ИЗ
| РегистрСведений.ТарифыДоставки.СрезПоследних(
| &НаДату,
| Перевозчик = &Перевозчик) КАК Тарифы";
Запрос.УстановитьПараметр("НаДату", ДатаЗаказа);
Запрос.УстановитьПараметр("Перевозчик", Перевозчик);
Результат = Запрос.Выполнить().Выгрузить();
СрезПервых работает зеркально: первая запись на дату не раньше указанной. Её применяют реже, например чтобы найти, когда значение впервые установили.
Для разовой проверки без запроса удобны методы менеджера:
РегистрыСведений.ТарифыДоставки.ПолучитьПоследнее(Дата, Новый Структура("Перевозчик, ЗонаДоставки", П, З))— структура с ресурсами на дату;ПолучитьПервое(...)— аналогично для среза первых;- у непериодического регистра —
Получить(Отбор).
Методы удобны в одной точке кода. В цикле по сотне строк документа они дают сотню обращений к базе, поэтому там нужен один запрос.
Если нужно получить тариф для каждой строки документа на её собственную дату, срез на одну дату не подойдёт. Соедините таблицу строк с регистром по условию Регистр.Период <= Строка.Дата, сгруппируйте по строке с МАКСИМУМ(Период) и вторым соединением заберите значение.
Ошибки при создании и работе с регистром сведений
Ещё несколько промахов, которые обнаруживаются поздно:
- 🔁 Смена периодичности на живой базе. Переход, скажем, с «в пределах секунды» на «в пределах дня» схлопнет записи одного дня. Платформа предупредит при реструктуризации, но данные к этому моменту надо проверить заранее.
- 🧱 Слишком много измерений. Каждое измерение входит в индекс и в ключ. Если поле не используется для поиска, сделайте его ресурсом или реквизитом.
- 🔗 Составной тип измерения без нужды. Поле «Контрагент или Организация» усложняет запросы и индексы. Чаще лучше два отдельных измерения или отдельный регистр.
- 🧮 Изменение регистра внутри цикла по одному. Менеджер записи в цикле на тысячу строк — тысяча транзакций. Набор записей с одним
Записать()выполнится заметно быстрее.