|   |   | 
| 
 | Сложная сортировка в регистре сведений. | ☑ | ||
|---|---|---|---|---|
| 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 - это какой-то информационный шум. Выбросить сразу! | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |