Запрос по экзамену "Специалист по платформе" по задаче на сложные расчеты

29.05.25

Разработка - Подготовка к аттестации

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

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

Итак, ниже сам запрос:

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

 

Основные переменные запроса:

  1. ТабСотр - выборка основных данных о начислениях:

    • Сотрудники, даты начала/окончания, подразделения

    • Фильтрация по конкретному документу начисления зарплаты (&Ссылка)

    • Только начисления типа "оклад"

  2. ТабСред - соединение с регистром сведений "СведенияОСотрудниках":

    • Получение данных об окладах сотрудников

    • Только записи, попадающие в период начисления

  3. ТабМаксМин - определение минимальных и максимальных дат:

    • Группировка по сотрудникам и подразделениям

    • Нахождение крайних дат периодов начисления

  4. ТабМин и ТабМинСгруп - поиск окладов на начало периода:

    • Находит последнюю запись об окладе до начала периода начисления

  5. ТабМакс и ТабМаксГрупп - поиск окладов на конец периода:

    • Находит последнюю запись об окладе до окончания периода начисления

  6. Финальный результат:

    • Объединение трех наборов данных:

      1. Оклады на начало периода

      2. Оклады в течение периода

      3. Оклады на конец периода

    • Сортировка по сотрудникам, подразделениям и периодам

 

Основная логика обработки:

 

Инициализация выборки:

Выборка = ВернутьРезультатЗапроса().Выбрать();

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

Цикл по основным начислениям:

Для Каждого ТекСтрокаОсновныеНачисления Из ОсновныеНачисления Цикл

Обрабатываем каждую строку начисления зарплаты, но работаем только с окладами:

Если ТекСтрокаОсновныеНачисления.ВидРасчета <> ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда 
    Продолжить;
КонецЕсли;

 

Инициализация переменных для отслеживания изменений:

 

прошлыйСотрудник = Неопределено;
НачПериод = Дата(1,1,1); 
прошлыйПодразделение = Неопределено;
ПерваяЗапись = Истина;

Эти переменные нужны для сравнения текущей записи с предыдущей.


Обработка выборки:

Пока Выборка.Следующий() Цикл

Последовательно читаем записи из результата запроса.

 

Логика обработки изменений окладов:

Если текущий сотрудник и подразделение совпадают с предыдущими:

Если Выборка.Сотрудник = прошлыйСотрудник и Выборка.Подразделение = прошлыйПодразделение Тогда

 

Создаем движение документа для регистрации периода действия оклада

Движение = Движения.ОсновныеНачисления.Добавить();
Движение.Регистратор = ссылка;
Движение.Сторно = Ложь;
Движение.ВидРасчета = ТекСтрокаОсновныеНачисления.ВидРасчета;
Движение.ПериодДействияНачало = ?(ПерваяЗапись, НачПериод, НачПериод+86400);
Движение.ПериодДействияКонец = КонПериод;
Движение.ПериодРегистрации = Дата; 
Движение.Сотрудник = Выборка.Сотрудник;
Движение.Подразделение = Выборка.Подразделение;

 

Ну или все вместе:

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


		      КонецЦикла;

		     КонецЦикла;

По итогу код создает движения документа для регистрации периодов действия разных окладов сотрудников. Он учитывает, что:

  • Оклад сотрудника мог меняться несколько раз в течение периода начисления

  • Нужно зарегистрировать каждый период с разным окладом

  • Периоды не должны пересекаться (поэтому к дате начала добавляется 1 день для последующих записей)

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

Экзамен Специалист по платформе Сложные запросы первоначальное значение оклада может быть неоднократно изменено.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    190306    1059    403    

989

Подготовка к аттестации Программист Платформа 1С v8.3 1C:Бухгалтерия Платные (руб)

Обучающая программа 1С Online представляет собой интерактивное изучение языка запросов с самого начала: - 50 практических заданий с различным уровнем сложности; - Методические материалы по практике написания запросов; - Описание назначения таблиц и индексов 1С Предприятие 8; - Методика решения реальных задач запросом 1С; - Автоматическая система проверки решений с указанием ошибок; - Инструкции по решению задач с разъяснениями; - Техническая поддержка пользователей. Тренажер запросов подходит для начинающих и действующих разработчиков 1С

1800 руб.

11.02.2014    81187    106    15    

200

Подготовка к аттестации Программист Запросы 1C:Бухгалтерия Платные (руб)

Желаете повысить свой уровень разработки? Не знаете, как оптимизировать работу тяжелых запросов 1С? Или знаете методы оптимизации, но на практике не получаете результат? Тогда эта интерактивная обучающая программа для Вас! Оптимизация запросов прямо в программе 1С:Предприятие 8. Несколько десятков практических заданий, рассматривающих методы оптимизации на практике. От Вас требуются реальные решения - оптимизация представленных запросов. Автоматизированная система оценит Ваш запрос и представит результат проверки.

3000 руб.

06.07.2015    73446    124    9    

137

Подготовка к аттестации Программист Россия Бесплатно (free)

Источники информации для подготовки к Эксперту.

18.12.2024    11581    GraVVitY    61    

67

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13997    sergey279    18    

66

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8837    XilDen    36    

92

Подготовка к аттестации Программист Стажер Платформа 1С v8.3 Россия Бесплатно (free)

Я Олег, разработчик 1С. Расскажу, как сдавал на сертификат Специалиста, в чём ошибся и что стоит учесть.

11.06.2024    18307    PROSTO-1C    54    

72

Подготовка к аттестации Программист Стажер Платформа 1С v8.3 Россия Бесплатно (free)

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

04.06.2024    12710    anton99    50    

58
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. gybson 29.05.25 11:37 Сейчас в теме
Условие, наверное, лучше сразу в запросе сделать.
Ну и итоги использовать вместо "прошлыйСотрудник"
2. leosoft 167 29.05.25 12:28 Сейчас в теме
А условие самой задачи почему не написали?
3. RealEscander 498 29.05.25 13:28 Сейчас в теме
Реально странно публиковать то, что непонятно что решает... или это предложение угадать что этим запросом получается?
4. KHoroshulinAV 171 30.05.25 00:20 Сейчас в теме
Я же описал выше. Часть задач экзамена которые подойдут под требования, будут нуждаться в подобном запросе. Тут не суть в конкретной задаче т.к. сам запрос универсален если рассматривать экзаменационные задачи.
Оставьте свое сообщение