Имя: Пароль:
1C
 
НайтиЗначение() в ТЗ по двум колонкам. Возможно ли?
0 User63
 
03.08.04
12:18
Допустим, у меня есть таблица значений с колонками номенклатура и партия. Можно ли методом НайтиЗначение() получить строку по этим двум параметрам, например,предварительно создав дополнительную колонку и какаим нибудь образом скопировав туда значения этих двух вышеуказанных колонок?
Спасибо.
1 SnarkHunter
 
03.08.04
12:19
Можно
2 Warlock
 
03.08.04
12:19
(0)Перебором строк...
3 Warlock
 
03.08.04
12:19
+2 Не устраивает?
4 Рупор абсурда
 
03.08.04
12:21
Можно и без доп. колонки ...
5 IAm
 
03.08.04
12:24
(0) Долго, быстрее
ТЗ.Сортировать("Номенклатура");
Поз = 0;
ТЗ.НайтиЗначение(НужнНоменклатура, Поз, "Номенклатура");
Для А = Поз По ТЗ.КоличествоСтрок() Цикл
Если ТЗ.ПолучитьЗначение(А, "Партия") = НужнПартия Тогда
Сообщить("Вот оно"); Прервать;
ИначеЕсли ТЗ.ПолучитьЗначение(А, "Номенклатура") <> НужнНоменклатура Тогда
Сообщить("А нэту");Прервать;
КонецЕсли;
КонецЦикла;
6 User63
 
03.08.04
12:25
Перебор строк не устраивает...
Хотелось бы через НайтиЗначение(). Вот только не знаю как в одну колонку два реквита вставить.
ТЗ.ДопКолонка =Стр(Номенклатура.Код)+Стр(Партия.Код)
Такой вариант у меня пройдет? Или есть более наработанные способы?
7 Рупор абсурда
 
03.08.04
12:27
(5) А что будет быстрее в случае, если в ТЗ в колонке Номенклатура всего пара различных значений, а строк всего сотня тысяч? ...
8 Композитор
 
03.08.04
12:28
(7) Быстрее будет повеситься.
9 IAm
 
03.08.04
12:28
7 Перестановка местами колонок партия и Номенклатура в алгоритме 5.
10 Матрейя
 
03.08.04
12:29
Можно поиском по двум колонкам. Ищещь в одно, затем во второй - если номера строк не совпадают - удаляешь в транзакции строку где найдено значение по второй колонке. Транзакцию в конце отменяешь.
11 User63
 
03.08.04
12:30
(7) Именно так. Не хочется в модуле перебор строк делать...
Специалисты, подскажите, пожалуйста!
12 IAm
 
03.08.04
12:32
10 Не где найдено второе, а которая имеет наименьший номер.
13 Рупор абсурда
 
03.08.04
12:33
Функция ПоискПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
 Перем ТЗ_;  
   Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк :)") КонецЕсли;
 ТЗ.Выгрузить(ТЗ_);
   Пока 1=1 Цикл
   Ном=0;
     ТЗ_.НайтиЗначение(Значение1,Ном,Колонка1);
   Если Ном=0 Тогда Возврат(0) КонецЕсли;
     Если ТЗ_.ПолучитьЗначение(Ном,Колонка2)=Значение2 Тогда Возврат(Ном) КонецЕсли;
     ТЗ_.УстановитьЗначение(Ном,Колонка1,ПолучитьПустоеЗначение());
   КонецЦикла;
   Возврат 0;
КонецФункции
14 Матрейя
 
03.08.04
12:34
12. Да. Я просто написал машинально.
15 IAm
 
03.08.04
12:34
Только непонятно, ято она вернет если транзакцию отменишь, ведь все запомненные во время этого значения тоже отменятся.
16 SnarkHunter
 
03.08.04
12:35
(12)Энурез?
17 Рупор абсурда
 
03.08.04
12:35
(10) Фигню ты сказал ... :))
18 SnarkHunter
 
03.08.04
12:36
Тьху...
19 IAm
 
03.08.04
12:36
13 быстрее по другому
20 IAm
 
03.08.04
12:41
Функция ПоискПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
Перем ТЗ_;  
  Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк :)") КонецЕсли;
ТЗ.Выгрузить(ТЗ_);
  Пока 1=1 Цикл
  Поз1=0; Поз2 =0;
  ТЗ_.НайтиЗначение(Значение1,Поз1,Колонка1);
  ТЗ_.НайтиЗначение(Значение2,Поз2,Колонка2);  
  Если (Поз1=0) ИЛИ (Поз2=0) Тогда
      Возврат(0)
  ИначеЕсли Поз1 = Поз2 Тогда
      Возврат Поз1;
  ИначеЕсли Поз1 > Поз2 Тогда
      ТЗ.Заполнить("", 1, Поз1 - 1, Колонка2);
  Иначе
      ТЗ.Заполнить("", 1, Поз2 - 1, Колонка1);
  КонецЕсли;
  КонецЦикла;  
КонецФункции
21 GrayT
 
03.08.04
12:43
(13) Что то я не въехал в красоту решения. Вроде такой же перебор, да же еще медленней 5, наверное.
22 IAm
 
03.08.04
12:43
Пля, к клиенту надо... А хочется тесты провести.
23 IAm
 
03.08.04
12:45
Можно в 20 ещё коррективы внести чтобы быстрее
24 IAm
 
03.08.04
12:48
Функция ПоискПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
Перем ТЗ_;  
ТЗ.Выгрузить(ТЗ_);
 ИндексПоиска = 0;
 Пока 1=1 Цикл  
 Если ИндексПоиска <> 1 Тогда
 Поз1=0;
 ТЗ_.НайтиЗначение(Значение1,Поз1,Колонка1);
 КонецЕсли;
 Если ИндексПоиска <> 2 Тогда
 Поз2 =0;
 ТЗ_.НайтиЗначение(Значение2,Поз2,Колонка2);  
 КонецЕсли;
 Если (Поз1=0) ИЛИ (Поз2=0) Тогда
     Возврат(0)
 ИначеЕсли Поз1 = Поз2 Тогда
     Возврат Поз1;
 ИначеЕсли Поз1 > Поз2 Тогда
     ТЗ.Заполнить("", 1, Поз1 - 1, Колонка2);
     ИндексПоиска = 1;
 Иначе
     ТЗ.Заполнить("", 1, Поз2 - 1, Колонка1);
     ИндексПоиска = 2;
 КонецЕсли;
 КонецЦикла;  
КонецФункции
25 Рупор абсурда
 
03.08.04
12:49
(21) Вся разница только в том, что ТЗ не сортируется ...
Т.е. если по окончании, нужно ТЗ оставить с той же сортировкой, придётся предварительно пронумеровать строки, чтоб использовать (5) ...
26 Рупор абсурда
 
03.08.04
12:51
(20,24) Ты ничего не забыл?
27 IAm
 
03.08.04
12:51
26 Времени 5 минут, давай правильный ответ. Вроде ничего не забыл.
28 Рупор абсурда
 
03.08.04
12:57
(27) Сори ..., продолжим, когда вернёшься ...
29 Олег_1978
 
03.08.04
13:03
Проще ввести ключ но 2-м полям - работать будет всегда быстрее, чем любой из описанных вариантов...
30 Рупор абсурда
 
03.08.04
13:05
(29) С учётом времени введения ключа?
31 Warlock
 
03.08.04
13:07
(29)Идея хороша, ведь получается что-то типа ускоренного перебора. Немножко модифицировав, можно получить(быстро) все вхождения комбинаций. При создании ключевого поля(на что, кстати, тоже время уходит) перебор тяжелее сделать...
32 User63
 
03.08.04
13:07
(29) Ключ по двум полям - как в (6) пройдет или есть более оптимальный вариант?
33 Олег_1978
 
03.08.04
13:10
Как в 6 - пойдет вполне, можно и другой подобрать, все от искомых колонок зависит, их типа. Я всегда так делаю, если поиск нужен.
34 GrayT
 
03.08.04
13:11
Мдя уж
35 Рупор абсурда
 
03.08.04
13:13
(32) Пойдет если коды у номенклатуры и партии железно уникальны ...
А ващще, лучше внутренние ид сравнивать ...
36 Олег_1978
 
03.08.04
13:14
(35) Так я и говорю - нужно смотреть, что за данные в колонках.
Можно и лучше сделать...
37 Tick
 
03.08.04
15:05
Можно попробовать так:
Перем ЗнСтроки1, ЗнСтроки2;
Табл.ВыбратьСтроки();
Пока (Табл.НайтиЗначение("Значение1", ЗнСтроки1, 1) = 1) или
    (Табл.НайтиЗначение("Значение2", ЗнСтроки2, 2) = 1) Цикл
    Если ЗнСтроки1 = ЗнСтроки2 Тогда
         //Делай что надо
    КонецЕсли;
КонецЦикла;

Попробуй может получится.
38 Рупор абсурда
 
03.08.04
15:15
(37) Мдя ...
Давненько к нам такие мастера не заходили ...
39 SiMazx
 
03.08.04
15:22
(37) Гениально... Либо ничего либо бесконечность... Глобально...
40 Тор
 
03.08.04
16:08
(Warlock) А ты значит до этого перебором пользовался??? Сильно...
Непонятен ответ в (2) и последующая похвала ключевого поля. В вопросе же уже почти содержался ответ про ключевую колонку "например,предварительно создав дополнительную колонку и какаим нибудь образом скопировав туда значения этих двух вышеуказанных колонок". IAm пошел по более верному пути: зачастую бывает нужно получить не только строго одну строку с данным значением а набор строк, когда искомые параметры совпадают, а остальные нет.
41 Рупор абсурда
 
03.08.04
16:15
(40) Какая длинная речь ...
Наверно, к тому же ещё и умная очень ...
Я правда не заметил ..., но что взять с тупого одинэсника ... :((
42 andersen
 
03.08.04
16:16
если
>нужно получить не только строго одну строку с данным значением а набор строк, когда искомые параметры совпадают, а остальные нет.
тады можно поступить так...
вызвать два раза функцию
Функция УстановитьЗначениеФильтра(Знач ТЗ,Колонка,значение)
   НачСтрока=0;
   КонСтрока=0;
   ТЗ.Сортировать(колонка + "+");
   ТЗ.НайтиЗначение(Значение,НачСтрока,колонка);
   бт=СоздатьОбъект("ТаблицаЗначений");
   Если НачСтрока>0 Тогда
       ТЗ.Выгрузить(бт,начСтрока);        
       бт.Сортировать(колонка + "-");
       БТ.НайтиЗначение(Значение,КонСтрока,колонка);
       бт.Выгрузить(бт,констрока);
   КонецЕсли;
   Возврат бт;
КонецФункции
тз1 = УстановитьЗначениеФильтра(ТЗ0,Колонка1,значение1)
тз2 = УстановитьЗначениеФильтра(ТЗ1,Колонка2,значение2)
Сама функция где-то отковырена в инете...
в принципе работает прекрасно :)))
43 Рупор абсурда
 
03.08.04
16:18
(42) Автор функции ROM ...
Но работает она не совсем прекрасно ...
44 Тор
 
03.08.04
16:19
(41) Какое предложение ты не понял???
45 Рупор абсурда
 
03.08.04
16:20
(43)+ http://rom1c.narod.ru/function.html
(44) Я что сильно похож на дебила?
46 Тор
 
03.08.04
16:24
(45)Хочешь поговорить об этом? Зачем тогда (41) написал?
47 andersen
 
03.08.04
16:24
(45) да, если нет вхождений то вернет ПустоеЗначение и второй выхов неотработает :)
48 Tick
 
03.08.04
16:25
Прошу прощеня, уже гуси летят
Перем знСтроки;
ВремТабл = СоздатьОбъект("ТаблицаЗначений");
ВремТабл.Загрузить(Табл);
~M1:
Если ВремТабл.НайтиЗначение("Значение1", знСтроки, 1) = 1 Тогда
   Если ВремТабл.ПолучитьЗначение(знСтроки, 2) = "Значение2" Тогда
       //Делай что надо
   Иначе
       ВремТабл.УстановитьЗначение(знСтроки, 1, "");
       ВремТабл.УстановитьЗначение(знСтроки, 2, "");
       Перейти ~M1;
   КонецЕсли;
Иначе
   //Не найдено
КонецЕсли;
49 Рупор абсурда
 
03.08.04
16:29
(46) Сори, конечно ..., но написал (41) я потому, что не нашёл в (40) ничего умного ...
50 Тор
 
03.08.04
16:32
Ну а я написал потому что не нашел в (2) и (29) ничего умного :)
51 Тор
 
03.08.04
16:33
(50)-->(49)
52 Рупор абсурда
 
03.08.04
16:34
(50) ... и решил добавить немножко тупизма от себя?
53 Тор
 
03.08.04
16:40
(52) Ну ОК, ты меня уел, ох уел... :) Просто звезда автора смутила, точнее спровоцировала...
ЗЫ. (Волшебнику) Вообще-то считаю эти звезды не нужны. Позерство какое-то. Вот у IAm их нет а по его знаниям ему можно штук 5 повесить... Звезды - не показатель ума и крутости.
54 Рупор абсурда
 
03.08.04
16:42
(53) Потому его (IAm'а) и выгоняют отсюда периодически ...
55 Матрейя
 
03.08.04
16:42
Уже придумали элитный код или мне предложить совершенное решение?
56 DimG
 
03.08.04
16:45
Матрейя давай, а то из вышеприведенных без корректировок работает только от рупора. А он мне как раз щас нужон. Только лень думать.
57 Матрейя
 
03.08.04
16:45
+55. Нужно вернуть массив подходящих условиям строк или одну строку?
58 Рупор абсурда
 
03.08.04
16:47
(55) Если то, с транзакциями, то валяй, конечно ...
59 Тор
 
03.08.04
16:47
(55) Давай. Условие: вернуть номер строки (либо строк), удовлетворяющей условию равенства НЕОГРАНИЧЕННОГО количества параметров.
60 User63
 
03.08.04
16:49
Вообще-то, мне нужна только одна строка удовлетворяющая заданным условиям.. ;)
61 Матрейя
 
03.08.04
16:49
Сейчас, минут через 10, подумаю немного.
62 Тор
 
03.08.04
16:50
(61) А то что в (59) сделаешь? Полезная вещь будет.
63 DimG
 
03.08.04
17:05
прошло 16 минут...
64 Матрейя
 
03.08.04
17:08
Я не могу запостить текст кода
65 Матрейя
 
03.08.04
17:08
Функция Поиск(Зн,Н1)
   Стр="";
   Если Тз.НайтиЗначение(зн,Стр,1)=1 Тогда  
       сч=1;
       Для Н=2 По Н1 Цикл
           Если  Тз.НайтиЗначение(зн,Стр,Н)=0 Тогда
               Прервать;  
               Тз.УдалитьСтроку(Стр);
           Иначе
               сч=Сч+1;
           КонецЕсли;    
       КонецЦикла;    
       Если Сч=Н1 тогда
           Сообщить(Стр);
           Тз.УдалитьСтроку(Стр);
           Возврат("");
       КонецЕсли;    
   Иначе
       Возврат(1);
   КонецЕсли;    
КонецФункции
66 Матрейя
 
03.08.04
17:09
Процедура Выполнить(Зн)
   П1=Тз.КоличествоСтрок();  
   Н1=Тз.КоличествоКолонок();
   НачатьТранзакцию();      
   Пока  Поиск(Зн,Н1)<>1 Цикл
   КонецЦикла;    
   ОтменитьТранзакцию();
КонецПроцедуры
67 Матрейя
 
03.08.04
17:10
Наконец-то. 63 - я сделал ровно за десять мин, но что-то видно с моим провайдером.
68 andersen
 
03.08.04
17:10
(65)кажисть я устал....
это что?
Если  Тз.НайтиЗначение(зн,Стр,Н)=0 Тогда
              Прервать;  
          >>>>Тз.УдалитьСтроку(Стр);
69 Матрейя
 
03.08.04
17:11
68. Я проверил - работает.
70 Матрейя
 
03.08.04
17:13
Хотя да, у меня удаляются строчки... Но можно выгрузить в Тз и там произвести поиск.
71 Матрейя
 
03.08.04
17:21
Но согласитесь - алгоритм неплохой. Транзакции надо закомментировать. Я не знал, что для ТЗ они не имеют никакого значения.
72 Матрейя
 
03.08.04
17:27
И строку можно не удалять, а сдвигать в конец. Немного изменить функцию Поиск()-> вызывать Возврат(1), если позиционирование на сдвинутых строках.
73 Рупор абсурда
 
03.08.04
18:12
Молодец! Я смеялся больше 10 минут ...
74 Рупор абсурда
 
03.08.04
18:15
(73)+ Молодец, конечно, Матрёня ...

Работать оно, конечно, будет ..., но дело в том, что метод удалитьСтроку() очень медленный ...

ЗЫ: С транзакциями тоже смешно получилось ... :))
75 Зам Матрейи
 
03.08.04
18:20
Перем П;

Функция Поиск(Зн,Н1,П)
   Стр="";
   Если Тз.НайтиЗначение(зн,Стр,1)=1 Тогда  
       сч=1;
       Для Н=2 По Н1 Цикл
           Если  Тз.НайтиЗначение(зн,Стр,Н)=0 Тогда
               Прервать;  
               Тз.СдвинутьСтроку(П-Стр,Стр);
               П=П-1;
           Иначе
               Если Стр<П тогда
                   сч=Сч+1;    
               Иначе
                   Возврат(0);
               КонецЕсли;    
           КонецЕсли;    
       КонецЦикла;    
       Если Сч=Н1 тогда
           Тз.СдвинутьСтроку(П-Стр,Стр);
           Сообщить(Стр+(П-Стр));
           П=П-1;
       КонецЕсли;    
   Иначе
       Возврат(0);
   КонецЕсли;
КонецФункции    


Процедура Выполнить(Зн)
   П=Тз.КоличествоСтрок();  
   Н1=Тз.КоличествоКолонок();
   Пока  Поиск(Зн,Н1,П)<>0 Цикл
   КонецЦикла;    
КонецПроцедуры
76 Громобой
 
03.08.04
18:22
Можно добавить в ТЗ колонку "Индекс", склеивать в нее значение тех колонок по которым нужен поиск к примеру методом ЗначениеВСтроку(...)+ЗначениеВСтроку(...)+...  А потом найти строку элементарно методом НайтиЗначение(Зн,Нстр,"Индекс"), где Зн сформировано похожим образом
77 Рупор абсурда
 
03.08.04
18:30
(76) Как ты считаешь, это ты счас умную мысль высказал?
78 Рупор абсурда
 
03.08.04
18:31
(77)+ Прежде, чем ответить, прочитай, пожалуйста, (0) ещё раз ...
79 IAm
 
03.08.04
20:01
Весело у вас тут
80 Рупор абсурда
 
03.08.04
20:05
(79) Угу ...
Тор сказал, что тебе нужно присвоить 5 звёзд ..., Волшебник испугался и звёзды отменил совсем ...
О как ...
81 IAm
 
03.08.04
20:13
В (54) очень смешно
82 Матрейя
 
03.08.04
22:30
Руппи, ну а как модуль в 75? Быстрее чем удалить строку?
83 NS
 
04.08.04
00:10
Все лохи.
84 Мэт
 
04.08.04
00:13
83. По себе о других не тактично судить.
85 NS
 
04.08.04
00:47
Avb, ну указывал же я метод...
Поиск скорей всего многократный...
Методов нормальных два  - хранить остсортированными по первому параметру в двух направлениях, и бинарный поиск, и сводный реквизит...
Остальное - порезанное (83)
86 NS
 
04.08.04
00:48
(84) Tot kj[b vyt ,elen erfpsdfnm!
87 Мэт
 
04.08.04
00:57
NS, новичок, ты ламер.
88 Рупор абсурда
 
04.08.04
00:57
(85) Один хрен, большая часть времени у тебя уйдёт на подготовку к поиску ...
А если тз предварительно никак не подготовлена для поиска ...
Изменять порядок строк в ней нельзя ...
И, допустим, найти нужно всего один раз ...

Ты пойми, я ж не навязываю никакого решения ..., просто предложил, как один из вариантов ...
89 NS
 
04.08.04
00:58
(87) Прикольно... Еще пошути...
(с) не мой.
90 IAm
 
04.08.04
00:59
88 Да
91 IAm
 
04.08.04
00:59
1) Сортировка. Не катит если нужно вернуть номер строки.
2) Бинарный поиск. Что это?
3) Отдельный реквизит. Ёжику понятно, только если поиск выполняется один раз для таблицы, то создавать его в несколько раз дольше.
92 Мэт
 
04.08.04
01:02
89. Конечно прикольно, когда ламер уверен что он спец:). И шашки - шахматы твои муйня. Какой кретин тебя 1с-су учил?
93 NS
 
04.08.04
01:02
(88) Колонка - номер строки.
Сортировка? Долго? Сколько секунд сортируется ТЗ на миллион?
По индексу? Меньше десяти секунд...
А поиск явно неоднократный.
94 NS
 
04.08.04
01:05
(92) Крылов про моську что-то базарил...
95 Рупор абсурда
 
04.08.04
01:05
(91) А бинарный поиск тоже предполагает предварительную сортировку ...
96 NS
 
04.08.04
01:06
(95) Я и говорб - сортировка в обе стороны и бинар.
97 IAm
 
04.08.04
01:07
потестировать надо будет завтра на предмет одиночного поиска.
Если искаться будет неоднократно, то ясно, что лучше колонку Индекс вводить и реквизиты в неё суммировать
98 Рупор абсурда
 
04.08.04
01:07
(93) Отсортировал, нашёл ..., зашибись! ..., пусть даже отсортировал обратно ..., как получить номер строки? ...
99 Мэт
 
04.08.04
01:08
93. Млин, кто этого юнца выпустил в инет? Откровенная лажа.
94. Да, ты похож.
100 NS
 
04.08.04
01:09
(98) (93)
101 IAm
 
04.08.04
01:09
Надо 83 в базу знаний добавить, может даже отдельной темой
102 NS
 
04.08.04
01:11
(101) Вторую тему понял?
103 IAm
 
04.08.04
01:16
102 про колонку в журнале? а хули там понимать? Я же код написал.
104 NS
 
04.08.04
01:19
какой пост?
105 Рупор абсурда
 
04.08.04
01:19
(100) >>Колонка - номер строки
Временем, которое уйдёт на добавление, заполнение этой колонки, ты, конечно, пренебрег? ...
106 NS
 
04.08.04
01:21
Я бы, для начала, убрал бы галочки...
Еще раз - явно поиск неоднокоатный.
107 NS
 
04.08.04
01:22
неоднокоатный - неоднократный.
108 IAm
 
04.08.04
01:23
= 0
109 NS
 
04.08.04
01:25
(108) Это не ответ.
110 ShootNICK
 
04.08.04
01:26
если неоднократный - лучше идексирование. а так - бинарный катит.
111 NS
 
04.08.04
01:28
(110) Бинарный - две сортировки не нравятся (одна по двум колонкам, другая по одной), и проставление номера строки.
112 ShootNICK
 
04.08.04
01:32
а получить надо именно номер строки? а не некое значение в третье например колонке ? что за бред- узнать в какой строке совпадение? практичность инфы какая то никакая :) номер строки бесполезняк простставлять - лучше уж индексы построиь.
113 ShootNICK
 
04.08.04
01:35
в полном хаосе на однократном поиске - первое совпдение и тупо перебором если без сортировки
114 IAm
 
04.08.04
01:38
112 Найти значения в табличной части документа, чтобы спозиционироваться на этой строке. К примеру.
115 Рупор абсурда
 
04.08.04
01:39
(113) Мы с IAm'ом быстрей найдём ... :))
116 NS
 
04.08.04
01:40
(114)Дима, а нет в ветке у тебя такого решения...
117 IAm
 
04.08.04
01:41
115 Кажется человек не понимает, что однократный поиск может повторяться многократно для бесконечного множества таблиц в нашей необъятной вселенной.
118 IAm
 
04.08.04
01:41
116 Какого? В какой?
119 ShootNICK
 
04.08.04
01:43
114 - так при выгрузке таб.части и колонка создается "номер строки" и остальные значения выгрузить можно
120 NS
 
04.08.04
01:43
В этой.
121 IAm
 
04.08.04
01:47
119 А в документе всегда строки автоматом нумеруются?
122 ShootNICK
 
04.08.04
01:47
вспомним - задача, которая решается за неприемлемое время - либо бездарно запрограммирована,либо ее решение не нужно:) так отваживали теоретиков от решения разнообразных задач :)
123 IAm
 
04.08.04
01:47
120 остался первый вопрос
124 NS
 
04.08.04
01:48
Причеим нерешенный ;-)
125 IAm
 
04.08.04
01:49
Вопрос звучит так
Какого? (перед вопросительным знаком нет троеточия)
126 ShootNICK
 
04.08.04
01:50
121 - ладно ладно :) мы таки ищем идеальное решение или промышленное ? :
127 IAm
 
04.08.04
01:52
Спокойной ночи, пошел онанировать и ссать.
128 IAm
 
04.08.04
01:52
в смысле и спать.
129 NS
 
04.08.04
01:52
Кто-то может галки эти поганные убрать?
130 ShootNICK
 
04.08.04
01:56
127,129 - стихи какие то :)
129 - какие галки ???
131 NS
 
04.08.04
01:57
(130) посмотри ветку с начала.
132 Warlock
 
04.08.04
01:59
(131)Перестроить или снести?
133 NS
 
04.08.04
02:00
(132) Снести, создать новую ветку, и дать ссылку на эту...
134 ShootNICK
 
04.08.04
02:01
типа "внесено в базу знаний" . ясно
135 Warlock
 
04.08.04
02:03
(NS)Создавай...
136 NS
 
04.08.04
02:05
(134) Пока нечего вносить в базу знаний.
137 Рупор абсурда
 
04.08.04
02:10
У меня есть одно замечательное знание ..., в самый раз, для базы знаний ...
138 NS
 
04.08.04
02:12
(137) А у меня их два!!!
139 ShootNICK
 
04.08.04
02:19
а я пожалуй глотну коньячку...
140 NS
 
04.08.04
02:50
А я из-за этого дерьма проснулся...
Если ТЗ совсем неотсортирована...
Сложность алгоритма -
Добавление любой колонки (номер строки, сводный реквизит) - эн логарифмов эн.
Пробег - Эн.
Лучшее решение..
ТЗ.ВыбратьСтроки();
пока тЗ.ПолучитьСтроку()=1 цикл
если ТЗ.Номенклатура=номенклатура тогда
 если ТЗ.Партия=партия Тогда
   сообщить(ТЗ.Номерстроки);
   прервать;
 конецесли;
конецесли;
КонецЦикла;
правильное решение - (2)
141 VladZagorsky
 
04.08.04
06:04
Э... Ндя... Мысли бурлят просто, когда такое читаешь...

В свое время сталкивался с такой задачей. Первая мысль была: "Вот блин, как неудобно-то!  Вот если бы с таблицей значений можно было работать как с базой данных!!!"..  А собственно, почему бы не применить идеалогию баз данных?

Делаем дополнительную колонку в таблице (обзовем ее "Индекс").

Дальше:
ТаблЗнач.ВЫбратьСтроки();
Пока ТаблЗнач.ПолучитьСТроку()=1 Цикл
   ТаблЗнач.Индекс=СокрЛП(ТаблЗнач.Номенклатура)+СокрЛП(ТаблЗнач.Партия);
КонецЦикла;

И если тебе нужно найти по этим двум параметрам:

ТекИндекс=СокрЛП(Номенклатура)+СокрЛП(Партия);
ТаблЗнач.НайтиЗначение()...

И определяется однозначно, и не нужно перебором искать, и номер строки таблицы тебе....
142 Z1
 
04.08.04
09:40
(141) Неправильный у тебя индекс - индекс надо тщательней продумывать
ситуация 1 товар1 называется "кефир"
          товар2 называется "кефир"
Товар1, Товар2 две строки справочника номенклатура
ситуация 2 ( абсурдная для товара и партий но все равно )
          товар1 называется  "123" партия1 "4"
          товар2 называется  "12"  партия1 "34"
(141) Рупор говорит что на создание индекса тратиться время больше чем на поиск и если поиск единичный то и не к чему вообще создавать индекс, а вместо этого надо написать свою быструю функцию для единичного(одноразового) поиска
143 Z1
 
04.08.04
09:50
(Рупор абсурда) Мой вариант поисковой функции
Идея 1 симметрия алгоритма по колонке1 и колонке2
Идея 2 улучшения  том что если нашли сразу то и не надо выгружать ТаблицуЗначений

// Возвращает номер строки где значения совпадают
Функция ПоискОдиночныйПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
   Перем ТЗ_;
   Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк1 :)") КонецЕсли;
   Если ПустоеЗначение(Значение2)=1 Тогда Возврат("Глюк2 :)") КонецЕсли;
   Ном1=0;
   ТЗ.НайтиЗначение(Значение1,Ном1,Колонка1);
   Если Ном1=0 Тогда Возврат(0) КонецЕсли;
   Ном2=0;
   ТЗ.НайтиЗначение(Значение2,Ном2,Колонка2);
   Если Ном2=0 Тогда Возврат(0) КонецЕсли;
   Если Ном1 = Ном2 Тогда
       Возврат(Ном1);
   ИначеЕсли Ном1 > Ном2 Тогда
       Зн2 = ТЗ.ПолучитьЗначение(Ном1,Колонка2);
       Если Зн2 = Значение2 Тогда
           Возврат(Ном1);
       КонецЕсли;
       Ном3 = Ном1 + 1;
   Иначе
       Зн1 = ТЗ.ПолучитьЗначение(Ном2,Колонка1);
       Если Зн1 = Значение1 Тогда
           Возврат(Ном2);
       КонецЕсли;
       Ном3 = Ном2 + 1;
   КонецЕсли;
   Дельта = Ном3;
   СписокКолонок = Колонка1 + "," + Колонка2;
   ТЗ.Выгрузить(ТЗ_,Ном3, ,СписокКолонок );
   Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   Пока 1=1 Цикл
       Ном1=0;
       ТЗ_.НайтиЗначение(Значение1,Ном1,Колонка1);
       Если Ном1=0 Тогда Возврат(0) КонецЕсли;
       Ном2=0;
       ТЗ_.НайтиЗначение(Значение2,Ном2,Колонка2);
       Если Ном2=0 Тогда Возврат(0) КонецЕсли;
       Если Ном1 = Ном2 Тогда
           Возврат(Дельта + Ном1);
       ИначеЕсли Ном1 > Ном2 Тогда
           Зн2 = ТЗ_.ПолучитьЗначение(Ном1,Колонка2);
           Если Зн2 = Значение2 Тогда
               Возврат(Дельта + Ном1);
           КонецЕсли;
           Ном3 = Ном1 + 1;
       Иначе
           Зн1 = ТЗ_.ПолучитьЗначение(Ном2,Колонка1);
           Если Зн1 = Значение1 Тогда
               Возврат(Дельта + Ном2);
           КонецЕсли;
           Ном3 = Ном2 + 1;
       КонецЕсли;
       Дельта = Дельта + Ном3;
       ТЗ_.Выгрузить(ТЗ_,Ном3, , );
       Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   КонецЦикла;
КонецФункции
144 Warlock
 
04.08.04
09:55
(140)NS, спасибо за поддержку. А ведь выше по тексту (2) раскритиковали немерянно(может быть не вдумавшись, да и я не объяснил...). Так что перебор - универсальнее, хотя надо смотреть для конкретных случаев по ситуации(может другой алгоритм будет работать лучше перебора)...
145 Громобой
 
04.08.04
10:01
(144) Шутишь? При неоднократном поиске твой метод - г...
Ты кстати наверное по-другому и не делал никогда?
146 Warlock
 
04.08.04
10:13
(145)В большинстве случаев результатами запроса являются небольшие объемы данных, и перебор справляется с небольшим количеством очень хорошо. Если объем данных велик, и поиск надо делать много раз, то я не зацикливаюсь на нахождении супероптимального поиска по ТЗ... Я оцениваю ситуацию комплексно(исходя из исходных данных и условий) и, возможно, перестраиваю запрос, меняю алгоритм получения даныых, и т.д. Все зависит от конкретной ситуации. Так вот. Ответ на (145)"Ты кстати наверное по-другому и не делал никогда?" - делал.
Ответ на (0) - универсальное решение(ведь кроме условия поиска других условий не было) - перебор строк.
147 VladZagorsky
 
04.08.04
10:24
(142) Я показал идею. По поводу твоего замечания про

"товар1 называется  "123" партия1 "4"
товар2 называется  "12"  партия1 "34""  

согласен, только в данном случае таких проблем не будет. Это факт.
148 User63
 
04.08.04
10:26
Даа... Тема то актуальной оказалась. С учетом всех всех вариантов, по моему, для меня самый оптимальный вариант (5) с учетом (9).
Спасибо всем.
149 Громобой
 
04.08.04
10:28
(146) Везет тебе, у тебя объемы данных маленькие... И задачи такие же...
Кстати, если в ТЗ всего на 10 000 строк 100 раз выполнять поиск твоим методом, то уходит времени в 40-50 раз больше, чем если 1 раз создать поле "индекс" (ты сказал что это хорошая ИДЕЯ, т.е. для тебя это новое) и потом по этому индексу искать.
150 User63
 
04.08.04
10:29
(147) Между "товар" и "партия", наверное, надо какой-нибудь символ добавить, например "_". Тогда все нормально должно пройти...
151 Z1
 
04.08.04
10:34
(150) Не какой то а тот который никогда не встречается в наименовании.
Например РазделительСтрок или Симв(255)
А еще лучше (уже было сказано выше ) использовать ID из справочника вместо названия, кода.
152 IAm
 
04.08.04
10:35
144 NS-у снились кошмары
153 Громобой
 
04.08.04
10:36
(IAm) Кстати твой вариант в (5) работает так же быстро, как и вариант с созданием индекса (кстати время на создание индекса тратится просто смешное). Но если нужно сравнивать хотя бы 3 параметра, например Склад,Товар,Номенклатура то будет работать хуже. А варианты типа (20)и(24) вообще не выдерживают критики. Время на выгрузку ТЗ тратится неслабое, а если искать нужно несколько раз, то вообще хана (это кстати относится к Рупору тоже).
154 IAm
 
04.08.04
10:37
Для множественного поиска ничего красивше индекса нету, для одиночного ничего элегантнее чем в (24) не придумано, и я не понял, куда галки делись.
155 Громобой
 
04.08.04
10:38
(151) Я же написал раньше что использовать надо ЗначениеВСтрокуВнутр() либо ЗначениеВСтроку(). Так накладок не будет.
156 IAm
 
04.08.04
10:39
153 Ну и ладно
157 Громобой
 
04.08.04
10:43
(154) "Для множественного поиска ничего красивше индекса нету" - согласен. Но для одиночного ничего элегантнее твоего (5) нет. (24) - не элегантно, т.к. при большой ТЗ будит ЗНАЧИТЕЛЬНО тормознее, потому что основное  время  займет  ТЗ.Выгрузить(ТЗ_).
158 VladZagorsky
 
04.08.04
10:44
(150) Еще раз повторюсь: я показал идею.

P.S. Никому никогда не давал готовых решений - это расслабляет.
159 IAm
 
04.08.04
10:47
157 Если нужно получить номер строки, то решение в 5 не покатит.
ТЗ.Выгрузить(ТЗ_); можно заменить на ТЗ.Выгрузить(ТЗ_,,,"Колонка1,Колонка2");
Время экономит.
160 IAm
 
04.08.04
10:49
Умные все стали, на вас не угодишь.
161 Z1
 
04.08.04
10:51
(157) ну и что решение (5) даст для ТЗ
1, 1  - 1000 строк ( тысяча одинаковых строк)
1, 2  - 1001-ая строка
при поиске 1, 2
162 Громобой
 
04.08.04
10:56
(160) :) В (159) ты прав на 100%.
Значит постановим: в случае многократного поиска ответ (76) - лучший
в случае однократного поиска вариант (24) с учетом (159) - лучший.
ЗЫ. IAm, повесим медали на грудь и разбежимся.
163 Громобой
 
04.08.04
11:00
(161) Друг мой, а что даст твое "Не какой то а тот который никогда не встречается в наименовании. Например РазделительСтрок или Симв(255)" если товары и номенклатуры имеют АБСОЛЮТНО одинаковое строковое представление и даже код, но как объекты они разные??? Давай не будем придумывать редковстречающиеся варианты? И вообще, читай (162)
164 Z1
 
04.08.04
11:06
(163) Когда споткнешься на таких "редковстечающихся вещах" , потратишь день-два
на поиск их, а еще если при этом у руковоства на столе будут неправильные цифры например по прибыли тогда прочувствуешь что есть редковстречающиеся случаи.
Ситуацию с такой ошибкой в ТЗ очень давно описывал NS.
(162)  143 чуть быстрее работает чем 24
165 VladZagorsky
 
04.08.04
11:07
Хм...  Перечитал все сначала...  Поймал себя на мысле, что похож на персонажа из анегдота:

Из дневника нового русского.
... "Вчера перечитал пейджер... Много думал..."
166 Громобой
 
04.08.04
11:35
(164) Ты заметь,я (5) не писал. А ты на (163) не ответил.
167 Den
 
04.08.04
11:51
Самый правильный ответ на (0) в (1). А все остальное - это только те самые размышления, после пейджера
168 Громобой
 
04.08.04
11:55
(167) О, еще один циклично-поточный программист...
169 Z1
 
04.08.04
12:00
(166) Но post 157 твой и на мой взгляд неправильный см 161.
В 163 я вообще не вижу вопроса ко мне. Сформулируй вопрос поконкретней - отвечу.
170 Громобой
 
04.08.04
12:20
(169) В 163 я говорю что ты дал неправильные указания для построения индекса. Это типа как в 161 ты привел редковстречающийся пример, а я тебе привел ответный пример.
171 Z1
 
04.08.04
12:37
(170) По поводу индеска как раз я и утверждал см 142
"индекс надо тщательней продумывать " ( с примером к чему может привести плохой индекс). и см также  151 как один из вариантов индекса.
Ну и чем же (161) редковстречающийся алгоритм 5 на нем не работает хорошо давай я тебе другой пример приведу ( более правдоподобный )
1,1
1,2
1,3
....
1, 1000
1, 1001
Алгоритм из 5 очень плохо будет искать 1, 1001
Ответного тобой примера не видел.
Опять же в 162 ты утверждаешь что для постановки Рупора 76 лучшее решение.
Обоснуй чем 76 лучше 143
172 Z1
 
04.08.04
12:40
"Опять же в 162 ты утверждаешь что для постановки Рупора 76 лучшее решение.
Обоснуй чем 76 лучше 143 "
Сорри надо читать так
Опять же в 162 ты утверждаешь что для постановки Рупора 24 лучшее решение.
Обоснуй чем 76 лучше 24
173 Громобой
 
04.08.04
12:47
(172) Замнем для ясности? Пора поесть :)
174 Den
 
04.08.04
15:03
(168) Почему это циклично-поточный? Вопрос был "можно ли..." (0), ответ "можно" (1)
175 User63
 
04.08.04
15:05
Обед закончился?
176 Громобой
 
04.08.04
15:27
(175) Ответ "да"
177 IAm
 
04.08.04
15:29
176 А обед?
178 Громобой
 
04.08.04
15:30
(177) Хорош. Прошлое совершенное время.
179 NS
 
04.08.04
15:34
Для разового поиска - всяко бытрее простой перебор...
Так как добавление любой колонки с заполнением - эн логарифмов эн....
в методе (5) - не узнать номер строки...
И раз уж отсортировал - то лучше бинарный поиск (логарифм вместо эн)
180 NS
 
04.08.04
15:35
Для разового поиска - всяко бытрее простой перебор...
Так как добавление любой колонки с заполнением - эн логарифмов эн....
в методе (5) - не узнать номер строки...
И раз уж отсортировал - то лучше бинарный поиск (логарифм вместо эн)
181 Громобой
 
04.08.04
15:45
(180) Оп-п-паааньки... Слушай, сделай одолжение, подумай: есть ТЗ в 100 000 строк (хотя это не важно), в 99 999 строке искомое значение, что быстрее - перебрать все строки, выполняя операцию сравнения (тоже время занимает), или  сделать хотя-бы раз ТЗ.Найти() а дальше перебирать и сравнивать?
182 Громобой
 
04.08.04
15:47
(IAm) Если я написал бы на (2) кг/ам это означало бы что я с ним типа согласен, не так ли?
183 Guk
 
04.08.04
15:49
(181) Я не проверял, но быстрее будет, как сказал NS. По-любому. ИМХО...
И вообще, если у человека теперь не светятся синие яйца, это еще не повод с ним спорить...
184 Громобой
 
04.08.04
15:54
(183) Не повод спорить? Даже если он НЕ ПРАВ? Я такие алгоритмы по методу (5) не раз переписывал после людей считающих как (180). Да, кстати, раз уж ты не проверял, то убыстрение в некоторых случаях в 5-7 раз. Я проверял.
185 IAm
 
04.08.04
16:01
182 Не знаю. Обычно пишут когда думают что несогласны.
186 Guk
 
04.08.04
16:02
(184) Ты проверял? Хорошо, теперь верю тебе. ТЫ ПРАВ! NS НЕ ПРАВ!
А вообще, мне насрать...
187 Громобой
 
04.08.04
16:05
(185) Спасибо. Ты подтвердил мои предположения :) "а" означает автор, "к" креатив, но что же за буквы "г" и "м"?
(186) Ай, молодца!
188 Z1
 
04.08.04
16:11
(180) Для разового поиска перебор это просто N.
Все дело в реалиции этого перебора.
Одно дело перебор через интерпретатор 1с и
другое дело тот же самый перебор через метод НайтиЗначение в ТЗ, реализованный
на языке Си++.
189 NS
 
04.08.04
16:21
Кто спорит - смотрим (140) и предыдущий диалог...
Есть ТЗ, неотсортированная, нужно найти любую строку, с данной партией, и товаром - и сообщить НОМЕР СТРОКИ в изначальной таблице...
Мной предложен способ - если кто-то считает, что можно разовый поиск сделать быстрее - предлагайте свой вариант.
стр=0;
ТЗ.ВыбратьСтроки();
пока тЗ.ПолучитьСтроку()=1 цикл
если ТЗ.Номенклатура=номенклатура тогда
если ТЗ.Партия=партия Тогда
  стр=ТЗ.Номерстроки;
  прервать;
конецесли;
конецесли;
КонецЦикла;
если стр=0 тогда
 сообщить("не нашли");
Иначе
 сообщить(стр);
КонецЕсли;
можно подготовить тестовый пример - ТЗ на 10000 строк, в первой и второй колонке случайное целое число из диапазона 1..100
190 IAm
 
04.08.04
16:22
187
"м" - молодец
"г" - очень хороший, лучше не бывает
191 Z1
 
04.08.04
16:42
(189) Осталось найди судью или судей. Создать несколько эталонных ТЗ и проверить алгоритмы
(189),  (24), (143)
для постановки задачи обозначеной в (189).
192 Тор
 
04.08.04
16:45
Варлок задолбал ветку в базу знаний добавлять
193 Тор
 
04.08.04
16:46
Варлок задолбал ветку в базу знаний добавлять
194 Warlock
 
04.08.04
16:48
(Тор)Что-то имешь против?! Говори!
195 Z1
 
04.08.04
16:48
(all) Интересно а по какому принципу ставят галки для базы знаний?
Некоторые посты без галок весьма ценЫ (например 188 не потому что мой ) а их не будет в базе знаний - обидно. Такие ветки или целиком все или ничего (ИМХО)
196 Тор
 
04.08.04
16:49
(194) Отдай свою звезду IAm! Посыпь голову пеплом.
197 NS
 
04.08.04
16:52
(191) И что победителю?
Как обычно, 500$?
198 Warlock
 
04.08.04
16:52
(Z1)Субъективно. Зависит от инженера знаний.
"Такие ветки или целиком все или ничего" - флеймят тут всякие...
(Тор)Наезжать каждый может... Бочки катить много ума не надо! И хватит IAm'ом прикрываться. Ты так судишь меня, а ведь я уверен, что все мои посты ты не читал.
199 Громобой
 
04.08.04
16:56
Для маленьких ТЗ (до 1000 строк) для нахождения строки по неограниченному количеству условий хорошо работает такая функция:
Функция НайтиСтрокуТЗ(ТЗ,Спис)  
 Н1=0;  
   ТЗ2=СоздатьОбъект("ТаблицаЗначений");
   ТЗ.Выгрузить(ТЗ2);
   ТЗ2.НоваяКолонка("Н","Число");
   ТЗ2.Заполнить(1,,,"Н");
   
   Для П=1 по Спис.РазмерСписка() цикл
       Кол="";
       Зн=Спис.ПолучитьЗначение(П,Кол);
       Нстр=0;
       Если ТЗ2.НайтиЗначение(Зн,Нстр,Кол)=1 тогда
           ТЗ2.Выгрузить(ТЗ2,Нстр);
       Иначе
           Возврат;
       КонецЕсли;              
       Если П=Спис.РазмерСписка() тогда
           Н1=ТЗ.КоличествоСтрок()-ТЗ2.КоличествоСтрок()+1;
       КонецЕсли;    
   КонецЦикла;                  
  Возврат Н1;
КонецФункции

где Спис - список значений с условиями, например:
   Спис=СоздатьОбъект("СписокЗначений");
   Спис.ДобавитьЗначение(ВыбСклад,"Склад");
   Спис.ДобавитьЗначение(ВыбТМЦ,"ТМЦ");
   Спис.ДобавитьЗначение(ВыбНоменклатура,"Номенклатура");
Строковое представление в списке такое как название столбца в ТЗ
200 Тор
 
04.08.04
17:01
(Варлок) Не будем спорить. Ты гениален.
201 Warlock
 
04.08.04
17:04
(200)Я не говорю, что я гениален. Я же человек, могу и ошибаться...
202 Тор
 
04.08.04
17:09
(Варлок) Опиши как ты понимаешь код в (24) если не сложно
203 IAm
 
04.08.04
17:11
:)))
204 Z1
 
04.08.04
17:23
(197) Не я на деньги не спорю.
205 Тор
 
04.08.04
17:26
(203) Молчание Варлока достаточно красноречиво. И он еще говорит, чтобы я не прикрывался тобой. Я вот к слову код понимаю нормально.
206 Warlock
 
04.08.04
17:27
Тор - это, наверно, моя тень. Очень вредная... ;))

Функция ПоискПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
Перем ТЗ_;  
//Объявляем переменную для временной ТаблицыЗначений
ТЗ.Выгрузить(ТЗ_);
//Выгружаем все данные из основной ТЗ в дополнительную (ТЗ_)
ИндексПоиска = 0;
//ИндексПоиска - доп. переменная, кот. содержит номер реквизита, который нашелся
Пока 1=1 Цикл//Запускаем вечный цикл. Выход по доп. условию.
   //Если найден номер строки, в которой встречается значение одного из искомых реквизитов, ищем другой
   Если ИндексПоиска <> 1 Тогда
       Поз1=0;
       ТЗ_.НайтиЗначение(Значение1,Поз1,Колонка1);
   КонецЕсли;
   Если ИндексПоиска <> 2 Тогда
       Поз2 =0;
       ТЗ_.НайтиЗначение(Значение2,Поз2,Колонка2);  
   КонецЕсли;
   //В Поз1 и Поз2 - Номера строк, в которых есть значения, удовлетворяющие поиску.
   Если (Поз1=0) ИЛИ (Поз2=0) Тогда
       //Какое-то или оба значения не нашлись....
       Возврат(0)
   ИначеЕсли Поз1 = Поз2 Тогда
       //Обя значения в одной строке - это и есть искомая строка!
       Возврат Поз1;
   ИначеЕсли Поз1 > Поз2 Тогда
       // Исходя из значнений Поз1, Поз2 обнуляем значения в ТЗ_, чтобы НайтиЗначение() больше не срабатывала на найденных значениях
       ТЗ.Заполнить("", 1, Поз1 - 1, Колонка2);
       ИндексПоиска = 1;
   Иначе
       ТЗ.Заполнить("", 1, Поз2 - 1, Колонка1);
       ИндексПоиска = 2;
   КонецЕсли;
КонецЦикла;

Объяснил?
207 Тор
 
04.08.04
17:27
+205. Кстати потому что понимаю, потому и уважаю автора.
208 Warlock
 
04.08.04
17:31
(Тор)Ну?
209 Тор
 
04.08.04
17:31
(Варлок) Эх, молодежь... Пойми, понять код и ПРИДУМАТЬ код разные вежи
210 Warlock
 
04.08.04
17:32
(209)Может ты и не веришь, но я _знаю_ эту разницу...
211 Тор
 
04.08.04
17:34
(Варлок) Да верю, верю, не нервничай. Хочешь еще вопросик?
212 Warlock
 
04.08.04
17:35
(211)Только в отдельной ветке!
213 Тор
 
04.08.04
17:38
(Варлок) Давай подадим пример. Я буду задавать вопросы, ты на них отвечать. Потом можно будет оценить уровень вопросов и ответов и возможно добавить тебе звезду, может и две. Может звезды потом так давать будут: типа по результатам тестов.
214 Warlock
 
04.08.04
17:43
(213)Ты еще скажи, что это твоя идея... :)
"Я буду задавать вопросы, ты на них отвечать." - это форум;
"Потом можно будет оценить уровень вопросов и ответов и возможно добавить тебе звезду, может и две." - вроде так и работает. Волшебник оценяет(-нял);
"Может звезды потом так давать будут: типа по результатам тестов." - была ветка по обсуждению данной темы. Вроде утопилась...
215 Тор
 
04.08.04
17:53
(Варлок) Все идеи мои и не мои одновременно. Пришла мне в голову - значит моя. Но все в этом мире уже когда-то было, значит - не моя. :)
216 Рупор абсурда
 
04.08.04
17:56
Тор, чё ты до парня домотался? ...
Ты тоже тут фигни достаточно наговорил ...
Отстань от него ..., а то я тебя самого счас с дерьмом мешать начну ...

Warlock, а ты не ведись ... как маленький ...
217 Тор
 
04.08.04
17:58
(216) 1.Раз ведется, значит маленький. 2.Фигни и ты наговорил 3.Попробуй
218 Warlock
 
04.08.04
18:01
(216)Да вот... Хотел конструктивной критики и ... "развелся"... Тор - негодяй!
219 Рупор абсурда
 
04.08.04
18:04
(217) Ответь-ка мне для начала на один вопрос ...
Ты стал считать себя таким сильно умным после того, как понял (24) или раньше с тобой такое тоже бывало?
220 Рупор абсурда
 
04.08.04
18:06
(218) Скажем так: Если ты не любишь конструктивную критику ..., это нормально ...
221 Тор
 
04.08.04
18:12
(219) Руппи, я себя никогда не считал. Я твердо знаю что меня получится ровно 1 штука.
(218) Угу, в таком случае отвечу тебе - кг/ам
222 Тор
 
04.08.04
18:18
+221. Правда, Варлок, ты все равно не поймешь, что я сказал... Ну и хорошо. Тебе спокойнее будет.
223 Warlock
 
04.08.04
18:20
(222)Я пытался понять, но решил даже не спрашивать...
224 NS
 
04.08.04
19:34
Это кто под моим ником деньги на кон ставит?
Так кто-нибудь мерял быстродействие?
225 Guk
 
04.08.04
20:37
(224) Наверное Бекас.
Он знает все пароли, ко всем никам...
226 NS
 
04.08.04
20:53
А вот и тест - параметры, как договаривались - первый 10000, второй 100...
Можно попробовать - первый 100000, второй 300...

перем случ;
Процедура Рандомизе()
   случ=_GetPerformanceCounter();
КонецПроцедуры                      
Функция Рандом(Интервал)  
   Случ=случ%1000000000000001;
   Случ=Случ*1103515245+12345;
   Возврат ((Случ/65536)%32768)%Интервал+1;
КонецФункции    
Процедура Сформировать()
   перем ТЗ,ТЗ_,КолстрокВТЗ,Разных;
   ввестичисло(колСтрокВТЗ,"Введите кол. строк в ТЗ",10,0);
   ввестичисло(Разных,"Введите количество разных значений",10,0);
   ТЗ=создатьОбъект("ТаблицаЗначений");
   ТЗ.Новаяколонка("Кол1","Число",10,0);
   ТЗ.НоваяКолонка("Кол2","Число",10,0);
   Рандомизе();
   Для а=1 по КолСтрокВТЗ цикл
       Если а%100=0 Тогда
           состояние(а);
       КонецЕсли;    
       ТЗ.НоваяСтрока();
       ТЗ.Кол1=Рандом(Разных);
       ТЗ.Кол2=Рандом(Разных);
   КонецЦикла;                            
   Ищем1=Рандом(Разных);
   Ищем2=Рандом(Разных);
   начвремя=_GetperformanceCounter();
   стр=0;
   ТЗ.ВыбратьСтроки();
   пока тЗ.ПолучитьСтроку()=1 цикл
       если ТЗ.Кол1=Ищем1 тогда
           если ТЗ.кол2=Ищем2 Тогда
               стр=ТЗ.Номерстроки;
               прервать;
           конецесли;
       конецесли;
   КонецЦикла;
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Простым перебором "+(конВремя-НачВремя)+" мс.");
   // способ 2;
   начвремя=_GetperformanceCounter();
   стр=0;  
   _ТЗ=создатьобъект("ТаблицаЗначений");
   ТЗ.Выгрузить(_ТЗ,,,"Кол1");
   Пока _ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
       если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
           прервать;
       Иначе          
           _ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
           стр=0;
       КонецЕсли;    
   КонецЦикла;        
   _ТЗ.Очистить();
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Метод 2: "+(конВремя-НачВремя)+" мс.");
   
   // метод IAm  
   начвремя=_GetperformanceCounter();
   _ТЗ=создатьобъект("ТаблицаЗначений");
   ТЗ.Выгрузить(_ТЗ);
   ИндексПоиска = 0;
   Пока 1=1 Цикл  
       Если ИндексПоиска <> 1 Тогда
           Поз1=0;
           _ТЗ.НайтиЗначение(Ищем1,Поз1,"Кол1");
       КонецЕсли;
       Если ИндексПоиска <> 2 Тогда
           Поз2 =0;
           _ТЗ.НайтиЗначение(Ищем2,Поз2,"Кол2");  
       КонецЕсли;
       Если (Поз1=0) ИЛИ (Поз2=0) Тогда
           прервать;
       ИначеЕсли Поз1 = Поз2 Тогда
           прервать;
       ИначеЕсли Поз1 > Поз2 Тогда
           _ТЗ.Заполнить("", 1, Поз1 - 1, "Кол2");
           ИндексПоиска = 1;
       Иначе
           _ТЗ.Заполнить("", 1, Поз2 - 1, "Кол1");
           ИндексПоиска = 2;
       КонецЕсли;
   КонецЦикла;  
   _ТЗ.Очистить();
   если (Поз1=0)или(поз2=0) тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Метод IAm: "+(конВремя-НачВремя)+" мс.");  
   // Если что не так - подправте модуль.
КонецПроцедуры
227 NS
 
04.08.04
21:08
Кого интересуют результаты теста - перебор, как я и говорил - быстрее,
и чем больше строк в ТЗ, тем перебор сильнее выигрывает...
228 Guk
 
04.08.04
21:27
(227) А я говорил, надо было на 500$ рубиться...
229 NS
 
04.08.04
21:30
(228) Рискованно было...
Метод (13) Близок по скорости (на маленьком количестве элементов - до тысячи - даже быстрее, но при больших медленней... (при 100000, более, чем в два раза))
ЗЫ. Я писал метод 2 - не видя 13-го поста.... как-то я этот пост упустил.
230 Z1
 
04.08.04
21:39
(229) Твои псевдослучайные числа у меня дают сплошной 0.
Мой тест
//*******************************************
Функция Ранд(Парам=0)
   Если Парам<>0 Тогда
       Случай=Парам;
   КонецЕсли;
   Если Число(Случай)=0 Тогда
       Случай=Число(СтрЗаменить(""+ТекущееВремя(),":",""));
       Случай=(16807*Случай)%2147483647;
   КонецЕсли;
   Случай=(16807*Случай)%2147483647;
   Случай=макс(Случай,-Случай);
   Возврат(Случай/2147483647);
КонецФункции

Функция ВычислитьДельта(Мин1, Макс1)
   Зн1 = Макс1 - Мин1 + 1;
   Ч1 = Ранд();
   Ч2 = Ч1 * Зн1;
   Ч3 = Мин1 + Цел( Ч2 );
   return Ч3;
КонецФункции

Функция ПоискОдиночныйПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
   Перем ТЗ_;
   //Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк1 :)") КонецЕсли;
   //Если ПустоеЗначение(Значение2)=1 Тогда Возврат("Глюк2 :)") КонецЕсли;
   Ном1=0;
   ТЗ.НайтиЗначение(Значение1,Ном1,Колонка1);
   Если Ном1=0 Тогда Возврат(0) КонецЕсли;
   Ном2=0;
   ТЗ.НайтиЗначение(Значение2,Ном2,Колонка2);
   Если Ном2=0 Тогда Возврат(0) КонецЕсли;
   Если Ном1 = Ном2 Тогда
       Возврат(Ном1);
   ИначеЕсли Ном1 > Ном2 Тогда
       Зн2 = ТЗ.ПолучитьЗначение(Ном1,Колонка2);
       Если Зн2 = Значение2 Тогда
           Возврат(Ном1);
       КонецЕсли;
       Ном3 = Ном1 + 1;
   Иначе
       Зн1 = ТЗ.ПолучитьЗначение(Ном2,Колонка1);
       Если Зн1 = Значение1 Тогда
           Возврат(Ном2);
       КонецЕсли;
       Ном3 = Ном2 + 1;
   КонецЕсли;
   Дельта = Ном3;
   СписокКолонок = Колонка1 + "," + Колонка2;
   ТЗ.Выгрузить(ТЗ_,Ном3, ,СписокКолонок );
   Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   Пока 1=1 Цикл
       Ном1=0;
       ТЗ_.НайтиЗначение(Значение1,Ном1,Колонка1);
       Если Ном1=0 Тогда Возврат(0) КонецЕсли;
       Ном2=0;
       ТЗ_.НайтиЗначение(Значение2,Ном2,Колонка2);
       Если Ном2=0 Тогда Возврат(0) КонецЕсли;
       Если Ном1 = Ном2 Тогда
           Возврат(Дельта + Ном1);
       ИначеЕсли Ном1 > Ном2 Тогда
           Зн2 = ТЗ_.ПолучитьЗначение(Ном1,Колонка2);
           Если Зн2 = Значение2 Тогда
               Возврат(Дельта + Ном1);
           КонецЕсли;
           Ном3 = Ном1 + 1;
       Иначе
           Зн1 = ТЗ_.ПолучитьЗначение(Ном2,Колонка1);
           Если Зн1 = Значение1 Тогда
               Возврат(Дельта + Ном2);
           КонецЕсли;
           Ном3 = Ном2 + 1;
       КонецЕсли;
       Дельта = Дельта + Ном3;
       ТЗ_.Выгрузить(ТЗ_,Ном3, , );
       Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   КонецЦикла;
КонецФункции

Процедура Рандомизе()
  случ=_GetPerformanceCounter();
КонецПроцедуры                      
Функция Рандом(Интервал)  
  Случ=случ%1000000000000001;
  Случ=Случ*1103515245+12345;
   Ч1 = ((Случ/65536)%32768)%Интервал+1;
   Ч2 = Цел(Ч1);
   Сообщить("Ч2 = " + Ч2);
  Возврат Ч2;
КонецФункции    
Процедура Сформировать()
  перем ТЗ,ТЗ_,КолстрокВТЗ,Разных;
  //ввестичисло(колСтрокВТЗ,"Введите кол. строк в ТЗ",10,0);
  //ввестичисло(Разных,"Введите количество разных значений",10,0);
  колСтрокВТЗ = 10000;
  Разных = 100;
  ТЗ=создатьОбъект("ТаблицаЗначений");
  ТЗ.Новаяколонка("Кол1","Число",10,0);
  ТЗ.НоваяКолонка("Кол2","Число",10,0);
  Рандомизе();
  Для а=1 по КолСтрокВТЗ цикл
      Если а%100=0 Тогда
          состояние(а);
      КонецЕсли;    
      ТЗ.НоваяСтрока();
      ТЗ.Кол1= ВычислитьДельта(0, Разных);
      ТЗ.Кол2=ВычислитьДельта(0, Разных);
  КонецЦикла;                            
  Ищем1= ВычислитьДельта(0, Разных);
  Ищем2=ВычислитьДельта(0, Разных);
  Сообщить("Ищем = " + Ищем1 + " " + Ищем2);
  начвремя=_GetperformanceCounter();
  стр=0;
  ТЗ.ВыбратьСтроки();
  пока тЗ.ПолучитьСтроку()=1 цикл
      если ТЗ.Кол1=Ищем1 тогда
          если ТЗ.кол2=Ищем2 Тогда
              стр=ТЗ.Номерстроки;
              прервать;
          конецесли;
      конецесли;
  КонецЦикла;
  если стр=0 тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Простым перебором "+(конВремя-НачВремя)+" мс.");
  // способ 2;
  начвремя=_GetperformanceCounter();
  стр=0;  
  _ТЗ=создатьобъект("ТаблицаЗначений");
  ТЗ.Выгрузить(_ТЗ,,,"Кол1");
  Пока _ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
      если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
          прервать;
      Иначе          
          _ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
          стр=0;
      КонецЕсли;    
  КонецЦикла;        
  _ТЗ.Очистить();
  если стр=0 тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Метод 2: "+(конВремя-НачВремя)+" мс.");
   
  // метод IAm  
  начвремя=_GetperformanceCounter();
  _ТЗ=создатьобъект("ТаблицаЗначений");
  ТЗ.Выгрузить(_ТЗ);
  ИндексПоиска = 0;
  Пока 1=1 Цикл  
      Если ИндексПоиска <> 1 Тогда
          Поз1=0;
          _ТЗ.НайтиЗначение(Ищем1,Поз1,"Кол1");
      КонецЕсли;
      Если ИндексПоиска <> 2 Тогда
          Поз2 =0;
          _ТЗ.НайтиЗначение(Ищем2,Поз2,"Кол2");  
      КонецЕсли;
      Если (Поз1=0) ИЛИ (Поз2=0) Тогда
          прервать;
      ИначеЕсли Поз1 = Поз2 Тогда
          прервать;
      ИначеЕсли Поз1 > Поз2 Тогда
          _ТЗ.Заполнить("", 1, Поз1 - 1, "Кол2");
          ИндексПоиска = 1;
      Иначе
          _ТЗ.Заполнить("", 1, Поз2 - 1, "Кол1");
          ИндексПоиска = 2;
      КонецЕсли;
  КонецЦикла;  
  _ТЗ.Очистить();
  если (Поз1=0)или(поз2=0) тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Метод IAm: "+(конВремя-НачВремя)+" мс.");  
  // Если что не так - подправте модуль.
  начвремя=_GetperformanceCounter();
   Зн1 = ПоискОдиночныйПоДвумКолонкам(ТЗ,Ищем1,Ищем2,"Кол1","Кол2");
  конвремя=_GetperformanceCounter();
  Сообщить("Зн1 = " + Зн1);
  сообщить("Метод Z1 (143) "+(конВремя-НачВремя)+" мс.");
  Сообщить(" ");
КонецПроцедуры

Результат теста
Ищем = 97 97
7604
Простым перебором 163 мс.
7604
Метод 2: 131 мс.
7604
Метод IAm: 248 мс.
Зн1 = 7604
Метод Z1 (143) 4 мс.

Ищем = 89 89
6706
Простым перебором 147 мс.
6706
Метод 2: 128 мс.
6706
Метод IAm: 252 мс.
Зн1 = 6706
Метод Z1 (143) 3 мс.

Ищем = 33 33
6483
Простым перебором 140 мс.
6483
Метод 2: 128 мс.
6483
Метод IAm: 251 мс.
Зн1 = 6483
Метод Z1 (143) 3 мс.
231 NS
 
04.08.04
21:46
Да уж...
Почему у тебя ищем1 всегда равно ищем2? ;-)
Ты просто с генератором накосячил...
Сделай ТЗ.ВыбратьСтроку();
232 Z1
 
04.08.04
21:52
(231) Не спорю может и накосячил. Твой генератор дает у меня на компьютере сплошные нули.
Предложи другой генератор лучше из какой нибудь ВК. после сравним.
Все до завтра - поеду я домой.
233 NS
 
04.08.04
21:56
(232) Не может, а точно....
Мой нули не выдает...
234 NS
 
04.08.04
22:07
перем случ;
Функция ПоискОдиночныйПоДвумКолонкам(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
   Перем ТЗ_;
   //Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк1 :)") КонецЕсли;
   //Если ПустоеЗначение(Значение2)=1 Тогда Возврат("Глюк2 :)") КонецЕсли;
   Ном1=0;
   ТЗ.НайтиЗначение(Значение1,Ном1,Колонка1);
   Если Ном1=0 Тогда Возврат(0) КонецЕсли;
   Ном2=0;
   ТЗ.НайтиЗначение(Значение2,Ном2,Колонка2);
   Если Ном2=0 Тогда Возврат(0) КонецЕсли;
   Если Ном1 = Ном2 Тогда
       Возврат(Ном1);
   ИначеЕсли Ном1 > Ном2 Тогда
       Зн2 = ТЗ.ПолучитьЗначение(Ном1,Колонка2);
       Если Зн2 = Значение2 Тогда
           Возврат(Ном1);
       КонецЕсли;
       Ном3 = Ном1 + 1;
   Иначе
       Зн1 = ТЗ.ПолучитьЗначение(Ном2,Колонка1);
       Если Зн1 = Значение1 Тогда
           Возврат(Ном2);
       КонецЕсли;
       Ном3 = Ном2 + 1;
   КонецЕсли;
   Дельта = Ном3;
   СписокКолонок = Колонка1 + "," + Колонка2;
   ТЗ.Выгрузить(ТЗ_,Ном3, ,СписокКолонок );
   Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   Пока 1=1 Цикл
       Ном1=0;
       ТЗ_.НайтиЗначение(Значение1,Ном1,Колонка1);
       Если Ном1=0 Тогда Возврат(0) КонецЕсли;
       Ном2=0;
       ТЗ_.НайтиЗначение(Значение2,Ном2,Колонка2);
       Если Ном2=0 Тогда Возврат(0) КонецЕсли;
       Если Ном1 = Ном2 Тогда
           Возврат(Дельта + Ном1);
       ИначеЕсли Ном1 > Ном2 Тогда
           Зн2 = ТЗ_.ПолучитьЗначение(Ном1,Колонка2);
           Если Зн2 = Значение2 Тогда
               Возврат(Дельта + Ном1);
           КонецЕсли;
           Ном3 = Ном1 + 1;
       Иначе
           Зн1 = ТЗ_.ПолучитьЗначение(Ном2,Колонка1);
           Если Зн1 = Значение1 Тогда
               Возврат(Дельта + Ном2);
           КонецЕсли;
           Ном3 = Ном2 + 1;
       КонецЕсли;
       Дельта = Дельта + Ном3;
       ТЗ_.Выгрузить(ТЗ_,Ном3, , );
       Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   КонецЦикла;
КонецФункции

Процедура Рандомизе()
   случ=_GetPerformanceCounter();
КонецПроцедуры                      
Функция Рандом(Интервал)  
   Случ=случ%1000000000000001;
   Случ=Случ*1103515245+12345;
   Возврат ((Случ/65536)%32768)%Интервал+1;
КонецФункции    
Процедура Сформировать()
   перем ТЗ,ТЗ_,КолстрокВТЗ,Разных;
   ввестичисло(колСтрокВТЗ,"Введите кол. строк в ТЗ",10,0);
   ввестичисло(Разных,"Введите количество разных значений",10,0);
   ТЗ=создатьОбъект("ТаблицаЗначений");
   ТЗ.Новаяколонка("Кол1","Число",10,0);
   ТЗ.НоваяКолонка("Кол2","Число",10,0);
   Рандомизе();
   Для а=1 по КолСтрокВТЗ цикл
       Если а%100=0 Тогда
           состояние(а);
       КонецЕсли;    
       ТЗ.НоваяСтрока();
       ТЗ.Кол1=Рандом(Разных);
       ТЗ.Кол2=Рандом(Разных);
   КонецЦикла;  
   Тз.ВыбратьСтроку();
   Ищем1=Рандом(Разных);
   Ищем2=Рандом(Разных);
   сообщить("Ищем: "+Ищем1+" "+Ищем2);
   начвремя=_GetperformanceCounter();
   стр=0;
   ТЗ.ВыбратьСтроки();
   пока тЗ.ПолучитьСтроку()=1 цикл
       если ТЗ.Кол1=Ищем1 тогда
           если ТЗ.кол2=Ищем2 Тогда
               стр=ТЗ.Номерстроки;
               прервать;
           конецесли;
       конецесли;
   КонецЦикла;
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Простым перебором "+(конВремя-НачВремя)+" мс.");
   // способ 2;
   начвремя=_GetperformanceCounter();
   стр=0;  
   _ТЗ=создатьобъект("ТаблицаЗначений");
   ТЗ.Выгрузить(_ТЗ,,,"Кол1");
   Пока _ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
       если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
           прервать;
       Иначе          
           _ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
           стр=0;
       КонецЕсли;    
   КонецЦикла;        
   _ТЗ.Очистить();
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Метод 2: "+(конВремя-НачВремя)+" мс.");
   
   // метод IAm  
   начвремя=_GetperformanceCounter();
   _ТЗ=создатьобъект("ТаблицаЗначений");
   ТЗ.Выгрузить(_ТЗ);
   ИндексПоиска = 0;
   Пока 1=1 Цикл  
       Если ИндексПоиска <> 1 Тогда
           Поз1=0;
           _ТЗ.НайтиЗначение(Ищем1,Поз1,"Кол1");
       КонецЕсли;
       Если ИндексПоиска <> 2 Тогда
           Поз2 =0;
           _ТЗ.НайтиЗначение(Ищем2,Поз2,"Кол2");  
       КонецЕсли;
       Если (Поз1=0) ИЛИ (Поз2=0) Тогда
           прервать;
       ИначеЕсли Поз1 = Поз2 Тогда
           прервать;
       ИначеЕсли Поз1 > Поз2 Тогда
           _ТЗ.Заполнить("", 1, Поз1 - 1, "Кол2");
           ИндексПоиска = 1;
       Иначе
           _ТЗ.Заполнить("", 1, Поз2 - 1, "Кол1");
           ИндексПоиска = 2;
       КонецЕсли;
   КонецЦикла;  
   _ТЗ.Очистить();
   если (Поз1=0)или(поз2=0) тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Метод IAm: "+(конВремя-НачВремя)+" мс.");
   //Метод Z1
   начвремя=_GetperformanceCounter();
   Зн1 = ПоискОдиночныйПоДвумКолонкам(ТЗ,Ищем1,Ищем2,"Кол1","Кол2");
   конвремя=_GetperformanceCounter();
   Сообщить("Зн1 = " + Зн1);
   сообщить("Метод Z1 (143) "+(конВремя-НачВремя)+" мс.");
   Сообщить(" ");
   
   // Если что не так - подправте модуль.
КонецПроцедуры
...
Добавил метод Z1, и проверку генератора (ТЗ выводит)
235 GrayT
 
04.08.04
22:11
Зачем выгрузку в промежуточную ТЗ и очистку таблицы внутри замера времени делаете?
236 NS
 
04.08.04
22:16
Все тесты - 10000,100
Мало того, что метод Z1 тормозит жутко - еще и результат неправильный ;-)
(и есно генератор в (230) неправильно работает - ТЗ кривая)

Ищем: 13 8
4477
Простым перебором 781 мс.
4477
Метод 2: 1517 мс.
4477
Метод IAm: 4002 мс.
Зн1 = 4505
Метод Z1 (143) 72650 мс.

Ищем: 20 1
не нашли
Простым перебором 1596 мс.
не нашли
Метод 2: 2417 мс.
не нашли
Метод IAm: 17113 мс.
Зн1 = 0
Метод Z1 (143) 112295 мс.

Ищем: 84 76
795
Простым перебором 142 мс.
795
Метод 2: 904 мс.
795
Метод IAm: 1645 мс.
Зн1 = 800
Метод Z1 (143) 10821 мс.

Ищем: 52 98
7540
Простым перебором 1008 мс.
7540
Метод 2: 1606 мс.
7540
Метод IAm: 11298 мс.
Зн1 = 7596
Метод Z1 (143) 95587 мс.
237 NS
 
04.08.04
22:19
(235) А в рабочей программе - алгоритмами (2) и (IAm) - делать не надо?
А память - кто подчищать будет?
Алгоритм Z1 ес-но исключаю, как сошедший с дистанции...
238 NS
 
04.08.04
22:20
(+237) Выгрузку делать не надо?
239 Рупор абсурда
 
04.08.04
22:21
(237) Я не понял ..., ты остался один на дистанции? ...
240 Рупор абсурда
 
04.08.04
22:23
Кстати, нули, про которые Z1 говорил, вероятно оттого у него были, что переменная Случ на уровне модуля не объявлена была ...
241 NS
 
04.08.04
22:24
перем случ;

Процедура Рандомизе()
   случ=_GetPerformanceCounter();
КонецПроцедуры                      
Функция Рандом(Интервал)  
   Случ=случ%1000000000000001;
   Случ=Случ*1103515245+12345;
   Возврат ((Случ/65536)%32768)%Интервал+1;
КонецФункции    
Процедура Сформировать()
   перем ТЗ,ТЗ_,КолстрокВТЗ,Разных;
   ввестичисло(колСтрокВТЗ,"Введите кол. строк в ТЗ",10,0);
   ввестичисло(Разных,"Введите количество разных значений",10,0);
   ТЗ=создатьОбъект("ТаблицаЗначений");
   ТЗ.Новаяколонка("Кол1","Число",10,0);
   ТЗ.НоваяКолонка("Кол2","Число",10,0);
   Рандомизе();
   Для а=1 по КолСтрокВТЗ цикл
       Если а%100=0 Тогда
           состояние(а);
       КонецЕсли;    
       ТЗ.НоваяСтрока();
       ТЗ.Кол1=Рандом(Разных);
       ТЗ.Кол2=Рандом(Разных);
   КонецЦикла;  
   Тз.ВыбратьСтроку();
   Ищем1=Рандом(Разных);
   Ищем2=Рандом(Разных);
   сообщить("Ищем: "+Ищем1+" "+Ищем2);
   начвремя=_GetperformanceCounter();
   стр=0;
   ТЗ.ВыбратьСтроки();
   пока тЗ.ПолучитьСтроку()=1 цикл
       если ТЗ.Кол1=Ищем1 тогда
           если ТЗ.кол2=Ищем2 Тогда
               стр=ТЗ.Номерстроки;
               прервать;
           конецесли;
       конецесли;
   КонецЦикла;
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Простым перебором "+(конВремя-НачВремя)+" мс.");
   // способ 2;
   начвремя=_GetperformanceCounter();
   стр=0;  
   _ТЗ=создатьобъект("ТаблицаЗначений");
   ТЗ.Выгрузить(_ТЗ,,,"Кол1");
   Пока _ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
       если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
           прервать;
       Иначе          
           _ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
           стр=0;
       КонецЕсли;    
   КонецЦикла;        
   если стр=0 тогда
       сообщить("не нашли");
   Иначе
       сообщить(стр);
   КонецЕсли;
   конвремя=_GetperformanceCounter();
   сообщить("Метод 2: "+(конВремя-НачВремя)+" мс.");
   _ТЗ.Очистить();
   // Если что не так - подправте модуль.
КонецПроцедуры

////////////

Ищем: 87 84
не нашли
Простым перебором 1171 мс.
не нашли
Метод 2: 1695 мс.
Ищем: 23 98
5995
Простым перебором 1030 мс.
5995
Метод 2: 1803 мс.
Ищем: 15 73
не нашли
Простым перебором 1170 мс.
не нашли
Метод 2: 1813 мс.
242 NS
 
04.08.04
22:25
(239) Второй метод был предложен тобой в 13-том посте.
243 NS
 
04.08.04
22:29
100000,300

Ищем: 45 219
50263
Простым перебором 7538 мс.
50263
Метод 2: 25402 мс.
244 Рупор абсурда
 
04.08.04
22:31
Вывод:
Не фиг бояться перебора и называть его тупым! ...
245 GrayT
 
04.08.04
22:32
Я не против замеров перегрузок и зачисток, но первый и последний методы их не имеют. Метдод Z1 модификацией IAm-овкого метода (просто отрезает ненужное вместо переприсвоения) - он не может сильно отличаться.
И вот еще что метод IAm'а переодически клинит на порядок, а Zl нет
246 NS
 
04.08.04
22:37
(245) Еще раз посмотри результаты и время...
метод z1 - выдает неправильный результат, и медленнее первого - на пару порядков!!!
Подчиску ТЗ я вынес за расчет времени...
В первом методе - просто нет выгрузки - поэтому ес-но и не входит в замер - второй и т.д. - без выгрузки работать не могут (портят ТЗ)
В методе Z1 - выгрузка входит в замер...
247 NS
 
05.08.04
00:58
(232) А чем генератор из ВК лучше???
248 Z1
 
05.08.04
10:24
(247) Ошибку у себя нашел.
надо    Дельта = Ном3 - 1;
и    Дельта = Дельта + Ном3 - 1;
тогда все результаты одинаковые.
но все равно у меня тормозит сильно.
99 % времени занимает  Выгрузить для ТЗ съедая все время.
Iam быстрее моего потому что у него только одна Выгрузить для ТЗ
249 Рупор абсурда
 
05.08.04
12:13
Вот вам ещё вариант ..., в среднем работает быстрее перебора ..., даже самого тупого перебора ...

  // способ Рупора;
  начвремя=_GetperformanceCounter();
  СЗ=СоздатьОбъект("СписокЗначений");
  стр=0;        
  Пока ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
      если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
          прервать;
      Иначе          
          СЗ.ДобавитьЗначение(ТЗ.ПолучитьЗначение(стр,"Кол1"));
          ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
          стр=0;
      КонецЕсли;    
  КонецЦикла;        
  если стр=0 тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
      Для стр=1 По СЗ.РазмерСписка() Цикл
          ТЗ.УстановитьЗначение(СЗ.ПолучитьЗначение(стр),"Кол1",Ищем1);
      КонецЦикла;    
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Метод Рупора: "+(конВремя-НачВремя)+" мс.");
250 NS
 
05.08.04
12:17
Протестируй на 100000,300...
Хотя должен быть быстрее...
сложность Корень*Логарифм.
251 Рупор абсурда
 
05.08.04
12:19
(250) Перебор иногда оказывается быстрее в случае когда "не нашли" ...
... Но редко ... :))
252 Волшебник
 
05.08.04
12:37
тест
253 Рупор абсурда
 
05.08.04
12:40
(249) Там ещё и ошибочка ..., внимательный GrayT указал ...
Надо так:

// способ Рупора;
начвремя=_GetperformanceCounter();
СЗ=СоздатьОбъект("СписокЗначений");
стр=0;        
Пока ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
    если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
        прервать;
    Иначе          
        СЗ.ДобавитьЗначение(стр); // <------- тут ошибка была !!!!
        ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
        стр=0;
    КонецЕсли;    
КонецЦикла;        
если стр=0 тогда
    сообщить("не нашли");
Иначе
    сообщить(стр);
    Для стр=1 По СЗ.РазмерСписка() Цикл
        ТЗ.УстановитьЗначение(СЗ.ПолучитьЗначение(стр),"Кол1",Ищем1);
    КонецЦикла;    
КонецЕсли;
конвремя=_GetperformanceCounter();
сообщить("Метод Рупора: "+(конВремя-НачВремя)+" мс.");

Т.е. должно работать ещё быстрее ...
254 Рупор абсурда
 
05.08.04
12:42
NS, кстати, в асю я к тебе, как и обещал, стукнулся ... :))
255 NS
 
05.08.04
12:42
Процедура Рандомизе()
  случ=_GetPerformanceCounter();
КонецПроцедуры                      
Функция Рандом(Интервал)  
  Случ=случ%1000000000000001;
  Случ=Случ*1103515245+12345;
  Возврат ((Случ/65536)%32768)%Интервал+1;
КонецФункции    
Процедура Сформировать()
  перем ТЗ,ТЗ_,КолстрокВТЗ,Разных1,Разных2;
  ввестичисло(колСтрокВТЗ,"Введите кол. строк в ТЗ",10,0);
  ввестичисло(Разных1,"Введите количество разных значений",10,0);
  ввестичисло(Разных2,"Введите количество разных значений",10,0);    
  ТЗ=создатьОбъект("ТаблицаЗначений");
  ТЗ.Новаяколонка("Кол1","Число",10,0);
  ТЗ.НоваяКолонка("Кол2","Число",10,0);
  Рандомизе();
  Для а=1 по КолСтрокВТЗ цикл
      Если а%100=0 Тогда
          состояние(а);
      КонецЕсли;    
      ТЗ.НоваяСтрока();
      ТЗ.Кол1=Рандом(Разных1);
      ТЗ.Кол2=Рандом(Разных2);
  КонецЦикла;  
  Тз.ВыбратьСтроку();
  Ищем1=Рандом(Разных1);
  Ищем2=Рандом(Разных2);
  сообщить("Ищем: "+Ищем1+" "+Ищем2);
  начвремя=_GetperformanceCounter();
  стр=0;
  ТЗ.ВыбратьСтроки();
  пока тЗ.ПолучитьСтроку()=1 цикл
      если ТЗ.Кол1=Ищем1 тогда
          если ТЗ.кол2=Ищем2 Тогда
              стр=ТЗ.Номерстроки;
              прервать;
          конецесли;
      конецесли;
  КонецЦикла;
  если стр=0 тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Простым перебором "+(конВремя-НачВремя)+" мс.");
  // способ 2;
  начвремя=_GetperformanceCounter();
  стр=0;  
  _ТЗ=создатьобъект("ТаблицаЗначений");
  ТЗ.Выгрузить(_ТЗ,,,"Кол1");
  Пока _ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
      если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
          прервать;
      Иначе          
          _ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
          стр=0;
      КонецЕсли;    
  КонецЦикла;        
  если стр=0 тогда
      сообщить("не нашли");
  Иначе
      сообщить(стр);
  КонецЕсли;
  конвремя=_GetperformanceCounter();
  сообщить("Метод 2: "+(конВремя-НачВремя)+" мс.");
  _ТЗ.Очистить();  
  начвремя=_GetperformanceCounter();
СЗ=СоздатьОбъект("СписокЗначений");
стр=0;        
Пока ТЗ.НайтиЗначение(Ищем1,Стр,"Кол1")>0 Цикл
    если ТЗ.ПолучитьЗначение(стр,"Кол2")=Ищем2 Тогда
        прервать;
    Иначе          
        СЗ.ДобавитьЗначение(стр);
        ТЗ.УстановитьЗначение(Стр,"Кол1",0);  
        стр=0;
    КонецЕсли;    
КонецЦикла;        
если стр=0 тогда
    сообщить("не нашли");
Иначе
    сообщить(стр);
    Для стр=1 По СЗ.РазмерСписка() Цикл
        ТЗ.УстановитьЗначение(СЗ.ПолучитьЗначение(стр),"Кол1",Ищем1);
    КонецЦикла;    
КонецЕсли;
конвремя=_GetperformanceCounter();
сообщить("Метод Рупора: "+(конВремя-НачВремя)+" мс.");
  // Если что не так - подправте модуль.
КонецПроцедуры
/////
Тест 10000,10,1000.
////
Ищем: 10 502
9909
Простым перебором 1220 мс.
9909
Метод 2: 12951 мс.
9909
Метод Рупора: 17829 мс.
//////
перебор стабильней.
256 Рупор абсурда
 
05.08.04
13:06
Серия тестов на 100 000 и 300 ...

Ищем: 211 71
4585
Простым перебором 177 мс.
4585
Метод 2: 2148 мс.
4585
Метод Рупора: 71 мс.


Ищем: 231 248
26687
Простым перебором 1858 мс.
26687
Метод 2: 3399 мс.
26687
Метод Рупора: 1377 мс.

Ищем: 261 59
1508
Простым перебором 115 мс.
1508
Метод 2: 2131 мс.
1508
Метод Рупора: 19 мс.
257 Z1
 
05.08.04
13:08
Этот метод если нет значения всегда быстрее чем линейный поиск.
Когда значение есть когда как.
Получается слишком медлено 1с работает со своими объектами СписокЗначений и ТаблицаЗначений. Может турбоускоритель  Orefkov включить ?
Хотя это протеворечит (189)

Функция ПоискОдиночныйПоДвумКолонкамсписок1(ТЗ,Значение1,Значение2,Колонка1,Колонка2)
   //Если ПустоеЗначение(Значение1)=1 Тогда Возврат("Глюк1 :)") КонецЕсли;
   //Если ПустоеЗначение(Значение2)=1 Тогда Возврат("Глюк2 :)") КонецЕсли;
   Ном1=0;
   ТЗ.НайтиЗначение(Значение1,Ном1,Колонка1);
   Если Ном1=0 Тогда Возврат(0) КонецЕсли;
   Ном2=0;
   ТЗ.НайтиЗначение(Значение2,Ном2,Колонка2);
   Если Ном2=0 Тогда Возврат(0) КонецЕсли;
   Если Ном1 = Ном2 Тогда
       Возврат(Ном1);
   ИначеЕсли Ном1 > Ном2 Тогда
       Зн2 = ТЗ.ПолучитьЗначение(Ном1,Колонка2);
       Если Зн2 = Значение2 Тогда
           Возврат(Ном1);
       КонецЕсли;
       Ном3 = Ном1 + 1;
   Иначе
       Зн1 = ТЗ.ПолучитьЗначение(Ном2,Колонка1);
       Если Зн1 = Значение1 Тогда
           Возврат(Ном2);
       КонецЕсли;
       Ном3 = Ном2 + 1;
   КонецЕсли;
   Дельта = Ном3 - 1;
//Сообщить("Ном3 = " + Ном3);
   //СписокКолонок = Колонка1 + "," + Колонка2;
   //ТЗ.Выгрузить(ТЗ_,Ном3,  ,СписокКолонок );

   Список1 = СоздатьОбъект("СписокЗначений");
   Список2 = СоздатьОбъект("СписокЗначений");
   ТЗ.Выгрузить(Список1,Ном3,  , Колонка1);
   ТЗ.Выгрузить(Список2,Ном3,  , Колонка2);
   Пока 1=1 Цикл
       Ном1 = Список1.НайтиЗначение(Значение1);
       Если Ном1=0 Тогда Возврат(0) КонецЕсли;
       Ном2 = Список2.НайтиЗначение(Значение2);
       Если Ном2=0 Тогда Возврат(0) КонецЕсли;
       Если Ном1 = Ном2 Тогда
           Возврат(Дельта + Ном1);
       ИначеЕсли Ном1 > Ном2 Тогда
           //Зн2 = Список2.ПолучитьЗначение(Ном1,);
           //Если Зн2 = Значение2 Тогда
           //    Возврат(Дельта + Ном1);
           //КонецЕсли;
           //Ном3 = Ном1;
           Ном3 = Ном1 - 1;
       Иначе
           //Зн1 = Список1.ПолучитьЗначение(Ном2,);
           //Если Зн1 = Значение1 Тогда
           //    Возврат(Дельта + Ном2);
           //КонецЕсли;
           //Ном3 = Ном2;
           Ном3 = Ном2 - 1;
       КонецЕсли;
//Сообщить("Ном3 = " + Ном3);
       Дельта = Дельта + Ном3;
       Список1.УдалитьЗНачение(1,Ном3);
       Список2.УдалитьЗНачение(1,Ном3);

       //Если ТЗ_.КоличествоСтрок() <= 0 Тогда Возврат(0) КонецЕсли;
   КонецЦикла;
КонецФункции
258 Рупор абсурда
 
05.08.04
13:08
(255) Я ничего не нашаманил ..., просто скопировал код (255) ...
Скажи честно, ты фальсифицировал результаты? ...
259 Рупор абсурда
 
05.08.04
13:12
Вот ещё для 10 000 и 30+30 ...

Ищем: 7 8
1630
Простым перебором 136 мс.
1630
Метод 2: 258 мс.
1630
Метод Рупора: 54 мс.

Ищем: 3 22
921
Простым перебором 75 мс.
921
Метод 2: 245 мс.
921
Метод Рупора: 34 мс.

Ищем: 15 28
1251
Простым перебором 112 мс.
1251
Метод 2: 260 мс.
1251
Метод Рупора: 51 мс.
260 Z1
 
05.08.04
13:34
У меня для 100 000 и 300 след результат
Ищем = 118 44
не нашли
Простым перебором 2365 мс.
не нашли
Метод 2: 6454 мс.
не нашли
Метод Z1 список1 (257) 2011 мс.
не нашли
Метод Рупора: 5206 мс.

Ищем = 86 135
28033
Простым перебором 626 мс.
28033
Метод 2: 1768 мс.
28033
Метод Z1 список1 (257) 1938 мс.
28033
Метод Рупора: 530 мс.

Ищем = 281 283
50645
Простым перебором 1136 мс.
50645
Метод 2: 2386 мс.
50645
Метод Z1 список1 (257) 1960 мс.
50645
Метод Рупора: 1144 мс.
261 Guk
 
05.08.04
14:31
(258)тест на 10000,10,1000.
ничего не фальсифицировал.
первая 10, вторая 1000./NS/