Часто в практике программиста 1С возникает ситуация, когда бухгалтер просит добавить возможность выбора периода в отчет, который изначально строился как срез остатков на конкретную дату. С точки зрения пользователя, это логичное требование, однако технически это требует кардинального изменения логики запроса и обработки параметров. Рассмотрим подробно, как преобразовать отчет по основным средствам, чтобы видеть динамику накопленной амортизации и стоимости за выбранный интервал времени.
Прежде чем приступать к коду, проанализируем ситуацию. Виртуальная таблица Остатки в регистре бухгалтерии предназначена для получения состояния счетов на конкретный момент времени. Если мы попытаемся «подсунуть» ей период (начало и конец), система не поймет, на какой именно момент считать итог, так как остаток в течение дня или месяца может меняться многократно.
Для решения задачи, когда нужно видеть изменения за период (например, на сколько выросла амортизация), необходимо использовать виртуальную таблицу ОстаткиИОбороты. Она позволяет получить:
При попытке программно передать период из Системы компоновки данных (СКД) в запрос, разработчики часто сталкиваются с ошибкой: «Преобразование значения к типу Дата не может быть выполнено». Выясним причину.
В настройках СКД параметр периода обычно имеет тип СтандартныйПериод. Этот объект содержит два поля: ДатаНачала и ДатаОкончания. Когда мы пытаемся выполнить код КонецДня(Параметр.Значение), система выдает ошибку, так как она не может превратить весь объект «период» в одну дату. Чтобы исправить это, нужно обращаться к конкретным свойствам объекта:
// Правильное извлечение дат из стандартного периода СКД
ПараметрПериод = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ПериодОтчета");
Если ПараметрПериод <> Неопределено И ПараметрПериод.Использование Тогда
НачалоПериода = ПараметрПериод.Значение.ДатаНачала;
КонецПериода = Новый Граница(КонецДня(ПараметрПериод.Значение.ДатаОкончания), ВидГраницы.Включая);
КонецЕсли;
Обратите внимание на использование объекта Граница. Если мы просто укажем дату, в отчет могут не попасть документы, проведенные в последнюю секунду дня. ВидГраницы.Включая гарантирует абсолютную точность данных.
В исходном примере кода из темы предлагалось соединять две виртуальные таблицы ОстаткиИОбороты (одну для счета 01, другую для 02). Это «тяжелая» операция для базы данных. Рассмотрим более элегантный и производительный способ решения задачи через использование одного обращения к таблице с фильтром по списку счетов.
Проанализируем пример оптимизированного запроса:
ВЫБРАТЬ
ХозрасчетныйОстаткиИОбороты.Субконто1 КАК ОС,
// Получаем стоимость (счет 01)
СУММА(ВЫБОР
КОГДА ХозрасчетныйОстаткиИОбороты.Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновныеСредства))
ТОГДА ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокДт
ИНАЧЕ 0
КОНЕЦ) КАК Стоимость,
// Получаем амортизацию (счет 02)
СУММА(ВЫБОР
КОГДА ХозрасчетныйОстаткиИОбороты.Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.АмортизацияОС_01)
ТОГДА ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокКт
ИНАЧЕ 0
КОНЕЦ) КАК Амортизация,
ЗначенияСвойств.Значение КАК ЗначениеСвойства
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
&НачалоПериода,
&КонецПериода,
Месяц, // Здесь задается периодичность для динамики
,
Счет В (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновныеСредства), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.АмортизацияОС_01)),
,
) КАК ХозрасчетныйОстаткиИОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойств
ПО ЗначенияСвойств.Объект = ХозрасчетныйОстаткиИОбороты.Субконто1
СГРУППИРОВАТЬ ПО
ХозрасчетныйОстаткиИОбороты.Субконто1,
ЗначенияСвойств.Значение
ИТОГИ ПО
ОС
Если бухгалтер хочет видеть не просто итоги, а именно динамику изменения амортизации по месяцам, нам нужно использовать параметр Периодичность в виртуальной таблице. В примере выше мы указали Месяц.
Теперь в выборку можно добавить поле Период. Это позволит в настройках СКД (на закладке «Настройки») добавить группировку по периоду в колонки отчета. В результате получится кросс-таблица, где в строках будут основные средства, а в колонках — месяцы с суммами начисленной амортизации.
Важно различать показатели:
СуммаОборотКт — это то, что было начислено за конкретный месяц.СуммаКонечныйОстатокКт — это накопленная амортизация на конец каждого месяца.Чтобы не писать сложный код обработки дат в модуле, лучше всего перенести логику в саму схему компоновки данных. Рассмотрим, как это сделать:
1. Настройка параметров: Создаем параметр ПериодОтчета с типом СтандартныйПериод. Для стандартных параметров виртуальной таблицы &НачалоПериода и &КонецПериода устанавливаем ограничение доступности (чтобы пользователь их не видел) и прописываем выражения:
&НачалоПериода: &ПериодОтчета.ДатаНачала&КонецПериода: &ПериодОтчета.ДатаОкончания2. Использование характеристик: Если отчет должен выводить свойства объектов (как в сообщении 1), в СКД это лучше настраивать через вкладку «Характеристики». Это позволит пользователю самому выбирать нужные свойства в настройках, не переписывая запрос.
Мы выяснили, что для перевода отчета на периодическую основу недостаточно просто добавить вторую дату. Необходимо сменить тип виртуальной таблицы на ОстаткиИОбороты, корректно обработать объект СтандартныйПериод и настроить группировки по времени. Такой подход не только решит задачу бухгалтера по анализу динамики, но и сделает отчет более производительным и гибким в настройке.