Создание и заполнение документа основания программно из модуля формы

28.11.24

Разработка - Универсальные функции

Работа с модулями форм документов УФ

Это очередная публикация, можно судить строго.

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

Надеюсь этой статьей помочь таким же, как и я в свое время (Таковых много, я смотрел на различных форумах аналогичные безответные запросы);

В моем случае необходимо было создать документ "Расходная накладная" на основании документа "Заказ покупателя" с проверкой на проведенность и с изменением реквизита в основном документе после проведения и самое главное баз открытия создаваемого документа.

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

Практика.

1. Методом несложных манипуляций создаем кнопку на командной панели списка документов "Заказы покупателей" с именем "СоздатьРасходнуюНакладную".

2. В модуле формы основного документа прописываем Функцию на Сервере и процедуру на Клиенте.

&НаСервере
Функция СоздатьРасходнуюНакладнуюНаСервере()
	
	ЭтотДокумент = РеквизитФормыВЗначение("Объект");
	ЭтотДокумент.Записать(РежимЗаписиДокумента.Проведение);
	ЗначениеВРеквизитФормы(ЭтотДокумент, "Объект");
	ДокРН=Документы.РасходнаяНакладная.СоздатьДокумент();
	ДокРН.Заполнить(Объект.ссылка);
	ДокРН.Дата=ТекущаяДата();
	ДокРН.Ответственный=Объект.Ответственный;
	ДокРН.Подразделение=Объект.СтруктурнаяЕдиницаПродажи;
	ДокРН.Автор=Объект.Автор;
	ДокРН.Комментарий=Объект.Комментарий;

//При повторном создании документа количество запасов в ТЧ запасы = 0 Заведомо запрещаем дальнейшие действия(ТАКОВ ПОДХОД)	
	Если ДокРН.Запасы.Количество()=0 тогда
				Сообщить("Вы уже создали ВАШ_ДОКУМЕНТ!");
		Возврат Ложь;
	КонецЕсли;	

//Проверяем документ на заполненность, если созданный на основании документ заполнен, то проводим и оповещаем пользователя 	
	    Если ДокРН.Запасы.Количество()>0 Тогда
		ДокРН.Записать(Режимзаписидокумента.Проведение);
		Сообщить("Создан документ "+ДокРН);

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

	    КонецЕсли;
КонецФункции

//Команду с кнопкой мы поместили на командной панели нашего документа основания и указываем нашу процедуру
//
&НаКлиенте
Процедура СоздатьРасходнуюНакладную(Команда)	
//Определяем наш ДокРН и выполняем команду и закрываем форму оновного документа;
ДокРН=СоздатьРасходнуюНакладнуюНаСервере();
Если ДокРН тогда
	Записать();
Конецесли;
//Закрывем форму
Закрыть();
КонецПроцедуры

Вот таким путем мы создали на основании документ с заполнением всех необходимых нам данных, с проведением документов и без открытия формы созданного документа!

End;

28.11.24 - готовимся к новому году, кукушка отъезжает, вспомнил как после клюшек - 8.3 изучать начал

Вступайте в нашу телеграмм-группу Инфостарт

Создать на основании заполнить по документу Документ основание Заполнить по основанию

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    3066    Abysswalker    7    

43

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    5871    DeerCven    15    

57

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    47452    dimanich70    83    

167

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    7119    6    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    58995    atdonya    31    

69

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    8867    ke.92@mail.ru    17    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. mvk4d 03.05.18 07:54 Сейчас в теме
"Закрыть" - это метод.
На ИТС есть микро статья про это: https://its.1c.ru/db/metod8dev/content/2484/hdoc
2. DENSKR 15 04.05.18 19:45 Сейчас в теме
(1)
"Закрыть"
Закрываем текущую форму а не форму созданного дока
3. MVK80 04.05.18 20:38 Сейчас в теме
(2) Так, а что это меняет? Нет такого свойства "Закрыть", есть только метод "Закрыть()". Скобок не хватает. Проверка модуля ругается.
4. DENSKR 15 04.05.18 20:59 Сейчас в теме
(3)Точно) Не заметил) Спасибо.
5. Бубузяка 62 10.05.18 11:52 Сейчас в теме
Я себе позволил изменить немного код автора. Правки отмечены "NB".


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

//Команду с кнопкой мы поместили на командной панели нашего документа основания и указываем нашу процедуру
//
&НаКлиенте
Процедура СоздатьРасходнуюНакладную(Команда)
	
	// ++ NB 
	// "Безопасная" запись и проведение.
	Если НЕ ПроверитьЗаполнение() Тогда
		// Текущий документ не готов к проведению.
		Возврат;
	КонецЕсли; 
	
	ПараметрыЗаписи = Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение); 
	Если НЕ Записать(ПараметрыЗаписи) Тогда
		// Что-то пошло не так и документ не удалось провести.
		Возврат;
	КонецЕсли; 
	// -- NB

	//Определяем наш Док1 и выполняем команду и закрываем форму оновного документа;
	Док1=СоздатьРасходнуюНакладнуюНаСервере();
	Если Док1 тогда
		Записать();
	Конецесли;
	//Закрывем форму
	Закрыть();
КонецПроцедуры
Показать
7. DENSKR 15 11.05.18 10:09 Сейчас в теме
(5)
(6) Хорошие замечания, возьму к вооружению.
6. user596590_pavel.kuznecov 48 10.05.18 12:37 Сейчас в теме
//Команду с кнопкой мы поместили на командной панели нашего документа основания и указываем нашу процедуру

Про дополнительные обработки и БСП не слышали? Все это можно оформить без изменения конфигурации, создав и подключив дополнительную внешнюю обработку. В модуле обработке должна присутствовать экспортная функция "СведенияОВнешнейОбработке":
Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиСозданиеСвязанныхОбъектов();
    ПараметрыРегистрации.Версия = "1.0.0.1";
    Команда = ПараметрыРегистрации.Команды.Добавить();
    Команда.Представление = НСтр("ru = '<Пишем наше представление команды>'");
    Команда.Идентификатор = "<Пишем наше имя команды>";
    Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
    Команда.ПоказыватьОповещение = Ложь;
    Возврат ПараметрыРегистрации; 
КонецФункции
Показать


Здесь же в модуле обработки создаете экспортную функцию ВыполнитьКоманду() :
 Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, СозданныеОбъекты, ПараметрыВыполнения) Экспорт
       	// Реализация логики команды.
       КонецПроцедуры

ОбъектыНазначения - Массив ссылок на документы-основания. Почему массив: для обеспечения возможности создания связанных объектов из формы списка множественным выделением. То есть выделили произвольно документы, нажали кнопку, и для всех выделенных документов будут созданы связанные объекты. Идентификатор команды нужен когда в одной обработке несколько команд, в вашем случае игнорируйте. Остальные параметры тоже Вам не понадобятся. Описание команд и их параметров можно посмотреть в комментарии к функции "ТипКомандыВызовСерверногоМетода".
cepera1575; 1cccc; DENSKR; +3 Ответить
8. German_Tagil 43 12.05.18 15:17 Сейчас в теме
Для отправки сообщения требуется регистрация/авторизация