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