Как правильно создать регистр накопления для разных документов с отличающимся набором реквизитов?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

При проектировании архитектуры конфигурации 1С часто возникает дилемма: создавать один универсальный регистр накопления "для всего" или плодить множество специализированных регистров под каждый вид документа. Ситуация усложняется, когда документы имеют как общие реквизиты (например, "Пациент", "Дата"), так и уникальные ("МКБ", "Гарантийное письмо", "Должность"), а одна строка документа может порождать множество записей в регистре (комплексные услуги).

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

Постановка задачи

Допустим, у нас есть три разных вида документов оказания услуг. Условия следующие:

  1. Документы имеют общие реквизиты: Пациент, ДатаОказанияУслуги, ОказаннаяУслуга.
  2. В каждом типе документа есть свой уникальный набор дополнительных полей (например, в одном важна Должность, в другом — МКБ и Врач).
  3. Отчеты требуются раздельные по каждому разделу учета (типу документа), но иногда нужна и общая картина.
  4. Существует механизм "Комплексных услуг": в документе это одна строка, но при проведении она должна распасться на 5–10 составляющих услуг в регистре.

Давайте рассмотрим, как правильно подойти к решению этой задачи.

Этап 1. Определение стратегии: Один регистр или несколько?

Главный вопрос архитектуры: сваливать все данные в одну таблицу или разделять. Рассмотрим аргументы "за" и "против", основанные на опыте разработки.

Подход А: Один "Мега-регистр"

Вы создаете один регистр накопления со всеми возможными измерениями: Пациент, Услуга, Врач, МКБ, Должность, ГарантийноеПисьмо.

Минусы этого подхода:

Подход Б: Раздельные регистры (Рекомендуемый)

Создается отдельный регистр под каждый логический блок (или под каждый тип документа, если они кардинально разные).

Почему это лучше:

Если вам все же потребуется сводный отчет (например, "Общая сумма продаж по пациенту"), его можно собрать запросом по нескольким регистрам или создать один дополнительный сводный регистр с минимумом измерений (только Пациент и Сумма).

Этап 2. Выбор Измерений, Ресурсов и Реквизитов

Самая частая ошибка начинающих разработчиков — попытка запихнуть в Измерения всю информацию из документа. Давайте разберем, что куда помещать.

Правило "Пляшем от отчета":

Прежде чем создать регистр, нарисуйте макет будущего отчета. Те поля, по которым вы будете группировать данные и получать ИТОГИ — это ваши Измерения. Те поля, которые вы просто хотите видеть в детальных записях как справочную информацию — это Реквизиты.

1. Измерения (Dimensions)

Сюда помещаем аналитику, в разрезе которой нужны цифры.
Пример: Нам нужно знать, "на какую сумму оказано услуг Врачом Ивановым". Значит, Врач — это измерение.

2. Ресурсы (Resources)

Сюда помещаем то, что мы суммируем.
Пример: Количество, Сумма.

3. Реквизиты (Attributes)

Сюда помещаем дополнительную информацию, которая не влияет на уникальность записи и по которой не считаются итоги.
Пример: НомерГарантийногоПисьма, Комментарий.

Важное предостережение про строки:

Никогда не добавляйте в измерения поля типа "Строка" неограниченной длины (например, "Комментарий"). СУБД индексирует измерения. Индекс по длинной строке "убивает" производительность, а слишком длинные строки вообще нельзя индексировать. Если вам нужно вывести комментарий в отчете, есть два пути:

  1. Сделать его Реквизитом регистра.
  2. Вообще не писать его в регистр, а подтягивать из документа при формировании отчета (через соединение с полем Регистратор).

Этап 3. Решение проблемы "Комплексных услуг"

Рассмотрим ситуацию: в документе одна строка "Операция", а в учете это должно отразиться как набор: "Осмотр", "Анестезия", "Операция", "Перевязка".

В этом случае данные в регистре будут отличаться от данных в табличной части документа по количеству строк. Возникает проблема: как потом в отчете понять, какая запись регистра к какой строке документа относится?

Способ 1. Использование реквизита связи

Добавьте в регистр накопления реквизит (не измерение!) с названием, например, КлючСтрокиДокумента или НомерСтрокиДокумента.

При проведении документа, когда вы в цикле формируете движения на основании комплектации:


Для Каждого СтрокаТЧ Из ДокументОбъект.Услуги Цикл
    
    // Получаем состав комплексной услуги
    СоставУслуги = ПолучитьСостав(СтрокаТЧ.Услуга); 
    
    Для Каждого ЭлементСостава Из СоставУслуги Цикл
        Движение = Движения.Продажи.Добавить();
        Движение.Период = Дата;
        Движение.Услуга = ЭлементСостава.Услуга; // Подменная услуга из состава
        Движение.Количество = ЭлементСостава.Количество;
        
        // Важный момент: сохраняем связь с исходной строкой
        Движение.НомерСтрокиДокумента = СтрокаТЧ.НомерСтроки; 
    КонецЦикла;
    
КонецЦикла;

Способ 2. Архитектурная аналогия "Системный блок"

Полезно мыслить аналогиями. Представьте сборку компьютера. Клиент покупает "Системный блок" (одна строка в накладной). Но со склада списываются: процессор, корпус, память (много строк).

Возможно, вам стоит разделить эти потоки данных. Не пытайтесь решить все задачи одним регистром.

Этап 4. Построение отчета: От регистра или от документа?

В обсуждении возник вопрос: "Если я не запишу Должность и Комментарий в регистр, как я их увижу в отчете?".

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

Метод "Неявного соединения":

Вы строите запрос к виртуальной таблице регистра (например, РегистрНакопления.Услуги.Обороты). В этой таблице есть поле Регистратор — ссылка на документ.

В запросе вы можете обратиться к реквизитам документа через точку:


ВЫБРАТЬ
    УслугиОбороты.Пациент,
    УслугиОбороты.Услуга,
    УслугиОбороты.СуммаОборот,
    // Получаем данные напрямую из документа, не храня их в регистре
    УслугиОбороты.Регистратор.ДолжностьПациента КАК Должность,
    УслугиОбороты.Регистратор.Комментарий КАК Комментарий
ИЗ
    РегистрНакопления.Услуги.Обороты(...) КАК УслугиОбороты

Преимущества такого подхода:

  1. Регистр остается легким и быстрым (в нем только цифры и ключевые аналитики).
  2. В отчете доступна абсолютно вся информация из шапки и табличных частей документа.
  3. Экономия дискового пространства.

Однако, помните про производительность: обращение к реквизитам через точку (особенно к реквизитам составного типа) может замедлять выполнение отчета на очень больших объемах данных. Если поле (например, Должность) критически важно для постоянной фильтрации и группировки в 99% отчетов — лучше вынести его в Измерение или хотя бы в Реквизит регистра. Если оно нужно "иногда посмотреть" — оставляйте в документе.

Итоговые рекомендации

Подводя итог дискуссии, сформулируем алгоритм действий:

  1. Разделите потоки. Для каждого типа документа, имеющего уникальную бизнес-логику и набор полей, создайте свой регистр накопления. Это упростит сопровождение.
  2. Определите измерения. В измерения включайте только те поля, по которым нужны итоги ("сколько услуг оказано Врачом X", "сколько услуг получил Пациент Y").
  3. Не мусорьте в измерениях. Комментарии, номера писем и прочую справочную информацию делайте Реквизитами регистра или вообще не храните в регистре, подтягивая из документа.
  4. Комплексные услуги. Декомпозируйте их при проведении. Если нужно сохранить связь с исходной строкой, запишите номер строки документа в реквизит регистра.
  5. Используйте мощь СКД. При построении отчета берите агрегированные данные (суммы, количества) из регистра, а уточняющие детали — через соединение с документом-регистратором.
← На главную