• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Вопрос про папки.

  • Автор темы Grrr
  • Дата начала
G

Grrr

Вопрос, который уже не раз обсуждался, прошу помочь разобраться.. Итак идея такая.. Сущ-ет база, в которой созданы документы по форме com, com2, comresp (ответ на ответ). Хочу сделать отбор всех (!) документов за определённый период, для этого создал форму поиска (SearchForm), там поля даты ну и соответственно с форума(за что спасибо) выдрал кодик. Выглядит всё примерно так:
Sub Click(Source As Button)
Dim ws As New NotesUIWorkspace
Dim session As New NotesSession
Dim db As NotesDatabase
Dim searchDoc As NotesDocument
Dim dc As notesdocumentcollection
Dim doc As notesdocument
Dim find As String
Dim askme As Integer
Set searchDoc = New NotesDocument(session.CurrentDatabase)
If ws.DialogBox("SearchForm", True, True, False, False, False, False, "Search", searchDoc , True) Then
find = {(Form = "commission")}
find = find + {&(ctbDateCreated >= @TextToTime("} + searchDoc.Date1(0) + {"))}
find = find + {&(ctbDateCreated <= @TextToTime("} + searchDoc.Date2(0) + {"))}
Messagebox find
Set dc = session.CurrentDatabase.Search(find, Nothing, 0)
If dc.Count = 0 Then
Call ws.ViewRefresh
Messagebox "Ничего не найдено"
Exit Sub
Else
Messagebox dc.count
Call dc.PutAllInFolder("PrivateFolder", False)
Call ws.ViewRefresh
End If
askme = ws.Prompt (PROMPT_YESNO, _
"Запрос выполнен, найдено " + Cstr(dc.Count) + " документов", "Создать лист Excel с выгруженными данными?")
If askme = 1 Then
Set xl=CreateObject("Excel.Application")
Set xlWorkbook = xl.Workbooks.Add
Set xlsheet = xl.Workbooks(1).Worksheets(1)
xl.Visible = False
xl.ReferenceStyle = 2
xlsheet.Cells(1,1).Value = "Отчет за период с: " + Cstr(searchDoc.Date1(0)) + " до " + Cstr(searchDoc.Date2(0))
xlsheet.Cells(2,1).Value = "Заголовок"
xlsheet.Cells(2,2).Value = "Статус"
xl.Visible = True
For i = 1 To dc.Count
Set searchDoc = dc.GetNthDocument(i)
xlsheet.Cells(i+2,1).Value = searchDoc.Subject(0)
xlsheet.Cells(i+2,2).Value = searchDoc.Executor(0)
Next
Set xl = Nothing
Call ws.ViewRefresh
End If
End If
End Sub
Теперь вопросы.. Правильно ли я понимаю, что если не указывать форму поиска, то поиск будет выполнен по всем документам в базе? Т.е. кодик поиска по периоду выглядит так:
find = {(ctbDateCreated >= @TextToTime("} + searchDoc.Date1(0) + {"))}
find = find + {&(ctbDateCreated <= @TextToTime("} + searchDoc.Date2(0) + {"))}
?
1. Не напутал ли я со смыслом и формулой?
2. Хотел спросить про свойство папки "Отображать ответные документы в виде иерархии". При выставленном флажке лотус ругается мол надо переносить документы верхнего уровня, без галочки всё окей.
3. И в том, и в другом случае часть документов в папке вываливаются с ошибкой "[Конфликт при репликации или сохранении]", wtf? Как от этого избавиться?? Добавил первый столбец со значением @IsResponseDoc, получаю "0" - документы, "1" - ответы (среди которых присутствуют документы, с той же ошибкой), может просто удалить эти ответы? Их важность непонятна, видимо, придётся их учитывать и выводить в отчёт.. Подскажите как разрулить.
Add: поиск решения в хелпе.. Получилось убрать ответы таким скриптом со столбцом @IsResponseDoc.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim vc As NotesViewEntryCollection
Dim ws As New NotesUIWorkspace
Set db = session.CurrentDatabase
Set view = db.GetView("PrivateFolder")
Set vc = view.GetAllEntriesByKey(1)
Call vc.RemoveAllFromFolder("PrivateFolder")
Call ws.ViewRefresh
4. Покажет ли след. код действительно созданные документы за период? (в начале был отбор по некоторому полю)
find = find + {&(@Created>= @TextToTime("} + searchDoc.Date1(0) + {"))}
find = find + {&(@Created<= @TextToTime("} + searchDoc.Date2(0) + {"))}
5. Как правильно составить условие просроченности выполнения документа? Т.е. существует поле, в котором хранится дата "исполнить до", как по ней сделать отбор? Как представляю, добавить поле "просроченные на " + какая то переменная времени. А потом оперировать этой датой и текущей? Каким будет условие на LS?
Пока что всё. Спасибо за ответы.
 
A

Akupaka

1) вроде нет :)
2) прально ругается... правда, не боролся, не подскажу...
3) конфликты могут быть либо в следствии нарушения индекса вида, либо они были в базе, но не отображались нигде, а теперь ты их увидел;
посмотри их даты создания и являются ли они конфликтами (поле $REF, а форма как у обычного, а не ответного док-та, поле $Conflict); судя по коду, тут неоткуда браться новым конфликтам (нет сохранения);
чтобы не подбирать конфликты можешь добавить в условие find = find + {& @IsUnavailable($Conflict)}
4) ой, не помню уже точно, но даты вроде можно сравнивать спокойно... соотв. тебе нужно получить значение дату и проверить входит ли она в промежуток времени, глянь @Adjust
на LS нужно юзать NotesDateTime + NotesDateTime.TimeDifference
 
G

Grrr

Вот сижу и ничего не понимаю.. Можно попродробнее? Посмотрел по формам создания получилось такое:
Все нормальные документы созданы по com1(документ) и com3(ответ на ответ),
С ошибкой репликации вывалиются документы, созданные по com2 (документ), причём форма создания у них имеет такое же название и сам вид, что и com1(Поручение, Поручение), отличается лишь синонимом (так что я думаю косяк не в одинаковом названии;)). В com2 как и в com3 поле $ref есть в этом и косяк? Ведь com2 не ответ, а простой документ.. Также в нём есть $Conflict пустое текстовое. Как исправить, чем лечить? Караул!
чтобы не подбирать конфликты можешь добавить в условие find = find + {& @IsUnavailable($Conflict)}
Действительно, конфликтные не отображаются ;). Но, стоит ли так делать? Есть ли ещё способы исправить ошибку? Заметил в форме какой то свойство "Обработка конфликтов", среди выбора "Создавать конфликты", "Объединять",.., "Не создавать конфликты". Выставление последнего не поправит дело?
Также, создал представление с формулой:
SELECT @IsAvailable($Conflict)
Ничего не показывает o_O.
Ещё один вопросик. Как лучше создать форму для поиска по разным условиям? Т.е. я буду искать по дате создания, по дате исполнения, по просроченным и т.д., т.е. надо будет дописывать условия если поле такое то пустое.., или есть другие способы? Пока что подумываю о самом простом, о разных кнопках в папке, вызывающих разные формы определённых поисков.
add: Нужна помощь по отбору просроченных.. Никак не получается сделать. Смысл такой:
В документе есть поле (дата), так вот нужно сделать отбор просроченных на x дней, т.е. в поисковой форме создаю поле даты, как по нему делать отбор? Допустим отобрать документы просроченные на 2 дня. Пример был бы очень полезен. Спасибо.

Если не трудно подскажите как добавить в строку поиска ответственного выбранного из acl? Пытаюсь сделать так:
find = find + {&(ctbAuthorLN= "} + Cstr(searchDoc.Isp(0)) + {")}
Где Isp поле имеет тип "список с окном" (выбирать в окне адресации), висит формула @UserName(0), поле изменяемое. Что про поле ctbAuthorLN, оно содержит значения типа ""CN=Виктор/O=ADMIN"". Почему то ничего не находит.. Убегаю..
 
A

Akupaka

В com2 как и в com3 поле $ref есть в этом и косяк?
Ведь com2 не ответ, а простой документ.. Также в нём есть $Conflict пустое текстовое. Как исправить, чем лечить? Караул!
вообще-то наличие поля $REF в документах, созданных по форме типа Document (а не Response) - это косяк архитектуры (скорее всего), либо выкручивание через задницу...
а вот когда в таком документе присутствует еещ и поле $Conflict, то это уже указывает на то, что этот документ является конфликтом!

Действительно, конфликтные не отображаются ;). Но, стоит ли так делать? Есть ли ещё способы исправить ошибку?
думаю, что да, т.к. в отчетах конфликты быть не должны, конфликты должны ликвидироваться до момента попадания в отчет, вообще, конфликт - признак некорректной работы системы, нужно попытаться выяснить причины его возникновения, и по возможности ликвидировать ее!

Заметил в форме какой то свойство "Обработка конфликтов", среди выбора "Создавать конфликты", "Объединять",.., "Не создавать конфликты". Выставление последнего не поправит дело?
это свойство помогает на определенном уровне избежать ситуаций возникновения конфликтов. рекомендую поискать книгу Inside Notes, глава 9 (?), Replication. Там хорошо описан процесс репликации и возникновения конфликтов (лучше чем в хэлпе), возможно, можно найти у Николая Норкина что-то по этому поводу (если по-русски), либо на форумах ;)
я бы рекомендовал устанавливать "Объединять", т.к. это позволит не создавать конфликты репликаций, если пользователи правили значения в разных полях документа.

Также, создал представление с формулой:
SELECT @IsAvailable($Conflict)
Ничего не показывает o_O.
видать, галку Отображать иерархию дочерних забыл снять... конфликт - дочерний документ!

Ещё один вопросик. Как лучше создать форму для поиска по разным условиям? Т.е. я буду искать по дате создания, по дате исполнения, по просроченным и т.д., т.е. надо будет дописывать условия если поле такое то пустое.., или есть другие способы? Пока что подумываю о самом простом, о разных кнопках в папке, вызывающих разные формы определённых поисков.
это приходит с практикой... посмотри как реализован поиск в других системах, попытайся продублировать... не обязательно создавать разные формы! можно на одной форме сделать переключатель, который будет указывать по чему искать, но этот вариант ограничевает поиск только по одному полю; можно сделать чек-боксы, и с их помощью указывать поля для поиска, и правильно формировать строку запроса... в общем, тут широкое поле для действий...

add: Нужна помощь по отбору просроченных.. Никак не получается сделать. Смысл такой:
В документе есть поле (дата), так вот нужно сделать отбор просроченных на x дней, т.е. в поисковой форме создаю поле даты, как по нему делать отбор? Допустим отобрать документы просроченные на 2 дня
не понял, что мешает по формуле отобрать? в первом после была формула, она не срабатывает?.. можешь для пробы, чтобы проверить прав ли ты, создать представление (если база маленькая или копию сделать частичную), задать ему формулой предполагаемую строку поиска и посмотреть, что получилось, если представление строится верно, а поиск из формы поиска нет, то где-то неверно передаешь параметры... надеюсь понятный пример :(
если у тебя в документе есть поле, которое хранит конечную дату исполнения, то нужно во-первых сравнивать его с текущей датой, чтобы определить просроченность, во-вторых сравнить разницу между текущей датой и этой датой, если она равна двум дням, то это нужный документ. тогда в поисковой форме нужно не дату указывать, а кол-во просроченных дней... но обычно ставят задачу найти просроченные (от текущей даты)

Если не трудно подскажите как добавить в строку поиска ответственного выбранного из acl? Пытаюсь сделать так:
Где Isp поле имеет тип "список с окном" (выбирать в окне адресации), висит формула @UserName(0), поле изменяемое.
не понял я куда ты запихал ту фомулу, и зачем парметр?... думаю, что параметр можно не использовать. правильно поле использовал, может не ctbAuthorLN?.. посмотри дебагерром, какая в итоге получает строка запроса (либо мессадж, но лучше дебаггером)! часто помогает найти ошибки!
 
G

Grrr

вообще-то наличие поля $REF в документах, созданных по форме типа Document (а не Response) - это косяк архитектуры (скорее всего), либо выкручивание через задницу...
а вот когда в таком документе присутствует еещ и поле $Conflict, то это уже указывает на то, что этот документ является конфликтом!

думаю, что да, т.к. в отчетах конфликты быть не должны, конфликты должны ликвидироваться до момента попадания в отчет, вообще, конфликт - признак некорректной работы системы, нужно попытаться выяснить причины его возникновения, и по возможности ликвидировать ее!
К сожалению времени практически нет, задание как бы это сказать заказное и срок уже истекает.

это свойство помогает на определенном уровне избежать ситуаций возникновения конфликтов. рекомендую поискать книгу Inside Notes, глава 9 (?), Replication. Там хорошо описан процесс репликации и возникновения конфликтов (лучше чем в хэлпе), возможно, можно найти у Николая Норкина что-то по этому поводу (если по-русски), либо на форумах ;)
я бы рекомендовал устанавливать "Объединять", т.к. это позволит не создавать конфликты репликаций, если пользователи правили значения в разных полях документа.
Постараюсь поискать книгу, спасибо.

видать, галку Отображать иерархию дочерних забыл снять... конфликт - дочерний документ!
Всё верно, забыл.. Увидел конфликтные, радует что их немного (11), но как их править ума пока что не приложу. Нет опыта..

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

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

не понял я куда ты запихал ту фомулу, и зачем парметр?... думаю, что параметр можно не использовать. правильно поле использовал, может не ctbAuthorLN?.. посмотри дебагерром, какая в итоге получает строка запроса (либо мессадж, но лучше дебаггером)! часто помогает найти ошибки!
Формулу пихал в поле Isp поисковой формы, незнаю влияет ли это на что то. Поле ctbAuthorLN содержит имя автора в виде "CN=Василий/O=ADMIN", есть ещё поле ctbAuthor, там просто в формате ФИО, думаю сейчас попробобую по нему поискать.
 
G

Grrr

Про выбор исполнителя кажется понял.. Вообщем в поле поисковой формы стоит просто поле выбора автора, которое передаёт в строку поиска имя в виде "Николай/ADM", а поле AuthorLN в документах имеет канонический тип т.е. "CN=..". Как можно преобразовать строку пользователя в канонический вид? Думал через @setfield и @name, не получилось.
Спасибо.
 
A

Akupaka

@Name([Canonicalizate]; "Some/Hierarhical/Name")
либо NotesName глянь, если преобразовывать скриптом будешь

по поводу поиска.
смотри, форма - эл-нт дизайна, который позволяет разместить набор эл-тов управления. т.е. если тебе нужно реализовать механизм, который зависит от указанных на форме значений, то не обязательно для этого лепить N-форм!
преимущества одной формы для настройки поиска:
- код грубо говоря в одном месте, если надо будет исправить, то достаточно провести исправления в одном месте;
- если нужно расширить параметры поика, то достаточно изменить одну форму, а не какое-то большее кол-во;
можно и другие найти, но это самое главное! и вообще, красиво будет ;)

тебе нужно определить возможные параметры поиска - то по чему пользователи смогут проводить поиск!
например, если в твоих поручениях поиск возможен по полям Исполнитель, Автор, Подписант, Утверждающий, Дата отправки на исполнение, Дата окончания исполнения, то можно сделать такие параметры: Исполнитель, Автор, Подписант, Утверждающий, Дата отправки на исполнение, Дата окончания исполнения, Просроченные

реализовать след образом:
на форме создать блоки, каждый из которых будет соответствовать одному параметру. каждый из этих блоков может быть доступен пользователю, если он поставит соответсвующую галочку. т.е. блок скрывается, если определенное поле-флаг не содержит нужного значения!
когда пользователь нажимает "поиск", то код смотрит поле-флаг, и на его основании включает параметр поиска либо нет.
если поле-флаг указывает на поиск по параметру, то мы просто нужным образом исправляем строку запроса поиска.

например, по исполнителю:

поле-флаг SearchExecutor, checkbox, label: Поиск по исполнителю, value: Да|1
ниже идет блок полей выбора значения исполнителя, по которому будем искать
например, поле ExecutorNotesName, Text, Single value, Computed when composed (or Computed), Value: ExecutorNotesName (т.е. сам на себя), рядом кнопка для выбора
(если нотес имя можно выбрать из общей Domino directory, а не справочника организаций, то поле может быть Editable, Names)

аналогично, другие поля:
SearchAutor, AuthorNotesName
SearchApprover, ApproverNotesName
и т.п.


когда мы жмем на Поиск, то код должен получить тек. док (через УИ), проверить наш флаг и сформировать строку поиска, например:


Код:
dim ws as new notesuiworkspace
dim s as new notessession
dim db as notesdatabase
dim searchCol as NotesDocumentCollection
dim doc as notesdocument
dim flag as boolean
dim searchParam as variant ' array
dim searchStr as string

set doc = ws.CurrentDocument.Document

' возможно нужно более "умное" преобразование имен, дат и т.п., прежде чем пихать их в параметры поиска
' да и пустые значения, возможно не стоит использовать, а ругаться, что они не заполнены, но это нужно делать раньше

flag = doc.GetItemValue("SearchExecutor")(0) = "1"
if flag then
call AddSearchParam(searchParam, {(ExecutorNotes = "} & doc.GetItemValue("ExecutorNotesName")(0) & {")})
end if

flag = doc.GetItemValue("SearchAutor")(0) = "1"
if flag then
call AddSearchParam(searchParam, {(AuthorNotes = "} & doc.GetItemValue("AuthorNotesName")(0) & {")})
end if

flag = doc.GetItemValue("SearchApprover")(0) = "1"
if flag then
call AddSearchParam(searchParam, {(ApproverNotesName = "} & doc.GetItemValue("ApproverNotesName")(0) & {")})
end if

' другие поля

searchParam = Arrayunique(Fulltrim(searchParam)) ' в общем-то это не обязательно, это убирает пустые эл-ты массива и одинаковыве
' тут мы тупо объединяем через AND параметры, возможно, это не подойдет в общем случае, но это лишь пример;)
searchStr = join(searchParam, " & ")

set db = s.currentDatabase
set searchCol = db.Search(searchStr)


sub AddSearchParam(AParamArray as variant, AParam as string)
if isarray(AParamArray) then
redim preserve AParamArray (lbound(AParamArray) to ubound(AParamArray) + 1)
else
redim AParamArray (0 to 0)
end if
AParamArray(ubound(AParamArray)) = AParam
end sub

зы: пример писан прямо в форуме, и не проверен на работоспособность... короче говоря, AS IS & use it on your own risk, автор не несет ;)
 
G

Grrr

Огромное спасибо за код, завтра попробую!:angry:
 
G

Grrr

Столкнулся со следующим если делать поиск из формы..
Set doc = ws.CurrentDocument.Document
flag = doc.GetItemValue("SearchDate1")(0) = "1"
If flag Then
Call AddSearchParam(searchParam, {(@Created >= @TextToTime("} + Doc.Date1(0) + {"))})
End If
..то всё работает, а при вызове из папки формы ругается на первую строку, т.е. форма сама то вызывается, выбираю поля и прочее, по нажатию на "ок", получаю "object variable not set" пытался через уи, тоже не идёт..
Set uidoc = ws.CurrentDocument
проходит, ругается на метод getiteamvalue, т.к. он предназначен для notesdocument. Через уи есть метод FieldGetText, но там возврат идёт строка..
 
G

Grrr

Не проходит.. Ругается на Set doc = uidoc.Document
 
G

Grrr

Из личной папки по нажатию кнопки вылетает диалогбокс.. Что то вроде этого
Dim uidoc As notesuidocument
Dim doc As notesdocument

Set searchDoc = New NotesDocument(s.CurrentDatabase)
If ws.DialogBox("GlobalSearchForm", True, True, False, False, False, False, "Search", searchDoc , True) Then
'проходит
Set uidoc = ws.CurrentDocument
'ошибка
Set doc = uidoc.Document

flag = doc.GetItemValue("SearchDate1")(0) = "1"
If flag Then
Call AddSearchParam(searchParam, {(@Created >= @TextToTime("} + doc.Date1(0) + {"))})
End If
 
M

morpheus

Код:
flag = doc.GetItemValue("SearchDate1")(0) = "1"
If flag Then 
Call AddSearchParam(searchParam, {(@Created >= @TextToTime("} + doc.Date1(0) + {"))})
End If

здесь и далее можно использовать уже не doc , а searchDoc
или Set doc = searchDoc


Akupaka
это я по пьяне
 
G

Grrr

Просто разрыв мозга, спасибо. Когда отойду от шока разберусь что это было.
 
A

Akupaka

отставить диалогбокс!
нужно делать notesUIWorkspace.ComposeDocument

DialogBox отобразит текущий в представлении документ по другой форме!!! читаем справку внимательно!

хотя, если в личной папке выбран документ настроек поиска (т.е. с параметрами)! то тогда можно, но т.к. это не было указано, то считаю, что это ошибка, и документы в папке никакого отношения к настройкам поиска не имеют...
 

Medevic

Что это ? :)
Green Team
10.12.2004
3 334
1
BIT
4
Akupaka, ты что-то путаешь. Диалогбоксу суется только что созданный searchDoc. Он и отобразится.
 
A

Akupaka

я не путаю... я сплю :wacko:) сори, я не досмотрел...

но все-равно, зачем после Dialogbox берется документ через УИ?.. он ведь не вернет этот док, т.к. диалог уже закрыт!
нужно просто searchDoc юзать... как Морфей написал выше, в общем...

хотя, я бы сделал все-таки Compose, а уже код поиска всобачил на форме, либо в либе, а на форму подтянул
а то как-то на кнопке вида кода цеплять не прикольно...
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!