Как правильно спроектировать документы и регистры для расчета плановой и фактической себестоимости в 1С 8.3?

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

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

Выясним причину, почему подход с фиксированными реквизитами табличной части («Сырье и материалы», «Комплектующие», «Заработная плата» и т.д.) нежизнеспособен. Если завтра на предприятии появится новый вид расходов, например, «Аренда оборудования» или «Логистика», вам придется полностью перестраивать структуру метаданных, переписывать код проведения документов и переделывать все отчеты. Разберем по шагам, как построить гибкую, масштабируемую и профессиональную архитектуру базы данных.

Шаг 1. Проектирование гибкой структуры справочников

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

  1. Справочник «Номенклатура». В нем мы будем хранить как готовую продукцию, так и сырье, материалы и комплектующие, которые используются для производства.
  2. Справочник «Статьи затрат» (или «Статьи калькуляции»). В этот справочник мы занесем все виды наших расходов: Сырье и материалы, Топливо и энергия, Оплата труда, Общепроизводственные расходы и другие. Мы можем создать их как предопределенные элементы конфигурации или позволить пользователю вводить их вручную в режиме «1С:Предприятие».

Теперь спроектируем табличную часть для документов «Плановая калькуляция» и «Фактическая калькуляция». Вместо десятка колонок под каждый вид затрат мы создадим всего одну универсальную табличную часть с именем Затраты. В ней будут следующие реквизиты:

Такая структура позволит нам добавлять неограниченное количество статей расходов без изменения конфигурации и написания нового кода.

Шаг 2. Создание единого регистра накопления для сопоставления плана и факта

Проанализируем ситуацию: нам нужно построить три отчета — плановую себестоимость, фактическую себестоимость и отклонение плана от факта. Если мы создадим отдельные регистры для плана и для факта, нам придется писать сложные запросы с полным соединением (ПОЛНОЕ СОЕДИНЕНИЕ) таблиц в СКД, обрабатывать значения NULL и бороться с потерей данных.

Чтобы избежать этих сложностей, мы применим стандартный паттерн разработки 1С — использование единого оборотного регистра накопления с измерением сценария.

Сначала создадим перечисление Сценарии со следующими значениями:

Затем создадим регистр накопления ЗатратыПродукции. В свойствах регистра обязательно укажем вид регистра: Обороты. Поскольку нам не нужно контролировать остатки на складах в рамках этой задачи, а интересует только накопленный объем затрат за период (месяц), оборотный регистр идеально подходит по производительности.

Настроим структуру регистра ЗатратыПродукции:

Измерения:

Ресурсы:

Шаг 3. Реализация логики проведения документов

Теперь рассмотрим, как документы будут отражать данные в нашей системе. У нас есть два ключевых документа: ПлановаяКалькуляция и ФактическаяКалькуляция. Оба документа должны иметь в шапке реквизит Продукция (тип СправочникСсылка.Номенклатура) и табличную часть Затраты.

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


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
	
	// Очищаем движения перед записью новых
	Движения.ЗатратыПродукции.Записывать = Истина;
	Движения.ЗатратыПродукции.Очистить();
	
	Для Каждого ТекСтрокаЗатраты Из Затраты Цикл
		// Создаем новую запись движения по регистру
		Движение = Движения.ЗатратыПродукции.Добавить();
		
		// Заполняем стандартные реквизиты
		Движение.Период = Дата;
		
		// Заполняем измерения регистра
		Движение.Продукция = Продукция;
		Движение.СтатьяЗатрат = ТекСтрокаЗатраты.СтатьяЗатрат;
		Движение.Сценарий = Перечисления.Сценарии.План; // Принудительно устанавливаем План
		
		// Заполняем ресурсы регистра
		Движение.Сумма = ТекСтрокаЗатраты.Сумма;
		Движение.Количество = ТекСтрокаЗатраты.Количество;
	КонецЦикла;
	
КонецПроцедуры

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


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
	
	Движения.ЗатратыПродукции.Записывать = Истина;
	Движения.ЗатратыПродукции.Очистить();
	
	Для Каждого ТекСтрокаЗатраты Из Затраты Цикл
		Движение = Движения.ЗатратыПродукции.Добавить();
		
		Движение.Период = Дата;
		Движение.Продукция = Продукция;
		Движение.СтатьяЗатрат = ТекСтрокаЗатраты.СтатьяЗатрат;
		Движение.Сценарий = Перечисления.Сценарии.Факт; // Принудительно устанавливаем Факт
		
		Движение.Сумма = ТекСтрокаЗатраты.Сумма;
		Движение.Количество = ТекСтрокаЗатраты.Количество;
	КонецЦикла;
	
КонецПроцедуры

Шаг 4. Автоматизация заполнения: Кнопка «Заполнить по плану»

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

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


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

Этот простой алгоритм решает проблему ручного переноса данных. Пользователю останется лишь скорректировать суммы и объемы ресурсов под реальные факты хозяйственной жизни предприятия.

Шаг 5. Построение отчетов с помощью СКД

Использование единой таблицы оборотов значительно упрощает построение всех трех отчетов на Системе компоновки данных (СКД). Разберем, как спроектировать их без единой строчки кода в модулях отчетов.

Для всех отчетов источником данных будет выступать одна и та же виртуальная таблица: РегистрНакопления.ЗатратыПродукции.Обороты.

  1. Отчет «Плановая себестоимость». В схеме компоновки данных на вкладке «Настройки» в окне «Отбор» мы устанавливаем фиксированное условие: Сценарий Равно Значение(Перечисление.Сценарии.План). В выбранные поля добавляем Продукция, СтатьяЗатрат, СуммаОборот и КоличествоОборот.
  2. Отчет «Фактическая себестоимость». Аналогично предыдущему отчету, на вкладке «Настройки» в окне «Отбор» мы задаем условие: Сценарий Равно Значение(Перечисление.Сценарии.Факт).
  3. Отчет «Отклонение плановой себестоимости от фактической». Это самый важный отчёт, который мы построим с использованием структуры кросс-таблицы СКД:
    • В схеме компоновки данных на вкладке «Настройки» создадим структуру типа «Таблица».
    • В Строки таблицы добавим группировки по полям Продукция и СтатьяЗатрат.
    • В Колонки таблицы добавим группировку по полю Сценарий.
    • В Выбранные поля структуры добавим ресурс СуммаОборот (предварительно добавив его на вкладку «Ресурсы» схемы компоновки данных).

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

Чтобы рассчитать само отклонение (разницу между планом и фактом), мы перейдем на вкладку «Вычисляемые поля» нашей схемы компоновки данных и добавим новое поле:

Затем перейдем на вкладку «Ресурсы» и добавим поле Отклонение с выражением расчета Сумма(Отклонение). В настройках структуры отчета выведем поле Отклонение в ресурсы таблицы. Система автоматически сгруппирует данные и выведет разницу в отдельном столбце.

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

← На главную