Форум » Clipper » [?] Предложите метод » Ответить

[?] Предложите метод

Dima: Имеем базу. В ней 2 поля COD (код товара) , NAIM (наименование) Необходимо выявить "не верные" записи по 2-м условиям. В идеале должно быть: Товар с одним и тем же кодом должен иметь одинаковое наименование Товар с одинаковым наименованием не должен иметь разные коды. Индексные файлы по этим полям есть.

Ответов - 10

Dima: примерчиг Код Наименование 12 XXX 12 XXX 12 X1X 12 XXX 12 X2X

Dima: На скорую руку , применительно к примеру. Собираем инфу о том сколько раз повторяется каждое наименование с кодом 12 Вероятно что то название которое встретилось наибольшее кол-во раз и является наиболее корректным. local amas:={{0,""}} local i:=0 local y:=0 use test new do while !eof() i:=ascan(amas,{|x| x[2]==naim }) if i==0 if amas[1][1]==0 amas[1][1]:=1 amas[1][2]:=naim else aadd(amas,{1,naim}) endif else amas[1]+=1 endif skip enddo aeval(amas,{|x| y:=max(x[1],y)}) // максимальное кол-во наименований с данным кодом ? y // 3 // -//-//-//-//- наименование ? amas[ascan(amas,{|x| x[1]==y})][2] // XXX

Петр: для xHarbour LOCAL hHash := Hash() LOCAL a1, a2 USE test NEW READONLY WHILE ! Eof() IF test->COD == 12 IF HHasKey( hHash, test->NAIM ) hHash[ test->NAIM ] += 1 ELSE hHash[ test->NAIM ] := 0 ENDIF ENDIF SKIP + 1 END WHILE USE a1 := HGetKeys(hHash) a2 := HGetValues(hHash) ну а дальше с двумя массивами работать Если надо в начале можно установить HSetCaseMatch( hHash, .F. )


Григорьев Владимир: Я бы все записал не в массив (массив ограничен 4096 записями), а в текстовый файл. Код написан "на коленках", поэтому не удивляйтесь, если некоторые функции или команды написаны неверно. Нет под рукой шпаргалки. На мой взгляд с файлом проще, так как с ним можно дальше работать. #DEFINE CRLF CHR( 13 ) + CHR( 10 ) #DEFINE TAB CHR( 09 ) #DEFINE EOF CHR( 26 ) PROCEDURE MAIN( cFileSpec ) LOCAL nHandle, cFileSpec LOCAL lNewCode, nIndex DEFAULT cFileSpec TO "C:\DBFCHECK.TXT" nHandle := FOPEN( cFileSpec ) // Здесь еще можно добавить флаг режима открытия IF ( FERROR() != 0 ) ERROROUT( cFileSpec + " open error! ) QUIT( 1 ) ENDIF USE TEST NEW READONLY lNewCode = .T. DO WHILE ( !EOF() ) IF ( lNewCode ) lNewCode := .F. nIndex = FIELD->COD // Увы, не помню формат функции FWRITE() ! FWRITE( nHandle, STR( nIndex, 10 ) + CRLF ) ENDIF IF ( nIndex != FIELD->COD ) lNewCode := .T. ELSE FWRITE( nHandle, TAB + NAIM + CRLF ) ENDIF SKIP ENDDO FWRITE( nHandle, EOF ) FCLOSE( nHandle ) CLOSE DATABASE RETURN

Григорьев Владимир: Извините, пропустил, что поле названия также не должно повторяться. Поэтому добавляем LOCAL cName ... IF ( lNewCode ) lNewCode := .F. nIndex := FIELD->COD cName := FIELD->NAIM // Увы, не помню формат функции FWRITE() ! FWRITE( nHandle, STR( nIndex, 10 ) + CRLF ) FWRITE( nHandle, TAB + cName + CRLF ) ENDIF ... IF ( nIndex != FIELD->COD ) lNewCode := .T. ELSEIF ( cName != FIELD->NAIM ) FWRITE( nHandle, TAB + NAIM + CRLF ) ENDIF

suv3: index on COD+NAIM unique далее - проход по базе и если какое-нибуь значение COD встречается более одного раза - ошибка OldCOD := NIL go top while !eof() if COD == OldCOD ?"Error:", COD,NAIM end end

Dima: suv3 пишет: index on COD+NAIM unique Эта идея была изначально , но сразу отмёл , так как задача сетевая и не хотелось блокировать базу на момент такой проверки в то время как задачу юзает 40 человечиков ;) По жизни такой индекс не нужен. Поэтому сделал в 2 прохода. Сначала по кодам проверил , затем по наименованиям. Работает шустро. Всем спасибо !!!!!!!!!

Dima: Григорьев Владимир пишет: Я бы все записал не в массив (массив ограничен 4096 записями) Cогласен , но это не критично. Максимум по одному коду может набежать не более 50 позиций (теоретически) А если уж упадет при переполнении тогда что то другое думать буду. По ходу в твоем коде не вижу где выясняется какая позиция наиболее корректна , ты просто скидываешь результат в файл...... Просто сбрасывать можно с успехом и через SET ALTERNATE.

Григорьев Владимир: Dima пишет: По ходу в твоем коде не вижу где выясняется какая позиция наиболее корректна , ты просто Всегда есть место для творчества!

Dima: Григорьев Владимир пишет: Всегда есть место для творчества!



полная версия страницы