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

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

При разработке отчетов в системе «1С:Предприятие» программисты часто сталкиваются со сложной архитектурной задачей: необходимо вывести в одном отчете данные из проводок регистра бухгалтерии (например, суммы и количество) и специфическую аналитику, которая хранится только в табличной части (ТЧ) документа-регистратора (например, сведения о сотрудниках, выполнявших работу). Классический пример из практики — документ «Надой молока» в специализированных сельскохозяйственных конфигурациях, где в табличной части детально расписаны сотрудники (дояры/операторы), но в проводках по бухгалтерскому учету эта аналитика отсутствует за ненадобностью для регламентированной отчетности.

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

Почему связь по «НомерСтроки» — это критическая ошибка?

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

  1. Разная природа поля «НомерСтроки». В табличной части документа НомерСтроки — это жесткий порядковый индекс строки на форме (1, 2, 3...). В регистре бухгалтерии поле НомерСтроки — это системный номер записи (проводки) в конкретном наборе движений по данному регистратору. Они генерируются независимо друг от друга.
  2. Сворачивание движений при проведении. Стандартные алгоритмы проведения документов в целях оптимизации размера базы данных и производительности часто группируют (сворачивают) строки табличной части с одинаковой номенклатурой, счетами учета и субконто. Если в табличной части документа у вас введено 10 строк по одной номенклатуре (но с разными работниками), при проведении программа может сформировать всего одну сводную проводку в регистр бухгалтерии. В этом случае связать строки по номеру «один к одному» физически невозможно.
  3. Ручные корректировки проводок. Бухгалтеры часто используют типовой механизм ручной корректировки движений (активируя флаг «Ручная корректировка»). При этом пользователь может вручную удалить проводку, добавить новую в середину списка или поменять их местами. После этого номера строк в регистре окончательно перестанут соответствовать номерам строк в документе. Отчет начнет сопоставлять данные случайным образом, привязывая суммы к неверным сотрудникам.
  4. Несколько табличных частей. Если документ содержит несколько ТЧ (например, «Товары» и «Услуги»), проводки по ним записываются в один регистр последовательно. Номера строк проводок для второй табличной части гарантированно начнутся со смещением и не совпадут с номерами строк самой ТЧ.

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

Решение 1. Метод пропорционального распределения в запросе СКД (без изменения конфигурации)

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

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

Разберем этот алгоритм по шагам в терминах языка запросов 1С:

Шаг 1. Получение итогов из регистра бухгалтерии. Сначала мы выбираем реальные суммы и количество, отраженные в учете, сгруппированные по регистратору и номенклатуре.

Шаг 2. Расчет общего количества по этой же номенклатуре в документе. Мы считаем суммарное количество по номенклатуре в табличной части документа, чтобы понять общий объем.

Шаг 3. Вычисление коэффициента (доли) строки. Для каждой строки табличной части мы делим количество строки конкретного сотрудника на общее количество по этой номенклатуре в документе.

Шаг 4. Расчет итоговых показателей. Умножаем реальную сумму и количество из регистра бухгалтерии на полученный коэффициент.

Посмотрим на пример реализации такого запроса:


ВЫБРАТЬ
    ТЧ.Ссылка КАК Регистратор,
    ТЧ.Номенклатура КАК Номенклатура,
    ТЧ.Работник КАК Работник,
    ТЧ.Количество КАК КоличествоВДокументе,
    СуммыДокумента.ВсегоКоличествоВДокументе КАК ВсегоКоличествоВДокументе
ПОМЕСТИТЬ ВТ_ДанныеДокумента
ИЗ
    Документ.НадойМолока.Продукция КАК ТЧ
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Ссылка КАК Ссылка,
            Номенклатура КАК Номенклатура,
            СУММА(Количество) КАК ВсегоКоличествоВДокументе
        ИЗ
            Документ.НадойМолока.Продукция
        ГРУППИРОВАТЬ ПО
            Ссылка,
            Номенклатура
    ) КАК СуммыДокумента ПО ТЧ.Ссылка = СуммыДокумента.Ссылка 
    И ТЧ.Номенклатура = СуммыДокумента.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Проводки.Регистратор КАК Регистратор,
    Проводки.Субконто1 КАК Номенклатура,
    СУММА(Проводки.Количество) КАК КоличествоБух,
    СУММА(Проводки.Сумма) КАК СуммаБух
ПОМЕСТИТЬ ВТ_ДанныеБухгалтерии
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК Проводки
ГДЕ
    Проводки.Регистратор ССЫЛКА Документ.НадойМолока
ГРУППИРОВАТЬ ПО
    Проводки.Регистратор,
    Проводки.Субконто1
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_ДанныеДокумента.Регистратор КАК Регистратор,
    ВТ_ДанныеДокумента.Номенклатура КАК Номенклатура,
    ВТ_ДанныеДокумента.Работник КАК Работник,
    // Распределяем количество пропорционально
    ВЫБОР 
        КОГДА ВТ_ДанныеДокумента.ВсегоКоличествоВДокументе = 0 ТОГДА 0
        ИНАЧЕ (ВТ_ДанныеДокумента.КоличествоВДокументе / ВТ_ДанныеДокумента.ВсегоКоличествоВДокументе) * ЕСТЬNULL(ВТ_ДанныеБухгалтерии.КоличествоБух, 0)
    КОНЕЦ КАК Количество,
    // Распределяем сумму пропорционально
    ВЫБОР 
        КОГДА ВТ_ДанныеДокумента.ВсегоКоличествоВДокументе = 0 ТОГДА 0
        ИНАЧЕ (ВТ_ДанныеДокумента.КоличествоВДокументе / ВТ_ДанныеДокумента.ВсегоКоличествоВДокументе) * ЕСТЬNULL(ВТ_ДанныеБухгалтерии.СуммаБух, 0)
    КОНЕЦ КАК Сумма
ИЗ
    ВТ_ДанныеДокумента КАК ВТ_ДанныеДокумента
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДанныеБухгалтерии КАК ВТ_ДанныеБухгалтерии 
        ПО ВТ_ДанныеДокумента.Регистратор = ВТ_ДанныеБухгалтерии.Регистратор
        И ВТ_ДанныеДокумента.Номенклатура = ВТ_ДанныеБухгалтерии.Номенклатура

Преимущества метода: Полная безопасность для обновлений. База остается абсолютно типовой. Метод корректно обрабатывает ситуации, когда бухгалтер вручную скорректировал общую сумму проводки — измененная сумма все равно распределится по сотрудникам согласно их доле в документе.

Недостатки метода: Запрос получается достаточно ресурсоемким, особенно при больших объемах данных. Кроме того, при очень сложных ручных корректировках (например, если бухгалтер полностью заменил номенклатуру в проводках на другую) распределение может дать сбой из-за отсутствия совпадений по ключевым полям.

Решение 2. Архитектурный стандарт «Ключ связи» через расширение

Если конфигурация поддерживает механизм расширений (что является стандартом для современных версий платформы «1С:Предприятие 8.3»), мы можем применить архитектурное решение, которое используется самой фирмой «1С» во всех современных типовых конфигурациях (ERP, Комплексная автоматизация, Управление торговлей).

Этот метод основан на генерации уникального идентификатора для каждой строки табличной части и последующей передаче этого идентификатора в проводки регистра.

Рассмотрим по шагам, как реализовать этот механизм:

  1. Добавление реквизита в табличную часть. Через расширение конфигурации добавьте в табличную часть документа «Надой молока» реквизит КлючСвязи с типом Число (длина 10, без знака) или УникальныйИдентификатор.
  2. Добавление реквизита в регистр бухгалтерии. В расширении добавьте аналогичный реквизит (или измерение, если по нему требуется быстрый отбор) КлючСвязиСтроки в Регистр бухгалтерии «Хозрасчетный».
  3. Заполнение ключей связи при редактировании документа. Нам необходимо гарантировать, что при добавлении строк в табличную часть у каждой строки будет уникальный номер. Для этого в модуле формы документа переопределим события ПриЗаписи или напишем обработчик в модуле объекта:

&Перед("ПередЗаписью")
Процедура Расшир_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    МаксимальныйКлюч = 0;
    // Сначала найдем максимальный существующий ключ, чтобы не дублировать
    Для Каждого СтрокаТЧ Из ЭтотОбъект.Продукция Цикл
        Если СтрокаТЧ.КлючСвязи > МаксимальныйКлюч Тогда
            МаксимальныйКлюч = СтрокаТЧ.КлючСвязи;
        КонецЕсли;
    КонецЦикла;
    
    // Заполняем пустые ключи новыми уникальными значениями в рамках этого документа
    Для Каждого СтрокаТЧ Из ЭтотОбъект.Продукция Цикл
        Если СтрокаТЧ.КлючСвязи = 0 Тогда
            МаксимальныйКлюч = МаксимальныйКлюч + 1;
            СтрокаТЧ.КлючСвязи = МаксимальныйКлюч;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры
  1. Трансляция ключа связи в проводки. В процедуре проведения документа (которую мы также переопределяем в расширении в режиме &После или &Вместо) при формировании набора записей регистра бухгалтерии в каждую проводку записывается соответствующий КлючСвязиСтроки из строки табличной части, на основании которой создана проводка.
  2. Построение отчета. Теперь в запросе СКД соединение табличной части документа и регистра бухгалтерии становится тривиальной задачей. Мы связываем их по условию:

ПО ТЧ.Ссылка = Движения.Регистратор 
И ТЧ.КлючСвязи = Движения.КлючСвязиСтроки

Преимущества метода: Это наиболее надежный и профессиональный способ связи. Он гарантирует абсолютную точность сопоставления даже при наличии абсолютно одинаковых строк с разной аналитикой. При ручной корректировке движений (если программист позаботился о выводе поля КлючСвязиСтроки на форму ручной корректировки движений) связь также не теряется.

Недостатки метода: Требуется небольшое программирование в расширении и добавление новых реквизитов в структуру данных.

Решение 3. Использование забалансового счета (без программирования метаданных)

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

Если нам нужно собирать аналитику по сотрудникам, почему бы не отражать ее на забалансовом счете? Рассмотрим, как это сделать:

  1. В режиме «1С:Предприятие» (в пользовательском интерфейсе, без Конфигуратора) бухгалтер открывает План счетов и добавляет новый забалансовый счет (например, счет «МС» — Материалы сотрудников, или любой другой свободный код).
  2. На этом забалансовом счете настраиваются два субконто: Номенклатура и Физические лица (или Сотрудники). Также включается ведение количественного и суммового учета.
  3. Поскольку конфигурация типовая, нам все же потребуется заставить документ «Надой молока» делать проводки по этому счету. Для этого используется расширение, в котором переопределяется только алгоритм проведения документа: при проведении, помимо основных проводок по балансовым счетам (например, 20 или 43), программа делает вспомогательную проводку в дебет нашего нового забалансового счета, куда детально переносит каждую строку табличной части с указанием конкретного работника.
  4. Отчет в СКД теперь строится невероятно просто — исключительно по виртуальной таблице РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт или Обороты по нашему забалансовому счету. Никаких соединений табличной части документов и регистров больше делать не нужно!

Преимущества метода: Чистота архитектуры. Данные хранятся в единой базе движений бухгалтерии. Исключены любые расхождения между «документом» и «регистром», поскольку вся информация извлекается из одного источника (оборотов забалансового счета). Бухгалтер может легко проверить правильность отчета стандартными отчетами (Оборотно-сальдовая ведомость по счету).

Резюме и рекомендации

Подводя итоги нашего анализа, выделим оптимальные сценарии для применения каждого метода:

← На главную