В конфигурации ЗУП КОРП 3.1 автоматизирован кадровый учет и расчет зарплаты крупного торгово-промышленного холдинга, имеющего широкую сеть фирменных магазинов по всей России. Организационно холдинг состоит из группы юридических лиц, магазины являются обособленными подразделениями. Как следствие, ряд форм регламентированной отчетности необходимо было сдавать по каждому из обособленных подразделений отдельно – в частности, формы статистической отчетности П-1, П-4, П-4 (НЗ).

ЗУП: Автоматизация заполнения форм регламентированной отчетности по группе обособленных подразделений

В ЗУП КОРП процесс заполнения форм отчетности (например П-4) с точки зрения пользователя выглядит так: выбирается конкретная форма отчетности, указывается период, указывается организация. После этого система открывает форму отчетности, в ней необходимо выбрать обособленные подразделения и запустить заполнение по данным информационной базы — отдельной командой на форме. Поскольку обособленных подразделений в базе введено порядка 100, процесс был длительным и была высока вероятность ошибки бухгалтера при вводе и заполнении: какие-то подразделения можно было пропустить или выбрать ошибочно, что грозило срывом сроков сдачи отчетности и штрафными санкциями.

ЗУП: Автоматизация заполнения форм регламентированной отчетности по группе обособленных подразделений

Для исключения этих негативных последствий было решено доработать ЗУП КОРП, реализовав массовый ввод и заполнение форм отчетности П-1, П-4, П-4 (НЗ).

Технически решение этой задачи началось с анализа типового алгоритма заполнения формы отчетности (на примере П-1).  Анализ показал, что алгоритм заполнения, как часто это бывает в современных типовых конфигурациях, полностью завязан на форму регламентированного отчета. Поскольку пользователю было удобно видеть прогресс создания отчетов и он занимал порядка 10 минут по всем обособленным подразделениям холдинга, было решено архитектурно построить работу по обходу подразделений на клиенте, создавая форму и вызывая заполнение на стороне сервера. Это связано с тем, что форму на сервер можно только передать, а вот создать в серверном контексте нельзя. По этим же особенностям постановки задачи варианты имитации формы на сервере Структурой с соответствующим набором свойств было решено отказаться.

Для решения задачи на форму создания отчета по организации через расширение конфигурации добавили новую команду — заполнение по обособленным подразделениям организации. В ходе ее выполнения для всех действующих в выбранном периоде обособленных подразделений организации инициировалось создание и заполнение отчетности, с группировкой всех обособленных подразделений с одним ОКПО в одном отчете. Далее бухгалтеру необходимо только просмотреть созданные и заполненные отчеты в списке и отправить их в контролирующий орган.

В результате пользователи системы получили существенную экономию времени на подготовку регламентированной отчетности (по одной форме отчетности — с одного полного 8-часового дня до 1 часа) и снижение вероятности ошибок.

Пример кода — фрагмент клиентского общего модуля, обрабатывающего команду заполнения:

#Область ПрограммныйИнтерфейс
	
Процедура СоздатьИЗаполнитьПоОрганизации(ОсновнаяФормаОтчета) Экспорт

	Если ОсновнаяФормаОтчета.мСкопированаФорма <> Неопределено Тогда
		ПоказатьПредупреждение(, НСтр("ru='Копирование формы при групповом создании и заполнении невозможно!'"));
		Возврат;
	КонецЕсли;
	
	Если НЕ ЗначениеЗаполнено(ОсновнаяФормаОтчета.Организация) Тогда
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='%1'"), 
			РегламентированнаяОтчетностьКлиент.ОсновнаяФормаОрганизацияНеЗаполненаВывестиТекст());
		Сообщение.Сообщить();
		Возврат;
	КонецЕсли;
	
	
	Если ОсновнаяФормаОтчета.ИмяФормы = "Отчет.РегламентированныйОтчетСтатистикаФормаП4.Форма.ОсновнаяФорма" Тогда
		СуществующиеОтчеты = ГрупповоеСозданиеРегламентированнойОтчетностиВызовСервера.ПолучитьУжеСозданныеОтчеты(
			"РегламентированныйОтчетСтатистикаФормаП4",
			ОсновнаяФормаОтчета.Организация, 
			ОсновнаяФормаОтчета.мДатаНачалаПериодаОтчета, 
			ОсновнаяФормаОтчета.мДатаКонцаПериодаОтчета);
	ИначеЕсли ОсновнаяФормаОтчета.ИмяФормы = "Отчет.РегламентированныйОтчетСтатистикаФормаП4НЗ.Форма.ОсновнаяФорма" Тогда
		СуществующиеОтчеты = ГрупповоеСозданиеРегламентированнойОтчетностиВызовСервера.ПолучитьУжеСозданныеОтчеты(
			"РегламентированныйОтчетСтатистикаФормаП4НЗ",
			ОсновнаяФормаОтчета.Организация, 
			ОсновнаяФормаОтчета.мДатаНачалаПериодаОтчета, 
			ОсновнаяФормаОтчета.мДатаКонцаПериодаОтчета);
	Иначе
		ВызватьИсключение "Не поддерживается групповое создание отчетов из формы " + ОсновнаяФормаОтчета.ИмяФормы;
	КонецЕсли;
	
	ГруппыПодразделений = ГрупповоеСозданиеРегламентированнойОтчетностиВызовСервера.ПолучитьГруппыОбособленныхПодразделений(
		ОсновнаяФормаОтчета.Организация, 
		ОсновнаяФормаОтчета.мДатаНачалаПериодаОтчета);
	
	ОписаниеГруппыПоОрганизацииВЦелом = Новый Структура("ОКПО, Подразделения", "", Неопределено);
	ГруппыПодразделений.Добавить(ОписаниеГруппыПоОрганизацииВЦелом);
		
	ВсегоГруппПодразделений = ГруппыПодразделений.Количество();
	ОрганизацияСтрокой = Строка(ОсновнаяФормаОтчета.Организация);
	Для Каждого ГруппаПодразделений Из ГруппыПодразделений Цикл
		
		НомерГруппыПодразделений = ГруппыПодразделений.Найти(ГруппаПодразделений) + 1;
		Прогресс = Окр(100 * НомерГруппыПодразделений / ВсегоГруппПодразделений);
		ТекстСостояния = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Сохраняется %1 (%2 из %3)...'"), 
			ОсновнаяФормаОтчета.Заголовок,
			НомерГруппыПодразделений,
			ВсегоГруппПодразделений);
		Состояние(ТекстСостояния, Прогресс, , БиблиотекаКартинок.Записать);
		
		ЭтоОтчетПоОрганизацииВЦелом = НЕ ЗначениеЗаполнено(ГруппаПодразделений.ОКПО);
		
		Если СуществующиеОтчеты[ГруппаПодразделений.ОКПО] <> Неопределено Тогда
			
			СуществующиеОтчетыПоОКПО = "";
			Для Каждого СуществующийОтчет Из СуществующиеОтчеты[ГруппаПодразделений.ОКПО] Цикл
				СуществующиеОтчетыПоОКПО = СуществующиеОтчетыПоОКПО + ?(СуществующиеОтчетыПоОКПО = "", "", ", ")
					+ Строка(СуществующийОтчет);
			КонецЦикла; 
			ПериодОтчета = ПредставлениеПериода(ОсновнаяФормаОтчета.мДатаНачалаПериодаОтчета, ОсновнаяФормаОтчета.мДатаКонцаПериодаОтчета);
			
			Если НЕ ЭтоОтчетПоОрганизацииВЦелом Тогда
				ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='По организации %1 за период %2 по ОКПО %3 уже сформированы отчеты %4'"),
					ОрганизацияСтрокой,
					ПериодОтчета,
					ГруппаПодразделений.ОКПО,
					СуществующиеОтчетыПоОКПО);
			Иначе
				ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='По организации %1 за период %2 без учета обособленных подразделений уже сформированы отчеты %3'"),
					ОрганизацияСтрокой,
					ПериодОтчета,
					СуществующиеОтчетыПоОКПО);
			КонецЕсли;
			Сообщить(ТекстСообщения);
			
			Продолжить;
			
		КонецЕсли; 
		
		ФормаОтчета = ПолучитьФормуОтчета(ОсновнаяФормаОтчета);
		
		Если НЕ ЭтоОтчетПоОрганизацииВЦелом Тогда
			// Имитируем выбор списка подразделений
			ДопПараметры = Новый Структура("Форма", ФормаОтчета);
			РегламентированнаяОтчетностьКлиент.ОбработкаВыбораОбособленногоПодразделенияМножественныйВыбор(ГруппаПодразделений.Подразделения, ДопПараметры);
			
			КомментарийОтчета = ГруппаПодразделений.ПодразделенияСтрокой;
		Иначе
			// Устанавливаем флаг исключения данных обособленных подразделений
			ФормаОтчета.ИсключитьДанныеОбособленныхПодразделений = Истина;
			Если ФормаОтчета.Элементы.Найти("ПолеТабличногоДокументаФормаОтчета") <> Неопределено Тогда
				ФормаОтчета.ПолеТабличногоДокументаФормаОтчета.Области.ИсключитьДанныеОбособленныхПодразделений.Значение = ФормаОтчета.ИсключитьДанныеОбособленныхПодразделений;
			ИначеЕсли ФормаОтчета.Элементы.Найти("ТабличныйДокумент") <> Неопределено Тогда
				ФормаОтчета.ТабличныйДокумент.Области.ИсключитьДанныеОбособленныхПодразделений.Значение = ФормаОтчета.ИсключитьДанныеОбособленныхПодразделений;
			КонецЕсли;
			
			КомментарийОтчета = ОрганизацияСтрокой + " без обособленных подразелений";
		КонецЕсли; 
		
		ФормаОтчета.ЗаполнитьОтчетНеФоново();
		
		ФормаОтчета.Комментарий = КомментарийОтчета;
		
		ФормаОтчета.СохранитьОтчетБезВопросов();
	
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ПолучитьФормуОтчета(ОсновнаяФормаОтчета)
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("мДатаНачалаПериодаОтчета", ОсновнаяФормаОтчета.мДатаНачалаПериодаОтчета);
	ПараметрыФормы.Вставить("мСохраненныйДок",          ОсновнаяФормаОтчета.мСохраненныйДок);
	ПараметрыФормы.Вставить("мСкопированаФорма",        ОсновнаяФормаОтчета.мСкопированаФорма);
	ПараметрыФормы.Вставить("мДатаКонцаПериодаОтчета",  ОсновнаяФормаОтчета.мДатаКонцаПериодаОтчета);
	ПараметрыФормы.Вставить("мПериодичность",           ОсновнаяФормаОтчета.мПериодичность);
	ПараметрыФормы.Вставить("Организация",              ОсновнаяФормаОтчета.Организация);
	ПараметрыФормы.Вставить("мВыбраннаяФорма",          ОсновнаяФормаОтчета.мВыбраннаяФорма);
	
	ИмяФормыОтчета = СтрЗаменить(ОсновнаяФормаОтчета.ИмяФормы, "ОсновнаяФорма", "") + ОсновнаяФормаОтчета.мВыбраннаяФорма;
	ФормаОтчета = ПолучитьФорму(ИмяФормыОтчета, ПараметрыФормы, , Истина);
	
	Возврат ФормаОтчета;
	
КонецФункции

#КонецОбласти