Создание качественного производственного отчета — одна из самых частых задач для разработчика 1С. Основная сложность здесь заключается не в получении списка заказов, а в сопоставлении плановых данных с фактическим выпуском. В данной статье мы разберем, почему нельзя строить такие отчеты на основе табличных частей документов, как правильно использовать регистры накопления и как реализовать логику «выполнен/не выполнен» для каждой строки продукции и материалов.
Рассмотрим типичную ситуацию: начинающий разработчик пытается получить данные напрямую из табличной части Документ.ЗаказНаПроизводство.Продукция. На первый взгляд это кажется логичным, ведь именно там указано, что мы планируем произвести. Однако документ — это лишь фиксация намерения. Он не содержит информации о том, сколько продукции уже реально поступило на склад по этому заказу.
Для получения фактических данных (сколько сделано) нам необходимо обратиться к регистрам накопления. В типовых конфигурациях (например, УПП или ERP) за это отвечают специальные регистры, такие как Заказы на производство или Производственные заказы. Проанализируем, как строится работа системы: когда мы проводим «Заказ на производство», он делает движение «Приход» в регистр, фиксируя долг предприятия перед самим собой. Когда же оформляется «Отчет производства за смену» или «Поступление из переработки», система делает «Расход» по этому же регистру, уменьшая остаток долга.
Чтобы увидеть в одной строке план, факт и остаток, мы должны использовать виртуальную таблицу ОстаткиИОбороты соответствующего регистра накопления. Выясним причину, почему это эффективнее: эта таблица позволяет за один запрос получить начальный остаток, приход (план), расход (факт) и конечный остаток.
Рассмотрим пример запроса к регистру накопления (на примере УПП/ERP-логики):
ВЫБРАТЬ
ЗаказыОстаткиИОбороты.ЗаказНаПроизводство КАК Заказ,
ЗаказыОстаткиИОбороты.Номенклатура КАК Номенклатура,
ЗаказыОстаткиИОбороты.ЗаказНаПроизводство.Подразделение КАК Подразделение,
ЗаказыОстаткиИОбороты.ЗаказНаПроизводство.ДатаЗапуска КАК ДатаЗапуска,
ЗаказыОстаткиИОбороты.ЗаказНаПроизводство.ДатаИсполнения КАК ДатаИсполнения,
ЗаказыОстаткиИОбороты.КоличествоПриход КАК Запланировано,
ЗаказыОстаткиИОбороты.КоличествоРасход КАК ВыполненоФакт,
ЗаказыОстаткиИОбороты.КоличествоКонечныйОстаток КАК ОсталосьПроизвести
ИЗ
РегистрНакопления.ЗаказыНаПроизводство.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , ) КАК ЗаказыОстаткиИОбороты
Важный момент: если мы хотим получить даты из самого документа, мы обращаемся к реквизитам через точку от измерения ЗаказНаПроизводство. Это допустимо в небольших базах, но в высоконагруженных системах лучше соединять таблицу регистра с таблицей документа по ссылке.
Проанализируем ситуацию, когда менеджеру нужно быстро понять статус строки заказа. Простого вывода цифр часто недостаточно. Мы можем вычислить статус прямо в запросе, используя конструкцию ВЫБОР.
Логика проста: если КоличествоКонечныйОстаток равно 0 (или меньше, в случае перевыполнения), значит заказ выполнен. Если остаток больше 0 — заказ находится в работе.
ВЫБОР
КОГДА ЗаказыОстаткиИОбороты.КоличествоКонечныйОстаток <= 0
ТОГДА "Выполнен"
ИНАЧЕ "В работе"
КОНЕЦ КАК СтатусВыполнения
Обратите внимание, что статус «Выполнен» может быть присвоен и в том случае, если заказ был закрыт принудительно (например, документом «Закрытие заказов на производство»). В этом случае движения регистра обнуляют остатки, и отчет корректно покажет, что работа по строке завершена.
Часто требуется видеть не только выпуск, но и обеспечение этого выпуска материалами. В одном запросе объединить табличные части продукции и материалов крайне сложно, так как это приведет к «размножению» строк (декартову произведению). Для решения этой задачи разберем использование Системы компоновки данных (СКД).
Нам необходимо создать два отдельных набора данных — запроса:
Запасы и потребности или ТЧ Материалы документа), где отражается потребность в сырье под этот заказ.Затем в СКД на закладке «Связи наборов данных» мы соединяем их по полю ЗаказНаПроизводство (и, при необходимости, по полю Номенклатура, если материалы привязаны к конкретным позициям продукции). Это позволит вывести в отчете сначала блок информации по продукции, а ниже — детализацию по необходимым материалам.
Посмотрим на пример запроса для получения данных по материалам. Нам важно знать, сколько материалов было запланировано и сколько реально списано в производство (например, документом «Требование-накладная» или «Списание материалов на выпуск»).
ВЫБРАТЬ
ЗаказМатериалы.Ссылка КАК Заказ,
ЗаказМатериалы.Номенклатура КАК Материал,
ЗаказМатериалы.Количество КАК ПланМатериала,
ЕСТЬNULL(СписанныеМатериалы.Количество, 0) КАК ФактМатериала
ИЗ
Документ.ЗаказНаПроизводство.Материалы КАК ЗаказМатериалы
ЛЕВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ
РегистрПроизводство.Заказ КАК Заказ,
РегистрПроизводство.Номенклатура КАК Номенклатура,
СУММА(РегистрПроизводство.Количество) КАК Количество
ИЗ
РегистрНакопления.ЗатратыНаПроизводство КАК РегистрПроизводство
СГРУППИРОВАТЬ ПО
РегистрПроизводство.Заказ,
РегистрПроизводство.Номенклатура) КАК СписанныеМатериалы
ПО
ЗаказМатериалы.Ссылка = СписанныеМатериалы.Заказ
И ЗаказМатериалы.Номенклатура = СписанныеМатериалы.Номенклатура
Для того чтобы отчет был читаемым и профессиональным, рекомендуем выполнить следующие настройки в компоновщике:
Заказу, а вложенные — по Номенклатуре (продукции) и Материалам.Подведем итог: использование регистров накопления вместо прямых запросов к документам — это единственный верный способ построить достоверный отчет по заказам на производство. Механизмы виртуальных таблиц остатков позволяют легко вычислять статус выполнения, а возможности СКД — объединять разнородные данные (продукцию и материалы) в единую удобную структуру.