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