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

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    210169    1151    413    

1042

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

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

3600 руб.

11.02.2014    83089    112    15    

207

Инструментарий разработчика Запросы Программист 1С v8.3 Сложные периодические расчеты Запросы 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    4869    83    zup_dev    20    

67

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

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

18.12.2024    13501    GraVVitY    61    

70

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

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

18.10.2024    16314    sergey279    18    

69

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

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

11.10.2024    10972    XilDen    38    

102

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

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

11.06.2024    20814    PROSTO-1C    54    

73

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

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

04.06.2024    15648    anton99    50    

59
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
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 208 30.05.25 00:20 Сейчас в теме
Я же описал выше. Часть задач экзамена которые подойдут под требования, будут нуждаться в подобном запросе. Тут не суть в конкретной задаче т.к. сам запрос универсален если рассматривать экзаменационные задачи.
Для отправки сообщения требуется регистрация/авторизация