Новости |  Решение экзаменационных задач 1С:Специалист |  Платформа. Задача 1 | 

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


Для решения задач по платформе нам потребуется каркасная конфигурация. Решения задач на этой странице будет дано по последней версии экзаменационного задания (ред. 8.1) .

Прочитав задание от начала до конца тщательно анализируйте его. Если вдруг, расчетная часть задания использует данные оперативного учета или для построения отчета требуется не оговоренный специально разрез аналитического учета, который вы не не заметили перед началом разработки, то придется все переделывать.

Уяснив цели и задачи составляем схему решения оперативных, бухгалтерских и расчетных частей.

Требования к оперативному учету:

Требования к бухгалтерскому учету:

Требования к расчетной части:

Решение. Оперативный учет

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

--------------------------------------------------------------------------------
| Номенклатура | Склад | Начальный остаток | Прихд | Расход | Конечный остаток |
--------------------------------------------------------------------------------

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

В каркасной конфигации регистр накопления "ОстаткиНоменклатуры" имеет только одно измерение Номенклатура, поэтому добавим еще одно измерение Склад тип данных СправочникСсылка.МестаХранения:

Далее запускаем нашу конфигурацию а режиме "1С:Предприятие". Изучим объекты метаданных, присутствующие в каркасной конфигурации, проанализируем какие регистры, справочники и документы уже заполнены, какие движения выполняются при проведении документов.

Учет остатков номенклатуры в конфигурации ведется документами "Приходная" и "Расходная". Открываем форму списка документов "Приходная" и в ней нажимаем на кнопку "Перейти". Из списка регистров выбираем "Остатки номенклатуры" - открывается форма списка регистров накопления "Остатки номенклатуры", из которого видно, что при проведении документа "Приходная" выполняются движения "Приход". В движения документа "Приходная" необходимо добавить разрез учета "Склад". Но добавить разрез учета можно в реквизиты "шапки" документа - тогда весь приход будет идти на один склад, или в реквизиты табличной части документа - тогда возможен приход одним документом товаров на разные склады. Так как в задании это не оговорено а на структуру регистров накопления и регистров бухгалтерии это не влияет, то добавим реквизит Склад тип данных СправочникСсылка.МестаХранения в "шапку" документа "Приходная", и изменяем форму документа

В процедуру ОбработкаПроведения() добавляем строку: Движение.склад = Склад;

	Для Каждого ТекСтрокаТовары Из Товары Цикл
		// регистр ОстаткиНоменклатуры Приход
		Движение = Движения.ОстаткиНоменклатуры.Добавить();
		Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
		Движение.Период = Дата;
		Движение.Регистратор = Ссылка;
		Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
		Движение.Количество = ТекСтрокаТовары.Количество;
		Движение.Сумма = ТекСтрокаТовары.Сумма;
		Движение.Склад = Склад; //kvv
	КонецЦикла;

Добавляем в форму списка регистра накопления "ОстаткиНоменклатуры" колонку Склад и с помощью клавиши F5 переходим в режим 1С:Предприятие. Перепроводим документы "Приходная" и проверяем движения регистра накопления в разрезе складов.

С приходной все, но могут возникнуть вопросы по проверке на заполнение реквизита "Склад". В свойствах реквизита формы "Склад" в категории "Использование" установлен флаг "Автоотметка незаполненного", если этого недостаточно, то необходимо в модуле формы документа сделать дополнительную проверку.

Далее в режиме 1С:Предприятие проверяем движения документа "Расходная". Движений по регистру накопления "ОстаткиНоменклатуры" - нет.

Для учета объемов закупки, в соответствии с заданием, используется оборотный регистр накопления.

Проанализировав структуру регистра накопления "Продажи", приходим к выводу, что он содержит все необходимые реквизиты и для решения поставленной задачи изменять ничего не надо. При проведении документа "Расходная" движений по регистру накопления "Продажи" - нет.

То есть для решения поставленной задачи необходимо сформировать движения в регистрах накопления "ОстаткиНоменклатуры" и "Продажи". Независимо от сложности процедуры "ОбработкаПроведения()", в любом случае ее реализацию необходимо начать с помощью конструктора движений документа.

В окне конструктора движений выбираем регистры, для каждого регистра выбираем табличную часть "Товары" и нажимаем кнопку "ЗаполнитьВыражения". Для регистра накопления "ОстаткиНоменклатуры" выбираем тип движения "Расход":

Теперь можно нажать кнопку "OK". В результате в модуле документа система создала процедуру "ОбработкаПроведения()" - обработчик события "Проведение документов".

Процедура ОбработкаПроведения(Отказ, Режим)
	//{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
	// Данный фрагмент построен конструктором.
	// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
	Для Каждого ТекСтрокаТовары Из Товары Цикл
		// регистр ОстаткиНоменклатуры Расход
		Движение = Движения.ОстаткиНоменклатуры.Добавить();
		Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
		Движение.Период = Дата;
		Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
		Движение.Склад = Склад;
		Движение.Количество = ТекСтрокаТовары.Количество;
		Движение.Сумма = ТекСтрокаТовары.Сумма;
	КонецЦикла;
	Для Каждого ТекСтрокаТовары Из Товары Цикл
	// регистр Продажи
		Движение = Движения.Продажи.Добавить();
		Движение.Период = Дата;
		Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
		Движение.Контрагент = Контрагент;
		Движение.Количество = ТекСтрокаТовары.Количество;
		Движение.Сумма = ТекСтрокаТовары.Сумма;
	КонецЦикла;
	// записываем движения регистров
	Движения.ОстаткиНоменклатуры.Записать();
	Движения.Продажи.Записать();
	//}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
КонецПроцедуры

Теперь приступаем к доработке процедуры "ОбработкаПроведения". Какими бы сложными не были условия проведения документа, они обычно касаются реквизитов шапки и реквизитов табличных частей.

Таким образом определяем следующий универсальный алгоритм проведения документа:

Проверка заполнения реквизитов шапки документа

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

Если Склад = Справочники.МестаХранения.ПустаяСсылка() Тогда
	Сообщить("Не указан склад", СтатусСообщения.Внимание);
	Отказ = Истина;
	Возврат;
КонецЕсли;
Формирование движений по шапке документа

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

Запрос по табличной части документа с получением данных из других объектов

Запрос по табличной части документа с получением данных из других объектов выполним в виде функции "СформироватьЗапросПоСтрокамДок(Режим)". Запрос формируем конструктором по методу запрос в запросе. Сначала формируем вложенный запрос по табличной части документа (нажимаем кнопку "Добавить" над средним полем закладки "Таблицы и поля"):

Далее отрабатываем дубли строк группировкой по номенклатуре (закладка "Группировка")

и не забываем про условия вложенного запроса (Док.Ссылка=&Ссылка;).

Нажимаем кнопку Запрос и проверяем текст запроса:

Нажимаем "OK". Попадаем во внешний запрос.

Далее добавляем еще один источник - виртуальную таблицу "РегистрНакопления.ОстаткиНоменклатуры.Остатки". Сразу указываем параметры Виртуальной таблицы (&Момент,Склад = &Склад И Номенклатура В). Параметр Номенклатура получает данные из вложенного запроса по табличной части документа, который содержит РАЗЛИЧНЫЕ товары из табличной части данной расходной (закладка Дополнително - установить флаг "Без повторяющихся записей"). Обеспечиваем, чтобы запрос брал номенклатуру не из всех расходных, а только из одной (закладка Условия).

Далее производим соединение реальной и виртуальной таблиц (закладка "Связи" конструктора запроса).

Таблица вложенного запроса "Накл" имеет только те поля, которые были выбраны в качестве выходных во вложенной таблице. Если вдруг потребуется во вложенном запросе что-то изменить - нужно вернуться на закладку "Таблицы и поля", активизировать вложенный запрос и нажать клавишу "Изменить текущий элемент(F2)".

В результате функция СформироватьЗапросПоСтрокамДок будет содержать следующий код:

//Запрос по табличной части с получением данных из регистра накопления
Функция СформироватьЗапросПоСтрокамДок(Режим)
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Накл.Номенклатура,
	|	Накл.Количество КАК КолДок,
	|	Накл.Сумма КАК СуммаДок,
	|	ЕСТЬNULL(Ост.КоличествоОстаток, 0) КАК КолОст,
	|	ЕСТЬNULL(Ост.СуммаОстаток, 0) КАК СуммаОст
	|ИЗ
	|	(ВЫБРАТЬ
	|		Док.Номенклатура КАК Номенклатура,
	|		СУММА(Док.Количество) КАК Количество,
	|		СУММА(Док.Сумма) КАК Сумма
	|	ИЗ
	|		Документ.Расходная.Товары КАК Док
	|	ГДЕ
	|		Док.Ссылка = &Ссылка
	|	
	|	СГРУППИРОВАТЬ ПО
	|		Док.Номенклатура) КАК Накл
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
	|		&Момент,
	|		Склад = &Склад
	|		    И Номенклатура В
	|		        (ВЫБРАТЬ РАЗЛИЧНЫЕ
	|		            Док.Номенклатура
	|		        ИЗ
	|		            Документ.Расходная.Товары КАК Док
	|		        ГДЕ
	|		            Док.Ссылка = &Ссылка)) КАК Ост
	|		ПО Накл.Номенклатура = Ост.Номенклатура";
	Если Режим = РежимПроведенияДокумента.Оперативный Тогда 
		Запрос.Текст = Запрос.Текст+"
		|ДЛЯ ИЗМЕНЕНИЯ
		|	РегистрНакопления.ОстаткиНоменклатуры.Остатки";
	КонецЕсли;
	
	Запрос.УстановитьПараметр("Ссылка",Ссылка);
	Запрос.УстановитьПараметр("Момент",МоментВремени());
	Запрос.УстановитьПараметр("Склад",Склад);
	РезультатЗапроса = Запрос.Выполнить();
	
	//For Test Only!	
	РезультатЗапроса.Выгрузить().ВыбратьСтроку("По РегистрНакопления.ОстаткиНоменклатуры.Остатки"); //kvv
	
	Возврат РезультатЗапроса;
КонецФункции //СформироватьЗапросПоСтрокамДок(Режим)
Проверка заполнения реквизитов в строке табличной части документа и условий возможности проведения

Теперь результат запроса содержит все необходимые данные для проверки заполнения реквизитов в строке табличной части документа и условий возможности проведения. Создадим процедуру "ПроверитьЗаполнениеСтроки", в которой проверим заполнение реквизитов табличной части документа. Если реквизиты не заполнены - выводим сообщение об отказе проведения документа.

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

Создадим процедуру "КонтрольПроведенияСтроки", в которой организуем контроль остатка товаров в разрезе складов. Если товара не хватает - выводим сообщение об отказе проведения документа.

Процедура КонтрольПроведенияСтроки(Выборка,Отказ)
//Контроль остатка
	Нехватка = Выборка.КолДок - Выборка.КолОст;
	Если Нехватка > 0 Тогда
		Сообщить("Hexватка товара "+СокрЛП(Выборка.Номенклатура)+ ": "+Нехватка+
			" на складе "+Склад);
		Сообщить("Документ: "+СокрЛП(Ссылка)+" не проводится!");
	Отказ = Истина;
	КонецЕсли;
КонецПроцедуры	
Формирование движений по строке табличной части документа

Переберем выборку в цикле, выполняя проверку заполнения строки и контроль проведения строки. Сформируем движения по строке документа со списанием себестоимости по средневзвешенному (по складу) методу.

В результате модуль объекта Документ Расходная ,будет содержть следующий код:

Процедура ОбработкаПроведения(Отказ, Режим)
	// Проверка заполнения реквизита "Склад"
	Если Склад = Справочники.МестаХранения.ПустаяСсылка() Тогда
		Сообщить("Не заполнен реквизит Склад", СтатусСообщения.Внимание);
		Отказ = Истина;
		Возврат;
	КонецЕсли;
	
	//Запрос по табличной части документа и по регистрам	
	РезультатПоСтрокамДок = СформироватьЗапросПоСтрокамДок(Режим);
	
	//В цикле по строкам табличной части будем добавлять информацию в движения документа
	Выборка = РезультатПоСтрокамДок.Выбрать();
	Пока Выборка.Следующий() Цикл 
		//Проверить заполнение реквизитов табличной части и возможность проведения
		ПроверитьЗаполнениеСтроки(Выборка,Отказ);
		КонтрольПроведенияСтроки(Выборка,Отказ);
		
		//Сформируем движения по строке документа
		Если Не Отказ Тогда
			//Вычисляем себестоимость списания.
			//Если списываем все количество, то и списываем всю себестоимость
			//для исключения ошибки деления
			Если Выборка.КолДок < Выборка.КолОст Тогда
				Себестоимость = Выборка.СуммаОст/Выборка.КолОст * Выборка.КолДок;
			Иначе
				Себестоимость = Выборка.СуммаОст;
			КонецЕсли;     
			//Все данные, необходимые для проведения, получены и рассчитаны
			//формируем движения по нужным регистрам.
			//регистр ОстаткиНоменклатуры Расход
			Движение = Движения.ОстаткиНоменклатуры.Добавить();
			Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
			Движение.Период = Дата;
			Движение.Номенклатура = Выборка.Номенклатура;
			Движение.Склад = Склад;
			Движение.Количество = Выборка.КолДок;
			Движение.Сумма = Себестоимость;
			
			//по регистру "Продажи"
			Движение = Движения.Продажи.Добавить();
			Движение.Период = Дата;
			Движение.Номенклатура = Выборка.Номенклатура;
			Движение.Контрагент = Контрагент;
			Движение.Количество = Выборка.КолДок;
			Движение.Сумма = Выборка.СуммаДок;
		КонецЕсли;
	КонецЦикла;
	// записываем движения регистров
КонецПроцедуры //ОбработкаПроведения(Отказ, Режим)

//Запрос по табличной части с получением данных из регистра накопления
Функция СформироватьЗапросПоСтрокамДок(Режим)

//Проверить заполнение реквизитов в строке табличной части и условий возможности проведения
Процедура ПроверитьЗаполнениеСтроки(Выборка,Отказ)
Процедура КонтрольПроведенияСтроки(Выборка,Отказ)

Переходим в режим 1С:Предприятие, перепроводим документы "Расходная" и проверяем движения по регистрам.

Проверяем списание себестоимости в регистре накопления "ОстаткиНоменклатуры"

Проверяем движения в регистре накопления "Продажи"

Автоматический расчет скидки покупателю при оформлении расходной накладной.

Размер скидки зависит от суммы уже произведенных закупок в предыдущем месяце. При подборе товара цена должна рассчитываться следующим образом: Цена = ЦенаЧист*(100-ПроцСкидки)/100. При изменении контрагента должны: устанавливаться соответствующий ему процент скидки; пересчитываться цены в строках накладной. Для этого необходимо сделать следующие изменения:

# добавить реквизит "ПроцентСкидки" в шапку документа

# создать обработчик при изменении поля ввода Номенклатура

Процедура ТоварыНоменклатураПриИзменении(Элемент)
	СтрокаТЧ = ЭлементыФормы.Товары.ТекущиеДанные;
	СтрокаТЧ.Цена=СтрокаТЧ.Номенклатура.ЦенаПродажи*(100-ПроцентСкидки)/100;
	ТоварыКоличествоПриИзменении(Элемент);
КонецПроцедуры

# создать обработчик при изменении поля ввода Контрагент

Процедура КонтрагентПриИзменении(Элемент)
	// Вставить содержимое обработчика.
	Если Контрагент <> Справочники.Контрагенты.ПустаяСсылка() Тогда 
		Отбор = Новый Структура("Контрагент", Контрагент);
		ОбъемЗакупки =
РегистрыНакопления.Продажи.Обороты(НачалоМесяца(ДобавитьМесяц(Дата,-1)),КонецМесяца(ДобавитьМесяц(Дата,-1)),Отбор,"Контрагент","Сумма");
		//KVV For Test Only!
		ОбъемЗакупки.ВыбратьСтроку("Продажи.Обороты за предыдущий месяц по "+Контрагент); //kvv*
		ПроцентСкидки = 0;
		Если ОбъемЗакупки.Количество() > 0 Тогда 
			СуммаЗакупки = ОбъемЗакупки[0].Сумма;
 			Если СуммаЗакупки >= 10000 Тогда ПроцентСкидки = 15;
				ИначеЕсли СуммаЗакупки >= 5000 Тогда ПроцентСкидки = 10;
				ИначеЕсли СуммаЗакупки >= 3000 Тогда ПроцентСкидки = 5;	
				ИначеЕсли СуммаЗакупки >= 1000 Тогда ПроцентСкидки = 2;	
			КонецЕсли;
		КонецЕсли;	
		// Пересчитаем цену во всех строках табличной части согласно новой скидки
		Для Каждого СтрокаТЧ Из Товары Цикл
			СтрокаТЧ.Цена = СтрокаТЧ.Номенклатура.ЦенаПродажи*(100-ПроцентСкидки)/100;
			СтрокаТЧ.Сумма = СтрокаТЧ.Цена*СтрокаТЧ.Количество;
		КонецЦикла;
	КонецЕсли;	
КонецПроцедуры //КонтрагентПриИзменении(Элемент)

Добавим в форму документа "Расходная" надпись "Процент скидки" и надпись "ПроцентСкидки" тип данных - реквизит документа "Расходная".

Переходим в режим 1С:Предприятие и проверяем документ "Расходная". При изменении реквизитов "Контрагент" и "Номенклатура" - надпись "Процент скидки" и табличная часть документа должны пересчитываться.

Сформировать конструктором отчет по регистру накопления – "Материальная ведомость" (начальный остаток, приход, расход, остаток) в разрезе складов и товаров.

Создадим отчет, дадим ему имя «МатериальнаяВедомость» и сразу же перейдем на закладку «Макеты». Используя кнопку «Конструкторы» вызовем нужный нам конструктор. В открывшейся сразу после этого форме нужно определить имя выходной формы отчета "МатериальнаяВедомость". Далее на закладке «Таблицы и поля» необходимо выбрать таблицу и поля запроса. Выберем виртуальную таблицу ОстаткиИОбороты регистра накопления "ОстаткиНоменклатуры". Именно в этом регистре накапливается информации о движении товаров в разрезе складов. Сразу же зададим параметры виртуальной таблицы (&НачПериода, &КонПериода, Периодичность - Регистратор). Выберем все поля виртуальной таблицы, за исключением "СуммаОборот" и "КоличествоОборот".

На закладке «Объединения/Псевдонимы» изменим псевдонимы полей и будем далее настраивать раздел «Итоги». Здесь в качестве группировочных полей выберем "Номенклатура" и "Склад", при этом поле "Склад" должно быть первым. Это позволит располагать итоги по складам “выше” итогов по товарам. В качестве итоговых полей укажем все остальные поля и нужно поставить птицу “Общие итоги”

На странице “Построитель" -> "Поля” определим порядок полей: с начала начальные остатки, потом приход, потом расход и конечные остатки.

На странице "Отчет" согласимся с параметрами, которые конструктор предложил по умолчанию, единственное, что изменим - вариант стандартного оформления установим "Бронза". На странице "Выходная форма" установим порядок параметров и укажим их тип - "Дата". На закладке "Форма настройки построителя отчета" страницы "Выходная форма" установим птицу "Отбор" и снимем птицу "Отбор в форме отчета".

Переходим в режим 1С:Предприятие (F5) и формируем отчет "Материальная Ведомость":

Таким образом разработан многофункциональный отчет, который полностью создан с помощью конструктора выходной формы. Многофункциональность позволяет с помощью формы "Настройки отчета" установить отбор и состав выбранных полей, порядок вывода результатов.

Решение. Бухгалтерский учет

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

На основании вышесказанного необходимо:

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

В качестве источника данных бухгалтерского учета добавим в запрос виртуальную таблицу Остатки регистра бухгалтерии Управленческий с помощью конструктора запроса.

Указываем параметры виртуальной таблицы Остатки:

Указываем соединение таблиц на закладке Связи

Указываем поля по которым сгруппируем информацию

В результате функция СформироватьЗапросПоСтрокамДок(Режим) имеет следующий вид:

//Запрос по табличной части с получением данных из регистра накопления
Функция СформироватьЗапросПоСтрокамДок(Режим)
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Накл.Номенклатура,
	|	СУММА(Накл.Количество) КАК КолДок,
	|	СУММА(Накл.Сумма) КАК СуммаДок,
	|	ЕСТЬNULL(Ост.КоличествоОстаток, 0) КАК КолОст,
	|	ЕСТЬNULL(Ост.СуммаОстаток, 0) КАК СуммаОст,
	|	ЕСТЬNULL(Упр.СуммаОстаток, 0) КАК СуммаУпр,
	|	ЕСТЬNULL(Упр.КоличествоОстаток, 0) КАК КолУпр
	|ИЗ
	|	(ВЫБРАТЬ
	|		Док.Номенклатура КАК Номенклатура,
	|		СУММА(Док.Количество) КАК Количество,
	|		СУММА(Док.Сумма) КАК Сумма
	|	ИЗ
	|		Документ.Расходная.Товары КАК Док
	|	ГДЕ
	|		Док.Ссылка = &Ссылка
	|	
	|	СГРУППИРОВАТЬ ПО
	|		Док.Номенклатура) КАК Накл
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
	|		&Момент,
	|		Склад = &Склад
	|		    И Номенклатура В
	|		        (ВЫБРАТЬ РАЗЛИЧНЫЕ
	|		            Док.Номенклатура
	|		        ИЗ
	|		            Документ.Расходная.Товары КАК Док
	|		        ГДЕ
	|		            Док.Ссылка = &Ссылка)) КАК Ост
	|		ПО Накл.Номенклатура = Ост.Номенклатура
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Управленческий.Остатки(
	|		&Момент,
	|		&Счет = Счет,
	|		&Субконто1,
	|		Субконто1 В
	|		    (ВЫБРАТЬ РАЗЛИЧНЫЕ
	|		        Док.Номенклатура
	|		    ИЗ
	|		        Документ.Расходная.Товары КАК Док
	|		    ГДЕ
	|		        Док.Ссылка = &Ссылка)) КАК Упр
	|		ПО Накл.Номенклатура = Упр.Субконто1
	|
	|СГРУППИРОВАТЬ ПО
	|	Накл.Номенклатура,
	|	ЕСТЬNULL(Ост.КоличествоОстаток, 0),
	|	ЕСТЬNULL(Ост.СуммаОстаток, 0),
	|	ЕСТЬNULL(Упр.СуммаОстаток, 0),
	|	ЕСТЬNULL(Упр.КоличествоОстаток, 0)";
	Если Режим = РежимПроведенияДокумента.Оперативный Тогда 
		Запрос.Текст = Запрос.Текст+"
		|ДЛЯ ИЗМЕНЕНИЯ
		|	РегистрНакопления.ОстаткиНоменклатуры.Остатки";
	КонецЕсли;
	
	Запрос.УстановитьПараметр("Ссылка",Ссылка);
	Запрос.УстановитьПараметр("Момент",МоментВремени());
	Запрос.УстановитьПараметр("Склад",Склад);
	Запрос.УстановитьПараметр("Счет",ПланыСчетов.Управленческий.Товары);
	Запрос.УстановитьПараметр("Субконто1",ПланыВидовХарактеристик.ВидыСубконто.Номенклатура);
	
	РезультатЗапроса = Запрос.Выполнить();
	//For Test Only!	
	РезультатЗапроса.Выгрузить().ВыбратьСтроку("По РегистрНакопления.ОстаткиНоменклатуры.Остатки"); //kvv
	
	Возврат РезультатЗапроса;
КонецФункции //СформироватьЗапросПоСтрокамДок(Режим)

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

Процедура ОбработкаПроведения(Отказ, Режим)
	// Проверка заполнения реквизита "Склад"
	Если Склад = Справочники.МестаХранения.ПустаяСсылка() Тогда
		Сообщить("Не заполнен реквизит Склад", СтатусСообщения.Внимание);
		Отказ = Истина;
		Возврат;
	КонецЕсли;
	
	//Запрос по табличной части документа и по регистрам	
	РезультатПоСтрокамДок = СформироватьЗапросПоСтрокамДок(Режим);
	
	//В цикле по строкам табличной части будем добавлять информацию в движения документа
	Выборка = РезультатПоСтрокамДок.Выбрать();
	Пока Выборка.Следующий() Цикл 
		//Проверить заполнение реквизитов табличной части и возможность проведения
		ПроверитьЗаполнениеСтроки(Выборка,Отказ);
		КонтрольПроведенияСтроки(Выборка,Отказ);
		
		//Сформируем движения по строке документа
		Если Не Отказ Тогда
			//Вычисляем себестоимость списания.
			//Если списываем все количество, то и списываем всю себестоимость
			//для исключения ошибки деления
			Если Выборка.КолДок < Выборка.КолОст Тогда
				Себестоимость = Выборка.СуммаОст/Выборка.КолОст * Выборка.КолДок;
			Иначе
				Себестоимость = Выборка.СуммаОст;
			КонецЕсли;     
			//Все данные, необходимые для проведения, получены и рассчитаны
			//формируем движения по нужным регистрам.
			//регистр ОстаткиНоменклатуры Расход
			Движение = Движения.ОстаткиНоменклатуры.Добавить();
			Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
			Движение.Период = Дата;
			Движение.Номенклатура = Выборка.Номенклатура;
			Движение.Склад = Склад;
			Движение.Количество = Выборка.КолДок;
			Движение.Сумма = Себестоимость;
			
			//по регистру "Продажи"
			Движение = Движения.Продажи.Добавить();
			Движение.Период = Дата;
			Движение.Номенклатура = Выборка.Номенклатура;
			Движение.Контрагент = Контрагент;
			Движение.Количество = Выборка.КолДок;
			Движение.Сумма = Выборка.СуммаДок;
			
			//регистр Управленческий
			//себестоимость списываемого товара по средневзвешенному методу
			Если Выборка.КолДок < Выборка.КолУпр Тогда
				СебестоимостьУпр = Выборка.СуммаУпр/Выборка.КолУпр*Выборка.КолДок;
			Иначе
				СебестоимостьУпр = Выборка.СуммаУпр;
			КонецЕсли;
			
			Движение = Движения.Управленческий.Добавить();
			Движение.Период = Дата;
			Движение.Сумма = СебестоимостьУпр;
			Движение.СчетДт = ПланыСчетов.Управленческий.Капитал;
			Движение.СчетКт = ПланыСчетов.Управленческий.Товары;
			Движение.КоличествоКт = Выборка.КолУпр;
			//Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = Выборка.Номенклатура;
			Движение.СубконтоКт.Номенклатура = Выборка.Номенклатура;
			Движение.Содержание = "Списана себестоимость";
		КонецЕсли;
	КонецЦикла;
	
	Движение = Движения.Управленческий.Добавить();
	Движение.Период = Дата;
    	Движение.Сумма = Товары.Итог("Сумма");
	Движение.СчетДт = ПланыСчетов.Управленческий.Дебиторка;
	Движение.СчетКт = ПланыСчетов.Управленческий.Капитал;
	Движение.СубконтоДт.Контрагенты = Контрагент;
	Движение.Содержание = "Выручка от реализации";
	
	// записываем движения регистров
КонецПроцедуры //ОбработкаПроведения(Отказ, Режим)

Переходим в режим 1С:Предприятие (F5), проводим Расходные накладные и проверяем движения по регистру Управленческий:

Изменение запроса с учетом новых возможностей 1С:Предприятия 8.1

В 1С:Предприятии 8.1 в механизм запросов добавлены новые возможности.

Использование предопределенных данных конфигурации

Данная возможность упрощает написание текстов запросов и делает их более легкими для восприятия. В тексте запроса можно использовать, аналогичные константным выражениям, предопределенные данные конфигурации.

Обращение в запросах к предопределенным данным конфигурации и значениям системных перечислений осуществляется с помощью литерала функционального типа ЗНАЧЕНИЕ.

Использование временных таблиц

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

Работа с временными таблицами обеспечивается объектом встроенного языка МенеджерВременныхТаблиц. Работа с временными таблицами осуществляется с помощью объекта Запрос. Связь с менеджером временных таблиц устанавливается с помощью свойства Запроса МенджерВременныхТаблиц.

Создаем временную таблицу на основе внешнего источника данных в конструкторе запросов:

На закладке Дополнительно конструктора запросов необходимо выбрать Создание временной таблицы и в поле ввода, справа, указать имя временной таблицы:

В результате данные, выбранные из внешнего источника, будут помещены во временную таблицу, и эта таблица будет связана с менеджером временных таблиц, указанным в качестве свойства МенджерВременныхТаблиц объекта Запрос:

  	//Сформируем временную таблицу значений со свернутыми данными
	//по Номенклатуре из табличной части документа
	ТаблицаНоменклатуры = Товары.Выгрузить(,"Номенклатура,Количество,Сумма");
	ТаблицаНоменклатуры.Свернуть("Номенклатура","Количество,Сумма");
	//Данные из таблицы значений помещаем во временную таблицу
	МенеджерВТ = Новый МенеджерВременныхТаблиц;
	Запрос = Новый Запрос;
	Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
	ТекстЗапроса =
	"ВЫБРАТЬ
	|	ВнешнийИсточник.Номенклатура,
	|	ВнешнийИсточник.Количество,
	|	ВнешнийИсточник.Сумма
	|ПОМЕСТИТЬ ТаблицаНоменклатуры
	|ИЗ
	|	&ВнешнийИсточник КАК ВнешнийИсточник";
	Запрос.Текст = ТекстЗапроса;
	Запрос.УстановитьПараметр("ВнешнийИсточник",ТаблицаНоменклатуры);
	Запрос.Выполнить();

Отчет по регистру бухгалтерии - "Движение товаров" (сальдо на начало дебетовое, дебетовый оборот, кредитовый оборот, сальдо на конец дебетовое) по счету "Товары" в разрезе субконто этого счета.

Создаем отчет Движение товаров. На закладке Макеты нажимаем на кнопку Конструкторы и выбираем Конструктор выходной формы и попадаем в знакомое окно конструктора запроса. В качестве источника информации для отчета выбираем виртуальную таблицу ОстаткиИОбороты регистра бухгалтерии Управленческий

Указываем параметры виртуальной таблицы ОстаткиИОбороты:

На закладке «Объединения/Псевдонимы» изменим псевдонимы полей. На закладке Итоги заполним Группировочное поле и Итоговое поле:

В настройках выходной формы указываем, что параметр счет в форме выбираться не будет и устанавливаем тип параметра Дата:

Для установки параметра Счет нужно исправить строку в процедуре ДвижениеТоваровВывести() модуля формы отчета ДвижениеТоваров: ПостроительОтчетаДвижениеТоваров.Параметры.Вставить("Счет", ПланыСчетов.Управленческий.Товары); и проверяем отчет в режиме предприятие:

Решение. Расчетная часть

По условию задачи в организации используется повременно-премиальная система оплаты труда по часам, следовательно необходимы два вида расчета:

Проверяем планы видов расчета каркасной конфигурации и обнаруживаем, что Оклад является предопределенным видом расчета плана видов расчета ОсновныеНачисления, а Премия является предопределенным видом расчета плана видов расчета ДополнительныеНачисления. Размер премии зависит от оклада. Для отражения этой зависимости установим у предопределенного вида расчета Премия базовым и ведущими видами расчета - Оклад.

Для расчета премий нам необходима информация об объемах продаж в разрезе менеджеров и плановые суммы продаж (Норма, как указано в задании). Документ Раходная каркасной конфигурации имеет реквизит Сотрудник (СправочникСсылка.ФизическиеЛица) и он размещен на форме документа. Учет объемов продаж ведется в регистре Продажи. В каркасной конфигурации регистр Продажи имеет два измерения: Номенклатура и Контрагент, значит мы можем получить информацию о продажах в разрезе товаров и покупателей. Нам необходимо еще получать информацию о продажах в разрезе менеджеров, для этого добавим в регистр еще одно измерение - Сотрудник (СправочникСсылка.ФизическиеЛица), добавим в форму списка регистра Продажи измерение Сотрудник с помощью контекстного меню на табличной части формы списка и добавим изменение в модуль объекта документа Расходная. Это будет всего одна строка (она выделена жирным шрифтом) в той части модуля, которая формирует движения по регистру Продажи:

//по регистру "Продажи"
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = Выборка.Номенклатура;
Движение.Контрагент = Контрагент;
Движение.Сотрудник = Сотрудник;
Движение.Количество = Выборка.КолДок;
Движение.Сумма = Выборка.СуммаДок;

Теперь надо определиться как хранить информацию о норме продаж. Для этого можно добавить дополнительные реквизиты в справочник ФизическиеЛица, создать новый отдельный справочник или константу, а также хранить норму в регистре сведений Сотрудники. Если принять во внимание возможность расчета зарплаты задним числом, то использование периодического регистра сведений Сотрудники является наиболее правильным решением (ведь планы продаж от месяца к месяцу могут меняться). Движения в регистре сведений Сотрудники выполняются документами ПриказОПриеме и ПриказОбУвольнении. Для храненения показателя Норма нужно добавить новый ресурс Норма в регистр сведений Сотрудники, а на форме документа ПриказОПриеме необходимо добавить поле ввода Норма. Можно так же использовать Оклад в качестве показателя Нормы - чем больше Оклад у менеджера, тем бльше должна быть и Норма продаж. Для уменьшения трудоемкости решения учебной задачи примем в качестве нормы размер оклада умноженный например на пять.

Повременно-премиальная система оплаты труда по часам означает, что для расчета оклада нужен календарь. В каркасной конфигурации календарь есть - регистр сведений Графики работы, однако его автоматического заполнения не предусмотрено. Делать механизм заполнения календаря? Этот вопрос пожалуй надо адресовать преподавателю... Предположим он сказал, что этого делать не надо. Тогда что бы не заполнять календарь вручную нужно создавать документы базы данных в периоде январь, февраль 2005 года. В противном случае для автоматизации процесса заполнения календаря нужно модифицировать форму списка справочника ГрафикиРаботы - разместить кнопку заполнения регистра сведений ГрафикиРаботы.

Перейдем к окну редактирования регистра расчета ОсновныеНачисления и проверим заполнение свойств регистра. На закладке данные добавим реквизит ГрафикРаботы. Напомним, что структура регистра, в первую очередь, определяется данными, которые необходимо вывести в отчет. Значения свойств атрибутов регистра должно быть заполнено согласно таблице, приведенной ниже:

Имя атрибута Запрет незаполненных значенийТип данных Базовое Связь с графиком
Сотрудник v СправочникСсылка. Сотрудники v -
Подразделение v СправочникСсылка.Подразделения v -
Должность v СправочникСсылка.Должности v -
Размер - (Число, 10, 2) - -
ГрафикРаботы - СправочникСсылка. ГрафикиРабот - ГрафикРаботы

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

Реквизит Тип данных
Сотрудник СправочникСсылка.ФизическиеЛица
Подразделение СправочникСсылка.Подразделения
Должность СправочникСсылка.Должности
ВидРасчета ПланВидовРасчетаСсылка.ДополнительныеНачисления
ДатаНачала Дата
ДатаОкончания Дата
Размер (Число, 10, 2)

Добавим в форму документа панель Дополнительные начисления и разместим на ней табличную часть ДополнительныеНачисления

На форме документа обеспечим автоматическое заполнение полей Подразделение, Должность и Размер оклада при изменении сотрудника. Создадим обработчик события ОсновныеНачисленияСотрудникПриИзменении(Элемент)

Процедура ОсновныеНачисленияСотрудникПриИзменении(Элемент)
	ОтборСотр = Новый Структура("Сотрудник",Элемент.Значение);
	СведенияСотр = РегистрыСведений.Сотрудники.СрезПоследних(НачалоМесяца(ПериодРегистрации),ОтборСотр);
	Если СведенияСотр.Количество() = 0 Тогда
		Сообщить("Не введены сведения по сотруднику "+Элемент.Значение+"!",СтатусСообщения.Внимание);
	ИначеЕсли СведенияСотр.Количество() = 1 Тогда  
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Подразделение = СведенияСотр[0].Подразделение;
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Должность = СведенияСотр[0].Должность;
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Размер = СведенияСотр[0].Оклад;
	Иначе
		//Если два и более приказов на одного сотрудника (например: основной и совместитель)
		ТекущаяСтрока = СведенияСотр.ВыбратьСтроку("Выберите строку");
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Подразделение = ТекущаяСтрока.Подразделение;
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Должность = ТекущаяСтрока.Должность;
		ЭлементыФормы.ОсновныеНачисления.ТекущиеДанные.Размер = ТекущаяСтрока.Оклад;
	КонецЕсли; 
КонецПроцедуры

Разработаем алгоритм проведения документа НачислениеЗарплаты. Последовательность записи информации в регистр расчета можно представить в следующем виде:

  1. Добавить в регистр необходимое количество записей:
  2. Получить дополнение и ввести сторнирующие записи;
  3. Записать получившийся набор записей;
  4. Получить данные графиков для набора записей в целом;
  5. Рассчитать записи из набора движений регистра расчетов, являющиеся базовыми для других видов;
  6. Записать получившийся набор записей;
  7. Определить расчетную базу, если это необходимо;
  8. Рассчитать оставшиеся записи из набора движений;
  9. Записать получившийся набор записей;

Для решения задачи начисления оклада в текущем периоде потребуется выполнение этапов: №№ 1, 3, 4, 5, 6. Программный код, позволяющий реализовать этапы №1 и №3 можно сформировать с помощью конструктора, после чего внести небольшие изменения:

Размер премии зависит от оклада. Разработаем алгоритм автоматического заполнения табличной части ДополнительныеНачисления на базе введенных сведений об Окладе.

Используются технологии uCoz