Как в запросе получить список сотрудников и товаров из документа «Реализация товаров списку ФЛ»?

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

При работе в специализированных конфигурациях, таких как «1С:Бухгалтерия сельскохозяйственного предприятия» (БСХП), разработчики часто сталкиваются с необходимостью извлечь данные из документов, имеющих сложную структуру. Одной из таких задач является получение связки «Сотрудник — Номенклатура — Сумма» из документа схРеализацияТоваровСпискуФЛ. Сложность здесь заключается в том, что информация разнесена по разным табличным частям, которые не всегда имеют прямую логическую связь «строка к строке».

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

Анализ проблемы: почему не работает простое соединение?

Рассмотрим типичную ошибку, которую совершают начинающие разработчики при написании запроса к документу. Попытка сравнить поле Сотрудник из одной таблицы с полем Ссылка или Номенклатура из другой таблицы заведомо обречена на провал. Проанализируем причину:

  1. Несовпадение типов данных: Поле Сотрудник имеет тип СправочникСсылка.Сотрудники, в то время как Номенклатура — это СправочникСсылка.Номенклатура. Система 1С никогда не приравняет ссылку на человека к ссылке на товар, поэтому условие ПО ТЧ1.Сотрудник = ТЧ2.Номенклатура всегда будет возвращать Ложь (и NULL при левом соединении).
  2. Связь через Ссылку на документ: Если мы попробуем соединить таблицы по полю Ссылка (которое в обеих ТЧ указывает на сам документ-владелец), мы получим так называемое декартово произведение в рамках одного документа.

Проанализируем ситуацию на примере. Допустим, в документе в таблице «Товары» указаны «Дизель» и «Бензин», а в таблице «Контрагенты» — «Иванов» и «Петров». При соединении по Ссылка = Ссылка запрос выдаст четыре строки: Иванов купил Дизель, Иванов купил Бензин, Петров купил Дизель, Петров купил Бензин. Если в ТЧ «Контрагенты» указана сумма долга, то при таком соединении общая сумма в отчете увеличится в два раза, так как она продублируется для каждой строки номенклатуры.

Вариант 1. Использование Ключа связи

Прежде чем переходить к сложным запросам, проверим структуру документа схРеализацияТоваровСпискуФЛ в конфигураторе. В современных решениях на базе 1С:БСП и ERP-подобных систем часто используется скрытый реквизит КлючСвязи (обычно числового типа). Он предназначен специально для того, чтобы связать строку из ТЧ «Товары» со строкой из ТЧ «Контрагенты».

Если такой реквизит есть, наш запрос будет выглядеть следующим образом:


ВЫБРАТЬ
    ТЧ_Контрагенты.Сотрудник КАК Сотрудник,
    ТЧ_Контрагенты.Сумма КАК Сумма,
    ТЧ_Товары.Номенклатура КАК Номенклатура
ИЗ
    Документ.схРеализацияТоваровСпискуФЛ.Контрагенты КАК ТЧ_Контрагенты
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.схРеализацияТоваровСпискуФЛ.Товары КАК ТЧ_Товары
    ПО ТЧ_Контрагенты.Ссылка = ТЧ_Товары.Ссылка
    И ТЧ_Контрагенты.КлючСвязи = ТЧ_Товары.КлючСвязи

Важно: Если в данной конфигурации (БСХП 3.0) КлючСвязи отсутствует, это означает, что документ реализует схему «распределения»: общая сумма реализованных товаров просто делится (или фиксируется) между списком сотрудников без детализации, кто именно какой товар забрал.

Вариант 2. Получение данных из регистров накопления

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

Рассмотрим, какие регистры могут быть полезны в БСХП:

Посмотрим на пример запроса к регистру накопления (предположим, что это типовой регистр «Продажи», адаптированный в БСХП):


ВЫБРАТЬ
    Продажи.Регистратор.Сотрудник КАК Сотрудник,
    Продажи.Номенклатура КАК Номенклатура,
    Продажи.СуммаВыручки КАК Сумма
ИЗ
    РегистрНакопления.Продажи КАК Продажи
ГДЕ
    Продажи.Регистратор ССЫЛКА Документ.схРеализацияТоваровСпискуФЛ
    И Продажи.Регистратор = &СсылкаНаДокумент

Если же информация о сотруднике хранится только в одной из табличных частей, а в регистре продаж его нет, нам придется использовать Регистр Бухгалтерии. Проанализируем ситуацию: на счете 70 (Расчеты с персоналом по оплате труда) в качестве субконто выступает РаботникОрганизации.

Вариант 3. Использование временных таблиц для распределения сумм

Если нам критично работать именно с документом (например, документ еще не проведен), а прямой связи между строками нет, мы можем прибегнуть к методу временных таблиц. Рассмотрим по шагам, как это реализовать:

  1. Выгрузим во временную таблицу список сотрудников и их долю в общей сумме документа.
  2. Выгрузим во вторую временную таблицу список товаров.
  3. Соединим их по полю Ссылка.

Этот метод допустим только в том случае, если бизнес-логика документа подразумевает, что каждый сотрудник из списка причастен к каждой позиции номенклатуры в указанной пропорции. Посмотрим на пример кода:


ВЫБРАТЬ
    ТЧ_Контрагенты.Сотрудник КАК Сотрудник,
    ТЧ_Контрагенты.Сумма КАК СуммаСотрудника,
    ТЧ_Контрагенты.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_Сотрудники
ИЗ
    Документ.схРеализацияТоваровСпискуФЛ.Контрагенты КАК ТЧ_Контрагенты
ГДЕ
    ТЧ_Контрагенты.Ссылка = &Ссылка;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЧ_Товары.Номенклатура КАК Номенклатура,
    ТЧ_Товары.Ссылка КАК Ссылка
ИЗ
    Документ.схРеализацияТоваровСпискуФЛ.Товары КАК ТЧ_Товары
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Сотрудники КАК ВТ_Сотрудники
    ПО ТЧ_Товары.Ссылка = ВТ_Сотрудники.Ссылка

Внимание: Помните о проблеме дублирования сумм! Если вы используете ИТОГИ СУММА(Сумма), то при таком соединении итоговая сумма по документу будет неверной. Чтобы этого избежать, сумму нужно брать либо только из одной таблицы, либо рассчитывать её пропорционально весу каждой строки.

Подведение итогов

Для решения задачи в БСХП 3.0 мы рекомендуем следующий алгоритм действий:

Используя эти методы, мы сможем построить надежный отчет или печатную форму, которая будет корректно отображать данные реализации товаров сотрудникам в счет заработной платы.

← На главную