Выборка неповторяющихся по определённым полям документов

dimat

Well-Known Member
Lotus team
31.07.2008
516
0
#1
Уважаемые программисты, помогите придумать алгоритм для решения следущуей задачи или подскажите с помощью чего ее можно решить.
1. есть коллекция документов.
2. документы созданы по форме, на которой 2 текстовый поля: название организации и этап работы с этой организацией.

из коллекции необходимо убрать документы в который содержание полей одинаково, напрмер есть коллекция:
(1) поле1=орг1, поле2=этап1
(2) поле1=орг3, поле2=этап2
(3) поле1=орг2, поле2=этап6
(4) поле1=орг3, поле2=этап2
(5) поле1=орг1, поле2=этап1
(6) поле1=орг5, поле2=этап3

на выходе должна быть коллекция вида:
(1) поле1=орг1, поле2=этап1
(2) поле1=орг3, поле2=этап2
(3) поле1=орг2, поле2=этап6
(4) поле1=орг5, поле2=этап3
 

nvyush

Well-Known Member
Lotus team
22.04.2009
2 317
0
#2
dimat
Можно создать скрытое представление с двумя сортированными столбцами, соответствующими нужным полям, и установить галку Generate unique keys in index (5-я закладка). Только нужно в формуле отбора отсечь конфликтные документы (SELECT Form = "MyForm" & !@IsAvailable($Conflict) ).
Другой вариант — создать категоризованное представление, где в качестве имени категории объединять значения нужных полей. В цикле перебирать Entry только категорий (см. Set notesViewNavigator = notesView.CreateViewNav; Set notesViewEntry = notesViewNavigator.GetNextSibling( entry ))
 

Kizarek86

Well-Known Member
Lotus team
20.07.2007
863
6
#3
Какая конечная цель данной коллекции? Что с ней делаться должно? Примерное кол-во документов в коллекции?
 

dimat

Well-Known Member
Lotus team
31.07.2008
516
0
#4
Какая конечная цель данной коллекции? Что с ней делаться должно? Примерное кол-во документов в коллекции?
На основании документов в этой коллекции формирую отчет, количество документов в пределах 50
 

Kizarek86

Well-Known Member
Lotus team
20.07.2007
863
6
#5
Если не принципиально какой из документов оставлять то можно так:

Код:
	Dim s As New NotesSession
Dim coll As NotesDocumentCollection, doc As NotesDocument
Dim ListDocumentID List As String, TAG As String
Set doc = coll.GetFirstDocument
While Not doc Is Nothing
TAG = doc.GetItemValue("ПОЛЕ1")(0)+"~~"+doc.GetItemValue("ПОЛЕ2")(0)
ListDocumentID(TAG) = doc.UniversalID
Set doc = coll.GetNextDocument(coll)
Wend

'ListDocumentID - Тут уже документы с уникальными значениями из TAG
Forall ID In ListDocumentID
Set doc = s.CurrentDatabase.GetDocumentByUNID(ID)
'Тут необходимые действия с документами
End Forall
 

nvyush

Well-Known Member
Lotus team
22.04.2009
2 317
0
#6
Если не принципиально какой из документов оставлять то можно так:
КМК, лучше всё-таки сразу получить нужную выборку документов/ентрисов. я бы использовал вариант №1 ( http://codeby.net/ipb.html?s=&sh...st&p=174774 ), вывел все необходимые данные в столбцах представления и получал их по notesViewEntry.ColumnValues.
 
D

Darker

Гость
#7
Лучше сразу из коллекции удалять
Код:
	Dim coll As NotesDocumentCollection, doc As NotesDocument, tempDoc as NotesDocument
Dim ListDocumentID List As String
Set doc = coll.GetFirstDocument
While Not doc Is Nothing
Set tempDoc = doc
Set doc = coll.GetNextDocument(doc)
if Iselement(ListDocumentID(tempDoc.GetItemValue("ПОЛЕ1")(0)+"~~"+tempDoc.GetItemValue("ПОЛЕ2")(0))) then coll.DeleteDocument(tempDoc) else ListDocumentID(TAG)=""
Wend
и дальше юзать coll
 

Kizarek86

Well-Known Member
Lotus team
20.07.2007
863
6
#8
КМК, лучше всё-таки сразу получить нужную выборку документов/ентрисов. я бы использовал вариант №1 ( http://codeby.net/ipb.html?s=&sh...st&p=174774 ), вывел все необходимые данные в столбцах представления и получал их по notesViewEntry.ColumnValues.
Ну если это представление будет делаться только для одного отчета то нафиг надо, а если таких отчетов будет 20 штук, и под каждое представление делать?

50 документов будут даже на самой дряхлой машине получаться очень быстро, а обрабатываться почти моментом.



Добавлено: Симпатичнее)
 

leiba

Well-Known Member
Lotus team
18.06.2010
47
0
#9
Очень понравился вариант Darker . Вот сразу в голову не пришло отсекать лишнее, а не выбирать нужное.

P.S. Часто в отчетах бывает нужно количество документов с одинаковыми тэгами. Удобно подсчитывать его в элементах списка. В варианте с категоризированым представлением это тоже легко решается, а с видом с уникальным ключем, наверное нет.
 

VladSh

начинающий
Lotus team
11.12.2009
1 248
2
#11
Эта дуристика с "удалением" не нужна вовсе.
Если пользовать класс notesDocumentCollection, то дубликаты там невозможны по определению. Для теста попробуйте метод AddDocument, при добавлении уже существующего документа поймаете ошибку 4469.
 
D

Darker

Гость
#13
VladSh, вопрос относительный.
К примеру есть мешок картошки, в котором нужно убрать гнилые.
Есть два метода:
1) Взять дополнительный пустой мешок, сшитый кустарным способом (в силу отсутствия стандартного метода получения нового пустого), и перекладывать туда не гнилые картофели
2) Сразу взять мусорку и бросать туда гнилые, и останется у нас мешок нормальных

Если у нас гнилых больше чем нормальных, то первый способ предпочтительней, в противном случае - второй



ошибку 4469, поймать невозможно, так как документы берутся из коллекции
 

VladSh

начинающий
Lotus team
11.12.2009
1 248
2
#14
Darker
Вариант 3-й и правильный (с точки зрения платформы) - получить коллекцию без гнилой картошки либо осуществить проход чисто по нормальной картошке :) для этого платформа предлагает кучу стандартных методов:
1). Отстройка видов:
а). Получение коллекций:
- GetAllDocumentsByKey
- GetAllEntriesByKey
б). "Онлайн" проход с помощью NotesViewNavigator'а.
2). Формирование строки запроса "на лету" и поиск - это notesDatabase.Search.

Иногда бывают случаи, когда все отобранные документы нужны, но по различным условиям данные из них вытягиваются или запихиваются разные, а некоторые - общие, т.е. времени на проверку уйдёт гораздо меньше, чем 2 разных поиска и 2 разных перебора. Но таких случаев очень немного; в большинстве же подобные решения - это неправильное использование платформы.
 
D

Darker

Гость
#15
VladSh, так задача тривиальная
По мне, получение документов для разовой задачи, с использованием вида - накладно, создание индексов, и т.д., случаются случаи слета индексов.
 

VladSh

начинающий
Lotus team
11.12.2009
1 248
2
#16
Darker
Чтобы индексы видов слетели это надо постараться. Слоган: "Берёшь вьюху - сделай ей Refresh!", никогда не подводило.
При правильном проектировании приложений, вьюхи, по которым ищешь, не содержат большого количества документов, и доки в них не накапливаются.
А бывают случаи, когда и для одного убойного отчёта лучше отстроить вьюху...
notesDatabase.Search, и никаких тебе индексов.