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

29.05.25

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

 

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

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

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

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

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

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

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

 

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

 

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

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


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

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

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

 

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

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

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

 

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

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

 

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

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


		      КонецЦикла;

		     КонецЦикла;

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

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

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

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

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

Вступайте в нашу телеграмм-группу Инфостарт

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

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

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

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

16500 руб.

02.09.2020    261360    1458    421    

1170

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

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

5094 руб.

11.02.2014    87880    118    15    

214

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

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

3050 руб.

06.07.2015    76084    127    9    

140

WEB-интеграция Запросы Программист 1С 8.3 Абонемент ($m)

Post1C - это внешняя обработка, которая превращает 1С в полноценный инструмент для тестирования REST API. Всё управление сосредоточено в одном окне: настройка запроса, выполнение, просмотр ответа и генерация кода - без переключения между формами. Аналог Postman, но работающий в привычной среде 1С.

1 стартмани

02.04.2026    2426    72    priem_nv    23    

65

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

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

1 стартмани

16.05.2025    11453    150    zup_dev    30    

83

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

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

18.12.2024    18560    GraVVitY    62    

78

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

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

18.10.2024    23429    sergey279    18    

74

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

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

11.10.2024    18891    XilDen    39    

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