![]() |
![]() |
|
Выборка уникальных значений и сравнение на двойные записи | ☑ | ||
---|---|---|---|---|
0
EvgeniuXP
27.02.06
✎
10:52
|
Алгоритм (тупой): Прохожу по всему регистру сведений хранящий все фио, заношу в таблицу значений, + к этому еще дата рождения и ссылки на физлица. Затем выгружаю в другую таблицу значений, свертываю, получаю уникальные фио и дата рождения. Перебираю эту уникальные значения и смотрю, встречались ли они в общей таблице, если да, то нужно чтобы это было абсолютно два разных физлица, если это так, то этих сотрудников нужно объединить, т.к. это два физлица, хотя это один и тот же... бухгалтеры приняли два раза и не посмотрели, что он уже присутствовал...
Сделал так, но очень тормознуто работает, может выход есть получше?: (весь регистр перебирает дольше, чем сам справочник, хотя элементов меньше, чем в справочнике физические лица) ТЗФИОДатаРожд=Новый ТаблицаЗначений(); ТЗФИОДатаРожд.Колонки.Добавить("ФИО"); ТЗФИОДатаРожд.Колонки.Добавить("ДатаРождения"); ТЗФИОДатаРожд.Колонки.Добавить("ФизЛицо"); // Получаем таблицу значений, которая хранит все "ФИО,ДатаРождения,ФизЛицо" Кол=0; Выборка=РегистрыСведений.ФИОФизЛиц.Выбрать(); Пока Выборка.Следующий() Цикл ФизЛицо=Выборка.ФизЛицо; НоваяСтрока=ТЗФИОДатаРожд.Добавить(); Если ФизЛицо.Пол.Наименование="Мужской" Тогда НоваяСтрока.ФИО=Выборка.Фамилия+" "+Выборка.Имя+" "+Выборка.Отчество; Иначе НоваяСтрока.ФИО=Выборка.Имя+" "+Выборка.Отчество; КонецЕсли; НоваяСтрока.ДатаРождения=ФизЛицо.ДатаРождения; НоваяСтрока.ФизЛицо=ФизЛицо; Кол=Кол+1; Если Кол%100=0 Тогда Состояние("Тестирование_00"+НО+": Пройдено по регистрам сведений ФИОФизЛиц: "+Кол); КонецЕсли; КонецЦикла; Состояние("Тестирование_00"+НО+": Ждите..."); // Вторая таблица хранит уникальные "ФИО,ДатаРождения" ТЗУникальныеФИОДатаРождения=ТЗФИОДатаРожд.Скопировать(); ТЗУникальныеФИОДатаРождения.Свернуть("ФИО,ДатаРождения"); // Перебираем уникальные записи в одной таблице и ищем во второй таблице на двойные записи разных физлиц Кол=0; Для Индекс=0 По ТЗУникальныеФИОДатаРождения.Количество()-1 Цикл УникальноеФИОДатаРождение=ТЗУникальныеФИОДатаРождения[Индекс]; Отбор=Новый Структура("ФИО,ДатаРождения"); Отбор.ФИО=УникальноеФИОДатаРождение.ФИО; Отбор.ДатаРождения=УникальноеФИОДатаРождение.ДатаРождения; Строки=ТЗФИОДатаРожд.НайтиСтроки(Отбор); Если Строки.Количество()>1 Тогда Для Индекс1=0 По Строки.Количество()-2 Цикл Для Индекс2=Индекс1+1 По Строки.Количество()-1 Цикл ФизЛицо1=Строки[Индекс1].ФизЛицо; ФизЛицо2=Строки[Индекс2].ФизЛицо; Если ФизЛицо1<>ФизЛицо2 Тогда ЗанестиВСпрНеразобранныеДанные(НО,ФизЛицо1,ФизЛицо2); КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; Кол=Кол+1; Если Кол%100=0 Тогда Состояние("Тестирование_00"+НО+": Пройдено по уникальным ФИОДатаРождения: "+Кол); КонецЕсли; КонецЦикла; |
|||
1
АперБот
27.02.06
✎
11:37
|
Я иногда пропускаю утонувшие ветки, но эту заметил. Такая моя работа.
|
|||
2
NuiNu
27.02.06
✎
16:31
|
Никогда не сталкивался с такой задачей :(.
Навскидку. В первой ТЗ поле "Флаг" типа число. При заполнении кладем туда 1. Свернул, если во "флаге" больше 1, значит повторяются ну а дальше че надо. Не надо 2-й ТЗ ну и ... Уверен, тоже неоптимальный алгоритм. |
|||
3
Широкий
27.02.06
✎
16:36
|
В запросе сделай левое соединение - найдет все дубликаты -будет быстрее
Пример ВЫБРАТЬ РАЗЛИЧНЫЕ Адреса.Ссылка КАК Адрес, Адреса.Наименование КАК Наименование ИЗ Справочник.Адреса КАК Адреса ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Адреса КАК Адреса1 ПО Адреса.Наименование = Адреса1.Наименование И Адреса.Ссылка <> Адреса1.Ссылка ГДЕ НЕ Адреса.ЭтоГруппа И Адреса.Наименование <> "" И НЕ Адреса1.ЭтоГруппа И Адреса1.Наименование <> "" УПОРЯДОЧИТЬ ПО Наименование |
|||
4
Mort
27.02.06
✎
16:41
|
(3) Кажется просто выберет весь справочник.
|
|||
5
Mort
27.02.06
✎
16:42
|
Тут поднимался подобный вопрос:
v8: Конкурс на самый лучший алгоритм |
|||
6
Широкий
27.02.06
✎
16:47
|
(4) Напугал... стал тестить обработку где используется :)) Нет, все нормально
|
|||
7
dimoff
27.02.06
✎
17:10
|
В запросе добавить поле со значением 1 и добавить поле Итогов, по прохождении верхнего уровня еслив итогах больше 1, то выбираем детальные записи
|
|||
8
dimoff
27.02.06
✎
17:11
|
добавить поле итогов = добавить секцию итогов
|
|||
9
EvgeniuXP
04.03.06
✎
17:30
|
сделал по другому, два запроса, один уникальные собирает, второй все.
Выгружаем уникальные в ТЗ1, все записи в ТЗ2. Перебираем ТЗ1 и находим строки в ТЗ2, создаем ТЗ3 и заносим выбранные строки, свертываем по ФизЛицу, если кол-во больше двух - это двойные записи и в конце цикла УДАЛЯЮ пройденные строки из ТЗ2. Работает быстро, 1 минута на 17 тысяч сотрудников :))), не то что в 7.7... Очень скорость увеличивается (после 3 тысяч уже заметно начинается, в конце черезчур быстро цифры летят), если в ТЗ2 (общая таблица) удалять уже пройденныые строки |
|||
10
EvgeniuXP
04.03.06
✎
17:33
|
левым соединением, все-равно не понял...
Так как мужской пол ФИО = Фамилия+Имя+Отчество+ДатаРождения. Женский пол ФИО = Имя+Отчество+ДатаРождения В запросе нельзя объединить строки: ФИО=Фамилия+Имя+Отчество+ДатаРождения ФИО=Имя+Отчество+ДатаРОждения :( и левое соединение не подходит... |
|||
11
EvgeniuXP
04.03.06
✎
17:36
|
и кстати, заметил, запросы на много быстрее работают, за две секунды любая моя выборка... только вот запись справочников хромает сильно... очень долго... может там как-то можно одним потоком писать? транзакция не помогает... по крайней мере для PIV 3.0E...
|
|||
12
EvgeniuXP
09.03.06
✎
08:20
|
все получилось :), вместо одной минуты теперь три секунды :), а на 77 около 10-15 минут перебирал...
|
|||
13
Гламурный Подонок
09.03.06
✎
08:26
|
Можно и на 80 минут 40 перебирать. Только одному не справиться - помощник нужен...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |