Getalletriesbykey и Notesdaterange и мультивэлью

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#1
начнём стого что подход удобен тем, что можно получить коллекцию в диапозоне дат, и работать с мультивэль списками (синхронными), через энтрисы и колмнвэлью
НО:
-напрямую получить энтрис и юзать колумнвэлью низя
-можно получить в коллекцию энтрисы не относящиеся к диапозону дат

ежели первый трабл решается получением Set reportNav=reportView.CreateViewNav
и преобразованием
Set Me.firstEntry=entries.GetFirstEntry
Set GetFirst=reportNav.GetEntry(Me.firstEntry)
а далее сканированием по нафигатору...
то второй решить можно влоб - перебором по нафигатору до dtStart и также по последнему (от lastEntry в прямом! направлении до даты > dtEnd)
но это не красиво, а может оказаться и накладно по времени (если даты в синхронном списке разнесены ощутимо, а промежутоные энтрисы в большом кол-ве)

в рамках одного дока, мультивэлью поле может оказаться гораздо меньше (по кол-ву в списке)
т.о. можно получить doc из firstEntry (а потом и lastEntry) и сканировать поле на нужную дату
принято допущение, что даты в списке расположены по-возрастанию
типа:
Код:
...
Forall d In v
dt.LocalTime=Fulltrim(d)
'д.б. dt >= dtStart, dt - dtStart>=0
If dt.TimeDifference(dtStart)>=0 Then
'для соответствия индексной колонке во вьюшке
dt.AdjustSecond(i)
'если дата больше или = началу периода - найти стартовый энтрис
Set Me.firstEntry=FindEntry(dt)
Exit Sub
End If
i=i+1
End Forall
...
Private Function FindEntry(dt As NotesDateTime) As NotesViewEntry
'может, при преобразовании, вывалится по ошибке ADT (поиск по ключу даст Nothing)
'вероятные причины: ошибка индекса, ошибка программирования;)
Set FindEntry=reportView.GetEntryByKey(dt, True)
End Function
и вот апосля начинается интересное...
мы теряем счетчик энтрисов и стало быть навигацию по reportNav
как быть?! :what?: выход прост - использовать:
Код:
	Private Property Get CurrentNum As Long
Dim v As Integer
v=curEntry.GetPosition(".")
CurrentNum=Clng(v)
End Property
т.о. мы можем "зафиксировать" "номер" скорректированных ентрисов по его "позиции":
Код:
...
Call checkStartDate() 'ф-ция, кусок кот. выше
Set Me.curEntry=reportNav.GetEntry(Me.firstEntry)
firstNum=CurrentNum
Call checkEndDate()
Set Me.curEntry=reportNav.GetEntry(Me.lastEntry)
lastNum=CurrentNum
...
скорректированное значение счетчика:
Код:
	Property Get Count As Long
Count=lastNum-firstNum+1
End Property
проход по навигатору, с контролем границ
Код:
	Property Get GetNext() As NotesViewEntry
If CurrentNum<lastNum Then
Set GetNext=reportNav.GetNext(curEntry)
Delete curEntry
Set curEntry=Me.GetNext
End If
End Property
 

Akupaka

А че я?.. О.о
04.10.2007
3 360
1
#2
А где вступление, прелюдия?
Как пульнул из пушки по воробьям! :what?:
Для чего подход удобен? О каких случаях идет речь? Еще и без явы...
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#3
Akupaka
коротко рассказано... - первый абзатц :what?:

а детально - представь что нужно сделать отчет (не редкая задача)
и нужны даты как фильтр - тоже частенько
в доке "логируются" операции - в синхронных списках (дата и связанные с ней "значения")
получать DbSearch - нужно будет парсить доки и опять фильтровать даты, разгребать соответствие синхронных полей...
во вьюшке, всё это доступно по навигатору, из энтриса и колумн-вэлью

я здесь уже постил подобный подход... создаем вьюшку и делаем отображение колонок как "show mutiple value as separate etnries"
ключём делаем колонку в датами
в примере выше - добавляются фэйковые секунды (чтобы была известна последовательность, в списке дат, в доке)
предполагается, что список не более 60-ти элементов:
Код:
tmpl:="0":"1":"2":"3":"4":"5":"6":"7":"8":"9";
dig:=tmpl *+ tmpl;
woBlank:=@Trim(H_When);
n:=@Elements(woBlank);
withSeconds:=woBlank + ":" + @Subset(dig;n);
v:=@TextToTime(withSeconds);
@If(@IsError(v);"";v)
и получаем энтрисы по рэнджу:
Код:
		Set dtRange=ses.CreateDateRange()
Set dtRange.StartDateTime=dtStart
Set dtRange.EndDateTime=dtEnd
Dim entries As NotesViewEntryCollection
Set entries=reportView.GetAllEntriesByKey(dtRange)
ЗЫ: если нужны к-л подробности - можно и уточнить... полагаю, тема отчётов из нотуса достаточна интересна, а здесь изложен один из подходов, и описаны грабли
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#4
небольшое отступление по стилю изложения...
это не руководство к действию, не книга, не готовый код
сделано так намерянно :what?: ибо наблюдаю тенденцию, когда появляются разработчики, кот. дай всё готовое и думать не желают...
здесь своего рода макет/квест... ;)
для разработчиков, кот. сталкивались с подобными граблями - это небольшие пояснения и ряд неочевидных преобразований, кот. в документации не всегда явно освещены:
- GetPosition
- GetEntry (у навигатора)
- получение "лишних" дат в коллекции (логично было бы - отсутствие)
 
30.05.2006
1 345
11
#5
а как Вам такое:
ЕСЛИ одна из колонок (1-я?) содержит мульти-значение, то GetFirstEntry из NotesViewEntryCollection выполняется 10..15 секунд!!!
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#6
не замечал...
в каких ситуациях?
 
30.05.2006
1 345
11
#7
не замечал...
в каких ситуациях?
В любых :)

Код:
...
set coll = view.GetAllEntriesByKey(key, True)
select case coll.Count
case 0
case 1
'set ve = coll.GetFirstEntry
set ve = view.GetEntryByKey(key, true) 'мой workaround. Иначе тоже замерзнет
case else
set ve = coll.GetFirstEntry  '<- вот тут-то и замерзает на 15 сек.
While not ve is Nothing
..
set ve = coll.GetNextEntry(ve)
Wend
end select
...
На IBM-е тоже кто-то напоролся

http://www-10.lotus.com/ldd/nd6forum.nsf/5...17?OpenDocument

но там коллеги не заметили, что явление имеет место при условии:
Show multiple values as separate entries. У меня это 1-я колонка (сортированная) с датами.
этот 1-й документ (или любой в коллекции??) реально содержит многозначное поле.
Если поле нечаянно с одной датой - GetFirstEntry срабатывает мгновенно
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#8
может я не наталкивался именно на мультивэлью в первом энтрисе...
посмотрю...
 

TIA

:-)
Lotus team
15.05.2009
790
3
#9
>а как Вам такое:
>ЕСЛИ одна из колонок (1-я?) содержит мульти-значение, то GetFirstEntry из NotesViewEntryCollection выполняется 10..15 секунд!!!

Запросто. Но касается это не только GetFirstEntry. Дело в том, что getView не получает сразу индекс, а следовательно и не инициирует его построение/обновление на сервере, а откладывает о до первого обращения к индексу. В вашем случае первым было обращение в GetFirstEntry. GetFirstDocument привёл бы к такойже зажержке.
 
30.05.2006
1 345
11
#10
Дело в том, что getView не получает сразу индекс, а следовательно и не инициирует его построение/обновление на сервере, а откладывает о до первого обращения к индексу. В вашем случае первым было обращение в GetFirstEntry. GetFirstDocument привёл бы к такойже зажержке.
Глупости. Перед циклом - view.Refresh в обязательном порядке.

Мало того: замена collection.GetFirstEntry на view.GetEntryByKey многократно ускоряет процесс
 
O

oshmianski

#11
Константин, что-то Вы ходите все вокруг да около.

Расскажите уже толком как что тормозит и как это обойти, если не сложно.

Скриптов, в которых используется обход коллекциии у всех туча.

Думаю, будет полезно всем. а?
 

TIA

:-)
Lotus team
15.05.2009
790
3
#12
Constantin A Chervonenko
>Глупости. Перед циклом - view.Refresh в обязательном порядке.
>Мало того: замена collection.GetFirstEntry на view.GetEntryByKey многократно ускоряет процесс

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

А то что я ранее написал - правда. Проверено NRPC-протоколами.

С тем, что замена GetFirstEntry на view.GetEntryByKey возможно ускоряет процесс не спорю.
 
30.05.2006
1 345
11
#13
Constantin A Chervonenko
>Глупости. Перед циклом - view.Refresh в обязательном порядке.
>Мало того: замена collection.GetFirstEntry на view.GetEntryByKey многократно ускоряет процесс
Вот view.Refresh всегда и в обязательном порядке, без всяких оговорок - вот это глупость и лишняя нагрузка на сервер.
1."Глупости" - в данном случае. Когда обнаружились тормоза, неужто я не подумал об индексах?
2.Если вьюшка "чистая", Refresh сервер не грузит


Добавлено:
Расскажите уже толком как что тормозит и как это обойти, если не сложно.
..
Думаю, будет полезно всем. а?
Ну, так уже всё рассказал, где тормозит и в каких случаях.
Обойти..
С коллекцией ViewEntry - х.з.. Комбинирую GetEntryByKey и NotesViewNavigator (который сам - тот ещё тормоз).
Придётся уходить на коллекцию документов
 
O

oshmianski

#14
вообще NotesViewNavigator стараюсь не использовать.
в 8.5 fp1 клиенты падают при его использовании (не на 100%, зависит от сложности вьюхи как я понял)
 

RAJ

Well-known member
17.01.2007
440
0
#15
вообще NotesViewNavigator стараюсь не использовать.
в 8.5 fp1 клиенты падают при его использовании (не на 100%, зависит от сложности вьюхи как я понял)
У меня была проблема: в версии 8.5 при переборе ентри с помощью GetNext на 106 итерации вылетает клиент. Замена на NextSibling проблему решило
 
30.05.2006
1 345
11
#17
Возможно, все давно это знают, но - напомню:
Навигатор перестаёт навигировать, если где-нибудь в процессе нечаянно выполнить view.Refresh
В общем-то логично, но коллекция, к примеру, сохранялась. А навигатор - нет
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 586
272
#18
я здесь (где-то) базу выкладывал (тесты делал) там есть документная коллекция, навигатор (но вьюшечный навигатор, а не по коллекции) и перебор энтрисов из ихней коллекции...
последняя показала себя медленнее всего
вьюшка с 10000 доков и с мультивэлью
но ключ не мультивэлью