Как в 1С:Бухгалтерия 3.0 КОРП настроить закрытие счета 25 только на счет 20, исключая счет 23

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

В типовой конфигурации 1С:Бухгалтерия предприятия 3.0 КОРП механизм закрытия месяца по умолчанию распределяет общепроизводственные расходы (счет 25) между всеми подразделениями и номенклатурными группами, на которых в течение месяца были зафиксированы прямые затраты. Это касается как основного производства (счет 20.01), так и вспомогательного (счет 23.01). Однако на практике часто возникает задача исключить вспомогательные производства из базы распределения косвенных расходов, направив всю сумму 25 счета исключительно на основное производство. Разберем, как это реализовать программно, используя современные механизмы платформы.

Анализ механизма распределения в БП 3.0

Начиная с версий 3.0.102 и выше, в «1С:Бухгалтерии предприятия» используется обновленный движок распределения затрат. В отличие от старых версий, где правила жестко прописывались в процедурах проведения, новая архитектура строится на базе динамически формируемых Схем запросов. Все ключевые настройки и алгоритмы сосредоточены в общем модуле ПравилаРаспределенияРасходов.

Когда система выполняет регламентную операцию «Закрытие счетов 20, 23, 25, 26», она обращается к правилам, которые описывают, что является источником (счет 25) и что является базой (обороты 20 и 23 счетов). Наша задача — вмешаться в процесс формирования этой базы и «отсечь» лишние счета или подразделения.

Вариант 1: Ограничение через фильтрацию подразделений

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

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


// В расширении для модуля ПравилаРаспределенияРасходовМодификацияКонфигурации
&После("ПриДобавленииПравилПоСчету")
Процедура Расш1_ПриДобавленииПравилПоСчету(Процессор)
    
    // Определяем список подразделений, на которые НЕ должно идти распределение
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Подразделения.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.ПодразделенияОрганизаций КАК Подразделения
        |ГДЕ
        |   Подразделения.ЭтоВспомогательноеПроизводство = ИСТИНА"; // Пример фильтра
    
    СписокИсключений = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
    
    Если СписокИсключений.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    // Перебираем правила, сформированные системой для 25 счета
    Для Каждого Правило Из Процессор.Правила Цикл
        
        // Нас интересует только распределение с 25 счета
        Если Правило.СчетЗатрат <> ПланыСчетов.Хозрасчетный.ОбщепроизводственныеРасходы Тогда
            Продолжить;
        КонецЕсли;

        // Модифицируем схему запроса базы распределения
        СхемыЗапросов = Процессор.Настройки.Контекст.СхемыЗапросов;
        ЗапросБазы = СхемыЗапросов.НайтиЗапросСозданияТаблицы(Правило.БазаРаспределения.ТекстЗапроса, Правило.БазаРаспределения.Имя);
        
        КолонкаПодразделение = ЗапросБазы.Запрос.Колонки.Найти("Подразделение");
        
        Для Каждого Оператор Из ЗапросБазы.Запрос.Операторы Цикл
            Индекс = ЗапросБазы.Запрос.Операторы.Индекс(Оператор);
            ВыражениеПодразделение = КолонкаПодразделение.Поля[Индекс];
            
            // Добавляем условие: Подразделение НЕ В (&СписокИсключений)
            Оператор.Отбор.Добавить(СтрШаблон("NOT %1 IN (&СписокИсключений)", ВыражениеПодразделение));
        КонецЦикла;
        
        // Передаем параметры и обновляем текст
        Правило.БазаРаспределения.ПараметрыЗапроса.Вставить("СписокИсключений", СписокИсключений);
        Правило.БазаРаспределения.Имя = ""; // Сбрасываем имя для перегенерации временной таблицы
        ПравилаРаспределенияРасходов.НастроитьТекстБазыРаспределения(Правило, ЗапросБазы);
        
    КонецЦикла;
КонецПроцедуры

Вариант 2: Универсальная блокировка по счету затрат

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

Проанализируем преимущества этого подхода:

  1. Надежность: Вам не нужно следить за актуальностью списка подразделений 23 счета.
  2. Простота: Условие фильтрации сокращается до одного конкретного счета.
  3. Производительность: Запрос к базе данных отрабатывает быстрее по индексированному полю счета.

В коде это реализуется аналогично первому варианту, но вместо ВыражениеПодразделение мы ищем колонку СчетЗатрат (или СчетПрямыхЗатрат в зависимости от конкретного релиза конфигурации) и устанавливаем отбор: Оператор.Отбор.Добавить(СтрШаблон("%1 = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство)", ВыражениеСчет));.

Вариант 3: Модификация таблиц базы распределения

Существует еще одна точка входа, которую стоит рассмотреть — метод ПодготовитьТаблицыБазыРаспределения. Этот способ считается более безопасным для тех, кто не хочет глубоко погружаться в объектную модель СхемаЗапроса.

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

  1. Найдем в модуле ПравилаРаспределенияРасходов место, где формируется массив структур с описанием баз.
  2. В расширении после формирования таблицы выполним очистку:
    
    ТаблицаБазы = РезультатыЗапросов[Индекс].Выгрузить();
    МассивСтрокКУдалению = ТаблицаБазы.НайтиСтроки(Новый Структура("СчетЗатрат", ПланыСчетов.Хозрасчетный.ВспомогательныеПроизводства));
    Для Каждого Строка Из МассивСтрокКУдалению Цикл
        ТаблицаБазы.Удалить(Строка);
    КонецЦикла;
    
  3. Этот метод требует осторожности, так как необходимо корректно пересчитать доли распределения, чтобы сумма коэффициентов осталась равной 1 (или 100%). Именно поэтому модификация самого текста запроса (Вариант 1) предпочтительнее — система сама пересчитает итоги на основе отфильтрованных данных.

Важные замечания и рекомендации

При внесении изменений в механизм распределения затрат необходимо учитывать специфику учета в КОРП-версии:

  1. Очередность закрытия: Убедитесь, что на 23 счете не возникнет «зависшего» сальдо. Если по учетной политике 23 счет должен был принимать часть затрат 25 счета для корректного формирования себестоимости своих услуг, то после вашей доработки себестоимость услуг вспомогательного производства будет занижена, а основного — завышена.
  2. Итерационный расчет: Программа может выполнять расчет себестоимости в несколько проходов (итераций). Ваше расширение должно стабильно работать на каждой итерации.
  3. Обновления: Поскольку вы используете &После или &Вместо для процедур в общем модуле, при обновлении конфигурации обязательно проверяйте, не изменилась ли структура параметров в ПриДобавленииПравилПоСчету. Разработчики 1С часто оптимизируют этот узел.

Таким образом, использование расширения для модификации СхемыЗапросов в модуле ПравилаРаспределенияРасходов является наиболее современным и правильным способом решения задачи. Это позволяет гибко управлять потоками затрат, не нарушая целостность типового решения и сохраняя возможность легкого обновления программы.

← На главную