|
Сложная сортировка в регистре сведений. | ☑ | ||
---|---|---|---|---|
0
Crimscon
05.03.19
✎
11:28
|
Пишу свою конфигурацию, где будет использован планировщик для отображения работы сотрудника и/или доступности данного сотрудника для приема.
Есть у меня справочник "графики работы". Где все данные раскиданы аккуратно и понятно. В ней я указываю сотруднику график работы. 2/2, 3/2, 5/2, будни. В справочнике указывается время и день по порядку, а дата уже в регистр пишется. Возникает проблема, при записи этих данных из справочника в регистр и происходит неведомое, и график из пользовательского варианта: Понедельник - с 9 до 15 Вторник - с 9 до 12 Среда - с 15 до 18. После вытаскивания данных запросом по двум таблицам превращается в: Понедельник с 9 до 15, номер дня 1 Понедельник с 9 до 12, номер дня 2 Понедельник с 15 до 18, номер дня 3 Вторник с 9 до 15, номер дня 1 Вторник с 9 до 12, номер дня 2 Вторник с 15 до 18, номер дня 3 ... Я выставляю дату, допустим 27 февраля. Это среда. И я не знаю какой этот день по порядку. Первый, второй или третий, а может и вовсе пятый. Я знаю только сколько всего дней в периоде графика. А за счёт регистра я могу узнать рабочий этот день в принципе или нет. Мне нужно из этих данных найти первый день в периоде и узнать сколько дней прошло относительно первого дня, чтоб узнать выбранный день. Проблема возникает тогда, когда мне нужно найти период более 1 дня. Допустим, с 27 по 28 число. Или с 25 февраля по 1 марта. И может быть так, что допустим, 27 не рабочий день вообще у конкретного сотрудника. И если период у меня работает, хоть и с костылем, то если на неделе появляется праздник - вся работа функции плывет на количество дней. Если 3 выходных в рабочие дни, то в понедельник будет записан график за четверг и т.д. В общем-то проблема именно в сортировке данных. Или я что-то накосячил с запросом, но честно говоря, я так и не пойму где ошибка. Код, если нужно, приложу отдельным сообщением. |
|||
1
Crimscon
05.03.19
✎
11:28
|
Функция ПолучитьВремяРаботыСотрудника(Сотрудник, Период) Экспорт
ТабГрафика = Новый ТаблицаЗначений; ТабГрафика.Колонки.Добавить("ДатаНачала"); ТабГрафика.Колонки.Добавить("ДатаОкончания"); ТабГрафика.Колонки.Добавить("ДатаГрафика"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | КалендариРасписаниеРаботы.НомерДня КАК НомерДня |ИЗ | Справочник.Календари.РасписаниеРаботы КАК КалендариРасписаниеРаботы |ГДЕ | КалендариРасписаниеРаботы.Ссылка.Сотрудник = &Сотрудник"; Запрос.УстановитьПараметр("Сотрудник", Сотрудник); ДниВРасписании = Запрос.Выполнить().Выгрузить(); КоличествоДнейГрафика = ДниВРасписании.Количество(); КоличествоДнейПериода = Окр((Период.ДатаОкончания - Период.ДатаНачала) / 86400); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика, | КалендариРасписаниеРаботы.НомерДня КАК НомерДня, | КалендариРасписаниеРаботы.ВремяНачала КАК ВремяНачала, | КалендариРасписаниеРаботы.ВремяОкончания КАК ВремяОкончания, | КалендарныеГрафики.ДеньВключенВГрафик КАК ДеньВключенВГрафик |ИЗ | Справочник.Календари.РасписаниеРаботы КАК КалендариРасписаниеРаботы | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики | ПО КалендарныеГрафики.Календарь = КалендариРасписаниеРаботы.Ссылка |ГДЕ | КалендарныеГрафики.ДатаГрафика МЕЖДУ &ДатаНачала И &ДатаОкончания | И КалендариРасписаниеРаботы.Ссылка.Сотрудник = &Сотрудник"; Запрос.УстановитьПараметр("Сотрудник", Сотрудник); Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(Период.ДатаНачала - (86400 * Окр(КоличествоДнейГрафика / 2, 0, 1)))); Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(Период.ДатаОкончания + (86400 * Окр(КоличествоДнейГрафика / 2, 0, 1)))); Результат = Запрос.Выполнить().Выгрузить(); Результат.Сортировать("ДатаГрафика Возр, НомерДня Возр"); РезультатДляНомераДня = Запрос.Выполнить().Выгрузить(); РезультатДляНомераДня.Сортировать("ДатаГрафика Возр, НомерДня Возр"); РезультатДляНомераДня.Свернуть("ДатаГрафика, ДеньВключенВГрафик"); Итератор = 0; НомерДня = 1; НомерДняНачала = 0; НомерДняОкончания = 0; Пока КоличествоДнейГрафика <> 0 Цикл Для Каждого Стр Из РезультатДляНомераДня Цикл Если Период.ДатаНачала - (86400 * Окр(КоличествоДнейГрафика / 2, 0, 1)) = Стр.ДатаГрафика И НЕ Стр.ДеньВключенВГрафик Тогда Если КоличествоДнейГрафика = 0 Тогда Прервать; КонецЕсли; КоличествоДнейГрафика = КоличествоДнейГрафика - 1; ИначеЕсли Период.ДатаНачала - (86400 * Окр(КоличествоДнейГрафика / 2, 0, 1)) = Стр.ДатаГрафика И Стр.ДеньВключенВГрафик Тогда Если КоличествоДнейГрафика = 0 Тогда Прервать; КонецЕсли; НомерДняНачала = НомерДняНачала + 1; КоличествоДнейГрафика = КоличествоДнейГрафика - 1; КонецЕсли; КонецЦикла; КонецЦикла; КоличествоДнейГрафика = ДниВРасписании.Количество(); ПараметрыОтбора = Новый Структура; НеРабочийДень = 0; Для Итератор = 0 По КоличествоДнейПериода - 1 Цикл НачалоПериода = Период.ДатаНачала + (86400 * Итератор) + (86400 * НеРабочийДень); Если НачалоПериода <= Период.ДатаОкончания Тогда Если Итератор = КоличествоДнейГрафика ИЛИ НомерДняНачала = КоличествоДнейГрафика Тогда НомерДняНачала = 1; ИначеЕсли Итератор > КоличествоДнейГрафика ИЛИ НомерДняНачала > КоличествоДнейГрафика Тогда НомерДняНачала = НомерДняНачала + 1; КонецЕсли; ПараметрыОтбора.Вставить("НомерДня", ?(Итератор + НомерДняНачала > КоличествоДнейГрафика, ?(Итератор > НомерДняНачала, НомерДняНачала, Итератор), Итератор + НомерДняНачала)); ПараметрыОтбора.Вставить("ДатаГрафика", НачалоПериода); Строки = Результат.НайтиСтроки(ПараметрыОтбора); Если Строки.Количество() = 1 Тогда Если НЕ Строки[0].ДеньВключенВГрафик Тогда Пока НЕ Строки[0].ДеньВключенВГрафик Цикл //Итератор = ?(Итератор > КоличествоДнейГрафика, Итератор + 1, КоличествоДнейГрафика); НеРабочийДень = НеРабочийДень + 1; //ПараметрыОтбора.Вставить("НомерДня", ?(Итератор + НомерДняНачала > КоличествоДнейГрафика, ?(Итератор > НомерДняНачала, НомерДняНачала, Итератор), Итератор + НомерДняНачала)); ПараметрыОтбора.Вставить("ДатаГрафика", Период.ДатаНачала + (86400 * Итератор) + (86400 * НеРабочийДень)); Строки = Результат.НайтиСтроки(ПараметрыОтбора); КонецЦикла; КонецЕсли; Строка = ТабГрафика.Добавить(); Строка.ДатаГрафика = Строки[0].ДатаГрафика; Строка.ДатаНачала = Дата(Лев(Строки[0].ДатаГрафика, 11) + Прав(Строки[0].ВремяНачала,8)); Строка.ДатаОкончания = Дата(Лев(Строки[0].ДатаГрафика, 11) + Прав(Строки[0].ВремяОкончания,8)); КонецЕсли; КонецЕсли; КонецЦикла; Возврат ТабГрафика; КонецФункции |
|||
2
sqr4
05.03.19
✎
11:31
|
Много букв, а че надо то
|
|||
3
sqr4
05.03.19
✎
11:33
|
И я бы вообще не признался что мое, тут люди злые.
|
|||
4
Crimscon
05.03.19
✎
11:33
|
Как сделать, чтоб график не плыл на выходных? Все написано на БСП 3.0.2, в справочник ГрафикиРаботы добавлено поле сотрудника, которое ссылается на аналогичный справочник. Это все изменения.
Поэтому собственно, либо косяк в запросе, либо данные из справочника так криво пишутся. |
|||
5
Йохохо
05.03.19
✎
11:36
|
укради из зупа то, что ты хочешь
|
|||
6
sqr4
05.03.19
✎
11:37
|
(4) А куда он плывет, хорошо взорвал?)
Мне нужно из этих данных найти первый день в периоде и узнать сколько дней прошло относительно первого дня, чтоб узнать выбранный день. Проблема возникает тогда, когда мне нужно найти период более 1 дня. Допустим, с 27 по 28 число. Или с 25 февраля по 1 марта. а это зачем? |
|||
7
sqr4
05.03.19
✎
11:37
|
(5) ты бы лучше сразу его проклял, чем в ЗУП посылать что то забрать)
|
|||
8
Йохохо
05.03.19
✎
11:37
|
(7) индивидуальные графики можно и в 2.5 подсмотреть
|
|||
9
Crimscon
05.03.19
✎
11:38
|
(6) Если график начинается в понедельник, а мне нужно найти среду? Учитывая то, каким образом выводятся данные из регистра, мне приходится узнавать на какую дату приходится первый день. И относительно него уже отсчитывать циклом тот, который мне нужен.
|
|||
10
Йохохо
05.03.19
✎
11:39
|
(9) есть такая фигня деньгода()
|
|||
11
Crimscon
05.03.19
✎
11:41
|
(10) Окей. Это если график с пн по пт. А если он 2/2? Первый день по порядку в четверг, потом пятница. А мне нужен понедельник, например. В уме то я могу понять то, что понедельник это 2 день, а программе как это сказать?
|
|||
12
Crimscon
05.03.19
✎
11:41
|
(11) Ну или 1 день, смотря в какую сторону считать.
|
|||
13
sqr4
05.03.19
✎
11:44
|
(9) я когда был студентом делал так. День с которого принят сотрудник и от него отсчитывал по графику. В регистр писал все дни напротив каждого указывая рабочий он или нет
|
|||
14
Crimscon
05.03.19
✎
11:46
|
(13) Ну в общем-то в БСП оно само так и пишется. Только по параметрам, которые в справочнике указываю. Ну и криво пишется, да.
|
|||
15
los_hooliganos
05.03.19
✎
11:48
|
Чем не устраивает типовой механизм "график работы" из подсистемы "расчеты сотрудников"?
|
|||
16
Garykom
гуру
05.03.19
✎
11:48
|
А когда запросами 2+2 начнем считать?
|
|||
17
Crimscon
05.03.19
✎
12:10
|
Отбой. Я немного идиот, потому что, что не смотрел общие модули.
(15) Как раз то, что нужно. В общем модуле "ГрафикиРаботы" уже все написано и работает. |
|||
18
VladZ
05.03.19
✎
12:15
|
(0) У тебя должен быть график работы сотрудников по датам. Привязать сотрудника к графику - этого недостаточно. Сотрудник мог заболеть, или заменить кого-то. Нужен график по датам.
|
|||
19
VladZ
05.03.19
✎
12:17
|
После вытаскивания данных запросом по двум таблицам превращается в:
Понедельник с 9 до 15, номер дня 1 Понедельник с 9 до 12, номер дня 2 Понедельник с 15 до 18, номер дня 3 Вторник с 9 до 15, номер дня 1 Вторник с 9 до 12, номер дня 2 Вторник с 15 до 18, номер дня 3 - это какой-то информационный шум. Выбросить сразу! |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |