При проектировании архитектуры конфигурации 1С часто возникает дилемма: создавать один универсальный регистр накопления "для всего" или плодить множество специализированных регистров под каждый вид документа. Ситуация усложняется, когда документы имеют как общие реквизиты (например, "Пациент", "Дата"), так и уникальные ("МКБ", "Гарантийное письмо", "Должность"), а одна строка документа может порождать множество записей в регистре (комплексные услуги).
В этой статье мы подробно разберем, как спроектировать структуру хранения данных, чтобы отчеты строились быстро, а система оставалась гибкой. Проанализируем подходы к выбору измерений, ресурсов и реквизитов регистра, а также решим проблему учета комплексных услуг.
Допустим, у нас есть три разных вида документов оказания услуг. Условия следующие:
Пациент, ДатаОказанияУслуги, ОказаннаяУслуга.Должность, в другом — МКБ и Врач).Давайте рассмотрим, как правильно подойти к решению этой задачи.
Главный вопрос архитектуры: сваливать все данные в одну таблицу или разделять. Рассмотрим аргументы "за" и "против", основанные на опыте разработки.
Вы создаете один регистр накопления со всеми возможными измерениями: Пациент, Услуга, Врач, МКБ, Должность, ГарантийноеПисьмо.
Минусы этого подхода:
Null там, где измерение не применимо к конкретному документу).Создается отдельный регистр под каждый логический блок (или под каждый тип документа, если они кардинально разные).
Почему это лучше:
Если вам все же потребуется сводный отчет (например, "Общая сумма продаж по пациенту"), его можно собрать запросом по нескольким регистрам или создать один дополнительный сводный регистр с минимумом измерений (только Пациент и Сумма).
Самая частая ошибка начинающих разработчиков — попытка запихнуть в Измерения всю информацию из документа. Давайте разберем, что куда помещать.
Правило "Пляшем от отчета":
Прежде чем создать регистр, нарисуйте макет будущего отчета. Те поля, по которым вы будете группировать данные и получать ИТОГИ — это ваши Измерения. Те поля, которые вы просто хотите видеть в детальных записях как справочную информацию — это Реквизиты.
Сюда помещаем аналитику, в разрезе которой нужны цифры.
Пример: Нам нужно знать, "на какую сумму оказано услуг Врачом Ивановым". Значит, Врач — это измерение.
Сюда помещаем то, что мы суммируем.
Пример: Количество, Сумма.
Сюда помещаем дополнительную информацию, которая не влияет на уникальность записи и по которой не считаются итоги.
Пример: НомерГарантийногоПисьма, Комментарий.
Важное предостережение про строки:
Никогда не добавляйте в измерения поля типа "Строка" неограниченной длины (например, "Комментарий"). СУБД индексирует измерения. Индекс по длинной строке "убивает" производительность, а слишком длинные строки вообще нельзя индексировать. Если вам нужно вывести комментарий в отчете, есть два пути:
Регистратор).Рассмотрим ситуацию: в документе одна строка "Операция", а в учете это должно отразиться как набор: "Осмотр", "Анестезия", "Операция", "Перевязка".
В этом случае данные в регистре будут отличаться от данных в табличной части документа по количеству строк. Возникает проблема: как потом в отчете понять, какая запись регистра к какой строке документа относится?
Добавьте в регистр накопления реквизит (не измерение!) с названием, например, КлючСтрокиДокумента или НомерСтрокиДокумента.
При проведении документа, когда вы в цикле формируете движения на основании комплектации:
Для Каждого СтрокаТЧ Из ДокументОбъект.Услуги Цикл
// Получаем состав комплексной услуги
СоставУслуги = ПолучитьСостав(СтрокаТЧ.Услуга);
Для Каждого ЭлементСостава Из СоставУслуги Цикл
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Услуга = ЭлементСостава.Услуга; // Подменная услуга из состава
Движение.Количество = ЭлементСостава.Количество;
// Важный момент: сохраняем связь с исходной строкой
Движение.НомерСтрокиДокумента = СтрокаТЧ.НомерСтроки;
КонецЦикла;
КонецЦикла;
Полезно мыслить аналогиями. Представьте сборку компьютера. Клиент покупает "Системный блок" (одна строка в накладной). Но со склада списываются: процессор, корпус, память (много строк).
Возможно, вам стоит разделить эти потоки данных. Не пытайтесь решить все задачи одним регистром.
В обсуждении возник вопрос: "Если я не запишу Должность и Комментарий в регистр, как я их увижу в отчете?".
Современные механизмы 1С, в частности Система Компоновки Данных (СКД), позволяют элегантно решать эту проблему без дублирования информации.
Метод "Неявного соединения":
Вы строите запрос к виртуальной таблице регистра (например, РегистрНакопления.Услуги.Обороты). В этой таблице есть поле Регистратор — ссылка на документ.
В запросе вы можете обратиться к реквизитам документа через точку:
ВЫБРАТЬ
УслугиОбороты.Пациент,
УслугиОбороты.Услуга,
УслугиОбороты.СуммаОборот,
// Получаем данные напрямую из документа, не храня их в регистре
УслугиОбороты.Регистратор.ДолжностьПациента КАК Должность,
УслугиОбороты.Регистратор.Комментарий КАК Комментарий
ИЗ
РегистрНакопления.Услуги.Обороты(...) КАК УслугиОбороты
Преимущества такого подхода:
Однако, помните про производительность: обращение к реквизитам через точку (особенно к реквизитам составного типа) может замедлять выполнение отчета на очень больших объемах данных. Если поле (например, Должность) критически важно для постоянной фильтрации и группировки в 99% отчетов — лучше вынести его в Измерение или хотя бы в Реквизит регистра. Если оно нужно "иногда посмотреть" — оставляйте в документе.
Подводя итог дискуссии, сформулируем алгоритм действий: