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

06.05.20

Разработка - Универсальные функции

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

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

 

 

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

&НаСервере
Функция ДанныеПроизводственногоКалендаря(ДатаНач,ДатаОконч,Помесячно);
	
	Времянка = Новый ТаблицаЗначений;
	Времянка.Колонки.Добавить("Дата",Новый ОписаниеТипов("Дата"));
	Времянка.Колонки.Добавить("ВидДня",Новый ОписаниеТипов("ПеречислениеСсылка.ВидыДнейПроизводственногоКалендаря"));
	Времянка.Колонки.Добавить("ДатаПереноса",Новый ОписаниеТипов("Дата"));
	Времянка.Колонки.Добавить("РабДни",Новый ОписаниеТипов("Число"));
	Времянка.Колонки.Добавить("Часы",Новый ОписаниеТипов("Число"));
	Времянка.Колонки.Добавить("Празд",Новый ОписаниеТипов("Число"));
	Времянка.Колонки.Добавить("Выходные",Новый ОписаниеТипов("Число"));
	
	Если Помесячно Тогда
		// "Раскладываем период ДатаНач,ДатаОконч по месяцам и для каждого месяца выполняем Запрос
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ДанныеПроизводственногоКалендаря.Дата КАК Дата,
		|	ДанныеПроизводственногоКалендаря.ВидДня КАК ВидДня,
		|	ДанныеПроизводственногоКалендаря.ДатаПереноса КАК ДатаПереноса
		|ИЗ
		|	РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
		|ГДЕ
		|	ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &ДатаНач И &ДатаОконч
		|
		|УПОРЯДОЧИТЬ ПО
		|	Дата";
	
	Запрос.УстановитьПараметр("ДатаНач", ДатаНач);
	Запрос.УстановитьПараметр("ДатаОконч", КонецДня(ДатаОконч));
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	ЧасДень = 8; //Кол-во часов в день при 40-часовой рабочей неделе
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		НС = Времянка.Добавить();
		НС.Дата = ВыборкаДетальныеЗаписи.Дата;
		НС.ВидДня = ВыборкаДетальныеЗаписи.ВидДня;
		НС.ДатаПереноса = ВыборкаДетальныеЗаписи.ДатаПереноса;
		Если ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий
			ИЛИ ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный Тогда
		НС.РабДни = 1;
		КонецЕсли;
		ЧасыРаб = ?(ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий,ЧасДень,0);
		ЧасыПр = ?(ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный,ЧасДень-1,0);
		НС.Часы = ЧасыРаб + ЧасыПр;
		НС.Празд = ?(ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Праздник,1,0);
		Суббота = ?(ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота,1,0);
		Воскресенье = ?(ВыборкаДетальныеЗаписи.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье,1,0);
		НС.Выходные = Суббота + Воскресенье;
	КонецЦикла;
	РабДни = Времянка.Итог("РабДни");
	Часы = Времянка.Итог("Часы");
	Празд = Времянка.Итог("Празд");
	Выходные = Времянка.Итог("Выходные");
	
	ВыбрРеквизиты = Новый Структура("РабДни,Часы,Празд,Выходные");
		
	ВыбрРеквизиты.Вставить("РабДни",РабДни);
	ВыбрРеквизиты.Вставить("Часы",Часы);
	ВыбрРеквизиты.Вставить("Празд",Празд);
	ВыбрРеквизиты.Вставить("Выходные",Выходные);
	Возврат ВыбрРеквизиты;
	
КонецФункции

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

Тестировалась на платформе 8.3.17, релиз 3.1.13.151, но думаю, что будет работать на любом релизе.

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

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2670    0    John_d    8    

54

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4606    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3960    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8818    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16143    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7243    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. vkozak 07.05.20 14:49 Сейчас в теме
Забавно. Буду решать подобную задачу воспользуюсь идеей.
2. ivnik 581 07.05.20 18:46 Сейчас в теме
(1) Когда мне что-то нравиться, я обычно ставлю Плюсик и сохраняю в "Избранное", чтобы когда понадобиться, не долго искать.
3. pepper62 12.05.20 13:11 Сейчас в теме
Вот Вам немножко типового функционала с двумя вариантами. В "бою" используется первый.


&НаСервере
Функция ПолучитьНормуФактВремени(ТаблицаСотрудников, МесяцПолучения)

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


&НаСервере
Функция ПолучитьВТСотрудники(ТаблицаСотрудников)
	МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	
	МассивСотрудников = ТаблицаСотрудников.ВыгрузитьКолонку("Сотрудник");
	
	
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|    ТаблицаСотрудники.Сотрудник,
	|    ТаблицаСотрудники.Месяц,
	|    ТаблицаСотрудники.ДатаАктуальности,        
	|    ТаблицаСотрудники.ДатаНачала,
	|    ТаблицаСотрудники.ДатаОкончания
	|ПОМЕСТИТЬ ВТСотрудники
	|ИЗ
	|    &ТаблицаСотрудники КАК ТаблицаСотрудники");
	
	Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	Запрос.УстановитьПараметр("ТаблицаСотрудники", ТаблицаСотрудников);
	Запрос.Выполнить();
	
	Возврат МенеджерВременныхТаблиц;
КонецФункции
Показать
user_2010; +1 Ответить
4. ivnik 581 12.05.20 14:02 Сейчас в теме
(3) Большое Спасибо!!! Очень интересный вариант.
5. charivnick 45 09.03.22 13:18 Сейчас в теме
Все хорошо, только норма рассчитанная через УчетРабочегоВремениРасширенный, не обязательно будет соответствовать норме по
производственному календарю. Поэтому пока вариант расчета нормы, предложенный автором, единственный.
6. kvikster 84 08.04.22 23:46 Сейчас в теме
Возможно кому-то потребуются сумма часов за период:

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

Запрос.УстановитьПараметр("Часов", ?(ДлительностьРабочейНедели>0,ДлительностьРабочейНедели,40));
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
Запрос.УстановитьПараметр("ПроизводственныйКалендарь", Объект.Календарь);

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

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

Пока ВДЗ.Следующий() Цикл
ТС.НормаПоКалендарю = ВДЗ.РабочихЧасовДлительностьНедели;
КонецЦикла;
Оставьте свое сообщение