Рассмотрим весьма показательную и поучительную ситуацию, с которой нередко сталкиваются начинающие разработчики 1С. Допустим, стоит задача: пользователи должны вводить данные о перемещении сумм с одного месяца на другой, а в отчете эти данные нужно видеть в классическом табличном виде, где колонками выступают месяцы (Январь, Февраль, Март и так далее до Декабря).
Пытаясь решить эту задачу «в лоб», разработчик может добавить в структуру регистра накопления новое измерение Дата, а ресурсы назвать Январь, Февраль, Март. Проанализируем, почему такой подход является грубейшей архитектурной ошибкой и выясним причину, по которой профессиональное сообщество 1С категорически не рекомендует так делать. После этого мы подробно разберем по шагам, как правильно реализовать подобный механизм.
Создание колонок (ресурсов), жестко привязанных к конкретным названиям месяцев, нарушает базовые принципы проектирования баз данных и логику работы платформы 1С. Рассмотрим основные проблемы этого подхода:
Период. Именно по нему платформа строит внутренние индексы и рассчитывает виртуальные таблицы остатков и оборотов. Если добавить собственное измерение с типом «Дата», платформа воспримет его просто как обычную аналитику (срез), а не как координату на оси времени.Дата остатки перестанут «перетекать» на следующие периоды, а будут зависать в разрезе конкретных дат. Механизм виртуальных таблиц не сможет работать правильно.Задачи, связанные с отображением данных по периодам в виде колонок, в 1С всегда решаются на уровне представления данных (отчетов), а не на уровне хранения данных (таблиц БД). Разберем по шагам, как должна выглядеть правильная структура регистра:
Сумма.Дата. В качестве даты операции платформа будет использовать стандартное поле Период, которое есть у регистра по умолчанию.Контрагент, Проект, СтатьяЗатрат и т.д.Теперь посмотрим на пример логики проведения документа. Как отразить операцию «перемещения» суммы из одного месяца в другой? Это делается двумя записями (движениями) в регистр:
// 1. Списание суммы из исходного месяца
ДвижениеМинус = Движения.НашРегистрОстатков.Добавить();
ДвижениеМинус.ВидДвижения = ВидДвиженияНакопления.Расход;
ДвижениеМинус.Период = ДатаИсходногоМесяца;
ДвижениеМинус.Сумма = СуммаПеремещения;
ДвижениеМинус.Аналитика = ЗначениеАналитики;
// 2. Поступление суммы в целевой месяц
ДвижениеПлюс = Движения.НашРегистрОстатков.Добавить();
ДвижениеПлюс.ВидДвижения = ВидДвиженияНакопления.Приход;
ДвижениеПлюс.Период = ДатаЦелевогоМесяца;
ДвижениеПлюс.Сумма = СуммаПеремещения;
ДвижениеПлюс.Аналитика = ЗначениеАналитики;
Таким образом, мы фиксируем отток средств в одном периоде и приток в другом, используя стандартные механизмы движений регистра накопления.
Мы спроектировали правильную базу. Теперь проанализируем ситуацию с отчетом. Пользователь хочет видеть привычную "шахматку", где строки — это аналитика, а колонки — названия месяцев. Настроим Систему компоновки данных (СКД):
НАЧАЛОПЕРИОДА(Таблица.Период, МЕСЯЦ). Назовем это поле, например, ПериодМесяц.ПериодМесяц.Сумма.Платформа сама динамически создаст столько колонок, сколько месяцев попало в выборку данных. При этом нам не пришлось жестко прописывать их в конфигурации.
Если мы просто выведем ПериодМесяц, то в шапке колонок пользователь увидит даты вида «01.01.2019 00:00:00». Чтобы сделать отчет понятным и красивым, зададим формат. Зайдем в настройки поля ПериодМесяц на вкладке «Наборы данных» и в свойстве «Оформление» найдем параметр Формат.
Пропишем форматную строку: ДФ='ММММ гггг'. Теперь вместо безликих дат в заголовках колонок будет выводиться понятный текст: «Январь 2019», «Февраль 2019» и так далее.
Применяя этот подход, мы получаем масштабируемую, быструю систему хранения данных, полностью соответствующую стандартам 1С, а всю визуальную работу перекладываем на мощный механизм СКД.