Создание Кнопки Hotspot Внутри Richполя

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

savl

Lotus Team
28.10.2011
2 625
314
BIT
545
CтарыйStarik
Лучше не добавлять строки...
По моим наблюдениям чаще надо нарисовать таблицу, которая имеет фиксированное количество строк и столбцов, да и содержание таблицы как правило уже известно.
Думаю стоит начать с функции, которая создает такую таблицу.
что-то вроде:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Скелет</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub CreateTable(Rows as Integer, Columns as Integer, ColumnsLabel as Variant, HotSpotScript as String, HotspotIndex as String, DataRow as Variant)
'Rows - количество строк таблицы + 1 строка на шапку
'Columns - столбцы
'ColumnsLabel - наименование стобцов
'HotSpotScript - текст скрипта для хотспота
'HotspotIndex - адрес ячейки куда вставить в хотспот (тут может быть массив, если надо несколько, но это просто продумать)
' формат индекса = Строка:Столбец
'DataRow - данные для таблицы, лучше список в списке. DataRow список строк. а внутри скажем список DataColumns.

For i=0 to Rows 
' открываем тег TableRows
DataElementList = DataRow("" & i) 
For j = 0 to Columns 
' открываем тег TableCell
If i = 0 then
' Записываем шапку таблицы ColumnsLabel(j)
Else
if ( i & ":" & j) = HotspotIndex Then
'Записываем тут HotSpotScript 
Else
' Записываем значение DataElementList("" & j)
End if
End If
' закрываем тег TableCell
next j
' закрываем тег TableRows
next i

Вот такой скелет у меня в голове получился, но может существует решение и лучше.
 
S

StarikStarik2705

CтарыйStarik
Лучше не добавлять строки...
По моим наблюдениям чаще надо нарисовать таблицу, которая имеет фиксированное количество строк и столбцов, да и содержание таблицы как правило уже известно.
Думаю стоит начать с функции, которая создает такую таблицу.
что-то вроде:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Скелет</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub CreateTable(Rows as Integer, Columns as Integer, ColumnsLabel as Variant, HotSpotScript as String, HotspotIndex as String, DataRow as Variant)
'Rows - количество строк таблицы + 1 строка на шапку
'Columns - столбцы
'ColumnsLabel - наименование стобцов
'HotSpotScript - текст скрипта для хотспота
'HotspotIndex - адрес ячейки куда вставить в хотспот (тут может быть массив, если надо несколько, но это просто продумать)
' формат индекса = Строка:Столбец
'DataRow - данные для таблицы, лучше список в списке. DataRow список строк. а внутри скажем список DataColumns.

For i=0 to Rows 
' открываем тег TableRows
DataElementList = DataRow("" & i) 
For j = 0 to Columns 
' открываем тег TableCell
If i = 0 then
' Записываем шапку таблицы ColumnsLabel(j)
Else
if ( i & ":" & j) = HotspotIndex Then
'Записываем тут HotSpotScript 
Else
' Записываем значение DataElementList("" & j)
End if
End If
' закрываем тег TableCell
next j
' закрываем тег TableRows
next i

Вот такой скелет у меня в голове получился, но может существует решение и лучше.


идея хорошая надо попробовать..но я пока у сеня не могу разрулить ситуацию что таблица не должнва превышать 255 строк. а у меня их больше 600
я такое сделал


tableRow = tableRow & Chr(10)& |
<tablerow>
<tablecell><pardef id = "|& i &|" align="center" /><par><doclink document='|& CStr(Trim(firstDoc.Universalid)) &|' database='|& CStr(Trim(dbS.replicaID)) &|' description='Ссылка на документ'/></par></tablecell>
<tablecell>|& createHotSpot("Перейти" , Script) &|</tablecell>
<tablecell><par>|& i &|</par></tablecell>
</tablerow>


If i > 254 Then
newTable = |
<table rightmargin="30%">
<border style="solid" Width="0px" color="black" />
<tablecolumn Width="50%"/><tablecolumn /><tablecolumn Width="32%"/>
<tablerow>
<tablecell bgcolor="#C0C0C0"><par>Ссылка на документ</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Переход в представление по документу</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Столбци поиска</par></tablecell>
</tablerow>|& newtablerow &|</table> |
End If

Set firstDoc=tempDoc
i = i + 1
Wend
но я ума не приложу как сделать что бы в новой таблице следующие доки пошли после 254 - го
 

savl

Lotus Team
28.10.2011
2 625
314
BIT
545
Самое простое так:
Код:
i=0
Set Doc = dc.GetFirstDocument()
' Открывает тег первой таблицы
While Not Doc is Nothing
' Заполняем таблицу данными из документа
i=i+1
if (i mod 254) > 0 then
' Закрываем тег таблицы
' Открываем тег таблицы
End if
Set Doc = dc.GetNExtDocument(Doc)
Wend
' Закрываем тег таблицы
 
S

StarikStarik2705

Готово))
с учётом если документов нашли больше 254
вот код
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"CODE"</div></div><div class="sp-body"><div class="sp-content">
Код:
%REM
Class createTable
Description: Comments for Class
%END REM
Class TableDXL	
Private s As NotesSession
Private db As NotesDatabase
Private doc As NotesDocument	

Sub New(doc_ As NotesDocument)
On Error GoTo errorProc

Set Me.s=New NotesSession()
Set Me.db=Me.s.Currentdatabase
Set Me.doc=doc_			
endofsub:
Exit Sub
errorproc:
MsgBox "Error #" & Err & " on line " & Erl 
Resume endofsub	
End Sub

Function createHotSpot (nameHotSpot As String, ScriptCode As String) As String
Dim hotSpot As String
hotspot = |
<par>
<run><font style='underline' color='blue'/></run>
<actionhotspot hotspotstyle='none'><run><font style='underline' color='blue'/>|& nameHotSpot &|
</run>
<code event='click'>
<lotusscript>
Sub Click(Source As Button)
| & ScriptCode & | 
end sub
</lotusscript>
</code>
</actionhotspot>	
</par>
|
createHotSpot = hotspot
End Function

Function appendTable(docCol As NotesDocumentCollection, sType As String, rt As NotesRichTextItem) As NotesDocument
On Error GoTo ErrorHandler
Dim tmpNoteID As String
Dim newdoc As NotesDocument
Dim stream As NotesStream
Dim dmp As NotesDXLImporter

Dim i As Long 
i = 1
Dim firstDoc As NotesDocument
Dim tempDoc As NotesDocument
Dim Script As String
Dim mainDoc As NotesDocument
Dim newTableRow As String
Dim SearchDB As String
Dim SearchDBView As String
Dim dbS As NotesDatabase
Dim ResArr() As String
ReDim resArr(0)

Select Case docCol.Parent.Filename
Case "etc_tbs.nsf":				
SearchDB = "OSV"
Set dbS = GetCurrentDb (SearchDB, "")					
Case "etccontent.nsf":
SearchDB = "contentmanager"
Set dbS = GetCurrentDb (SearchDB, "")
Case "var.nsf":
SearchDB = "VAR"
Set dbS = GetCurrentDb (SearchDB, "")
Case "etcdocflow.nsf"
SearchDB = "etcdocflow"
Set dbS = GetCurrentDb (SearchDB, "")				
End Select	

newTable = |		
<table rightmargin="30%"> 
<border style="solid" Width="0px" color="black" /> 	
<tablecolumn Width="50%"/><tablecolumn /><tablecolumn Width="32%"/>
<tablerow> 		
<tablecell bgcolor="#C0C0C0"><par>Ссылка на документ</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Переход в представление по документу</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Столбци поиска</par></tablecell>
</tablerow>|

Set firstDoc=docCol.GetFirstDocument
While Not (firstDoc Is Nothing)
Set tempDoc = docCol.GetNextDocument(firstdoc)	
If resArr(0) = "" Then
resArr(0) = firstDoc.UniversalID
Else
ReDim Preserve resArr(UBound(ResArr) + 1)
resArr(UBound(ResArr)) = firstDoc.UniversalID
End If		
Select Case sType
Case "Requirement","CardPD":
Set mainDoc = GetMainDoc(firstDoc)
If Not mainDoc Is Nothing then
If GetMainDoc(firstDoc).Getitemvalue("Form")( 0 ) = "Requirement" Then
SearchDBView = "RequirementByBusinessUnit"	
Else
SearchDBView = "TaxPacketByBusinessUnit"
End If			
End If 	

Case "TaxPackage":		
SearchDBView = "TaxPacketByBusinessUnit"	

Case "NAR","PD","Dog":				
SearchDBView = "NAR"	

Case "In":
SearchDBView = "InByStatusNew"
Case "Out":		
SearchDBView = "OutByStatus"
Case "Task":
SearchDBView = "TaskWithChangedExecutor"
Case "DocFlowNAR":
SearchDBView = "NARALL"
Case "TaxPack":
SearchDBView = "TaxPackByStatus"
Case "OSV":
SearchDBView = "OSVStatus"			
End Select			
Script = |
on error goto 	ErrorHandler
unid = "| & Trim(firstDoc.Universalid) & |"		
Dim db As NotesDatabase	
Dim view As NotesView	
Dim mDoc As NotesDocument
Set db = GetCurrentDb ("|& SearchDB &|", "")	
Set mDoc = db.getDocumentByUnid(unid)
Set view = db.GetView("|& SearchDBView &|")
If Not view Is Nothing Then
If Not mDoc Is Nothing Then
Call wsGL.Opendatabase(db.Server, db.FilePath, view.Aliases(0))
Call wsGL.Currentview.Selectdocument(mDoc)	
End If
End If
endsub:
Exit sub
ErrorHandler:	
MsgBox {ошибка на.. >> Error } + Error + { on } + Erl
Resume endsub
|			


If i >254 Then
i = 1
tableRow = tableRow & |</table>
<table rightmargin="30%"> 
<border style="solid" width="0px" color="black" /> 	
<tablecolumn width="50%"/><tablecolumn /><tablecolumn width="32%"/>
<tablerow> 		
<tablecell bgcolor="#C0C0C0"><par>Ссылка на документ</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Переход в представление по документу</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Столбци поиска</par></tablecell>
</tablerow>	|
Else
tableRow = tableRow	& Chr(10)& |
<tablerow> 		
<tablecell><pardef id = "|& i &|" align="center" /><par><doclink document='|& CStr(Trim(firstDoc.Universalid)) &|' database='|& CStr(Trim(dbS.replicaID)) &|' description='Ссылка на документ'/></par></tablecell>
<tablecell>|& createHotSpot("Перейти" , Script) &|</tablecell>
<tablecell><par>|& UBound(resArr)+ 1 &|</par></tablecell>
</tablerow>|
End If 
Set firstDoc=tempDoc	
i = i + 1		
Wend
Set stream = s.CreateStream
stream.WriteText |<?xml version='1.0' encoding='utf-8' ?>
<database xmlns='http://www.lotus.com/dxl' version='8.5.3'> 
<document form='Form'> 
<item name='Subject'><text>DXL table</text></item>
<item name='Body'>
<richtext>
<table rightmargin="30%"> 
<border style="solid" width="0px" color="black" /> 	
<tablecolumn width="50%"/><tablecolumn /><tablecolumn width="32%"/>
<tablerow> 		
<tablecell bgcolor="#C0C0C0"><par>Ссылка на документ</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Переход в представление по документу</par></tablecell>
<tablecell bgcolor="#C0C0C0"><par>Столбци поиска</par></tablecell>
</tablerow>	| & tableRow & |							
</table>
</richtext>
</item>
</document>
</database>	|	
' Import new document with button into current database
Set dmp = s.CreateDXLImporter(stream, me.db)
dmp.DocumentImportOption = DXLIMPORTOPTION_CREATE
dmp.Process

' Get the NoteID of the newly created document
tmpNoteID = dmp.GetFirstImportedNoteID()

' Get the document by the NoteID and return it
Set newdoc = me.db.GetDocumentByID(tmpNoteID)


Call docgl.Replaceitemvalue("Count",UBound(resArr)+ 1)	
Call docGL.ReplaceItemValue("ResultUNIDList", resArr)
Call rt.AppendRTItem(newdoc.GetFirstItem("Body"))
Set appendTable = newdoc		
endsub:
Exit Function
ErrorHandler:	
MsgBox "appendTable ошибка на.. >> Error " & Error & " on " & Erl
Resume endsub		
End Function	
End Class
 
S

StarikStarik2705

Самое простое так:
Код:
i=0
Set Doc = dc.GetFirstDocument()
' Открывает тег первой таблицы
While Not Doc is Nothing
' Заполняем таблицу данными из документа
i=i+1
if (i mod 254) > 0 then
' Закрываем тег таблицы
' Открываем тег таблицы
End if
Set Doc = dc.GetNExtDocument(Doc)
Wend
' Закрываем тег таблицы

сейчас над вашим вариантом попробуюу поработать
 

savl

Lotus Team
28.10.2011
2 625
314
BIT
545
Дык, в вашем коде он есть. Вы там i=1 делаете.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Чтобы в цикле не садить скорость на
if (i mod 254) > 0 then
лучше внешний цикл сделать ~ до dc.count / 254, а внутренний от 1 до 254.
Ну или что-то типа того.

CтарыйStarik
Лучше код писать не такой простынёй, а выделять специальные части и реализовывать их отдельно.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
циклы...
вход в подчиненные ноды - рекурсия, при выходе - закрываем тег
 
S

StarikStarik2705

у меня родился вопрос, в строковую переменную XML не безконечно же влезет. У меня 1800 документов, а можно эти строки ложить в рич поле, а потом передать их Стриму? потому что строку точно переполнить обычного типа Стринк. а вот в рич поле помойму до двух гигов влазит. Реально ли это сделать?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
непонятно - чего класть-то резалт?!
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
циклы...
вход в подчиненные ноды - рекурсия, при выходе - закрываем тег
Рекурсия требовательна к памяти, на больших объёмах данных отпадает. Здесь лучше 2 вложенных цикла, тем более что нет никаких предпосылок, что "Лотус" в скором времени станет поддерживать не 254, а больше.

Перед внутренним циклов открываем тэг, после внутреннего цикла - закрываем.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
Рекурсия требовательна к памяти, на больших объёмах данных отпадает. Здесь лучше 2 вложенных цикла, тем более что нет никаких предпосылок, что "Лотус" в скором времени станет поддерживать не 254, а больше.

Перед внутренним циклов открываем тэг, после внутреннего цикла - закрываем.
"накладность" по памяти определяется глубиной вложенности...
как глубоко будет вложена нода в ДХЛ ? ;)
а вот читабельность - важна
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Мы наверное о чём-то о разном.
Есть задача: over1000 строк данных, которые надо вставить в ричтекст в виде строк таблицы, т.е. разбить на таблицы с определённым количеством строк. Причём тут "подчинённые ноды" и рекурсия?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
ключевое слово - ДХЛ, через кот. и создается таблица
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
доп. поясню свое высказывание...
предполагается что будет шаблон/ы для ДХЛ (в т.ч. костяк таблицы, с тегами подстановки)
получаем ДОМ (если шаблон не слишком велик), здесь и будет рекурсия по нодам (с выводом в стрим)
встречая строки таблицы - инициируем цикл (да - тут цикл д.б.), теги для подстановки - обращаемся к "тек." доку
 

ToxaRat

Чёрный маг
Green Team
06.11.2007
3 332
42
BIT
0
доп. поясню свое высказывание...
предполагается что будет шаблон/ы для ДХЛ (в т.ч. костяк таблицы, с тегами подстановки)
получаем ДОМ (если шаблон не слишком велик), здесь и будет рекурсия по нодам (с выводом в стрим)
встречая строки таблицы - инициируем цикл (да - тут цикл д.б.), теги для подстановки - обращаемся к "тек." доку
если уж с тегами то лучше сделать проще

1) есть документ-шаблон с РТ

2) делаем эекспорт DXML в один стринг

3) меняем в стринге теги на значения

4) импортим и новый док

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

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
ToxaRat самая "затратная" - изменяемая часть
стринг надо парсить, ДОМ и есть парсер, кот. на малом объеме удобен и достаточно эффективен
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
былаж ссылка по VTD...

сотни килобайт (для единоразового) - вполне себе ;)
 
Мы в соцсетях:

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