При разработке отчетов для конфигурации «1С:Бухгалтерия предприятия 8.3» программисты часто сталкиваются с ловушкой: попыткой использовать привычные для торговых решений (УТ, КА, ERP) регистры накопления. Однако в бухгалтерской конфигурации структура данных иная. В этой статье мы разберем, как правильно получить данные о 15 самых продаваемых позициях за период, вычислить их себестоимость, среднюю цену и подтянуть розничные цены из регистров сведений.
Рассмотрим распространенную ошибку, упомянутую в обсуждении. В типовой «Бухгалтерии предприятия» отсутствует регистр накопления Продажи. Все движения товаров и отражение выручки проходят через План счетов и записываются в основной регистр бухгалтерии — Хозрасчетный.
Для решения нашей задачи мы проанализируем следующие счета:
Выясним причину популярности товаров. Самые продаваемые позиции определяются по оборотам счета 90.02. Нам потребуется виртуальная таблица Обороты регистра бухгалтерии Хозрасчетный.
Проанализируем пример кода для получения первичного списка ТОП-15:
ВЫБРАТЬ ПЕРВЫЕ 15
ХозрасчетныйОбороты.Субконто1 КАК Номенклатура,
СУММА(ХозрасчетныйОбороты.КоличествоОборотДт) КАК КоличествоПродано,
СУММА(ХозрасчетныйОбороты.СуммаОборотДт) КАК СебестоимостьИтого
ПОМЕСТИТЬ ВТ_ТопПродаж
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.СебестоимостьПродаж), , , , ) КАК ХозрасчетныйОбороты
СГРУППИРОВАТЬ ПО
ХозрасчетныйОбороты.Субконто1
УПОРЯДОЧИТЬ ПО
КоличествоПродано УБЫВ
;
Важный нюанс: В «Бухгалтерии предприятия» Субконто1 на счетах 90-й группы обычно соответствует справочнику Номенклатура. Однако всегда проверяйте настройки плана счетов в конкретной информационной базе.
Теперь нам нужно дополнить данные суммой выручки, чтобы вычислить среднюю цену продажи. Мы присоединим данные со счета 90.01 к нашей временной таблице. Рассмотрим, как избежать ошибки деления на ноль при расчете цены.
ВЫБРАТЬ
Топ.Номенклатура,
Топ.КоличествоПродано,
Топ.СебестоимостьИтого,
ЕСТЬNULL(Выручка.СуммаОборотКт, 0) КАК СуммаВыручки,
ВЫБОР
КОГДА Топ.КоличествоПродано = 0 ТОГДА 0
ИНАЧЕ ЕСТЬNULL(Выручка.СуммаОборотКт, 0) / Топ.КоличествоПродано
КОНЕЦ КАК СредняяЦенаПродажи
ИЗ
ВТ_ТопПродаж КАК Топ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Выручка), , , , ) КАК Выручка
ПО Топ.Номенклатура = Выручка.Субконто1
Розничная цена в 1С хранится в периодическом регистре сведений ЦеныНоменклатуры. Чтобы получить цену на конкретную дату, мы воспользуемся виртуальной таблицей СрезПоследних. Поскольку нам нужны две разные даты (начало и конец), мы обратимся к этой таблице дважды с разными параметрами времени.
Разберем структуру соединения:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&НачалоПериода, ТипЦен = &ТипЦенРозничная) КАК ЦеныНаНачало
ПО Топ.Номенклатура = ЦеныНаНачало.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.SрезПоследних(&КонецПериода, ТипЦен = &ТипЦенРозничная) КАК ЦеныНаКонец
ПО Топ.Номенклатура = ЦеныНаКонец.Номенклатура
Соберем все части воедино. Проанализируем финальную структуру запроса, который выдаст нам требуемые 15 позиций с учетом специфики 1С:Бухгалтерии:
ВЫБРАТЬ ПЕРВЫЕ 15
ХозрасчетныйОбороты.Субконто1 КАК Номенклатура,
СУММА(ХозрасчетныйОбороты.КоличествоОборотДт) КАК КоличествоПродано,
СУММА(ХозрасчетныйОбороты.СуммаОборотДт) КАК СебестоимостьИтого
ПОМЕСТИТЬ ВТ_Топ
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.СебестоимостьПродаж), , , , ) КАК ХозрасчетныйОбороты
СГРУППИРОВАТЬ ПО
ХозрасчетныйОбороты.Субконто1
УПОРЯДОЧИТЬ ПО
КоличествоПродано УБЫВ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Топ.Номенклатура КАК Номенклатура,
ВТ_Топ.КоличествоПродано КАК Количество,
ВТ_Топ.СебестоимостьИтого КАК СуммарнаяСебестоимость,
ВЫБОР
КОГДА ВТ_Топ.КоличествоПродано = 0 ТОГДА 0
ИНАЧЕ ЕСТЬNULL(ОборотыВыручка.СуммаОборотКт, 0) / ВТ_Топ.КоличествоПродано
КОНЕЦ КАК СредняяЦенаПродажи,
ЕСТЬNULL(ЦенаНаНачало.Цена, 0) КАК РозничнаяЦенаНаНачало,
ЕСТЬNULL(ЦенаНаКонец.Цена, 0) КАК РозничнаяЦенаНаКонец
ИЗ
ВТ_Топ КАК ВТ_Топ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Выручка), , , , ) КАК ОборотыВыручка
ПО ВТ_Топ.Номенклатура = ОборотыВыручка.Субконто1
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&НачалоПериода, ТипЦен = &ТипЦенРозничная) КАК ЦенаНаНачало
ПО ВТ_Топ.Номенклатура = ЦенаНаНачало.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&КонецПериода, ТипЦен = &ТипЦенРозничная) КАК ЦенаНаКонец
ПО ВТ_Топ.Номенклатура = ЦенаНаКонец.Номенклатура
Для того чтобы отчет работал корректно и данные были достоверными, обратим внимание на несколько технических моментов:
&ТипЦенРозничная ссылку на конкретный элемент справочника ТипыЦенНоменклатуры. В противном случае срез последних может вернуть непредсказуемое значение, если для товара задано несколько типов цен.Субконто2 в группировку и условия соединений, чтобы не «схлопнуть» продажи разных видов одного товара.Таким образом, мы рассмотрели, как обойти отсутствие торговых регистров в бухгалтерии и получить качественную аналитику продаж, используя возможности бухгалтерского регистра и срезов цен.