Export To Excel (v.2)
И снова возвращаемся к построению отчетов в Excel из Lotus‘а.
Задача сводится к тому, чтобы в отчете были отображены выделенные документы из представления, или все документы из представления.
Также убрал наличие файла-пустышки, куда будут формироваться данные, и путь к которому мы жестко задаем в коде.
Также, к этому отчету можно присовокупить другие документы из других баз, если они связаны по ключевым позициям. Но это в том случае, если того требует ваша задача и логика баз-приложений в Лотусе построена должным образом.
Исходные данные: в базе есть представление с документами. Из этого представления необходимо выполнить экспорт данных выделенных документов в Excel. Экспортом у нас будет заниматься программный агент, которого мы и будем описывать в этой статье. Если документы не выделены, то при вызове агента в Excel будут передаваться данные по ВСЕМ документам нашего представления.
В свойствах программного агента в группе Runtime указываем триггер запуска «Trigger: On Event». Событие у нас «Action Menu Selection», агент применим ко всем выделенным документам (Target: All selected documents).
>>Листинг программного агента Export To Excel<<
>>Listing of Lotus Notes agent for Export to MS Excel documents from Lotus<<
Давайте попробуем разобрать этот код.
Листинг программного агента.
Комментарии - по коду движения пьесы 🙂
комментарии к разбору кода
%REM
Agent Экспорт в Excel
Created Apr 20, 2016 by Maksym Gluschenko/DOMAINLOTUSNOTES
Description: Comments for Agent
%END REM
Option Public
Option Declare
Объявление глобальных переменных и констант в программном агенте.
Dim nc As Long
Dim nmore As Long
Dim i As Long
Dim x As Long
Dim nchar As String
Dim remarks As String
' Excel
Dim xlApp As Variant
Dim xlWorkSheet As Variant
Const DEBAG = False
Const SendToAddr = {<e-mail_addreses@lst&rt;}
Инициализация агента.
Sub Initialize
Dim ses As New NotesSession
Так как мы работаем с выделенными документами текущего представления, то небоходимо определить классы NotesUIWorkspace и NotesUIView.
Dim UIws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim UiView As NotesUIView
Dim currentView As NotesView
Dim viewName
Dim viewAlias
Dim coll As NotesDocumentCollection
Dim countSelectedDocs As Long
Dim gowithselection As Integer
Dim goonall As Integer
Dim doc As NotesDocument
Dim countall As Long
Dim ViewEntryColl As NotesViewEntryCollection
Dim ViewEntry As NotesViewEntry
On Error GoTo Handler
remarks = ""
i = 0
Set db = ses.Currentdatabase
Set UiView = UIws.CurrentView
viewName = UiView.ViewName
viewAlias = UiView.ViewAlias
Set currentView = db.getView(viewAlias)
Set coll = db.UnprocessedDocuments
countSelectedDocs = coll.Count
Определяем, будет ли агент обрабатывать только выделенные документы представления, или все документы из текущего представления.
gowithselection = 0
goonall = 0
If countSelectedDocs >1 Then
gowithselection = UIws.Prompt(PROMPT_YESNO, "Есть выбранные документы!", "Экспортировать только выбранные документы?")
Set doc=coll.getfirstdocument
'Check if there is really a doc selected
If (doc Is Nothing) And (gowithselection=1) Then
MsgBox "Выбраны некорректные документы"
Exit Sub
End If
Set doc = Nothing
Else
goonall = UIws.Prompt(PROMPT_YESNO, "Выбранных документов нет!", "Экспортировать все документы в представлении?" _
+ Chr$(13) + "Подсказка:" _
+ Chr$(13) + "Для экспорта только выбранных документов," _
+ Chr$(13) + "сделайте отметки перед экспортом.")
If goonall=0 Then
Print "Выход ..."
Exit Sub
End If
Set coll = Nothing
End If
Работает с Excel объектом.
' Создаем Excel объект
Set xlApp = CreateObject("Excel.Application")
If xlApp Is Nothing Then
MsgBox "Не удалось создать открыть приложение Excel"
GoTo ex
End If
xlApp.Visible = True ' Приложение Excel запустится сразу
Call xlApp.Workbooks.Add
Set xlWorkSheet = xlApp.ActiveSheet
' Формируем 1-ю строчку с шапкой
'Add the table labels
Глобальные переменные nc и nmore. Определяются их начальные значения перед использованием в ф-ции countcol(nchar), которая формирует горизонтальный порядок столбцов.
nc=64
nmore=0
nchar - переменная с порядковым номером столбца в документе MS Excel.
nchar = 0
Значение переменной nchar (столбец) определяется в функции countcol(nchar). Порядок горизонтальной нумерации в MS Excel буквенный, т.е. идут буквы латинского алфавита: A, B, C, D,...... После достижения 26-ой позиции, нумерация продолжается добавлением второго регистра "числа" ...Y, Z, AA, AB, AC,..... - и так до 3-го регистра - 26^2 (26 во 2-ой степени) позиций. Затем добавляется 3-ий регистр буквенного числа ...ZX, ZY, ZZ, AAA, AAB,...., и т.д.
Формируем шапку нашего документа. Количество столбцов в шапке (если она предусмотрена ТЗ) должно соответствовать количеству столбцов в экспортируемых данных.
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "№" ' 1 - Value 01
'xlWorkSheet.Range("A1").Value = "№" ' 1
' Документ сотрудника
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 02" ' 2
'xlWorkSheet.Range("B1").Value = "Value 02" ' 2
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 03" ' 3
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 04" ' 4
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 05" ' 5
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 06" ' 6
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 07" ' 7
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 08" ' 8
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 09" ' 9
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + "1").Value = "Value 10" ' 10
If gowithselection = 1 Then
countall = countSelectedDocs
Else
countall = currentView.AllEntries.Count
End If
В зависимости от типа выбора документов для экспорта (только выделенные или все документы из представления), в цикле перебора документов запускаем процедуру ExportDoc(doc), которая наполняет наш MS Excel документ согласно предусмотренной в процедуре логикой.
If countSelectedDocs > 1 AND gowithselection = 1 Then
' Работаем с коллекцией выделенных документов
Set doc = coll.getFirstDocument
While Not (doc Is Nothing)
Call ExportDoc(doc)
Set doc = coll.getNextDocument(doc)
Wend
Else
' Работаем со всеми документами представления
' (!!!) Все документы представления обрабатываются, если при выборанных документах
' выполнить отказ от выполнения только выбранных - тогда будут обработаны
' ВСЕ документы.
Set ViewEntryColl = currentView.Allentries
Set ViewEntry = ViewEntryColl.Getfirstentry()
While Not (ViewEntry Is Nothing)
Set doc = ViewEntry.Document
Call ExportDoc(doc)
Set ViewEntry = ViewEntryColl.GetnextEntry(ViewEntry)
Wend
End If
remarks = {Обработано документов: } & Chr(014) & i & { шт.}
MsgBox {Обработано документов: } & i & { шт.}
GoTo ex
Handler:
Print "Ошибка в строке " + CStr(Erl) + " : " + CStr(Error)
xlApp.DisplayAlerts = False
xlApp.Quit
GoTo ex
ex:
If Not remarks = "" Then
If DEBAG Then
' Отправляем ошибку на почту если DEBAG = True,
Dim maildoc As NotesDocument
Set maildoc = New NotesDocument(db)
Dim rtItem As NotesRichTextItem
maildoc.Form="Memo"
maildoc.SendTo = SendToAddr
maildoc.Subject = " - remark"
Set rtItem = maildoc.Createrichtextitem({Body})
Call rtItem.Appendtext(" ")
Call rtItem.Addnewline(1)
Call rtItem.Appendtext("export.excel.full - remark")
Call rtItem.Addnewline(2)
Call rtItem.Appendtext(remarks)
Call maildoc.ConvertToMIME(CONVERT_RT_TO_HTML)
Call maildoc.Send( False )
End If
End If
Exit Sub
End Sub
Функция countcol(nchar), которая выполняет горизонтальную нумерацию столбцов в документе MS Excel.
Function countcol(nchar As String)
nc=nc+1
If nc=91 Then
nmore = nmore+1 'PreChar = Axx (AC23)
nc=65 'reset to A
End If
If nmore > 0 Then
nchar = CStr(Chr(nmore+64))+Cstr(Chr(nc))
Else
nchar = CStr(Chr(nc))
End If
'Print {nchar = } & nchar
countcol = nchar
End Function
Процедура ExportDoc(doc), которая как раз выполняет экспорт данных из полей документа, передаваемого в качестве параметров этой процедуры, в MS Excel.
%REM
Sub ExportDoc
Description: Comments for Sub
%END REM
Sub ExportDoc(doc As NotesDocument)
On Error GoTo Handler
' Заполняем Excel файл
nc=64
nmore=0
nchar = 0
i = i + 1
x = i + 1 ' Строка в Excel файле_
' Потому что i начинается с 0, а 1-я строка в файле_
' уже заполнена шапкой
' 1 - value 01 - № П/п
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = CStr(i)
If Not (doc Is Nothing) Then
' 2 - value 02
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Evaluate({@Text(@Year(@Created)) + "." + @Right(@Text(@Power(10;2) +@Month(@Created));2)},doc)
' 3 - value 03
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Trim(CStr(doc.NAME(0))) ' value 03
' 4 - value 04
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Evaluate({@Text(@Name([CN];@Trim(Remote_User:CurrentUser)))},doc) ' value 04 - LN User name, saved doc (field)
' 5 - value 05
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Evaluate({@Text(@Trim(Remote_Addr:CurrentComputer))},doc) ' From saved doc IP address
' 6 - value 06
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Trim(CStr(doc.DATESAVE(0))) ' value 06
' 7 - value 07
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Trim(CStr(doc.DATEAPP(0))) ' value 08
' 8 - value 08
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Trim(CStr(doc.DTDISM(0))) ' value 08
' 9 - value 09
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Trim(CStr(doc.LOCATIONNAME(0))) ' value 09
' 10 - value 10
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = Evaluate({@Text(@If(_Field_A_="2";@Trim(_Field_B_);""))},doc) ' value 10
' _Field_A_ - <key_field_name>
' _Field_B_ - <a_particular_field_name>
Else
' 2 - value 01
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 3 - value 02
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 4 - value 03
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 5 - value 04
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 6 - value 05
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 7 - value 06
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 8 - value 07
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 9 - value 08
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
' 10 - value 09
nchar = countcol(nchar)
xlWorkSheet.Range(nchar + CStr(x)).Value = "Is NaN"
End If
GoTo ex
Handler:
Print {итерация цикла : } & i
Print "\ExportDoc - Ошибка в строке " + CStr(Erl) + " : " + CStr(Error)
Resume ex
ex:
Exit Sub
End Sub
Если у вас возникли вопросы по данному материалу, требующие дополнительных пояснений, пишите на e-mail: maximke@ukr.net