gifts2017

Расширения... Использование на практике. Пример заполнения табличных частей в 1С Бухгалтерия 3.0.

Опубликовал Михаил Канаев (mrBart) в раздел Обработки - Обработка документов

В 1С Бухгалтерия 3.0, возникла проблема, может мелочь но дико мешает. При заполнении табличных частей постоянно просит записать документ.

Пользователям после перехода с 2.0 эта функция очень не нравиться: документ проведен, пользователь нажимает заполнение, разумеется, не читая о чем, его спрашивает программа. Далее  документ записывается, остатки двигаются, оригинал документа теряется, шум, гам, крик, истерика.

Посмотрели БСП.... никаких настроек по этому поводу нет. Проблема та вроде ерундовая, как заноза, вроде мелочь а неприятно.

И вот наконец то вышел релиз Бухгалтерии 3.0.41.48, с которого разрешено создавать расширения, с помощью них мы и решили данную проблему.

И так, мы создали расширение с названием "ЗаполнениеТЧ", перенесли в него документ "Перемещение материалов" и его основную форму. 

В Форме разместили следующий код:

&НаКлиенте
Процедура Расш_ЗаполнениеТЧ_ПриОткрытии(Отказ)
	Расш_ЗаполнениеТЧ_ПриОткрытииНаСервере();
КонецПроцедуры

&НаСервере
Процедура Расш_ЗаполнениеТЧ_ПриОткрытииНаСервере()
	
	ПриСозданииФормыНаСервере();
	
КонецПроцедуры

Процедура ПриСозданииФормыНаСервере() Экспорт 
	
	Попытка
		ОчиститьЭлементыФормы();        	
		ПриСозданииНаСервере_1();
	Исключение
		ДополнительныеОтчетыИОбработки.ПриСозданииНаСервере(ЭтаФорма);
	КонецПопытки;
	
КонецПроцедуры
Процедура "ОчиститьЭлементыФормы" убирает кнопки заполнения и команды с формы, которые были созданы типовым кодом в процедуре "ПриСозданииНаСервере":
Процедура ОчиститьЭлементыФормы() Экспорт 
	
	ИИ = 0 ;
	
	Пока Истина Цикл 
		
		Попытка
			Этаформа.Элементы.Удалить(Этаформа.Элементы.Найти("КомандаДополнительнойОбработки"+ Формат(ИИ, "ЧГ=")));
			ЭтаФорма.Команды.Удалить(ЭтаФорма.Команды.Найти("КомандаДополнительнойОбработки"+ Формат(ИИ, "ЧГ=")));
		Исключение  
			Прервать;
		КонецПопытки;
		
	КонецЦикла;
	
	ЭтаФорма.Команды.Удалить(ЭтаФорма.Команды.Найти("АдресКомандДополнительныхОбработокВоВременномХранилище"+ Формат(ИИ, "ЧГ=")));
	
КонецПроцедуры
Следующая процедура: "ПриСозданииНаСервере_1" взята из БСП, с одним изменением, действия команды изменено.
Процедура ПриСозданииНаСервере_1(ТипФормы = Неопределено) Экспорт
	
	Если Не ПолучитьФункциональнуюОпцию("ИспользоватьДополнительныеОтчетыИОбработки") Тогда
		Возврат;
	КонецЕсли;
	
	// Установка параметров формы для команд вызова дополнительных отчетов и обработок.
	Параметры_1 = ДополнительныеОтчетыИОбработкиПовтИсп.ПараметрыФормыНазначаемогоОбъекта(ЭтаФорма.ИмяФормы, ТипФормы);
	Если ТипЗнч(Параметры_1) <> Тип("ФиксированнаяСтруктура") Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыФункциональныхОпций = Новый Структура;
	ПараметрыФункциональныхОпций.Вставить("ДополнительныеОтчетыИОбработкиОбъектНазначения", Параметры_1.СсылкаРодителя);
	ПараметрыФункциональныхОпций.Вставить("ДополнительныеОтчетыИОбработкиТипФормы",         ?(ТипФормы = Неопределено, Параметры_1.ТипФормы, ТипФормы));
	
	УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункциональныхОпций);
	            
	Если Параметры_1.ВыводитьПодменюЗаполнениеОбъекта Тогда
		СформироватьПодменюКомандЗаполнения(Параметры_1);
	КонецЕсли;
	
КонецПроцедуры

Процедура СформироватьПодменюКомандЗаполнения(Параметры_1)
	
	ТекстЗапроса =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
	|	ДополнительныеОтчетыИОбработкиНазначение.Ссылка
	|ПОМЕСТИТЬ втСсылки
	|ИЗ
	|	Справочник.ДополнительныеОтчетыИОбработки.Назначение КАК ДополнительныеОтчетыИОбработкиНазначение
	|ГДЕ
	|	ДополнительныеОтчетыИОбработкиНазначение.ОбъектНазначения = &ОбъектНазначения
	|	И ДополнительныеОтчетыИОбработкиНазначение.Ссылка.Вид = &Вид
	|	И ДополнительныеОтчетыИОбработкиНазначение.Ссылка.ИспользоватьДляФормыОбъекта = ИСТИНА
	|	И ДополнительныеОтчетыИОбработкиНазначение.Ссылка.Публикация = &Публикация
	|	И ДополнительныеОтчетыИОбработкиНазначение.Ссылка.ПометкаУдаления = ЛОЖЬ
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	ДополнительныеОтчетыИОбработкиКоманды.Ссылка,
	|	ДополнительныеОтчетыИОбработкиКоманды.Идентификатор,
	|	ДополнительныеОтчетыИОбработкиКоманды.ВариантЗапуска,
	|	ДополнительныеОтчетыИОбработкиКоманды.Представление КАК Представление,
	|	ДополнительныеОтчетыИОбработкиКоманды.ПоказыватьОповещение,
	|	ДополнительныеОтчетыИОбработкиКоманды.Модификатор,
	|	ДополнительныеОтчетыИОбработкиКоманды.Ссылка.Вид
	|ИЗ
	|	втСсылки КАК втСсылки
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДополнительныеОтчетыИОбработки.Команды КАК ДополнительныеОтчетыИОбработкиКоманды
	|		ПО втСсылки.Ссылка = ДополнительныеОтчетыИОбработкиКоманды.Ссылка
	|
	|УПОРЯДОЧИТЬ ПО
	|	Представление";
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ОбъектНазначения", Параметры_1.СсылкаРодителя);
	Запрос.УстановитьПараметр("Вид", Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗаполнениеОбъекта);
	Запрос.УстановитьПараметр("ВариантЗапуска", Перечисления.СпособыВызоваДополнительныхОбработок.ЗаполнениеФормы);
	Если Пользователи.РолиДоступны("ДобавлениеИзменениеДополнительныхОтчетовИОбработок") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "Публикация = &Публикация", "Публикация <> &Публикация");
		Запрос.УстановитьПараметр("Публикация", Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Отключена);
	Иначе
		Запрос.УстановитьПараметр("Публикация", Перечисления.ВариантыПубликацииДополнительныхОтчетовИОбработок.Используется);
	КонецЕсли;
	Запрос.Текст = ТекстЗапроса;
	
	Результат = Запрос.Выполнить();
	Если Результат.Пустой() Тогда
		Возврат;
	КонецЕсли;
	
	// Определение группы, в которую будут добавлены команды.
	
	ПредустановленныеКоманды = Новый Массив;
	Подменю = Элементы.Найти("ПодменюДополнительныхОбработокЗаполнения");
	Если Подменю = Неопределено Тогда
		КоманднаяПанель = Элементы.Найти("КоманднаяПанель");
		Если КоманднаяПанель = Неопределено Тогда
			КоманднаяПанель = ЭтаФорма.КоманднаяПанель;
		КонецЕсли;
		Подменю = Элементы.Вставить("ПодменюДополнительныхОбработокЗаполнения", Тип("ГруппаФормы"), КоманднаяПанель);
		Подменю.Заголовок = НСтр("ru = 'Заполнить'");
		Подменю.Вид = ВидГруппыФормы.Подменю;
		Подменю.Картинка = БиблиотекаКартинок.ЗаполнитьФорму;
		Подменю.Отображение = ОтображениеКнопки.КартинкаИТекст;
	Иначе
		Для Каждого Элемент Из Подменю.ПодчиненныеЭлементы Цикл
			ПредустановленныеКоманды.Добавить(Элемент);
		КонецЦикла;
	КонецЕсли;
	
	ТаблицаКоманд = Результат.Выгрузить();
	ТаблицаКоманд.Колонки.Добавить("ИмяЭлемента", Новый ОписаниеТипов("Строка"));
	ТаблицаКоманд.Колонки.Добавить("ЭтоОтчет", Новый ОписаниеТипов("Булево"));
	
	Для НомерЭлемента = 0 По ТаблицаКоманд.Количество() - 1 Цикл
		ОписаниеКоманды = ТаблицаКоманд[НомерЭлемента];
		ИмяЭлемента = "КомандаДополнительнойОбработки" + Формат(НомерЭлемента, "ЧГ=");
		ОписаниеКоманды.ИмяЭлемента = ИмяЭлемента;
		
		Команда = ЭтаФорма.Команды.Добавить(ИмяЭлемента);
		Команда.Действие  = "Подключаемый_ВыполнитьНазначаемуюКоманду_Зеркало";
		Команда.Заголовок = ОписаниеКоманды.Представление;
		
		Элемент = ЭтаФорма.Элементы.Добавить(ИмяЭлемента, Тип("КнопкаФормы"), Подменю);
		Элемент.ИмяКоманды = ИмяЭлемента;
		Элемент.ТолькоВоВсехДействиях = Ложь;
	КонецЦикла;
	
	Команда = ЭтаФорма.Команды.Добавить("АдресКомандДополнительныхОбработокВоВременномХранилище");
	Команда.Действие = ПоместитьВоВременноеХранилище(ТаблицаКоманд, ЭтаФорма.УникальныйИдентификатор);
	
	Для Каждого Элемент Из ПредустановленныеКоманды Цикл
		Элементы.Переместить(Элемент, Подменю);
	КонецЦикла;
	
КонецПроцедуры
Готово, теперь на форме типовые команды заполнения ТЧ, которые вызывают нашу процедуру:
&НаКлиенте
Процедура Подключаемый_ВыполнитьНазначаемуюКоманду_Зеркало(Команда)
	
	Попытка
		
		Если НЕ ВыполнитьНазначаемуюКомандуНаКлиенте(Команда.Имя) Тогда
			РезультатВыполнения = Неопределено;
			ДополнительныеОтчетыИОбработкиВыполнитьНазначаемуюКомандуНаСервере(Команда.Имя, РезультатВыполнения);
			ДополнительныеОтчетыИОбработкиКлиент.ПоказатьРезультатВыполненияКоманды(ЭтаФорма, РезультатВыполнения);
		КонецЕсли;
				
	Исключение
		
		Если НЕ ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьНазначаемуюКомандуНаКлиенте(Команда.Имя) Тогда
			РезультатВыполнения = Неопределено;
			ДополнительныеОтчетыИОбработкиВыполнитьНазначаемуюКомандуНаСервере(Команда.Имя, РезультатВыполнения);
			ДополнительныеОтчетыИОбработкиКлиент.ПоказатьРезультатВыполненияКоманды(ЭтаФорма, РезультатВыполнения);
		КонецЕсли;
		
	КонецПопытки;
	
КонецПроцедуры

&НаКлиенте
Функция ВыполнитьНазначаемуюКомандуНаКлиенте(ИмяЭлемента) Экспорт
	ОчиститьСообщения();
	
	ВыполняемаяКоманда = ДополнительныеОтчетыИОбработкиВызовСервера.ОписаниеКомандыОбработки(ИмяЭлемента, 
		ЭтаФорма.Команды.Найти("АдресКомандДополнительныхОбработокВоВременномХранилище").Действие);
	
	Если ВыполняемаяКоманда.ВариантЗапуска = ПредопределенноеЗначение("Перечисление.СпособыВызоваДополнительныхОбработок.ЗаполнениеФормы") Тогда
		Возврат Ложь; // Для выполнения команды требуется контекстный вызов сервера.
	КонецЕсли;
		
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("Форма",  ЭтаФорма);
	ДополнительныеПараметры.Вставить("Объект", Объект);
	ДополнительныеПараметры.Вставить("ВыполняемаяКоманда", ВыполняемаяКоманда);
	//
	//Если Объект.Ссылка.Пустая() Или Форма.Модифицированность Тогда
	//	ТекстВопроса = СтрШаблон(
	//		НСтр("ru = 'Для выполнения команды ""%1"" необходимо записать данные.'"),
	//		ВыполняемаяКоманда.Представление);
	//	
	//	Кнопки = Новый СписокЗначений;
	//	Кнопки.Добавить(КодВозвратаДиалога.Да, НСтр("ru = 'Записать и продолжить'"));
	//	Кнопки.Добавить(КодВозвратаДиалога.Отмена);
	//	
	//	Обработчик = Новый ОписаниеОповещения("ВыполнитьНазначаемуюКомандуНаКлиентеЗавершение", ЭтотОбъект, ДополнительныеПараметры);
	//	ПоказатьВопрос(Обработчик, ТекстВопроса, Кнопки, 60, КодВозвратаДиалога.Да);
	//Иначе
		ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьНазначаемуюКомандуНаКлиентеЗавершение(-1, ДополнительныеПараметры);
	//КонецЕсли;
	
	Возврат Истина; // Для выполнения команды достаточно клиентского контекста.
	
КонецФункции 

В процедуре "ВыполнитьНазначаемуюКомандуНаКлиенте" закоментарили проверку модифицированности формы. Готово, программа больше не заставляет записывать документ перед заполнением.
Для того что бы работала во всех документах, конечно необходимо процедуры вынести в общий модуль(для удобства), и раскидать вызовы этих процедур по другим документам.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Расширение ЗаполнениеТЧ
.cfe 47,93Kb
05.08.15
1
.cfe 47,93Kb 1 Скачать
Пример заполнения табличной части (Перемещение товаров, по всем остаткам)
.epf 16,56Kb
05.08.15
2
.epf 16,56Kb 2 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Игорь Фелькер (Brawler) 05.08.15 16:00
Не вижу ничего страшного в том, что документы записываются перед изменением.
К тому же, если в базе данных включено версионирование при записи, то всегда можно вернуть документ в исходное состояние.
rimma_n; demkonst; +2 Ответить
2. Михаил Коваль (mihey) 05.08.15 16:16
Запись перед заполнением это не ошибка ее исправлять не нужно.
demkonst; +1 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа