Подробное описание работы механизма расчета себестоимости в программах начиная с версии ERP 2.1.3 (и соответствующих ей версий КА и УТ)

Управление - Теория учета

Зачастую, когда встаёт вопрос о валовой прибыли предприятия, то большой проблемой становится корректная оценка себестоимости товаров. Для того, чтобы программисту было понятно, как программа рассчитывает себестоимость, нужно понимать алгоритмы, которых придерживались разработчики. Данная статья описывает, как это работает в актуальных (начиная с версии ERP 2.1.3 (и соответствующих ей версий КА и УТ)) версиях программы, и наиболее полезна для программиста. Данные алгоритмы описаны разработчиками в комментариях расчета себестоимости.

Механизм оффлайнового (неоперативного) расчета себестоимости, движения по регистрам себестоимости, общая информация.

Начиная с версии ERP 2.1.3 (и соответствующих ей версий КА и УТ) различаются два типа движения:

  • "первичные" - формируемые в соответствии с логикой документов при их проведении;
  • "расчетные" - формируемые данным механизмом (идентификатором типа движения является новый реквизит "РасчетСебестоимости" регистров накопления).

Список регистров, обслуживаемых механизмом расчета себестоимости, см. в ИсходящиеДанныеМеханизма()

Регистратором расчетных движений теперь является первичный документ (из реквизита ДокументДвижения), а не документ РасчетСебестоимостиТоваров. Документ РасчетСебестоимостиТоваров больше не делает движений по следующим регистрам: ВыручкаИСебестоимостьПродаж, Закупки, ПрочиеРасходыНезавершенногоПроизводства (есть только в ERP и КА) (документ остается регистратором для этих регистров для обратной совместимости).

При перепроведении документов расчетные движения сохраняются, независимо от внесенных в документ изменений (Для этого в модуле набор записей обслуживаемых регистров размещен специальный код. Для примера см. модуль регистра накопления СебестоимостьТоваров - вызовы процедур этого модуля.). Изменения в документе будут учтены в расчетных движениях при перерасчете себестоимости.

Начиная с версии ERP 2.1.3 изменился алгоритм формирования и записи движений.
Теперь по каждому обслуживаемому механизмом регистру движения формируются следующим образом:

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

Данные изменения позволяют:

  • посмотреть себестоимость по документу из самого документа - отчетом "Движения документа";
  • при перерасчете себестоимости перезаписывать только реально измененные расчетные движения;
  • регистрировать к отражению в учете только документы с перезаписанными движениями (в ERP и КА).


Переход на версию ERP 2.1.3 (и соответствующие ей версии КА2 и УТ11)

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


 Запуск расчета себестоимости.

Точкой входа в алгоритм расчета является процедура РассчитатьВсе() в которую предаются параметры:

  • период расчета - месяц;
  • возможен "облегченный" предварительный расчет себестоимости - позволяет формировать некоторые отчеты (если за указанный период уже был выполнен фактический расчет, то предварительный расчет выполняться не будет);
  • расчет выполняется или по указанному массиву организаций, или по всем организациям, связанным с указанной организацией по схеме Интеркампани (см. СвязиОрганизацийПоСхемеИнтеркампани()):
    • если организация для расчета не указана, то будет выполнен расчет по всем организациям, имеющим в указанном периоде движения по регистрам себестоимости;
    • все организации, по которым выполняется фактический расчет, должны иметь одинаковый метод оценки стоимости запасов (см. ОпределитьМетодОценкиСтоимости());
  • запуск расчета себестоимости возможен как интерактивно (из механизма закрытия месяца), так и из регламентного задания.
 Оригинальное описание

Перед расчетом для каждой организации будет сформирован документ РасчетСебестоимостиТоваров (если его еще не было) со следующим заполнением:

  • в реквизите Организация шапки документа будет указана организация, которой принадлежит данный документ;
  • в табличной части Организации будут указаны все организации, связанные с ней по схеме Интеркампани, в т.ч. и она сама:
    • до версии ERP 2.1.3 (и соответствующих ей версий КА и УТ) такого реквизита шапки не было, а документ расчета себестоимости создавался один на всю группу организаций, связанных по схеме Интеркампани (информация о документах расчета себестоимости в разрезе организаций хранится в общих параметрах расчета - во временной таблице ВТДокументыРасчетаСебестоимости и свойстве ДокументыРасчетаПоОрганизациям).

Для выполнения расчета без падения в случае возникновении ошибки, есть функция-обертка РассчитатьВсеВПопыткеИсключении() параметры аналогичны процедуре РассчитатьВсе(), но функция возвращает значение - Булево - признак успешного выполнения расчета.


Выполнение расчета себестоимости.

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

  • выполняется инициализация общих параметров для всего алгоритма (см. ИнициализироватьПараметрыРасчета());
  • последовательно вызываются процедуры-этапы расчета (подробнее ниже)
    • некоторые этапы могут быть пропущены из-за настроек системы и/или параметров запуска расчета;
    •  результатом выполнения этапа являются сформированные расчетные движени и/или "глобальные" временные таблицы (используемые на следующих этапах);
  • выполняется запись измененных расчетных движений;
    • запись может выполняться в несколько потоков, с использованием фоновых заданий (см. свойство "МаксимальноеКоличествоФЗ");
  • выполняется отражение измененных документов в учете.


Структура этапа расчета.

Схематически процедура-этап расчета выглядит следующим образом:

  • создается запрос выборки исходных данных для этапа; заполняются его свойства; запрос выполняется;
    • если целью этапа является только формирование "глобальных" временных таблиц, дальнейшее к нему не относит;
  • по данным запроса выполняется формирование расчетных движений по регистрам расчета себестоимости;
    • некоторые этапы движений не формируют - формируют только "глобальные" временные таблицы;
    • код формирования движений вынесен в процедуры вида СформироватьДвижения<Имя регистра><Уточнение операции>();
    • внутри этих процедур для добавления движения обязательно используется процедура ДобавитьЗаписьВТаблицуДвижений();
  • удаляются "локальные" временные таблицы, используемые только внутри этапа (см. УничтожитьВременныеТаблицы());
  • сформированные движения перекладываются из таблиц значений во временные таблицы (см. КэшироватьСформированныеДвижения());
    • при этом также выполняется обновление служебных кэшей оборотов и остатков (подробнее ниже);
    • т.о. в промежутке между выборкой исходных данных и окончанием этапа обращаться к кэшам нельзя - они не актуализированы.


Обращение к данным ИБ в запросах.

Поскольку новые расчетные движения по регистрам себестоимости записываются в ИБ только в конце расчета,
то в ходе расчета при обращении к таблицам этих регистров (реальным или виртуальным) надо соблюдать некоторые правила (касается только регистров, перечисленных в ИнициализироватьРегистры()).
1. Обороты (движения) регистра за период должны получаться объединением:

  • основной таблицы регистра с отбором "Т.РасчетСебестоимости = Ложь" (первичные движения);
  • временной таблицы ВТКэш<Имя регистра> (новые расчетные движения);

Для удобства, по некоторым регистрам эти данные автоматически кэшируются во временной таблице ВТКэшЗаписи<Имя регистра>.
Список регистров указан в свойстве "РегистрыСРасчетнымиЗаписями" общих параметров расчета.

2. Остатки регистра (для регистров остатков) на конец периода должны получаться объединением:

  • остатков регистра на начало периода;
  • основной таблицы регистра с отбором "Т.РасчетСебестоимости = Ложь" (первичные движения за период);
  • временной таблицы ВТКэш<Имя регистра> (новые расчетные движения за период).

Для удобства, по некоторым регистрам эти данные автоматически кэшируются во временной таблице ВТКэшРасчетныеОстатки<Имя регистра>.
Список регистров указан в свойстве "РегистрыСРасчетнымиОстатками" общих параметров расчета.

3. Новые движения, сформированные на предыдущих этапах расчета, хранятся во временной таблице ВТКэш<Имя регистра>.
Данная временная таблица создается для всех регистров, обслуживаемые механизмом расчета себестоимости.

Также имеются ряд дополнительных особенностей работы с запросами (причины: оптимизация, платформа и т.д.).

1. Данные, используемые для отборов во всех запросах механизма расчета, хранятся 

  • в общих параметрах расчета (организации, период, значения функциональных опций и т.п.);
  • в "глобальных" временных таблицах (например, ВТОтборАналитикаПоПартнерам - см. ИнициализироватьВременныеТаблицыДляОтборов()).

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

2. Существует ошибка Платформы 30025997, в результате которой возникают проблемы с полем ВидДвижения во временных таблицах.
Для обхода ошибки во всех временных таблицах вида ВТКэш, ВТКэшЗаписи, ВТКэшРасчетныеОстатки
вместо стандартного поля ВидДвижения хранится техногенное поле СлужебноеВидДвиженияПриход с типом "Булево" алгоритм работы с ним следующий:

  • в запросах к этим временным таблицам следует обращаться только к полю СлужебноеВидДвиженияПриход;
  • в таблицах значений, в которых предварительно накапливаются новые расчетные записи, есть только стандартное поле ВидДвижения;
  • преобразование поля между таблицей значения и временной таблицей выполняется автоматически, дополнительных действий не требуется.

 
Отладка и поиск проблем.

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

  • при начале очередного этапа расчета в журнал регистрации делает запись - для отслеживания прогресса выполнения расчета;
  • при окончании расчета в журнал регистрации выводится подробный протокол расчета.

Также реализована возможность переопределения некоторых параметров расчета (см. РассчитатьВсе(), параметр ПараметрыОтладки).

P.S. Данная статья наиболее полезной будет для программистов. За её основу былим взяты комментарии программистов 1С в решении 1С: Предприятие: "Управление торговлей" редакции 11.2.3.

См. также

В этой теме еще нет сообщений.
Оставьте свое сообщение