Имя: Пароль:
1C
1C 7.7
v7: Индексированная таблица
0 ildary
 
02.04.14
11:54
Уважаемые специалисты, подскажите пожалуйста, как правильно пользоваться функцией НайтиСтроку() и ПолучитьСтроку(), чтобы потом перебрать все найденные варианты? Для примера - чтобы обработать найденные строки, придется обработчик писать в двух местах, а хочется в одном:

    ИТЗСкидок = СоздатьОбъект( "ИндексированнаяТаблица" );
    ИТЗСкидок.НоваяКолонка( "Номенклатура"  );
    ИТЗСкидок.НоваяКолонка( "ЭтоБонус"        );
    ИТЗСкидок.ДобавитьИндекс( "ЭтоБонус", "ЭтоБонус" );
    
    Если ИТЗСкидок.НайтиСтроку( "ЭтоБонус", 1,, 1 ) <> 0 Тогда
        
        //тут придется обработать первый найденный результат
        
        Пока ИТЗСкидок.СледующаяСтрока( "ЭтоБонус" ) = 1 Цикл
            
            //тут обработаются прочие результаты
            
        КонецЦикла;
        
    КонецЕсли;
1 ADirks
 
02.04.14
11:58
может быть,

ит.УстановитьФильтр(1, 1, "ЭтоБонус");
ит.ВыбратьСтроки("ЭтоБонус");
...

?

так то, НайтиСтроку() находит лишь первую попавшуюся
2 ildary
 
02.04.14
12:00
(1) спасибо за идею, а если переборов будет несколько, то надо будет в конце перебора сделать ИТЗСкидок.ВыключитьФильтр( "ЭтоБонус" )?
3 ildary
 
02.04.14
12:04
+(2) я имею в виду, если индексов несколько и перебор будет вестись по разным индексам, то надо будет предыдущий отключать через ВыключитьФильтр?

p.s. до того приятно, что на мой нубский вопрос отвечает один из авторов семерочного счастья 1cpp :)
4 Mikeware
 
02.04.14
12:04
Начнем с другой стороны.
Что ты хочешь сделать?
5 ADirks
 
02.04.14
12:04
(2) не, выключать не надо
вот ни разу в жизни не было случая, чтоб это понадобилось. Так, для полноты интерфейса сделали.
6 Mikeware
 
02.04.14
12:05
(5) иногда нужно
7 ildary
 
02.04.14
12:07
(4) есть ИТЗ с разными индексами (ну пусть это будут "Контрагент" и "Товар"). Хочу перебрать все строки в ИТЗ, в которых Контрагент = заданному, и потом перебрать все строки, в которых Товар = заданному. Надо ли после первого перебора убрать фильтр по первому индексу?
8 ADirks
 
02.04.14
12:07
(3) выборки по разным индексам независимы
к примеру

ИТ.ВыбратьСтроки("Путь");
Пока ИТ.ПолучитьСтроку("Путь") = 1 Цикл
    стрГруппа = ИТ.Путь;
    
    сзФильтр = СоздатьОбъект("СписокЗначений");
    сзФильтр.ДобавитьЗначение(стрГруппа);
    ИТ.Подмножество(сзФильтр, 1, "ТоварУ");
    ИТ.ВыбратьСтроки("ТоварУ");
    Пока ИТ.ПолучитьСтроку("ТоварУ") = 1 Цикл
        Товар = ИТ.Товар;
        ИТ.УстановитьФильтр(Товар, Товар, "Товар");
        ВывестиСтроку(Т, Товар, ИТ, нКоличествоСвойств);
    КонецЦикла;
КонецЦикла;
9 ildary
 
02.04.14
12:28
Спасибо, Подмножество() решило мою задачу
10 Ёпрст
 
гуру
02.04.14
12:34
можно и без подмножества, тупо бегать по индексам..
а можно еще проще - сгруппировать ИТЗ..
11 ildary
 
02.04.14
12:35
(10) а как правильно бегать по индексам, особенно если они составные? Я нашел только НайтиСтроку(), но вот как сделать полный перебор в одном цикле?
12 ildary
 
02.04.14
12:37
+(11) допустим в ИТЗ есть 2 колонки - Товар и Контрагент и составной индекс "ТоварКонтрагент", как перебрать все строки и что-то сделать в один проход? Подмножество() - похоже работает по простому индексу.
13 Ёпрст
 
гуру
02.04.14
12:39
дык кидаешь в СЗ 2 значения ключа и находишь все пары Клиентос-Товар с этими значениями ключа.
14 ildary
 
02.04.14
13:27
(13) еще небольшой вопрос - как в табличном поле сделать самостоятельную сортировку: табличное поле выводит справочник "Действия", с реквизитоом Контрагент, тип "справочник.Контрагенты". 1С сортирует эту колонку по внутреннему идентификатору, а хочется, чтобы сортировал по наименованию. Пытался сделать дополнительное текстовое поле (чтобы сортировать по нему), вот так:

Данные.ДобавитьСоединениеДанных( "Справочник_Контрагенты","JOIN Справочник.плнДействия as СпрДействия
|ON СпрДействия.id = ТекущийОбъект.id
|LEFT JOIN Справочник.Контрагенты as СпрКонтр ON СпрКонтр.id = СпрДействия.Контрагент" );

Данные.ДобавитьКолонкуДанных("НаимКонтрагента","НаимКонтрагента","$СпрКонтр.Наим
енование","Строка",15,,1);
Данные.НоваяКолонка( "НаимКонтрагента" );

но по нему вообще не сортирует. Есть ли способы отсортировать кроме перехода на Табличное поле ИТЗ?
15 Salimbek
 
02.04.14
14:01
(14) Там разбираться надо с Поставщиком
16 ildary
 
02.04.14
14:17
(15) поставщик типа Справочник. Я думаю, что проще переделать на тип поставщика=ИТЗ.
17 monsterZE
 
02.04.14
14:55
Источник.УстКлючПорядка("НаимКонтрагента");
не?
18 ildary
 
02.04.14
15:00
(17) прошу прощения, а куда эту строку вписать?
19 monsterZE
 
02.04.14
15:04
(18)

Источник            = СоздатьОбъект("ODBCDataProvider.MSSQL");
    Источник.БазаДанных = СоздатьОбъект("ODBCDataBase");

[...]

Источник.УстТекстЗапроса(ТекстЗапроса);
        
        Источник.УстИДПоле("Док");
        //Источник.УстКлючПорядка("Док");
        Источник.УстКлючПорядка("ПозДок");
        
        Поле               = Источник.Поля.Добавить("Док");
        Поле.АвтоУдаление  = 0;
        Поле               = Источник.Поля.Добавить("Маркер");
        Поле.АвтоУдаление  = 0;
        
        ТП.ПоставщикДанных = Источник;
        ТП.ОбновитьСтроки();
20 ildary
 
02.04.14
15:05
+(18) и эта строка будет работать, когда пользователь нажмет по залоговку колонки "НаимКонтрагента"?
21 monsterZE
 
02.04.14
15:09
(20)
    ТП.Источник.Поля.КлиентИмя.ТипБыстрогоПоиска    = 1;
22 monsterZE
 
02.04.14
15:10
ТП.ПоставщикДанных = Источник;
        ТП.ОбновитьСтроки();    
        
        ТП.ПоставщикДанных.Поля.НомерДок.ТипБыстрогоПоиска     = 1;
        ТП.ПоставщикДанных.Поля.КлиентИмя.ТипБыстрогоПоиска    = 1;
23 Mikeware
 
02.04.14
15:10
(20) эта строка будет работать по умолчанию.
24 ildary
 
02.04.14
15:23
Спасибо большое за советы, попробую.
25 ildary
 
02.04.14
15:34
(22) разве ТипБыстрогоПоиска работает для тп справочника? В документации это поле есть только у ПоставщикДанныхODBC.
26 monsterZE
 
02.04.14
17:36
(25) что есть "тп справочника"?
27 Mikeware
 
02.04.14
17:39
(26) Он через ПоставщикДанных делает
28 Serginio1
 
02.04.14
17:53
(11) Если нужное поле первое в индексе то НайтиБлижайшуюБольше или НайтиБлижайшуюМеньше в зависимости от того как создашь ключ.
29 monsterZE
 
02.04.14
17:56
(25) (27) не внимательно прочитал =(
30 ildary
 
02.04.14
18:03
(29) то есть для ПоставщикДанных - Справочник - работать не будет?
31 ildary
 
02.04.14
18:04
(28) мне надо получить все записи с нужным мне индексом и перебрать их одним циклом. К сожалению НайтиБлижайшуюБольше и НайтиБлижайшуюМеньше - не сработают.
32 monsterZE
 
02.04.14
18:06
(30) я пробывал =)
33 Serginio1
 
02.04.14
18:20
(31) У тебя поле искомое поле первое в индексе?
34 ildary
 
02.04.14
18:23
(33) не обязательно. Есть также составной индекс (Товар + Контрагент).
35 Serginio1
 
02.04.14
18:26
Обычно индекс составляют так. Искомое значение + минимальные значения в следующих индексах.
При нахождении НайтиБлижайшуюБольше должна спозиционироваться на первыю запись.
Вообще обычно существуют методы БольшеИлиРавно
36 Salimbek
 
02.04.14
20:56
Что касается задачи в (0) то варианты уже приводили, еще один вариант (которым пользовался я) - это использовать "Группировать" с параметром 1 в конце, т.е. кроме сгруппированной таблицы, которую перебираешь, в каждой строке будет Индексированная таблица ТЗПотомки (с выборкой только отфильтрованных по группируемому полю строк), которую далее можно проиндексировать как угодно, перебрать и т.д.

Что же задачи в (14), то, по идее, как то оно должно работать. Если очень надо, могу завтра выкроить немного время, посмотреть на внутренности поставщика.
37 ildary
 
02.04.14
21:21
(36) спасибо за помощь. раз так лучше - то буду группировать.
38 Mikeware
 
03.04.14
07:53
(37) не нужно тебе группировать. составной индекс по двум полям, и все.
39 Salimbek
 
03.04.14
09:06
(38) Так тоже можно, только придется самостоятельно следить, началась ли новая цепочка бонусов.
Т.е. варианты:

(38)
ИТЗ.ДобавитьИндекс("индБонус","ЭтоБонус,Номенклатура");
ИТЗ.ВыбратьСтроки("индБонус");
ТекущийБонус = "";
Пока ИТЗ.ПолучитьСтроку("индБонус")=1 Цикл
  Если ИТЗ.ЭтоБонус<>ТекущийБонус Тогда
    ТекущийБонус = ИТЗ.ЭтоБонус;
    //Обработать новую секцию с бонусом
  КонецЕсли
  //Обработать очередную строку
КонецЦикла;

(10) и (36)
ИТЗ.Группировать("индБонус: ЭтоБонус","",1);
ИТЗ.ВыбратьСтроки();
Пока ИТЗ.ПолучитьСтроку()=1 Цикл
  //Обработать новую секцию с бонусом
  итзНоменклатуры = ИТЗ.ТЗПотомки;
  итзНоменклатуры.Сортировать("Номенклатура"); //Можно и через ДобавитьИндекс
  итзНоменклатура.ВыбратьСтроки();
  Пока итзНоменклатура.ПолучитьСтроку()=1 Цикл
    //Обработать очередную строку
  КонецЦикла;
КонецЦикла;
40 ildary
 
03.04.14
09:31
(40) я с индексированными таблицами только начинаю работать и я надеялся, что их функционал позволит накладывать фильтр по значению индекса с последующим перебором только отфильтрованного, а получается, что ИТЗ будет перебираться как обычная ТЗ?
41 Mikeware
 
03.04.14
09:35
(39) задачи есть разные. где-то нужно группировка , где-то индекс и фильтр.
42 Mikeware
 
03.04.14
09:36
(40)имено так. Накладываешь фильтр, и видишь только отфильтрованное.
43 ildary
 
03.04.14
09:41
(42) я дико извиняюсь, но вот я смотрю в (39)и вижу:

Пока ИТЗ.ПолучитьСтроку("индБонус")=1 Цикл
  Если ИТЗ.ЭтоБонус<>ТекущийБонус Тогда

чем это отличается от полного перебора обычной ТЗ?
44 Mikeware
 
03.04.14
09:44
(43) ахез. лениво разбираться, что он там хотел выродить.
45 Ёпрст
 
гуру
03.04.14
09:48
(40) так и есть
46 ildary
 
03.04.14
09:53
(45) "так и есть" = "ИТЗ будет перебираться как обычная ТЗ"?
если да, то остается только группировка с обращением к ТЗ_Потомки.
47 Salimbek
 
03.04.14
10:17
(44) Ну как же, добавив индекс по двум полям, как предложено в (38), мы же не накладываем фильтр по первому полю, верно?
48 Ёпрст
 
гуру
03.04.14
10:47
(46) нет, будет отбираться по установленному фильтру или, например, можно бегать только по уникальным записям индекса..
49 ildary
 
03.04.14
10:57
(48) я бы не отказался от простейшего примера. устал искать рабочий вариант методом научного тыка.
50 Ёпрст
 
гуру
03.04.14
11:05
эээ..ща поищу
51 Ёпрст
 
гуру
03.04.14
11:29
Это, установи фильтр по нужному индексу и обходи тз с установленным фильтром по этому индексу.. Тебе это надо в итоге ?
52 Ёпрст
 
гуру
03.04.14
11:29
+51  установи фильтр по нужному индексу с нужными значениями ключей
53 ildary
 
03.04.14
16:51
(53) попутно ковыряясь с ИТЗ нашел еще одну непонятку:

есть у нее метод Группировать. Решил испытать его:
Берем ИТЗ с колонками "Фирма", "СуммаРуб", "Контрагент" (так она из регистра выгрузилась). СуммаРуб- числовой, первые два - справочники. Далее:

//Добавляю два индекса
ИТЗ.ДобавитьИндекс( "Контрагент", "Контрагент" );
ИТЗ.ДобавитьИндекс( "Фирма"     , "Фирма" );

ИТЗ.Группировать( "Контрагент: Контрагент; Фирма: Фирма", "СуммаРуб" );

хочу увидеть в ИТЗ свертку - и вижу, что таблица не сгруппировалась (т.е. как шли колонки Фирма, СуммаРуб, Контрагент, так и осталось, добавленная колонка ТЗ_Потомки  - пустая). Единственное, что смущает - порядок колонок в ИТЗ не совпадает с тем, как я ее группирую, но разве это должно влиять?
54 ildary
 
03.04.14
16:59
+(53) извините, был напуган. Создавать индексы было не только лишним, но и вредным.
55 Salimbek
 
03.04.14
23:54
(54) Чтобы была тзПотомки надо

ИТЗ.Группировать( "Контрагент: Контрагент; Фирма: Фирма", "СуммаРуб" , 1);
56 ildary
 
04.04.14
06:39
(55) пардону прошу, но у меня и без 1 в параметрах получилось, надо было только не создавать индексы.
57 Mikeware
 
04.04.14
07:42
(56) что "получилось"?
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.