Имя: Пароль:
1C
1C 7.7
v7: Объединение строк в таблице значений по условию
0 useruseruser
 
15.12.19
11:22
Добрый день. Подскажите как правильно будет объединить строки в таблице значений по условию, а именно, имеется ТЗ с колонками дата начала, дата конец, профессия.
Пример:
1 строка: 01.01.2019 - 05.01.2019 инженер
2 строка: 06.01.2019 - 20.01.2019 инженер
3 строка: 21.01.2019 - 25.01.2019 менеджер
4 строка 26.01.2019 - 31.01.2019 - инженер

Необходимо получить вида:
1 строка: 01.01.2019 - 20.01.2019 инженер
2 строка: 21.01.2019 - 25.01.2019 менеджер
3 строка 26.01.2019 - 31.01.2019 - инженер
т.е период продолжается и профессия не изменилась, значит надо свернуть.
Посоветуйте правильный алгоритм.
1 botman4
 
15.12.19
11:36
Добавить колонки в которых будет храниться НачПериода и КонПериода, и при формировании ТЗ, проверять, если Период существует и профессия не изменилась, тогда просто обновляем  значение конец периода!
2 botman4
 
15.12.19
11:37
И период для Вас это что, квартал, месяц, год ?
3 botman4
 
15.12.19
12:00
Лучше использовать конечно "ИндексированнаяТаблица", но если религия не позволяет:

    
ТЗ = СоздатьОбъект("ТаблицаЗначений");
    ТЗ.НоваяКолонка("ДатаНач", "Дата");
    ТЗ.НоваяКолонка("ДатаКон", "Дата");
    ТЗ.НоваяКолонка("НачПериода", "Дата");
    ТЗ.НоваяКолонка("Профессия", "Строка");
    ТЗ.НоваяКолонка("НачПериода_Профессия", "Строка");
    
    
    
    Пока Выборка.ПолучитьСтроку() = 1 Цикл
        НачПериода     = НачКвартала(Выборка.ДатаНач);
        ЗначениеПоиска = Строка(НачПериода)+"_"+ВРЕГ(СокрЛП(Выборка.Профессия)) + "";
        
        Стр = 0;
        Если ТЗ.НайтиЗначение(ЗначениеПоиска, Стр, "НачПериода_Профессия") = 0 Тогда
            ТЗ.НоваяСтрока();
            ТЗ.ДатаНач = Выборка.ДатаНач;
            ТЗ.ДатаКон = Выборка.ДатаКон;
            
            ТЗ.НачПериода = НачПериода;    
            
            ТЗ.Профессия = Выборка.Профессия;
            
            ТЗ.НачПериода_Профессия = ЗначениеПоиска;
            
        Иначе
            
            ТЗ.УстановитьЗначение(Стр, "ДатаКон", Выборка.ДатаКон);
            
        КонецЕсли;
        
        
    КонецЦикла;
4 Cthulhu
 
15.12.19
13:21
а вдрух у тебя между датой увольнения и датой приема на одну и ту же должность - только выходные или празднчные? или нерабочие дни?
(это просто намек на то, что - неа, не надо тебе так объединять, оно и так представительно достаточно - ну т.е. ежели он увольнялся ведь в том числе и "по среднему" разное должно быть, например))))
5 useruseruser
 
15.12.19
14:42
(4) мне необходимо для выгрузки по сзв стажу, если классы условий труда и особые условия труда совпадают то выгружать одним периодом )
6 useruseruser
 
15.12.19
14:45
(2) Будет период год, и будет заполнение таблицы значений по датам всех переводов за год. Но если переводят с одной должности на другую, и классы условий труда и особые условия труда совпадают и профессии, то объединить эти строки в одну
7 useruseruser
 
15.12.19
14:56
(3) я наверно не уточнил, не получить именно строку как тип, а строку табличного значения с колонками дата нач, дата кон, и профессия.
8 Garykom
 
гуру
15.12.19
15:41
1. Все даты из двух колонок копируешь в отдельную ТЗ из одной колонки
2. Сортируешь, находишь соседние пары дат разница в день 05.01.2019 и 06.01.2019
3. Для каждой соседней пары дат находишь строки из исходной ТЗ, которые подходят чтобы первая дата была КонПериода, вторая дата была НачПериода и профессия равна, если такие строки нашел (их может быть несколько и надо все сочетания проверять но на след этапе) то в ТЗ результата переносим сводную строку а исходные удаляем.
4. Повторить п.3 для других сочетаний, учитывая что часть строк уже перенесли, если не нашли подходящих то берем следующую пару дат
5. Когда все пары соседних дат обработаны переносим остаток строк из исходной в результат
9 Cthulhu
 
15.12.19
17:40
// ну если похрен выходные/праздничные/нерабочие между приемом-увольнением, то тупо "по календарным дням" в лоб типа так, наверное:
    //ТЗ=СоздатьОбъект("ТаблицаЗначений");
    //ТЗ.НоваяКолонка("НачДата","Дата");
    //ТЗ.НоваяКолонка("КонДата","Дата");
    //ТЗ.НоваяКолонка("Должость","Строка");
    // допустим оно такое и заполнено...
    ТЗ.Сортировать("+НачДата,Должность");
    КвоСтр=ТЗ.КоличествоСтрок(); ТекСтр=1; Пока ТекСтр<КвоСтр Цикл
        ТЗ.ПолучитьСтрокуПоНомеру(ТекСтр);
        Для ПоискСтр=-КвоСтр По -ТекСтр+1 Цикл
            Если ТЗ.ПолучитьЗначение(-ПоискСтр,"Должность")=ТЗ.Должность Тогда
                Если ТЗ.ПолучитьЗначение(-ПоискСтр,"НачДата")=ТЗ.КонДата+1 Тогда
                    ТЗ.КонДата=ТЗ.ПолучитьЗначение(-ПоискСтр,"КонДата");
                    ТЗ.УдалитьСтроку(-ПоискСтр); КвоСтр=КвоСтр-1;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
10 Cthulhu
 
15.12.19
17:44
// хотя не, так будут пропуски и пролеты. вот так вроде должно как надо сработать:
    ТЗ.Сортировать("+НачДата,Должность");
    КвоСтр=ТЗ.КоличествоСтрок(); ТекСтр=1; Пока ТекСтр<КвоСтр Цикл
        ТЗ.ПолучитьСтрокуПоНомеру(ТекСтр); ПоискСтр = ТекСтр+1; Пока ПоискСтр<=КвоСтр Цикл
            Если ТЗ.ПолучитьЗначение(ПоискСтр,"Должность")=ТЗ.Должность Тогда
                Если ТЗ.ПолучитьЗначение(ПоискСтр,"НачДата")=ТЗ.КонДата+1 Тогда
                    ТЗ.КонДата=ТЗ.ПолучитьЗначение(ПоискСтр,"КонДата");
                    ТЗ.УдалитьСтроку(ПоискСтр); КвоСтр=КвоСтр-1;
                КонецЕсли;
            КонецЕсли;
            ПоискСтр=ПоискСтр+1;
        КонецЦикла;
        ТекСтр=ТекСтр+1;
    КонецЦикла;
11 Djelf
 
15.12.19
17:50
Продолжайте, продолжайте... Давайте больше и еще БОЛЬШЕ решений примитивного перебора.
Кто еще хочет потрать свое время на это элементарное решение?
12 Garykom
 
гуру
15.12.19
17:52
(11) В том то и прикол что вроде бы задачка элементарная но банально не решается.
Особенно для всевозможных приколов, например когда совместительство и сроки перекрываются.
13 useruseruser
 
15.12.19
18:54
Всем спасибо, буду тестировать и отпишусь что в итоге подошло)
14 Cthulhu
 
15.12.19
18:58
(11): ты говоришь это так, как будто в этом есть что-то плохое... (с)
lmao