Имя: Пароль:
1C
 
v7: Подскажите алгоритм по обработке ТЗ
0 mg-samara
 
02.10.09
11:57
Есть ТЗ
Подразделение Имя
Подр1         Сидоров
Подр2         Сидоров
Подр1         Петров
Подр3         Иванов
Подр3         Сидоров

Нужно преобразовать его так

Подразделение Имя
Подр1         Сидоров,Петров
Подр2         Сидоров
Подр3         Иванов,Сидоров

Колонка Имя - текстовое поле

[11:49:03] Marat Gimaev: Можно-ли это сделать не тупым перебором?...
[11:49:15] Marat Gimaev: Или других вариантов в 7.7 нет...
1 ДенисЧ
 
02.10.09
11:57
Друггих вариантов нет
2 mg-samara
 
02.10.09
11:58
"Светрка" может идти не только по одному полю.. В примере это одно поле "Подразделение"
3 mg-samara
 
02.10.09
11:58
(1) Мне тоже пока ничего не приходит в голову...
4 mg-samara
 
02.10.09
11:59
(1) Но я надеюкь на коллективный разум! А вдруг!

Просто ТЗ может быть довольно большой и обработка много времени бедут занимать..
5 DGorgoN
 
02.10.09
11:59
тз заполняется запросом?
6 mg-samara
 
02.10.09
12:01
(5) Нет. Это уже результат вычислений.
7 also
 
02.10.09
12:02
Можно взять 1с++ и класс, который позволяет делать запрос к тз
8 Valery
 
02.10.09
12:03
Вот в процессе вычислений сразу и заполняй как нужно. Только думается не очень удобно с такой таблицей будет потом работать.
9 1Сергей
 
02.10.09
12:04
Выгрузить столбец Подразделение в другую ТЗ, свернуть, добавить колонку Сотры. потом цикл по первой таблице, разнося сотров по нужным строкам во второй ТЗ
10 1Сергей
 
02.10.09
12:04
хоть десятки тысячь, должно делаться быстро
11 also
 
02.10.09
12:05
(9) Ну про перебор уже выяснили :)
12 mg-samara
 
02.10.09
12:08
(8) Да там уже все вычеслено - не хочется алгоритм править, просто еще одну колонку к отчету добавляется...
13 SaM58
 
02.10.09
12:09
(12) без перебора никак. ИМХО
14 also
 
02.10.09
12:09
(12) Ну раз не хочется, то либо перебор, либо (7)
15 SaM58
 
02.10.09
12:09
я бы сделал как в (9)
16 leshikkam
 
02.10.09
12:09
Индексированная таблица рассматривается?
17 mg-samara
 
02.10.09
12:10
В общем мыслей пока нету... Будем перебирать. А заказчику скажу, что это очень сложный отчет и поэтому так долго формируется... :-)
18 also
 
02.10.09
12:10
(16) А она поможет?
19 mg-samara
 
02.10.09
12:11
(16) Индексированная таблица рассматривается... Но поможет-ли она?
20 also
 
02.10.09
12:11
(17) Это выход :)
21 SaM58
 
02.10.09
12:11
(17) + и так дорого стоит :)
22 1Сергей
 
02.10.09
12:11
да уж, лень не всегда двигатель прогресса
23 also
 
02.10.09
12:12
24 mg-samara
 
02.10.09
12:12
А индектированная таблица поможет быстро искать. Буду ее использовать.
25 NS
 
02.10.09
12:14
Долго формироваться? у вас миллион сотрудников?
26 mg-samara
 
02.10.09
12:14
(25) Да сотрудников я написал для примера, там на самом деле другие параметры.
27 Mikeware
 
02.10.09
12:15
(19) Однозначно поможет
28 mg-samara
 
02.10.09
12:17
(23) Спасибо, но 1С++ не используется.
29 mg-samara
 
02.10.09
12:17
Всем оргомное спасибо за обсуждение! - пойду делать.
30 also
 
02.10.09
12:17
(28) Прости, а ИТ ты откуда возьмешь тогда?
31 mg-samara
 
02.10.09
12:18
Огромное спасибо! (опечатался) :-)
32 leshikkam
 
02.10.09
12:18
(30) он заново её напишет :-)))
33 mg-samara
 
02.10.09
12:19
(30) Не совсем понял, что ты имеешь ввиду?
34 vde69
 
02.10.09
12:19
делай на основе сортировки и текущего значения, примерно так

   _ТЗ.Сортировать("Контрагент,ДатаДоговора,Договор");
   ТекКонтрагентТхт = "";
   ТекКонтрагент = "";  
   
   ТекДатаДоговора = "";  
   ТекДоговор = "";    
   
   _ТЗ.ВыбратьСтроки();
   Пока  _ТЗ.ПолучитьСтроку() = 1 Цикл  
       
       Если ПустоеЗначение(_ТЗ.Дебитор) = 0 Тогда
           // есть что связывать
           Если ТекКонтрагентТхт = СокрЛП(_ТЗ.Дебитор) Тогда
               _ТЗ.Дебитор = ТекКонтрагент    
           Иначе
               //ТабДоговоров.УдалитьСтроки();
               ТекКонтрагентТхт = СокрЛП(_ТЗ.Дебитор);
               ТекКонтрагент = СвязатьКонтрагента(ТекКонтрагентТхт, Connection);
               _ТЗ.Дебитор = ТекКонтрагент;    
               Если ТекКонтрагент = "" Тогда
                   Сообщить("Не связался контрагент - " + ТекКонтрагентТхт);
                   ТабДоговоров.УдалитьСтроки();
               Иначе
                   // надо закешировать таблицу договоров  
                   ЗакешироватьДоговора(ТабДоговоров, ТекКонтрагент, 2);
               КонецЕсли;
           КонецЕсли;
       КонецЕсли;
       
       Если (ПустоеЗначение(_ТЗ.СчетФактура) = 0) и (ТекКонтрагент <> "")  Тогда
           // есть что связывать
           Если (ТекДоговор = СокрЛП(_ТЗ.СчетФактура)) и (ТекДатаДоговора = _ТЗ.ДатаСчетФактуры) Тогда
               _ТЗ.СчетФактура = ТекДоговор    
           Иначе
               ТекДоговор = СокрЛП(_ТЗ.СчетФактура);
               ТекДатаДоговора = _ТЗ.ДатаСчетФактуры;
               ТекДоговор = СвязатьДоговор(ТабДоговоров, ТекКонтрагент, ТекДоговор, ТекДатаДоговора, "Счет фактура", Connection, _ТЗ.ID, 2, ТекДатаДоговора);
               _ТЗ.СчетФактура = ТекДоговор;    
               Если ТекДоговор = "" Тогда
                   Сообщить("Не связался Договор - " + ТекДоговор + " от " +ТекДатаДоговора + " для "  + ТекКонтрагентТхт);            
               КонецЕсли;
           КонецЕсли;
       КонецЕсли;  
       
   КонецЦикла;
35 mg-samara
 
02.10.09
12:20
А-а-а, индектированную таблицу?
Ну кэш сделаю...
36 NS
 
02.10.09
12:20
(26) А свернуть разве делает не проходом?
Каким образом один проход может сильно затормозить отчет?
Индексированная ТЗ НЕ ПОМОЖЕТ.
Свернуть("Подразделение,Сотрудник","")
Сортировать("Подразделение+,Сотрудник+");
ПослПодр="паыувпва";
стр="";
Выбратьстроки();
Пока получитьстроку()=1 цикл
Если Подразделение=подр тогда
  стр=стр+","+сотр;
Иначе
 //записали предыдущего
 подр=подразделение;
 стр=сотр;
конецесли;

вроде всё понятно, никаких поисков, один проход.
37 mg-samara
 
02.10.09
12:22
(36) На каждое подразделение один проход... А их может быть много.
38 mg-samara
 
02.10.09
12:23
(36) Прошу прощенья... не считался с код... Все ок!
39 mg-samara
 
02.10.09
12:23
Что-то туплю с утра...
40 Ёпрст
 
гуру
02.10.09
12:23
(37) чего курим ?
Всего 1 проход на ВСЁ.
41 SaM58
 
02.10.09
12:23
если без 1С++ то попробуй как в (9)
42 mg-samara
 
02.10.09
12:23
(40) Ага!
43 mg-samara
 
02.10.09
12:25
Всем спасибо, что-то мозг в пятницу с утра уже отключается...
44 Serginio1
 
02.10.09
12:25
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019
Там есть группирование по полю полям
45 NS
 
02.10.09
12:26
Как я предложил NlnN (быстрых, ибо встроенный метод) на сортировку, а дальше О(N)
Как в (9) О(N*К), где К - количество подразделений (из-за найтизначение())
N -  размер свернутой таблицы.
(9) Всяко будет медленней.
46 Эльниньо
 
02.10.09
12:53
ТЗ1 выгрузить в ТЗ2
ТЗ2 свернуть и сделать трёхмерной.
Перебирая ТЗ2, выбираем из ТЗ1 в ТЗ2 в колонку типа ТЗ.
47 Serginio1
 
02.10.09
14:50
(36) Не сработает если у объектов есть дубли по представлению. Тз сортируется по представлению без
учета уникального значения. Для получения уникальности желательно добавить уникальное поле например значениеВстрокуВнутр.
48 NS
 
02.10.09
14:56
(47) Точно? Уверен? "*" В сортировать это что?
49 Serginio1
 
02.10.09
15:44
Ну у тебя без *, а во вторых хочется иметь готовую сортировку по представлению.
Поэтому сортировка по двум полям предпочтительнее.
50 NS
 
02.10.09
16:15
(49) По каким двум полям? У меня конечно без звездочки, ибо нигде не сказано что в ТЗ элементы справочника. Тем более врятли у вменяемой фирмы будут два разных подразделения с одним названием. Более того у меня с ошибками, так как я только показал (наметил) однопроходный алгоритм за линейное время.
51 NS
 
02.10.09
16:16
А, ты наверно не умеешь написать так "Подразделение*,Подразделение+" - это имел в виду?
52 NS
 
02.10.09
16:16
Или наоборот "Подразделение+,Подразделение*" - так правильней.
53 Serginio1
 
02.10.09
17:17
(50) По представлению и уникальному полю
(52) Согласен.
54 Serginio1
 
02.10.09
17:18
(50) Ну сотрудники то точно объекты. А вот их то на моей памяти могут дублировать со страшной силой. Правда легче заранее избавиться от дублей.
55 Serginio1
 
02.10.09
20:40
(51) Сейчас проверил на 25 релизе. Создал кучу дублей и заполнил по 10 значений каждого и коды для отличия.Ни 51 ни 52 не прокатывает сортирует по представлению.
Ставил звездочки и спереди и сзади с пробелами и без них. Может и чего делаю не так.
Но большое спасибо за * спасибо  вылетело из головы.
Просто в (44) вставлю для справочников сортировку по Внутреннему значению,
а затем уже для групп по представлению.

Хотя с добавлением уникального поля тоже ничего.
56 NS
 
02.10.09
21:47
(55) Не понял. Сортирует как задашь. Если сначала * тогда сначала по внутреннему предствлению, если сначала +, то по алфавиту, а внутри по внутреннему представлению.
57 Serginio1
 
02.10.09
22:35
Процедура СоздатьТз()
   Тз.НоваяКолонка("Товар","Справочник.Номенклатура");
   Тз.НоваяКолонка("Код","Строка");
КонецПроцедуры // СоздатьТз

Процедура ЗаполнитьТз(Спр)
   Пока Спр.ПолучитьЭлемент()=1 Цикл
       Тз.НоваяСтрока();
       Тз.Товар=Спр.ТекущийЭлемент();
       Тз.Код=Спр.Код
   КонецЦикла;
   КонецПроцедуры
Процедура Сформировать()
   СоздатьТз();
Спр=СоздатьОбъект("Справочник.Номенклатура");
Спр.НайтиПоКоду("00000011",0);
Группа=Спр.ТекущийЭлемент();
Спр.ИспользоватьРодителя(Группа);
Для Сч=1 по 10 Цикл
   Спр.ВыбратьЭлементы();
   ЗаполнитьТз(Спр)
КонецЦикла;
КонецПроцедуры

//======================================================================
Процедура СортироватьПоПредставлению(ПоВнутр=0)
   Если ПоВнутр=1 Тогда
       Сообщить(ПоВнутр);
       Тз.Сортировать("Товар+,Товар*");//Тз.Сортировать("Товар*,Товар+");
   ИначеЕсли ПоВнутр=2 Тогда
       Тз.Сортировать("Товар*");
   Иначе
       Тз.Сортировать("Товар");
   КонецЕсли;
КонецПроцедуры // СортироватьПоПредставлению()


Тз.Сортировать("Товар+,Товар*");
Что
Тз.Сортировать("Товар*,Товар+");

Сортирует по представлению
58 Serginio1
 
02.10.09
22:42
В папке 00000011 находится куча элементов с одинаковым наименованием. (Только одно наименование)
Причем если отсортировано по внутреннему представлению, то при сортировке 2 или 0 все равно рассортировывает по своему компареру/
Явно что то добавляет, и явно не квик сорт.
Буду рад заблуждаться.
59 Serginio1
 
03.10.09
09:25
(58) С квиксортом я конечно лоханулся, т.к. при наборе одинаковых значений  на
каждом шаге будет меняться местами первый с последним, так что не все так
очевидно. Но вот сортировка по представлению не зависит от набора данных.
(первичный вариант и отсортированный по представлению). Не зная внутренносте й
сложно судить.

Для оправдания алгоритм набора данных непригодный для квик сорта

j:=count-1;
    i:=j shr 1;
    k:=i;
    l:=1;
     while (i>=0)  do
       begin
         IntAr[i]:=j;
         IntAr[count-l]:=j-1;
         inc(l);
         dec(i); dec(j,2);
       end;
60 Serginio1
 
03.10.09
09:45
61 Serginio1
 
04.10.09
14:40
http://1c.proclub.ru/modules/mydownloads/viewcat_personal.php?uid=5702
В отчете C1InDelphi\ErtОбщегоНазначения\ТестЕрт.ert
Для функций
глСгруппироватьПоПолюСТЗБыстр(Тз,Поле)
глСгруппироватьПоПолямСТЗБыстр(Тз,Поля,Ресурсы)
Начальная сортировка учитывает типы Справочник и документ для сортировки по значению, после группирования данных тз содержащая группы сортируется по представлению.
Для последней функции параметру Ресурсы можно указать пустую строку, что бы итоги не считались.
Основная теорема систематики: Новые системы плодят новые проблемы.