• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Как контролировать содержимое поля формы при вводе ?

  • Автор темы Sch
  • Дата начала
S

Sch

Есть форма FTtype и связанный с ней view - FTypeView
Хочу проверять содержимое при выходе из поля FTType после редактирования,
и если в view-е по данному полю уже есть такое значение - то заменять его на значение до редактирования.
Все как бы работает, Но :

при замене на запомненное значение Call doc.ReplaceItemValue("FTType", FTTypeTemp)
Он его не запоминает в поле, хотя значения правильные, это видно по MessageBox тестовому...
В чем дело, и как это сделать ?

У формы :
_______________________

Код:
Sub Postopen(Source As Notesuidocument)
FTTypeTemp=GetFieldByName("FTType",0)
Messagebox("Open:"+FTTypeTemp)
End Sub

У поля FTType
___________ ' check Type for existing

Код:
Sub Exiting(Source As Field)
Dim FTTypeA As String
Dim flag As Boolean 
Dim session As New NotesSession
Dim db As NotesDatabase 
Dim view As NotesView
Dim doc As NotesDocument

Set db = session.CurrentDatabase 
Set view = db.GetView("FTypeView")
Set doc = view.GetFirstDocument

'''' FTTypeA = doc.GetItemValue("FTType")(0) 
FTTypeA =GetFieldByName("FTType",0) 

If FTTypeA FTTypeTemp Then 
flag = False
If doc.HasItem("FTType") Then
While Not(doc Is Nothing) And flagTrue
Forall FTTypeI In doc.GetItemValue("FTType")

If FTTypeI = FTTypeA Then 
flag = True 
End If 
End Forall
Set doc = view.GetNextDocument(doc)
Wend

If flag = True Then 
Messagebox ("Этот тип "FTTypeA" уже присутствует") 
Call doc.ReplaceItemValue("FTType", FTTypeTemp) 
End If
End If
End If

End Sub


в Script Library :
Function GetFieldByName (Nam As String, Pos As Integer) As Variant
Dim ws As New NotesUIWorkspace
Dim doc As NotesDocument
GetFieldByName = "" 


If Not ws.CurrentDocument.IsNewDoc Then ' ?
Set doc = ws.CurrentDocument.Document
If Pos < 0 Then 
GetFieldByName = doc.GetItemValue(Nam)
Else 
GetFieldByName = doc.GetItemValue(Nam)(Pos)
End If
End If

End Function
_______________________

То есть я запоминаю содержимое поля - до редактирования его в переменной FTTypeTemp.

После ввода пользователем в поле нового значения, в Exiting я проверяю это поле в определенном View на уникальность. Не ввели ли значения, которое уже есть в базе в этом поле ?
Статус этого положения записывается в переменную flag.

Ну и когда она true - я хочу восстановить содержимое поля до ввода. Вставить в него старое, запомненное значение. Бывшее до редактирования.
If flag = True Then
Messagebox ("Этот тип "FTTypeA" уже присутствует")
Call doc.ReplaceItemValue("FTType", FTTypeTemp)
End If

Ну и он не вставляет. Оставляет тем же, что было после редактирования-ввода.

Посоветовали поставить Refresh после Call doc.ReplaceItemValue("FTType", FTTypeTemp)
Ничего не дало.


_____________________

Еще такой вопрос : Как вывести в колонке View-а содержимое поля типа RichText ?

Ставлю в ней следующую формулу :

@Left(@Text(FTComment);10)

Содержимое, тем не менее, не отображает.
Как и просто @Text(FTComment)
 
A

Akupaka

1) у тебя в коде Sub Exiting() doc - не текущий док, который правят, а док, который ты из вида взял
дальше разберешься;

2) вообще-то это плохая затея, есть там функция @Abstract, но что-то я о ней ничего хорошего не помню :)
лучше сохранять раз надо это в отдельном обычном поле и показывать в виде уже его...
 
S

Sch

1) у тебя в коде Sub Exiting() doc - не текущий док, который правят, а док, который ты из вида взял
дальше разберешься;

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


1. А какая разница ? Содержимое я корректно получаю. То есть с этим вроде бы нечего разбираться.

Я обратно после редактирования пользователем и Exiting изменить не могу. Хотя все значения переменных корректны.

Этот вот блок :

if flag = True Then
Messagebox ("Этот тип "FTTypeA" уже присутствует")
Call doc.ReplaceItemValue("FTType", FTTypeTemp)
End If

2. Abstract вроде тоже не подходил... А в text-поле как ? Копировать из RichText при его вводе чтоль, конвертируя тем же @Text ? Если он работает для этого все таки... Криво как-то...
 
A

Akupaka

1. А какая разница ? Содержимое я корректно получаю. То есть с этим вроде бы нечего разбираться.

Я обратно после редактирования пользователем и Exiting изменить не могу. Хотя все значения переменных корректны.
ты шутишь? :) ты же хочешь поменять значение в открытом на редактирование документе! так зачем ты делаешь замену поля в документе взятом из вида?!

if flag = True Then
Messagebox ("Этот тип "FTTypeA" уже присутствует")
Call doc.ReplaceItemValue("FTType", FTTypeTemp)
End If

если надо

Код:
if flag = True Then
Dim ws As New NotesUIWorkspace
Messagebox ("Этот тип "FTTypeA" уже присутствует")
Call ws.CurrentDocument.ReplaceItemValue("FTType", FTTypeTemp)
End If


2. создаешь на форме текстовое поле TextField, Computed, в формулу пихаешь @Abstract() (см. справку для уточнения параметров), а в виде тянешь значение из TextField...
вот вырезка из справки по @Name:
Rich text conversion does not work in column formulas. Use @Abstract to convert the contents of a rich text field to plain text. Then reference the plain text field in the view. For example, if you add the following code to a hidden computed field called plainText, you can then set the default value of the view column to "plainText" to display the contents of the RTField:
@Abstract([TextOnly];15360;"";"RTField")
 
S

Sch

Насчет абстракта - спасибо, работает. Но все таки это криво ведь, поля плодить по таким поводам...

P :=@Abstract(TextOnly;400;""; FTFunc);
PA :=@Word(P; " " ; 1);+" "@Word(P; " " ; 2);" "+@Word(P; " " ; 3);
P4 :=@Word(P; " " ; 4);
@If(PA="";"n/a"; P4!=""; PA+" ...."; PA);

А еще связанный вопрос - как в зависимости от того, есть ли в поле richtext - картинка или нет, то есть занято оно или нет - выводить в view определенную, custom, иконку...

@isnull не срабатывает, ="" тоже, length(@Abstract(... дает 0 все время.
Опять чтоли второе поле пробовать ? Так и оно не срабатывает...
P :=@Abstract(TextOnly;10;""; FTImage);
@Length (P)


То есть как определить в формулах - загружена картинка или нет ?
 
A

Akupaka

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

а что тебя так смущает в плодении полей? если грамотно реализовано, то ничего страшного нет, вот бестолковое программирование - страшно :)

учти, что картинку в RTItem нельзя определить никаким способом, кроме как проверить его размер, который будет, к тому же, не больше нуля, а больше какого-то значения, не помню какого :) и то, только из предположения, что в поле можно вставлять только картинку...
 
S

Sch

"а что тебя так смущает в плодении полей? "

Разрастание этой кучи, что в Lotuse называют БД. Больше данных - больше нагрузка на комп, а данные-то эти - даже получаются не прикладные. Ну не эстетично, и именно с точки зрения программирования, то есть построения системы :)
Кстати, как поля ненужные удалять из БД ?


С первым вопросом пока толком не разбирался, а как обычно принято в Lotuse контролировать уникальность значения поля ?
 
A

Akupaka

начнем с того, что NotesDB не реляционная БД, а документарная.
эстетичность не применима ко всем случаям одинаково.
никакие поля удалять не надо.

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

Sch

Вообщем, пока получается так (2 способами) :


Код:
Sub Exiting(Source As Field)
Dim FTTypeA As String
Dim FTTypeUI As String

Dim flag As Boolean		

Dim session As New NotesSession
Dim view As NotesView
Dim doc As NotesDocument

Dim ws As New NotesUIWorkspace '?

Set view = session.CurrentDatabase.GetView("FTypeView")
FTTypeA = ws.CurrentDocument.Document.GetItemValue("FTType")(0) ' - c экрана
FTTypeUI =ws.CurrentDocument.Document.UniversalID	


If FTTypeA <> FTTypeTemp Then		'document by key variant 1
Set doc = view.GetDocumentByKey (FTTypeA)
If Not (doc Is Nothing) Then	
Messagebox ("Этот тип "+FTTypeA+" в коллекции")
' rem тест			Call ws.CurrentDocument.Document.ReplaceItemValue("FTType", FTTypeTemp)		
End If
End If

'without key 
If FTTypeA <> FTTypeTemp Then				
flag = False
Set doc = view.GetFirstDocument

While Not(doc Is Nothing) And flag<>True
FTTypeI = doc.GetItemValue("FTType")(0)						
Messagebox("Iterator "+FTTypeI+" New:"+FTTypeA+" Temp:"+FTTypeTemp)

If (FTTypeI = FTTypeA ) And (FTTypeUI <>doc.UniversalID) Then		 
flag = True 
End If		
Set doc = view.GetNextDocument(doc)
Wend	

If flag = True Then
Messagebox ("Этот тип "+FTTypeA+" уже присутствует")
Call ws.CurrentDocument.Document.ReplaceItemValue("FTType", FTTypeTemp)
End If				
End If

End Sub
Модератор: Теги кода для кого придуманы? Сколько можно намеки делать?
__________________

то есть для способа с GetDocumentByKey (FTTypeA) нужно, что проверямое поле было в 1 колонке view и отсортировано, как я понял, а для второго - не нужно...

А вот еще - текущий документ со всеми его Replace-Get Item - можно взять только из NotesUIWorkspace ? из NotesView, например, или где-нибудь в этой иерархии :
Dim session As New NotesSession
Dim view As NotesView
Dim doc As NotesDocument
нельзя ?
 
A

Akupaka

"текущий" для УИ документ (фронтэнд), если говорить об открытом документе, можно получить лишь через NotesUIWorkspace
даже, если этот документ не новый и уже был сохранен в базе, то его открытый экземпляр висит в памяти отдельно.
если ты изменишь значение какого-то поля фронтэнд-документа, то до сохранения документа, значение этого поля взятого из бэкэнд-документа будет другим - "старым", т.е. таким, которое было с момента последнего сохранения...
 
S

Sch

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

Чудесно. Почему тогда у меня выдаются одинаковые значения , хотя второе при переборе я получаю через Session-> ..... ->GetFirst-Next-Document, и значения такого в базе - нет реально, и приходится сравнивать UID и пропускать соответствующий текущему документ в базе ?


Код:
			FTTypeI = doc.GetItemValue("FTType")(0)						
Messagebox("Iterator "+FTTypeI+" New:"+FTTypeA+" Temp:"+FTTypeTemp)

If (FTTypeI = FTTypeA ) And (FTTypeUI <>doc.UniversalID) Then		 
flag = True
End If


Например :

1. в базе :

A
B
C
D

2. Входим в форму на позиции C, вводим в поле - "Q", Save не делаем

проверка выглядит так

A = Q ? нет, дальше
B = Q ? нет, дальше
Q = Q ? да. - (!?) флаг установлен
D = Q ? нет, но это уже не важно
 
S

Sch

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


формулами это сделать тоже нельзя ?
Код:
@Command([EditGotoField];"FTImage");
REM {@PostedCommand([FileImport]);};

REM {@If(@Command([FileImport]); FIELD FTIm1 := 1; FIELD FTIm1 := 2 );};

@Command([FileImport]);
@IfError( FIELD FTIm1 := 1; FIELD FTIm1 := 2)

и @command, и @postcommand, а также @ifError не ловят ситуацию, например, если юзер нажал Cancel при выборе картинки...
 
A

Akupaka

во всяком случае я о таком не знаю...
 
S

Sch

Код:
	Call doc.GotoField("FTImage")
Call doc.Import	
Call doc.ReplaceItemValue("FTIm1", 1)

А как в LotusScript проконтролировать реальный результат импорта ?
 
A

Akupaka

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

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
реально проверить присутствие картинки тока после сохранения РТ ондиск
там ДХЛ-ем берёш РТ и парсишь на картинку, апосля пишешь поле (дополнительное)
 
S

Sch

реально проверить присутствие картинки тока после сохранения РТ ондиск
там ДХЛ-ем берёш РТ и парсишь на картинку, апосля пишешь поле (дополнительное)

Я с Лотусом познакомился полторы недели назад. Можно изложить более доступным языком ?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 940
609
BIT
210
есть классы для получения доков (да в общем итемов) в виде Домино XML, что и называется DXL...
если имеете опыт работы с XML - то далее дело техники
примеры выдергивания кусков из дока:

и далее мой код (на сайте) по ссылкам (типа LAX)
последний вам больше подойдет (мне так кажется) - там можно написать несколько классов на разные виды объектов в теле
 
Мы в соцсетях:

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