Как правильно рассчитать итоги по строкам в СКД 1С при использовании вычисляемых полей с делением?

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

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

Представьте, что мы формируем отчет по произведенной продукции, где для каждого дня и сотрудника вычисляется объем продукции, приходящийся на одного человека. Формула для детальной строки может выглядеть как Товары.Количество / Смена. Однако, когда мы пытаемся получить общий итог за период, СКД по умолчанию может посчитать не сумму значений по дням, а общий объем продукции за период, деленный на общее число смен (или какое-то другое агрегированное значение параметра "Смена"). Это приводит к искажению итоговых данных, поскольку Сумма(Товары.Количество / Смена) не равно Сумма(Товары.Количество) / Сумма(Смена).

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

Почему стандартные итоги в СКД могут быть неверными для вычисляемых полей?

Когда мы определяем вычисляемое поле в СКД, например, КоличествоНаСотрудника = Товары.Количество / Смена, и затем указываем его в ресурсах, СКД по умолчанию применяет агрегатные функции (такие как Сумма, Среднее и т.д.) к исходным полям, а затем выполняет операции над агрегированными значениями. Это означает, что при расчете общего итога по нашему полю КоличествоНаСотрудника, СКД может попытаться сделать следующее:

  1. Сначала просуммировать все значения Товары.Количество за весь период.
  2. Затем просуммировать все значения Смена (количество человек) за весь период.
  3. И только после этого разделить первую сумму на вторую: Сумма(Товары.Количество) / Сумма(Смена).

Такой подход даст верный результат только в очень специфических случаях (например, если Смена всегда равна 1 или не меняется). Но в нашей задаче, где количество людей в смене может быть разным в разные дни, мы ожидаем, что СКД сначала рассчитает Товары.Количество / Смена для каждого дня (или каждой детальной записи), а затем просуммирует эти уже рассчитанные дневные (или детальные) значения. Именно для решения таких сценариев нам на помощь приходит мощная функция СКД — ВычислитьВыражениеСГруппировкойМассив.

Использование функции ВычислитьВыражениеСГруппировкойМассив для корректного расчета итогов

Функция ВычислитьВыражениеСГруппировкойМассив специально разработана для выполнения расчетов на более детальном уровне группировки, а затем агрегации этих промежуточных результатов. Это именно то, что нам нужно для получения правильных итогов по нашему полю.

Давайте рассмотрим подробнее синтаксис и применение этой функции.

Синтаксис функции:


ВычислитьВыражениеСГруппировкойМассив(<Выражение>, <ВыражениеПолейГруппировки>, <ОтборЗаписей>, <ОтборГруппировок>)

Для нашей задачи нас будут интересовать первые два параметра:

  1. <Выражение>: Это строка, содержащая выражение, которое должно быть вычислено для каждого элемента промежуточной группировки. Важно отметить, что это выражение выполняется в контексте более глубокой группировки, поэтому внутри него можно использовать агрегатные функции, которые будут работать для этой промежуточной группировки. В нашем случае, мы хотим получить количество продукции на одного сотрудника за каждый день, поэтому наше выражение будет "Сумма(Товары.Количество/Смена)". Обратите внимание на наличие Сумма() внутри выражения – она агрегирует значения Товары.Количество/Смена по самой глубокой доступной группировке (в нашем случае, по дням).
  2. <ВыражениеПолейГруппировки>: Это поле или список полей, по которым будет формироваться промежуточная группировка. Для каждого уникального значения этих полей будет вычислено <Выражение>, и результаты будут собраны в массив. В нашем примере, где мы хотим суммировать ежедневные показатели, таким полем будет "Дата".

Функция ВычислитьВыражениеСГруппировкойМассив возвращает массив значений. Чтобы получить единый итоговый результат (например, общую сумму), нам необходимо обернуть эту функцию в соответствующую агрегатную функцию, в нашем случае — Сумма().

Пошаговое решение проблемы на примере

Рассмотрим, как мы можем применить эту функцию для исправления расчета итогов в нашем отчете по сдельной зарплате:

Шаг 1: Определяем требуемый ресурс

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

Шаг 2: Формируем выражение для ресурса

Мы хотим, чтобы для каждого дня СКД сначала вычислила Товары.Количество / Смена, а затем для каждого сотрудника просуммировала эти дневные результаты. С учетом специфики работы ВычислитьВыражениеСГруппировкойМассив, финальное выражение для нашего ресурса будет выглядеть так:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(Товары.Количество/Смена)", "Дата"))
  1. "Сумма(Товары.Количество/Смена)": Это внутреннее выражение. Оно говорит СКД: "Для каждой записи, сгруппированной по полю 'Дата' (следующий параметр), вычисли сумму значений 'Количество/Смена'". Если у нас в один день может быть несколько записей с одинаковым количеством людей в смене, это выражение сначала вычислит результат деления для каждой из них, а затем просуммирует их для данного дня.
  2. "Дата": Это поле, по которому происходит промежуточная группировка. СКД сначала сгруппирует все данные по полю Дата, для каждой уникальной даты выполнит внутреннее выражение "Сумма(Товары.Количество/Смена)", и соберет полученные ежедневные итоги в массив.
  3. Сумма(...): Внешняя функция Сумма. Она получает массив ежедневных итогов (который вернула ВычислитьВыражениеСГруппировкойМассив) и суммирует все элементы этого массива. Таким образом, мы получаем корректный общий итог за весь период, который является суммой корректно рассчитанных ежедневных значений.

Шаг 3: Настраиваем ресурс в СКД

Для применения данного выражения необходимо выполнить следующие шаги в настройках СКД:

  1. Перейдите на вкладку "Ресурсы" в настройках отчета СКД.
  2. Создайте новый ресурс (если его еще нет) или измените существующий, который соответствует вашему полю ПродукцияНаСотрудника.
  3. В колонке "Выражение" для этого ресурса укажите полную конструкцию:
    
    Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(Товары.Количество/Смена)", "Дата"))
    
  4. В колонке "Рассчитывать по" убедитесь, что выбраны те группировки, по которым должен производиться расчет итогов. Если вы хотите видеть общий итог для каждого сотрудника за весь период, а также итоги по другим, более высоким группировкам, установите соответствующую настройку. Например, для получения общего итога по сотруднику за период, мы бы отметили группировку "Сотрудник" и "Общий итог".

После применения этих настроек, СКД будет сначала корректно вычислять долю продукции на человека для каждого дня, а затем суммировать эти дневные значения, предоставляя вам точный общий итог за весь отчетный период.

Пример из практики и подтверждение решения

В ходе обсуждения на форуме пользователи столкнулись с проблемой, когда стандартный расчет давал 383,33, в то время как ожидаемый результат по сумме ежедневных данных составлял 335. После применения предложенного выражения ВычислитьВыражениеСГруппировкойМассив("Сумма(Товары.Количество/Смена)", "Дата"), пользователь получил массив ежедневных значений, таких как "24; 31; 27; 31; 19; 26; 87; 48,333333333333333333333333333; 17; 73". После суммирования этих значений, итоговая сумма совпала с ожидаемой, что подтверждает правильность данного подхода. Некоторая путаница изначально возникла из-за особенностей отображения чисел в Excel, но в итоге было установлено, что расчет в 1С был верным.

Важные моменты и советы

  1. Кавычки в выражениях: Всегда заключайте в кавычки строковые литералы и имена полей внутри функций ВычислитьВыражениеСГруппировкойМассив. Например, "Дата" и "Сумма(Товары.Количество/Смена)".
  2. Уровень агрегации: Будьте внимательны к тому, какие агрегатные функции вы используете внутри <Выражения> (например, Сумма(), Среднее()) и какая функция агрегирует массив (внешняя Сумма()). Это определяет логику ваших расчетов.
  3. Тестирование: После изменения выражений ресурсов всегда тщательно тестируйте отчет, сравнивая его с данными, рассчитанными вручную или в других системах, чтобы убедиться в корректности итогов на разных уровнях группировки.

Таким образом, функция ВычислитьВыражениеСГруппировкойМассив является мощным инструментом в арсенале разработчика 1С, позволяющим решать сложные задачи по расчету ресурсов и агрегации данных в СКД, особенно когда стандартные механизмы не дают желаемого результата из-за специфики вычисляемых полей. Мы надеемся, что это подробное объяснение поможет вам создавать более точные и информативные отчеты.

← На главную