powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Удаление дублей
2 сообщений из 2, страница 1 из 1
Удаление дублей
    #33547682
AlexanderKR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите пожалуйста решить следующую проблему
средствами Fox Pro 2.6.

У меня имеется таблица (скажем, spis-fed.dbf).

Мне необходимо найти в ней все записи,
которые дублируются по трем полям и удалить все дубли.
При этом дубли могут встретиться не друг за другом,
а "на протяжении" всего файла.
Например:
Иванов Иван Иванович 40
Петров Петр Петрович 50
Иванов Иван Иванович 80.

У меня есть prg-шник, который удаляет дубли,
идущие друг за другом.

Код:
**********************************************************
** ПОИСК ЗАПИСЕЙ-ДУБЛЕЙ В ФАЙЛЕ
set talk on
set date to german

im_f="spis-fed.dbf"

define window file_name from 4,23 to 10,55 color W/B
activate window file_name
@ 0,3 say "УДАЛЕНИЕ ДУБЛЕЙ"
@ 2,5 say "Введите имя файла"
@ 4,7 get im_f
read
release window file_name

use sys(2003)+"\"+im_f
goto top
count1=0
do while .not. eof()
store recno() to rec1
goto rec1
f1=eval(field(2)) && ПО ФАМИЛИИ ! ПЕРВАЯ ЗАПИСЬ
i1=eval(field(3)) && ПО ИМЕНИ !
o1=eval(field(4)) && ПО ОТЧЕСТВУ !

skip
rec2=rec1+1
f2=eval(field(2)) && ПО ФАМИЛИИ ! ВТОРАЯ ЗАПИСЬ
i2=eval(field(3)) && ПО ИМЕНИ !
o2=eval(field(4)) && ПО ОТЧЕСТВУ !

* СРАВНИВАЕМ ЗАПИСИ ПО ПОЛЯМ:
if f1=f2 .and. i1=i2 .and. o1=o2
delete record rec2 && удаляем вторую запись-дубль
count1=count1+1
endif
**
enddo
pack
WAIT WINDOW 'ВСЕГО УДАЛЕНО '+alltrim(str(count1))+' ДУБЛЕЙ'
release all
close all
quit
**********************************************************

Как сделать двойной цикл, чтобы
первая запись по порядку сравнивалась со всеми остальными и
они удалялись, затем вторая и т.д. ло конца файла?
Спасибо.
...
Рейтинг: 0 / 0
Удаление дублей
    #33547708
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если сумма длин всех 3 полей не превышает 120 символов и не имеет значения, какую из повторяющихся записей оставить, то можно это решить через индекс типа UNIQUE

Код: plaintext
1.
2.
3.
4.
5.
select MyTab
DELETE ALL
SET DELETED OFF
INDEX ON f1+i1+o1 TO fio.idx COMPACT UNIQUE
RECALL ALL

Идея в том, что индекс типа UNIQUE позволяет таблице иметь повторяющиеся значения, но отображает только уникальные (первые попавшиеся)

Если есть принципиальная разница, какую из повторяющихся записей удалять, то можно просто создать нужный индекс, чтобы сканрование записей шло в строго определенном порядке и возможные дубли следовали друг за другом.

Код: plaintext
1.
2.
3.
4.
5.
select MyTab
INDEX ON f1+i1+o1 TO fio.idx COMPACT
SCAN
* записи с одинаковым значением полей окажутся друг за другом
ENDSCAN

если же по каким-либо причинам создание временного индекса абсолютно невозможно, то остается делать выборку во временную таблицу

Код: plaintext
1.
2.
3.
4.
5.
SELECT f1, i1, o1, count(*) as kol ;
FROM MyTab ;
INTO CURSOR curDoubl ;
GROUP BY f1, i1, o1 ;
HAVING count(*)> 1 

Далее сканируешь результат этой выборки, ищешь все дубли в исходной таблице (LOCATE FOR ... + CONTINUE) и удаляешь их.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Удаление дублей
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]