Имя: Пароль:
1C
 
XBase - НайтиПоКлючу()
0 1C programmer
 
28.07.05
14:57
Подскажите, пожалуйста, как получить все записи, содержащие определенное слово, например VIKA, но не перебором всех записей, а методом НайтиПоКлючу(). Приведенный ниже код находит только одну запись.
БД = СоздатьОбъект("XBase");
БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
БД.КодоваяСтраница(0);
БД.ТекущийИндекс("DESCR");
БД.Ключ.DESCR = "VIKA";
БД.НайтиПоКлючу(0);
Сообщить(БД.НомерЗаписи());
Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
1 Лис в курятнике
 
28.07.05
15:02
Пока БД.Ключ.DESCR = "VIKA" Цикл
 Сообщить(БД.НомерЗаписи());
 Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
 БД.Следующая();
КонецЦикла;
2 Забаненный Директор
 
28.07.05
15:04
(1) Проверял сам то?
3 Лис в курятнике
 
28.07.05
15:05
(2) нет конечно.
4 Лис в курятнике
 
28.07.05
15:05
+(3) а в чем трабла?
5 goodfella
 
28.07.05
15:07
(0) Погодь, ты в своей рабочей базе пытаешься открыть один из файлов базы.
По-моему это работать не должно.
6 Забаненный Директор
 
28.07.05
15:08
(4) Не знал что так можно(Если это конечно работет).
7 Лис в курятнике
 
28.07.05
15:13
(5) он же написал что "Приведенный ниже код находит только одну запись"
(6) учись ;))
8 1C programmer
 
28.07.05
15:20
(5) Файл можно открывать, если режим не монопольный.
9 Забаненный Директор
 
28.07.05
15:24
(8) Ты лучше скажи спаботал код Лиса или нет
10 1C programmer
 
28.07.05
15:27
Код не работает...
11 Лис в курятнике
 
28.07.05
15:28
(10) почему? тема не раскрыта.
12 Забаненный Директор
 
28.07.05
15:31
А если:
1. Нашел -- Удаляешь запись
2. Ищешь следующую
3. Отменяешь изменения
13 1C programmer
 
28.07.05
15:33
(11) Не знаю почему... Как-нибудь можно без перебора обойтись? Интересует именно НайтиПоКлючу() или Найти(). Файл очень большой, перебором долго ищет.
14 zzzzz
 
28.07.05
15:37
(13) Домой вернусь - погляжу. Где-то года два назад делал такое. Конфа дома точно есть.
15 Лис в курятнике
 
28.07.05
15:38
(13) не работает или не охота перебором? у тебя записи по индексу стоят... отсортированы они... друг под дружкой тобишь... че те исчо надо?
16 zzzzz
 
28.07.05
15:41
Но там дальше нужно (по воспоминаниям) просто использовать метод следующая и проверять индекс.
17 zzzzz
 
28.07.05
15:44
БД = СоздатьОбъект("XBase");
БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
БД.КодоваяСтраница(0);
БД.ТекущийИндекс("DESCR");
БД.Ключ.DESCR = "VIKA";
БД.Первая(0);
Пока БД.Ключ.DESCR = "VIKA" Цикл
Сообщить(БД.НомерЗаписи());
Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
БД.Следующая();
КонецЦикла;
Проверь. Это не из дома, но должно работать.
18 Valery
 
28.07.05
15:45
Без перебора необойтись.
19 шон
 
28.07.05
15:46
Не мучайся.Возьми фокспро и делай скока надо.
20 denpro
 
28.07.05
15:47
Фильтр ДБФ по вхождению в код_чегото "Код", работает без проблем.
AX_TNR - поле в ДБФ код_чегото.
База.ДобавитьИндекс("IDXCODE", "AX_TNR", 1, 0, Строка(""""+СокрЛП(Код)+""""+" $ AX_TNR" ));
База.СоздатьИндексныйФайл("IDXCNEW.CDX");
База.ТекущийИндекс("IDXCODE");
21 Valery
 
28.07.05
15:51
Да проще надо
БД = СоздатьОбъект("XBase");
БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
БД.КодоваяСтраница(0);
БД.ТекущийИндекс("DESCR");
БД.Найти("VIKA");

Пока БД.DESCR = "VIKA" Цикл
Сообщить(БД.НомерЗаписи());
Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
БД.Следующая();
КонецЦикла;
22 denpro
 
28.07.05
15:51
+(20) Очень большое значение играет регистр символов. К поле ДБФ желательно чтобы всегда вводилось в верхнем регистре соотв. СокрЛП(Врег(Код)).
23 denpro
 
28.07.05
15:55
(21) Все херня, если сделать как в (20), в базе будут записи удовлетворяющие вхождению строки "Код", в поле (здесь AX_TNR). и не надо делать больше никаких сравнений.
База.Первая();
Пока База.ВКонце()=0 цикл  
 База.Следующая();      
КонецЦикла
24 Valery
 
28.07.05
15:56
Поддерживаю (20) лучще создать свой индекс, если неизвестен готовый.
Может надо Искать не "VIKA", а "VIKA     ".
25 denpro
 
28.07.05
16:00
(24) Что искать не важно, если Код="VIKA", то в базе будут записи удовлетворяющие "%VIKA%"
26 1C programmer
 
28.07.05
16:05
(21) Такой код не работает.
27 Лис в курятнике
 
28.07.05
16:07
а так?
БД = СоздатьОбъект("XBase");
БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
БД.КодоваяСтраница(0);
БД.ТекущийИндекс("DESCR");
БД.Найти("VIKA");

Пока СокрЛП(БД.DESCR) = "VIKA" Цикл
Сообщить(БД.НомерЗаписи());
Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
БД.Следующая();
КонецЦикла;
28 denpro
 
28.07.05
16:07
(26) ... Написано используй (20) (22) (23)
29 Valery
 
28.07.05
16:07
(25) Что-то я не понял,  что ты лепишь.
В 20 понятно. Создал индекс, 23 что такое. Перебор всей базы что-ли
30 denpro
 
28.07.05
16:09
(29) Я написал - создал индекс и можешь перебирать всю базу без всяких "Если".
31 Valery
 
28.07.05
16:11
(26) он у тебя не работает потому, что не находит запись.
32 Valery
 
28.07.05
16:14
(30) И как же ты найдешь нужную запись без условия?
33 Лис в курятнике
 
28.07.05
16:18
(32) условие в индексе...
34 denpro
 
28.07.05
16:20
(32) Не понял...
База.ДобавитьИндекс("IDXCODE", "AX_TNR", 1, 0, Строка(""""+СокрЛП(Код)+""""+" $ AX_TNR" ));
Фильтрует База по вхождению в поле AX_TNR строки Код. Я понимаю именно это нужно было автору.
35 Valery
 
28.07.05
16:23
(34) И что для каждого икомого значения ты будешь индекс создавать?
36 Лис в курятнике
 
28.07.05
16:23
будет ли это быстрее?
37 denpro
 
28.07.05
16:41
ДБФ 400000 записей, создание индекса с перебором и загрузкой в ТЗ занимает меньше 1 минуты. (локально на моей машине: индекс 2 сек и выгрузка в ТЗ примерно 15 сек)
38 Соратник
 
28.07.05
16:45
Вопросик дополнительный. А чтоб это дело универсальней сделать нужно программно определить название файла дбф, соответствующего справочнику. Для этого только ДД парсить? или проще способы есть?
39 Valery
 
28.07.05
16:52
(37)Первый класс вторая четверть.
Для каких-то задач, где фильтр не меняеся, это еще прокатит, но для данной ситуации, это ерунда.
поиск и перебор несколких записей будет быстрее, т.к при создании индекса база сканируется целиком, это всегда будет медленней, да тут даже не в скорости дело, а в технологии.
40 1C programmer
 
28.07.05
16:55
Всем спасибо за совет. Теперь все работает... Воспользовался (27), только переделал немного...
БД = СоздатьОбъект("XBase");
   БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
   БД.КодоваяСтраница(0);
   БД.ТекущийИндекс("DESCR");
   БД.Ключ.DESCR = "сталь";
   БД.НайтиПоКлючу(0);
   
   Пока Найти(НРег(СокрЛП(БД.ПолучитьЗначениеПоля("DESCR"))), "сталь") > 0 Цикл
       Сообщить(БД.ПолучитьЗначениеПоля("DESCR"));
       БД.Следующая();
   КонецЦикла;
41 Лис в курятнике
 
28.07.05
16:58
БЛИН. ну в (1) же ответ дал... тока сокрлп() надо было поставить...
42 denpro
 
28.07.05
17:02
(39) Странно, вопрос задавал не ты, но что то пытаешся доказать. В прочем, мне все равно. Я не навязываю свой вариант. Однако в моем случае (для моей базы), это работает намного быстрее, даже если пользователь введет код такой что в базе только одна запись будет ему соответствовать, мой код сработает в разы быстрее чем перебор всех 400000.
43 1C programmer
 
28.07.05
17:03
(41 ) Все дело было не в СокрЛП(), а в ВРег() (или НРег)... Можно так еще:
   БД = СоздатьОбъект("XBase");
   БД.ОткрытьФайл(КаталогИБ() + "sc46.dbf", КаталогИБ() + "sc46.cdx", 1);
   БД.КодоваяСтраница(0);
   БД.ТекущийИндекс("DESCR");
   БД.Найти("СТАЛЬ");
   
   Пока Найти(ВРег(БД.DESCR), "СТАЛЬ") > 0 Цикл
       Сообщить(БД.DESCR);
       БД.Следующая();
   КонецЦикла;
44 Лис в курятнике
 
28.07.05
17:06
(43) неработает... неработает... все нормально работает... просто ты условия правильно не поставил...
45 1C programmer
 
28.07.05
17:12
Лису в курятнике отдельное списибо ;-)
Закон Брукера: Даже маленькая практика стоит большой теории.