Имя: Пароль:
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
Для функций
глСгруппироватьПоПолюСТЗБыстр(Тз,Поле)
глСгруппироватьПоПолямСТЗБыстр(Тз,Поля,Ресурсы)
Начальная сортировка учитывает типы Справочник и документ для сортировки по значению, после группирования данных тз содержащая группы сортируется по представлению.
Для последней функции параметру Ресурсы можно указать пустую строку, что бы итоги не считались.