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

  • Автор темы Автор темы 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

Вот такой скелет у меня в голове получился, но может существует решение и лучше.
 
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 - го
 
Самое простое так:
Код:
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
' Закрываем тег таблицы
 
Готово))
с учётом если документов нашли больше 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
 
Самое простое так:
Код:
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
' Закрываем тег таблицы

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

CтарыйStarik
Лучше код писать не такой простынёй, а выделять специальные части и реализовывать их отдельно.
 
циклы...
вход в подчиненные ноды - рекурсия, при выходе - закрываем тег
 
у меня родился вопрос, в строковую переменную XML не безконечно же влезет. У меня 1800 документов, а можно эти строки ложить в рич поле, а потом передать их Стриму? потому что строку точно переполнить обычного типа Стринк. а вот в рич поле помойму до двух гигов влазит. Реально ли это сделать?
 
непонятно - чего класть-то резалт?!
 
циклы...
вход в подчиненные ноды - рекурсия, при выходе - закрываем тег
Рекурсия требовательна к памяти, на больших объёмах данных отпадает. Здесь лучше 2 вложенных цикла, тем более что нет никаких предпосылок, что "Лотус" в скором времени станет поддерживать не 254, а больше.

Перед внутренним циклов открываем тэг, после внутреннего цикла - закрываем.
 
Рекурсия требовательна к памяти, на больших объёмах данных отпадает. Здесь лучше 2 вложенных цикла, тем более что нет никаких предпосылок, что "Лотус" в скором времени станет поддерживать не 254, а больше.

Перед внутренним циклов открываем тэг, после внутреннего цикла - закрываем.
"накладность" по памяти определяется глубиной вложенности...
как глубоко будет вложена нода в ДХЛ ? ;)
а вот читабельность - важна
 
Мы наверное о чём-то о разном.
Есть задача: over1000 строк данных, которые надо вставить в ричтекст в виде строк таблицы, т.е. разбить на таблицы с определённым количеством строк. Причём тут "подчинённые ноды" и рекурсия?
 
ключевое слово - ДХЛ, через кот. и создается таблица
 
доп. поясню свое высказывание...
предполагается что будет шаблон/ы для ДХЛ (в т.ч. костяк таблицы, с тегами подстановки)
получаем ДОМ (если шаблон не слишком велик), здесь и будет рекурсия по нодам (с выводом в стрим)
встречая строки таблицы - инициируем цикл (да - тут цикл д.б.), теги для подстановки - обращаемся к "тек." доку
 
доп. поясню свое высказывание...
предполагается что будет шаблон/ы для ДХЛ (в т.ч. костяк таблицы, с тегами подстановки)
получаем ДОМ (если шаблон не слишком велик), здесь и будет рекурсия по нодам (с выводом в стрим)
встречая строки таблицы - инициируем цикл (да - тут цикл д.б.), теги для подстановки - обращаемся к "тек." доку
если уж с тегами то лучше сделать проще

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

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

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

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

даже по нодам проходиться не придется, работа будет как с обычным стрингом, ограничения в 2 гига вам с головой хватит для маневров
 
ToxaRat самая "затратная" - изменяемая часть
стринг надо парсить, ДОМ и есть парсер, кот. на малом объеме удобен и достаточно эффективен
 
былаж ссылка по VTD...

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

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