Имя: Пароль:
1C
1C 7.7
v7: Поиск по dbf
,
0 Mihenius
 
19.11.14
18:04
Есть 2 dbf с частично совпадающими полями.
1-й небольшой dbf, кот. нужно проверить по 2-му
2-й dbf очень большого размера

Задача:
Проанализировать 1 dbf, найти совпадающие по ключевым полям строки во 2-м dbf и добавить недостающие поля со значениями.

Сделал индекс по ключевым полям 2-го dbf и поиск по индексу.
Все отлично и быстро работало, пока вдруг не стали появляться дубли во 2-м dbf. Теперь при поиске по индексу находит только первую попавшуюся строку.

Как без перебора выбрать все строки по ключу? Других уникальных и одинаковых полей в таблицах нет, для того чтобы расширить индекс.
По Найти/НайтиПоКлючу находит только 1 значение.

DBF большого размера >1Gb Может попробовать работать с ТЗ/ИТЗ или?

Или читать dbf не через 1с, а через ADO или VFP OLEDB, тогда можно запросом отобрать нужные строки.
1 spero
 
19.11.14
19:38
(0) Не помню, как в 7.7, но в большинстве библиотек XBase, если открыл базу с индексом, тогда записи следуют в порядке индекса. Т.е. найти(), а потом следующая() по идее должны решить твой вопрос. Проверь.
2 Сияющий Асинхраль
 
19.11.14
19:48
А чем тебе мешает дубль во 2-м дбф? Я так понимаю, тебе надо добавить строки которых нет в принципе, а если у тебя строка есть, то в каком количестве 2-3-4 или больше вроде бы тебя не должно волновать...
3 jarett
 
19.11.14
20:01
Переиндексация, не?
4 Злопчинский
 
19.11.14
21:33
5 Mihenius
 
19.11.14
22:11
(1) По следующая() он переходит на следующую по порядку запись. Хотя надо еще раз проверить по
dbf.ключю.N1=x
dbf.НайтиПоКлючу(0)

(2) Надо найти ту запись, кот. по дате будет самой свежей.
Добавить надо не строки, а только те парметры, кот. нет в 1-й таблице.

(3) чем поможет переиндексация?
Просто раньше мой индекс был уникальным, а сейчас стал не уникальным. А в 77 не нашел отбора по индексу, только поиск.

(4) увидит, напишет )
6 Ёпрст
 
19.11.14
22:44
ну делай через оледб (только там еще постараться надо, чтоб твой индекс задействовался)
7 ado
 
21.11.14
03:26
1sqlite же может как-то цеплять dbf-ки вроде?
8 NS
 
21.11.14
03:47
Всё отлично выбирается средствами 1С.
9 NS
 
21.11.14
03:59
xbase.ТекущийИндекс("твой_индекс");
Если xbase.Найти(зн)>0 тогда
Пока xbase.поле=зн цикл
   сообщить(xbase.name);
   xbase.следующая();
   Если xbase.вконце()>0 тогда
       прервать;
   КонецЕсли;
КонецЦикла;
КонецЕсли;
10 Ёпрст
 
21.11.14
16:02
(7) нет
11 ALoHA
 
22.11.14
12:55
Выгрузи большой файл в ТЗ. 2й перебирай по строкам и проверяй в цикле принадлежность каждой строки к ТЗ.
12 NS
 
22.11.14
14:35
(11) обычно делают ровно наоборот.
Ибо тз в принципе медленней xbase, да вдобавок еще и не индексированная структура.
13 G-Re
 
22.11.14
18:56
Должен отработать (9). Ведь индексация это та же Сортировка, только ключей, поэтому Следующий() должен дать именно следующую запись в этой сортировке.
14 1s_ivan
 
22.11.14
21:32
Предлагаю загрузить оба файла в ТаблицуЗначений (ТЗ), обработать , если надо, то сделать 3-ю ТЗ.., а результат выгрузить в файл обратно.
15 КонецЦикла
 
23.11.14
01:51
>>Или читать dbf не через 1с, а через ADO или VFP OLEDB, тогда можно запросом отобрать нужные строки

А вот это попробуйте (цы)
16 NS
 
23.11.14
02:21
(15) Так всё-же легко делается штатно, средствами 1С, при этом работает 1С с дбф никак не медленней чем ADO.
17 Shaman100M
 
23.11.14
18:00
Создавай индекс у объекта с признаком "убывание" ( ДобавитьИндекс(,,0,1,"") ), тогда метод XBase Найти() вернет тебе последнюю добавленную неуникальную запись
18 Shaman100M
 
23.11.14
18:01
Дб    = СоздатьОбъект("XBase");
    Дб.ДобавитьПоле("INDEX_VAL" ,2,2,0);
    Дб.ДобавитьПоле("RECORD_NOM",1,2,0);
    
    Дб.СоздатьФайл("REPSORT.DBF");
    Для М1    = 1 По 10 Цикл
        Дб.Добавить();
        Дб.INDEX_VAL    = "AA";
        Дб.RECORD_NOM    = М1;
        Дб.Записать();
    КонецЦикла;      
                                                      
    // по возрастанию
    Дб.ДобавитьИндекс("INDEX_VAL","INDEX_VAL",0,0,"");
    Дб.СоздатьИндексныйФайл("REPSORT.DBF");
    Дб.ТекущийИндекс("INDEX_VAL");
    Дб.Найти("AA",0);
    Сообщить("номер записи при поиске неуникального индекса 1 при сортировке по возрастанию: "    + Дб.RECORD_NOM);
    
    // по убыванию
    Дб.ДобавитьИндекс("INDEX_VAL","INDEX_VAL",0,1,"");
    Дб.СоздатьИндексныйФайл("REPSORT.DBF");
    Дб.ТекущийИндекс("INDEX_VAL");
    Дб.Найти("AA",0);
    Сообщить("номер записи при поиске неуникального индекса 10 при сортировке по убыванию: "    + Дб.RECORD_NOM);
19 Mihenius
 
24.11.14
13:54
Всем спасибо )

Варианты (9), (15), (17,18) рабочие

Остальным, кто советовал большую dbf в ТЗ загнать.
А вы сами пробовали? Если сама 1с не загнется, то по быстродействию получится намного медленнее.

Сам сделал с обратным порядком еще на выходные.

ПС: А ошибка у меня была, что индекс стал не уникальным. А я не поменял параметр в команде ДобавитьИндекс(,0,)
20 Mihenius
 
24.11.14
14:12
С обратным поиском только обнаружилась проблема.

Почему-то часть записей по ключу найти не может.
С обычным порядком находит.
Странно, код отличается только 1 и 0 в параметре команды.

Еще раз переделал на (9)
21 Mihenius
 
24.11.14
14:16
(20) Покопался.  
И разобрался в чем дело. У файлов различная кодировка.
При обычном порядке она не влияет.
А при обратном порядке кодировка влияет на построение индекса.
22 Mihenius
 
24.11.14
14:46
Мда )

Если у файла win кодировка, то с обратным порядком индекса не ищет.
Ставим Dos и ищет.
Или это я глючу.
23 МишельЛагранж
 
25.11.14
09:43
(21) (22) не помню в 7-ке, в 8-ке можно задать кодировку создаваемого файла.
Просто 1С как всегда соригинальничала и создает файлы непонятно зачем принудительно в win-кодировке.
24 Mihenius
 
25.11.14
12:03
(23) Создаваемого можно.
У существующего при перекодировке получатся кракозябры.
25 Ёпрст
 
25.11.14
12:23
через оледб пробовал ?
26 Serginio1
 
25.11.14
12:37
Вообще то кодировка прописываетя в DBase явно
http://www.sql.ru/forum/725956/kodirovka-dbf-formata-foxpro-versiya-2-0-2-5-2-6

Кстати а уникальность индекса стоит
ДобавитьИндекс(<Название>,<Выражение>,<Уникальность>,<Убывание>,<Фильтр>)
27 МишельЛагранж
 
25.11.14
14:19
(26) в DBAse - да, а создает-то и пишет файл через 1С...
28 Woldemar22LR
 
25.11.14
14:21
(26) вообще то фокспро и 1с Xbase не много по разному работают :)
29 Woldemar22LR
 
25.11.14
14:25
(0) а какой примерно размер первого dbf?
30 МишельЛагранж
 
25.11.14
14:57
(29) в чем DBF замечателен (DBase) - там пофиг на размер файла и количество обрабатываемых записей.
100 000, миллион.... вот тут немного притормозит... 10 млн...
31 Serginio1
 
25.11.14
17:32
(28) Поясни?
32 Woldemar22LR
 
25.11.14
18:02
(30) Мишель, "Ты нанюхался?" (С) The wire = Прослушка
Максимальный размер DBF файла?
Основная причина перевода под SQL это размер файла dbf, потом идут количество пользователей записей и тп. Вообще я имел ввиду конечно же число записей, потому что в ТЗ идет не стыковка небольшая.

(31) 1с Xbase 7.7 и 1с Xbase 8.1  работают немного про разному, а если брать еще и кодировку по сравнению с фохпро то тем более по разному.  
Пояснять очень долго, но попробую, можно завтра?