Регистры в 1С 8.3: как они хранят данные и зачем их четыре вида
Содержание
Регистр в 1С — это таблица, куда документ при проведении пишет «движения»: что, где, сколько и когда изменилось. Сами документы остатков не хранят. Остаток товара, долг контрагента или курс валюты система берёт из регистров, а не пересчитывает по документам.
Отсюда большинство вопросов разработчика: почему отчёт показывает не то, откуда тормоза при проведении, какой вид регистра выбрать под задачу. Ниже — устройство всех четырёх видов регистров, как работает запись движений и как читать данные быстро.
Как устроены регистры 1С: общая схема
В платформе 1С:Предприятие 8.3 есть четыре вида регистров. Каждый решает свою задачу, и путать их дорого: переделка структуры регистра в работающей базе почти всегда означает перепроведение документов .
| Вид регистра | Что хранит | Пример в типовых конфигурациях | Нужен ли документ-регистратор |
|---|---|---|---|
| Регистр накопления | Количества и суммы, которые растут и убывают | Остатки товаров, взаиморасчёты, продажи | Всегда |
| Регистр сведений | Значения в разрезе измерений, часто во времени | Цены, курсы валют, настройки, адреса | Не обязательно |
| Регистр бухгалтерии | Проводки по плану счетов | Хозрасчётный регистр в Бухгалтерии | Всегда |
| Регистр расчёта | Начисления с периодом действия и вытеснением | Начисления зарплаты в ЗУП | Всегда |
У любого регистра три группы полей:
- 📐 Измерения — разрезы учёта: склад, номенклатура, контрагент. По ним данные группируются и отбираются.
- 🔢 Ресурсы — то, что накапливается или хранится: количество, сумма, цена.
- 🏷️ Реквизиты — справочная информация к записи. По ним итоги не считаются.
Плюс служебные поля, которые платформа добавляет сама: Период, Регистратор, НомерСтроки, Активность. У регистра накопления остатков есть ещё ВидДвижения (Приход или Расход).
Правило выбора простое. Если значение надо складывать (сколько пришло и ушло) — регистр накопления. Если значение надо знать на дату (какая цена действовала 15 марта) — регистр сведений.
Регистры накопления: остатки и обороты
Регистр накопления — основа складского и финансового учёта. Он бывает двух видов, и вид задаётся один раз при создании.
Регистр остатков
Хранит движения с видом Приход и Расход. По нему можно получить остаток на любой момент времени.
Пример. Пришло 100 штук бумаги на склад «Основной», затем отгрузили 30. В регистре две записи:
| Период | Регистратор | Вид движения | Склад | Номенклатура | Количество |
|---|---|---|---|---|---|
| 01.10 10:00 | Поступление №12 | Приход | Основной | Бумага А4 | 100 |
| 03.10 14:20 | Реализация №45 | Расход | Основной | Бумага А4 | 30 |
Остаток на 04.10 — 100 − 30 = 70 штук.
Регистр оборотов
Знает только суммы за период. Понятия «остаток» у него нет, вида движения тоже. Подходит для продаж, закупок, выработки: важно, сколько продали за месяц, а не «сколько продаж осталось».
Что лежит в базе физически
Один регистр накопления в СУБД — это не одна таблица, а несколько:
- Таблица движений — все записи, которые сделали документы.
- Таблица итогов — рассчитанные остатки (для регистра остатков) или обороты (для регистра оборотов) по месяцам и актуальные итоги на текущий момент.
- Таблицы агрегатов — только у регистров оборотов, если их включили.
Итоги — ключ к скорости. Чтобы получить остаток на 15 октября, платформе не нужно складывать движения за пять лет. Она берёт итог на ближайшую границу месяца и досчитывает движения за несколько дней.
Если в регистре остатков ресурс по какому-то сочетанию измерений «никогда не обнуляется» (например, в измерение попала дата или номер документа), таблица итогов разрастается и регистр тормозит. Измерения должны давать конечный набор сочетаний.
Регистры сведений: периодичность и режимы записи
Регистр сведений хранит не изменения, а сами значения. Главный вопрос при проектировании — нужна ли история.
Периодичность
- 📌 Непериодический — одно значение на сочетание измерений. Например, настройка пользователя.
- 🕒 Периодический — значение действует с указанной даты до следующей записи. Периодичность выбирается: в пределах секунды, дня, месяца, квартала, года или позиции регистратора.
Курс доллара — классический периодический регистр сведений с периодичностью «в пределах дня». Запись «01.10 — 95,00» действует, пока не появится запись с более поздней датой.
Режим записи
| Режим | Кто пишет | Типичный пример |
|---|---|---|
| Независимый | Пользователь вручную, обработка, код | Цены номенклатуры (в части конфигураций), курсы валют |
| Подчинение регистратору | Только документ при проведении | Кадровая история, статусы документов |
В независимом режиме у записи нет регистратора, её можно поправить прямо в списке регистра. В режиме подчинения запись живёт и умирает вместе с документом: отменили проведение — запись исчезла.
Для периодических регистров сведений можно включить итоги среза последних и среза первых. Тогда платформа хранит отдельную таблицу с последними значениями, и запрос к СрезПоследних без даты отрабатывает быстрее.
Регистры бухгалтерии и регистры расчёта
Эти два вида — специализированные. В самописных конфигурациях они встречаются реже, но в Бухгалтерии и ЗУП составляют ядро учёта.
Регистр бухгалтерии
Опирается на план счетов . Каждая запись — проводка: счёт дебета, счёт кредита, сумма, субконто по обеим сторонам. Если у регистра включена поддержка корреспонденции, запись хранит обе стороны сразу. Без корреспонденции — каждая строка относится к одному счёту с признаком Дт или Кт.
Субконто — аналитика счёта. Их виды хранит план видов характеристик, а максимальное количество субконто на счёте задаётся в плане счетов. Например, на счёте 62 аналитика ведётся по контрагенту, договору и документу расчётов.
В базе регистр бухгалтерии тоже состоит из нескольких таблиц: движения, значения субконто, итоги по счетам и итоги по счетам с субконто.
Регистр расчёта
Создан для периодических расчётов с зависимостями. Он работает в паре с планом видов расчёта. У каждой записи есть:
- 📅 период регистрации — месяц, в котором начислено;
- ⏳ период действия — за какое время начисление (с 1 по 15 число);
- 📊 базовый период — за какое время брать базу для расчёта.
Отсюда механизмы вытеснения и перерасчёта. Больничный за 5–9 октября вытесняет оклад за эти дни, а платформа сама вычисляет фактический период действия оклада. Если регистр связан с графиком, через виртуальную таблицу ДанныеГрафика можно получить норму дней или часов.
Регистр расчёта без чёткого понимания вытеснения и базовых видов расчёта легко даёт двойное начисление. Типовой ЗУП реализует эту логику годами доводки, повторять её с нуля без необходимости не стоит.
Как проведение документа записывает движения в регистры
Движения появляются в регистрах только в момент проведения. Логику пишет разработчик в модуле объекта документа, в обработчике ОбработкаПроведения.
Порядок работы
- Пользователь нажимает «Провести».
- Платформа открывает транзакцию и записывает сам документ.
- Срабатывает
ОбработкаПроведения(Отказ, Режим). Код заполняет наборы записейДвижения.<ИмяРегистра>. - Наборам, которые нужно записать, ставится признак
Записывать = Истина. После обработчика платформа записывает их сама. - Если где-то установлен
Отказ = Истина, транзакция откатывается целиком: ни документ, ни движения не меняются.
Минимальный пример для регистра остатков:
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ТоварыНаСкладах.Записывать = Истина;
Для Каждого СтрокаТЧ Из Товары Цикл
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Склад = Склад;
Движение.Номенклатура = СтрокаТЧ.Номенклатура;
Движение.Количество = СтрокаТЧ.Количество;
КонецЦикла;
КонецПроцедуры
Перепроведение и отмена
Набор записей регистра привязан к регистратору целиком. При повторном проведении старые движения документа заменяются новыми, а не добавляются к ним. При отмене проведения набор очищается.
Из этого следует важная вещь для отчётов: нельзя править движения регистра вручную, если регистр подчинён регистратору. Следующее перепроведение документа сотрёт вашу правку.
Контроль остатков
Чтобы не уйти в минус, документ проверяет остаток. Современный подход такой:
- 🔒 перед записью у набора включают
БлокироватьДляИзменения = Истина— платформа ставит управляемую блокировку на изменяемые данные; - 📝 движения записываются;
- 🔍 запросом к виртуальной таблице
Остаткипроверяют, не появилось ли отрицательных значений; - ❌ если появились —
Отказ = Истина, транзакция откатывается.
Так проверка делается одним запросом по уже записанным данным, а параллельные документы не продадут один и тот же товар дважды.
Оперативное проведение (документ датой «сейчас») и неоперативное (задним числом) различаются для регистров остатков. При оперативном режиме можно смело контролировать текущие остатки. При проведении задним числом остатки на дату документа могли «уйти» позже — это частая причина последовательностей и перепроведения.
Виртуальные таблицы регистров и скорость запросов
Читать регистры напрямую из таблицы движений можно, но обычно незачем. Платформа даёт виртуальные таблицы — они собираются на лету из итогов и движений.
| Вид регистра | Виртуальные таблицы |
|---|---|
| Накопления (остатки) | Остатки, Обороты, ОстаткиИОбороты |
| Накопления (обороты) | Обороты |
| Сведений (периодический) | СрезПоследних, СрезПервых |
| Бухгалтерии | Остатки, Обороты, ОстаткиИОбороты, ОборотыДтКт, ДвиженияССубконто |
| Расчёта | ФактическийПериодДействия, ДанныеГрафика и таблицы баз |
Пример запроса остатков по складу:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Момент, Склад = &Склад) КАК Остатки
Что ускоряет запросы
- ✅ Условия — в параметры виртуальной таблицы. Отбор
Склад = &Складвнутри скобок применяется до расчёта итогов. Тот же отбор вГДЕсрабатывает после, когда платформа уже посчитала всё по всем складам. - ✅ Граница момента. Если передать в
Остаткипросто дату, движения ровно в эту секунду не попадут. Чтобы учесть сам документ, передаютНовый Граница(МоментВремени(), ВидГраницы.Включая). - ✅ Индексирование. Измерения регистров индексируются платформой. Реквизит, по которому часто отбирают, стоит индексировать вручную в его свойствах.
- ✅ Разделение итогов. Свойство «Разрешить разделение итогов» убирает конкуренцию за запись итогов, когда много пользователей проводят документы одновременно.
- ✅ Агрегаты. Для регистров оборотов с большими объёмами — заранее рассчитанные обороты по выбранным измерениям и периодам.
- ✅ Период рассчитанных итогов. Для регистров остатков итоги можно рассчитать до конца закрытого периода, а новые движения досчитываются сверху.
Пересчёт итогов на большой базе занимает от минут до часов и нагружает сервер. Запускайте его вне рабочего времени: пользователи в этот момент будут ждать или получать ошибки блокировок.
Типичные ошибки при работе с регистрами
Эти ошибки встречаются в самописных доработках чаще всего:
- 🚫 Ресурс вместо измерения и наоборот. Цена, положенная в ресурс регистра остатков, суммируется: две партии по 100 ₽ дают «цену» 200 ₽.
- 🚫 Слишком много измерений. Каждое лишнее измерение множит строки итогов. Если разрез нужен только для отображения — делайте его реквизитом.
- 🚫 Запрос в цикле. Получение остатка по каждой строке документа отдельным запросом вместо одного запроса по всей табличной части.
- 🚫 Отбор в
ГДЕпо виртуальной таблице. Работает правильно, но медленно, особенно на больших регистрах. - 🚫 Регистр накопления под данные «на дату». Курс или ставку пытаются хранить приходом-расходом, а потом мучаются с отрицательными «остатками» курса.
- 🚫 Ручная правка подчинённых движений. Помогает до первого перепроведения.
Если отчёт показывает остатки, которых не может быть, сначала сравните виртуальную таблицу Остатки с суммой движений за тот же период. Расхождение говорит о сбитых итогах — их пересчитывают через «Тестирование и исправление» в Конфигураторе или через пересчёт итогов в режиме Предприятия. Перед этим сделайте резервную копию базы.