Еще раз о рабочих днях. Быстрый способ расчета в запросах

20.06.19

Разработка - Запросы

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

Скачать исходный код

Наименование Файл Версия Размер
Еще раз о рабочих днях. Быстрый способ расчета в запросах.:
.dt 316,74Kb
15
.dt 316,74Kb 15 Скачать

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

На мой взгляд, предлагаемые решения обладают теми или иными недостатками. В их числе:

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

Предлагаю свой вариант решения.

Постановка задачи:

Предположим, на предприятии ведется учет выполняемых работ. Каждая работа выполняется целое число дней, всегда начинается в начале дня, а заканчивается через несколько дней в конце дня. Продолжительность работ может быть от 1 дня, до нескольких лет (важность условия этого будет упомянута ниже). Необходимо иметь инструмент, позволяющий выполнять расчеты дат начала, окончания работ, продолжительностей работ, временных промежутков между работами. Все расчеты выполнять в рабочих днях. Решение должно позволять использование его в запросах.

В чем могут быть "подводные камни" при решении?  Например токарь работает по стандартному рабочему графику - пятидневке. 01 апреля 2019 он начинает изготавливать деталь №1, тратит на ее изготовление 5 дней, и начинает изготавливать следующую деталь №2. Когда он закончит изготовление детали №1? Когда начнет изготавливать деталь №2? Казалось бы в обоих случаях ответ: через 5 рабочих дней после 01 апреля, т.е. к 01.04.2019 надо прибавить 5 рабочих дней. Но в первом случае ответ - 05.04.2019, а во втором - 08.04.2019.

Решение:

Решение поставленной задачи неожиданно получилось довольно простым.

Предлагается следующее:

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

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

Дата - дата графика (без времени)

ЭтоРабочийДень - флаг рабочий/нерабочий день

КолВоДнейСНачалаПериода - Число рабочих дней, прошедших до начала даты записи, начиная с определенной, наперед заданной даты. В моем примере используется 01.01.2000.

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

Пример содержимого:

 

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

// Возвращает разность в днях между двумя датами (Дата2-Дата1) с учетом рабочего графика 
// Даты до полудня округляются вниз, после - вверх
// Параметры:
//  Дата1  - Дата -  Начальная дата
//  Дата2  - Дата -  Конечная дата
//  РабочийГрафик  - СправочникСсылка.РабочиеГрафики - Рабочий график
// Возвращаемое значение:
//  Число    - разность дат
Функция РазностьДат(Знач Дата1, Знач Дата2, Знач РабочийГрафик)Экспорт
	
	СекундВ12Часах = 12 * 60 * 60;
	Дата1 = НачалоДня(Дата1 + СекундВ12Часах);
	Дата2 = НачалоДня(Дата2 + СекундВ12Часах);
	
	Запр = Новый Запрос;
	Текст = "ВЫБРАТЬ
	        |	РабочиеДни2.КолВоДнейСНачалаПериода - РабочиеДни1.КолВоДнейСНачалаПериода КАК КолВоДней
	        |ИЗ
	        |	РегистрСведений.РабочиеДни КАК РабочиеДни1
	        |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РабочиеДни КАК РабочиеДни2
	        |		ПО (РабочиеДни2.РабочийГрафик = &РабочийГрафик)
	        |			И (РабочиеДни2.Дата = &Дата2)
	        |ГДЕ
	        |	РабочиеДни1.РабочийГрафик = &РабочийГрафик
	        |	И РабочиеДни1.Дата = &Дата1";
	Запр.Текст = Текст;
	Запр.УстановитьПараметр("Дата1", Дата1); 
	Запр.УстановитьПараметр("Дата2", Дата2); 
	Запр.УстановитьПараметр("РабочийГрафик", РабочийГрафик); 
	
	РезЗапроса = Запр.Выполнить();
	Если НЕ РезЗапроса.Пустой() Тогда   
		Выб = РезЗапроса.Выбрать(ОбходРезультатаЗапроса.Прямой);
		Выб.Следующий(); 		
		Результат = Выб.КолВоДней;			
	Иначе	
	КонецЕсли; 
	Возврат Результат;
КонецФункции // 


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

 

Примеры использования

// Когда завершится работа токаря №1?
ДобавитьКДате('20190401', 5, РабочийГрафик, Ложь);

// Когда токарь начнет работу №2 после завершения пятидневной работы №1?
ДобавитьКДате('20190401', 5, РабочийГрафик, Истина);

// Сколько фактически токарь делал работу - от начала до конца?
РазностьДат(НачалоДня(Дата1), КонецДня(Дата2), РабочийГрафик);

// Сколько рабочих дней токарь прогулял между окончанием работы №1 и началом работы №2?
РазностьДат(КонецДня(Дата1), НачалоДня(Дата2), РабочийГрафик);

// Сколько рабочих дней прошло от окончания работы №1 до сегодняшней вечерней планерки?
РазностьДат(КонецДня(Дата1), КонецДня(ТекущаяДата()), РабочийГрафик);

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

Может возникнуть вопрос: оправдано ли с точки зрения производительности использование дополнительного регистра такой структуры, ведь при изменении флага рабочего/выходного дня надо пересчитывать все записи с большей датой? Я считаю, что вполне. Во-первых, изменение производственного календаря происходит обычно не чаще одного раза в месяц, а полный пересчет и сохранение набора записей за 100 лет(~40000 записей) по выбранному графику занимает считанные секунды. А во-вторых, выгода от использования быстрого массового расчета как правило с лихвой перекроет все время, потраченное на предварительную подготовку.

А что же БСП?

Опытный разработчик, использующий БСП, может сказать: "Так ведь в БСП реализовано почти что то же самое!". Да, действительно в БСП есть аналогичный регистр:

Есть также программный интерфейс модулей "ГрафикиРаботы", "КалендарныеГрафики" с функциями "РазностьДатПоКалендарю", "ДатыПоГрафику" и т.п. Но если присмотреться, то можно увидеть, что в регистре имеется измерение "Год". То есть в этом регистре отсчет количества дней идет с начала каждого года. Когда мы работаем с датами в пределах одного года, то подход при расчете совпадает с рассмотренным. Но если даты попадают в разные года, а особенно если рассматривается промежуток в несколько лет, то алгоритм получается весьма сложным. Все интересующиеся могут самостоятельно сравнить объем программного кода в библиотеке и в предложенном решении. Скорее всего, разработчики БСП стремились к упрощению процедуры заполнения - каждый год рабочего графика заполняется отдельно и не зависит от других. Но в результате мы получаем существенное усложнение алгоритмов при решении практических задач. Я бы рекомендовал использовать регистры БСП как источник для заполнения регистра "РабочиеДни", а все дальнейшие операции производить уже с ним.

UPD 25.06.2019:

Для конфигураций с БСП добавлено заполнение регистра на основе данных из типовых объектов - регистра КалендарныеГрафики и справочника Календари. В процессе обработки заполняется регистр за период с 2000 г. по примерно 2109 г. - 40000 дней.

 

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

Рабочие дни запрос календарь график производственный добавить дате разность дат

См. также

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

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

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    124927    682    389    

732

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

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

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    2242    andrey_sag    10    

28

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    6006    KawaNoNeko    23    

25

Набор-объект для СКД по тексту или запросу

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

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2149    2    Yashazz    0    

31

Запрос 1С copilot

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

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6637    31    mkalimulin    27    

51

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

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

14.12.2023    1880    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

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

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5625    user1923546    26    

46

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16593    skovpin_sa    14    

101
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 20.06.19 13:42 Сейчас в теме
Решение поставленной задачи неожиданно получилось довольно простым.

и далее идет описание таблицы которую необходимо добавить конфигурацию для ...простоты.

Мне кажется, что не может быть простым решение для которого требуется добавлять в конфигурацию таблицу. Ведь эту таблицу необходимо обслуживать самостоятельно.
Риник; Meverix; user1835472; Abbra; Nelli_A86; soci0pat; vv2; boln; +8
2. Alxby 1144 20.06.19 15:39 Сейчас в теме
(1)В ваших словах есть доля истины - при обслуживании конфигураций, стоящих на поддержке, придется провести дополнительные работы. Если же абстрагироваться от типовых конфигураций и рассматривать разработку "с нуля", то решение действительно простое - один регистр и несложные алгоритмы расчета. Конечно же, каждый разработчик, принимая решение о внедрении в свою систему какого-либо механизма, должен соотнести трудозатраты с выгодой от такого внедрения. В статье я привел пример задачи, для которой, на мой взгляд, плюсы от его использования с лихвой перекрывают затраты на доработки. В приложенном файле есть пример заполнения регистра - дополнительной таблицы, эту функцию несложно доработать при встраивании в типовую конфигурацию.
user591389_aska_rabota; +1
3. Alxby 1144 25.06.19 10:23 Сейчас в теме
Update: Добавлено заполнение информации на основе данных из типовых объектов БСП
+
4. valej 17.12.19 14:45 Сейчас в теме
Мне помогло в конфигурации ЗКГУ добавить рабочие дни к дате функция общего модуля. КалендарныеГрафики.ДатаПоКалендарю(Сюда график работы или ссылка на производственный календарь, Сюда дату отсчета, Сюда число рабочих дней сколько надо прибавить, Сюда Истину если ошибку выдавать на пустое значение графика)
Divedition; vikb11; +2
5. Alxby 1144 17.12.19 16:56 Сейчас в теме
(4) Возможно ли в этой функции не добавить, а вычесть рабочие даты из заданной даты?
+
6. valej 17.12.19 20:37 Сейчас в теме
(5) Описание функции:
Возвращаемое значение: Дата, Неопределено - дата, увеличенная на количество дней, входящих в график.
+
7. blackhorse1976 29 03.03.20 17:09 Сейчас в теме
Запрос ниже делает Вашу таблицу на лету

ВЫБРАТЬ
	КалендарныеГрафики.Год КАК Год,
	МАКСИМУМ(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) КАК КоличествоДнейВГрафикеСНачалаГода
ПОМЕСТИТЬ ПредыдущиеГода
ИЗ
	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики

СГРУППИРОВАТЬ ПО
	КалендарныеГрафики.Год
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КалендарныеГрафики.Календарь КАК Календарь,
	КалендарныеГрафики.Год КАК Год,
	КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КалендарныеГрафики.ДеньВключенВГрафик) КАК ДеньВключенВГрафик,
	СУММА(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) + СУММА(ЕСТЬNULL(ПредыдущиеГода.КоличествоДнейВГрафикеСНачалаГода, 0)) КАК КоличествоДнейВГрафикеСНачалаГода
ИЗ
	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
		ЛЕВОЕ СОЕДИНЕНИЕ ПредыдущиеГода КАК ПредыдущиеГода
		ПО (КалендарныеГрафики.Год > ПредыдущиеГода.Год)

СГРУППИРОВАТЬ ПО
	КалендарныеГрафики.Календарь,
	КалендарныеГрафики.Год,
	КалендарныеГрафики.ДатаГрафика
Показать
+
8. Alxby 1144 04.03.20 10:07 Сейчас в теме
(7)
Можно конечно обойтись без создания дополнительных метаданных в конфигурации и решать поставленные задачи исключительно запросом. Но цель публикации немного в другом - показать как достаточно простыми средствами обеспечить быстрый способ расчета. Ваш вариант требует а) чтение всего регистра календарных графиков, б) записи промежуточной временной таблицы, в) использование "СГРУППИРОВАТЬ" - достаточно тяжелая операция. Все это приводит к тому, что в ряде случаев он может не удовлетворять требованиям по быстродействию.
Я сейчас не могу потестировать запрос, но у меня вызывают некоторые сомнения строки:
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КалендарныеГрафики.ДеньВключенВГрафик) КАК ДеньВключенВГрафик,
и
СУММА(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) + СУММА(ЕСТЬNULL(ПредыдущиеГода.КоличествоДнейВГрафикеСНачалаГода, 0)) КАК КоличествоДнейВГрафикеСНачалаГода
для тех случаев, когда в ИБ заполнены графики за несколько лет.
+
9. blackhorse1976 29 05.03.20 07:46 Сейчас в теме
(8) В целом согласен, что по реальным записям будет быстрее - но если в ТИПОВОЙ конфиге этого нет - можно обойтись моим "костыликом"... :)

Согласен - строка
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КалендарныеГрафики.ДеньВключенВГрафик) КАК ДеньВключенВГрафик,
лишняя....

По второй части - даже если за один - то тогда первый запрос пустой и срабатывает EСЛИNULL
Номера пофигу от чего считать - он рождетва христова или от первого заполненного дня...
+
10. Alxby 1144 05.03.20 15:43 Сейчас в теме
(9) Я имею в виду вот что:

Это результат работы запроса на моих данных.
Во-первых поле "ДеньВключенВГрафик" всегда равно 1,
во-вторых - данные в последней колонке должны быть неубывающими, а в результате запроса это не так.
+
11. blackhorse1976 29 06.03.20 08:46 Сейчас в теме
Я просто показывал концепцию - в реальном отчете этот запрос оказался уже доработанным до такого вида
ВЫБРАТЬ
	КалендарныеГрафики.Год КАК Год,
	МАКСИМУМ(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) КАК КоличествоДнейВГрафикеСНачалаГода,
	КалендарныеГрафики.Календарь КАК Календарь
ПОМЕСТИТЬ ПредыдущиеГода
ИЗ
	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики

СГРУППИРОВАТЬ ПО
	КалендарныеГрафики.Год,
	КалендарныеГрафики.Календарь
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КалендарныеГрафики.Календарь КАК Календарь,
	КалендарныеГрафики.Год КАК Год,
	КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика,
	СУММА(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) + СУММА(ЕСТЬNULL(ПредыдущиеГода.КоличествоДнейВГрафикеСНачалаГода, 0)) КАК КоличествоДнейВГрафикеСНачалаГода
ПОМЕСТИТЬ ДатыПоГодам
ИЗ
	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
		ЛЕВОЕ СОЕДИНЕНИЕ ПредыдущиеГода КАК ПредыдущиеГода
		ПО КалендарныеГрафики.Год > ПредыдущиеГода.Год
			И КалендарныеГрафики.Календарь = ПредыдущиеГода.Календарь

СГРУППИРОВАТЬ ПО
	КалендарныеГрафики.Календарь,
	КалендарныеГрафики.Год,
	КалендарныеГрафики.ДатаГрафика
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДатыПоГодам.КоличествоДнейВГрафикеСНачалаГода КАК КоличествоДнейВГрафикеСНачалаГода,
	МИНИМУМ(ДатыПоГодам.ДатаГрафика) КАК ДатаГрафика,
	ДатыПоГодам.Календарь.ПроизводственныйКалендарь КАК Календарь
ПОМЕСТИТЬ ДатыПоРабочимДням
ИЗ
	ДатыПоГодам КАК ДатыПоГодам

СГРУППИРОВАТЬ ПО
	ДатыПоГодам.КоличествоДнейВГрафикеСНачалаГода,
	ДатыПоГодам.Календарь,
	ДатыПоГодам.Календарь.ПроизводственныйКалендарь
;
Показать
+
12. ILNIK 32 22.04.21 15:38 Сейчас в теме
Не до конца понял, как будет работать функция ДобавитьКДате().
Таблица1 соединяется с таблицей2, по номеру дня.
Но в случае, если полученная дата будет попадать на рабочие дни , а у них номер дня одинаковый с предыдущим рабочим днем, то запрос выведет несколько дат, нужно брать максимальную?
+
13. Alxby 1144 22.04.21 18:53 Сейчас в теме
(12)У всех рабочих дней в регистре разный "номер дня", в запросе условие (РабочиеДни2.ЭтоРабочийДень), поэтому в результат попадет только один день.
+
14. ILNIK 32 22.04.21 22:23 Сейчас в теме
(13)я имел ввиду попадет на "нерабочий"
Например, мне нужно прибавить к понедельнику 4 рабочих дня

Номера дней.
Понедельник 1
Вторник 2
Среда 3
Четверг 4
Пятница 5
Суббота 6
Воскресенье 6
Понедельник 6

Мне запрос выведет три строки пятница 6, суббота 6 , воскресенье 6
Так?

Ps: понял, у вас там реквизит РабочиеДни2.ЭтоРабочийДень.
Я по-другому сделал немного

Ещё один кейс, если я у меня исходная дата, это нерабочий день, например заполнили в поле воскресенье, и нужно прибавить 6 рабочих дней.
Ваш запрос сработает?
+
15. Alxby 1144 23.04.21 09:32 Сейчас в теме
(14) В Вашем примере запрос выдаст "Понедельник", так как это рабочий день.
Если исходная дата - нерабочий день, запрос также отработает корректно, т.е. результат будет одинаков для исходной даты в субботу, воскресение и утро понедельника.
+
16. fantik33323333 01.09.22 12:20 Сейчас в теме
....
дней = 12;
....
Запрос.Текст =  "ВЫБРАТЬ ПЕРВЫЕ  "+ Строка(Дней) +" 
	                |	ДанныеПроизводственногоКалендаря.Дата КАК Дата
	                |ПОМЕСТИТЬ ВТвыборкаДат
	                |ИЗ
	                |	РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
	                |ГДЕ
	                |	ДанныеПроизводственногоКалендаря.ПроизводственныйКалендарь = &ПроизводственныйКалендарь
	                |	И ДанныеПроизводственногоКалендаря.Дата >= &ДатаНачала
	                |	И ДанныеПроизводственногоКалендаря.ВидДня В(&ВидДня)
	                |
	                |УПОРЯДОЧИТЬ ПО
	                |	Дата
	                |;
Показать


в зависимости от сортировки - первая/последняя строка и будет искомая дата - рабочего или выходного дня от текущего.....
+
17. Alxby 1144 01.09.22 16:18 Сейчас в теме
(16)Для большого количества дней ВТвыборкаДат будет избыточно большая, а нужна из нее только одна строка. И, к тому же, как с таким подходом получить из таблицы с колонками ДатаНачала, КолВоРабДней таблицу ДатаНачала, КолВоРабДней, ДатаОкончания?
+
18. fantik33323333 01.09.22 20:43 Сейчас в теме
поместить это ВТ , затем взять МАКСИМУМ()/Минимум() - минимум - дата начала - максимум - тот самый (например рабочий) день через

ЧислоДней
+
19. Alxby 1144 02.09.22 10:08 Сейчас в теме
(18)Попробуйте, напишите и посмотрите что получиться. А потом оцените объем промежуточных таблиц и скорость выполнения запроса)
+
20. fantik33323333 15.09.22 16:05 Сейчас в теме
коллега, я как раз оценил ради вычисления рабочих дней идею добавления новых "сущностей" в конфигурацию....
+
21. Alxby 1144 15.09.22 19:32 Сейчас в теме
(20) Я не спорю, возможно бывают ситуации, когда добавление новых объектов метаданных нерационально, а задачи из статьи встречаются редко. В моем случае часто встречается необходимость рассчитать разность дат для нескольких тысяч объектов, причем разница дат - несколько лет. Стандартными средствами красиво это не решается. Поверьте, на этом фоне трудозатраты на добавление новых объектов в конфигурацию - исчезающе малая величина.
user1835472; user591389_aska_rabota; +2
22. user1835472 14.06.23 10:24 Сейчас в теме
"Регистр необходимо заполнить на весь период, в пределах которого будут производится расчеты."


А как его заполнить?
+
23. Alxby 1144 14.06.23 10:35 Сейчас в теме
(22)
К статье приложена информационная база, в которой реализован описанный функционал, примеры отчетов, а также процедура заполнения и пересчета регистра.
user1835472; +1
Оставьте свое сообщение