| 
    
            
         
         | 
    
    
  | 
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 работают немного про разному, а если брать еще и кодировку по сравнению с фохпро то тем более по разному. Пояснять очень долго, но попробую, можно завтра?  | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |