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