Кто-нибудь может оставить отзыв о моем агенте LotusScript?
-
22-07-2019 - |
Вопрос
Привет, я не разработчик и поэтому не знаком с лучшими практиками.Я создал это, чтобы обойти ручное копирование данных журнала.Этот агент предназначен для одного канала, который я буду копировать и корректировать для каждого дополнительного.Для указанного канала он считывает журнал за последнее время обработки и количество файлов, обработанных на сегодняшний день и за вчерашний день.Он также подсчитывает файлы во входной папке и считывает часовой пояс сервера.Каждый элемент данных в формате csv разделяется запятой и отправляется по электронной почте, которая позже размещается на веб-сайте.Спасибо за любую конструктивную критику.
Sub Initialize
Dim customername As String
Dim servername As String
Dim feedname As String
Dim alertthresholdinhours As Integer
Dim inputfeedpath As String
' Set for each feed
customername = "gRrhio"
servername = "gRrhioEdge2"
feedname = "FF Thompson ADT"
alertthresholdinhours = 6
inputfeedpath = "\\mhinec\elycon\data\adt\*.*"
' Counts files in input folder
Dim pathName As String, fileName As String
Dim inputfeedcounter As Integer
inputfeedcounter = 0
pathName$ = inputfeedpath
fileName$ = Dir$(pathName$, 0)
Do While fileName$ <> ""
inputfeedcounter = inputfeedcounter + 1
fileName$ = Dir$()
Loop
Dim entry As NotesViewEntry
Dim vc As NotesViewEntryCollection
Dim filesprocessed As Integer
Dim session As New NotesSession
Dim db As NotesDatabase
Dim newDoc As NotesDocument
Dim rtitem As NotesRichTextItem
Set db = session.CurrentDatabase
Dim view As NotesView
Set view = db.GetView( "Sessions\by Feed" )
Set newDoc = New NotesDocument( db )
Set rtitem = New NotesRichTextItem( newDoc, "Body" )
Dim todaysdate As New NotesDateTime("Today")
Dim flag As Integer
Dim counter As Integer
Dim files As Integer
Dim errors As Integer
Dim lastdate As String
Dim lastdayran As String
Dim lasttime As String
Dim lasttimeran As String
Dim filesp As Integer
Dim lastdayfiles As Integer
Dim lastdaysfiles2 As Integer
Dim terrors As Integer
Dim lastdayerrors As Integer
lastdate = ""
lastdayran = ""
counter = 0
flag = 0
filesp = 0
lastdayfiles = 0
lastdaysfiles2 = 0
terrors = 0
lastdayerrors = 0
' Finds date for last time processed, counts files processed and errors
While flag = 0
Dim dateTime As New NotesDateTime(todaysdate.DateOnly)
Dim keyarray(1) As Variant
keyarray(0) = feedname
Set keyarray(1) = dateTime
Set vc = view.GetAllEntriesByKey(keyarray, False)
Set entry = vc.GetFirstEntry
If entry Is Nothing Then
Call todaysdate.AdjustDay(-1)
End If
While Not entry Is Nothing
files = 0
Forall colval In entry.ColumnValues
If counter = 9 Then
counter = 0
Elseif counter = 8 Then
counter = 9
Elseif counter = 7 Then
counter = 8
Elseif counter = 6 Then
errors = Cint(colval)
counter = 7
Elseif counter = 5 Then
counter = 6
Elseif counter = 4 Then
files = Cint(colval)
counter = 5
Elseif counter = 3 Then
counter = 4
Elseif counter = 2 Then
counter = 3
lasttime = colval
Elseif counter = 1 Then
counter = 2
lastdate = colval
Elseif counter = 0 Then
counter = 1
End If
End Forall
filesp = filesp + files
terrors = terrors + errors
Set entry=vc.GetNextEntry (entry)
flag = 1
Wend
Wend
lastdayfiles = filesp
lastdayerrors = terrors
lastdayran = lastdate
lasttimeran = lasttime
'Counts previous files processed
filesp = 0
terrors = 0
lastdate = ""
flag = 0
Call todaysdate.AdjustDay(-1)
While flag = 0
Dim dateTime2 As New NotesDateTime(todaysdate.DateOnly)
Dim keyarray2(1) As Variant
keyarray2(0) = feedname
Set keyarray2(1) = dateTime2
Set vc = view.GetAllEntriesByKey(keyarray2, False)
Set entry = vc.GetFirstEntry
If entry Is Nothing Then
Call todaysdate.AdjustDay(-1)
End If
While Not entry Is Nothing
files = 0
Forall colval In entry.ColumnValues
If counter = 9 Then
counter = 0
Elseif counter = 8 Then
counter = 9
Elseif counter = 7 Then
counter = 8
Elseif counter = 6 Then
counter = 7
Elseif counter = 5 Then
counter = 6
Elseif counter = 4 Then
files = Cint(colval)
counter = 5
Elseif counter = 3 Then
counter = 4
Elseif counter = 2 Then
counter = 3
Elseif counter = 1 Then
counter = 2
Elseif counter = 0 Then
counter = 1
End If
End Forall
filesp = filesp + files
Set entry=vc.GetNextEntry (entry)
flag = 1
Wend
Wend
lastdaysfiles2 = filesp
' Prints line of CSV into body of email
Call rtitem.AppendText ( customername )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( servername )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( datetime.timezone )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( lastdayran )
Call rtitem.AppendText ( " " )
Call rtitem.AppendText ( lasttimeran )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( lastdayfiles )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( lastdayerrors )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( lastdaysfiles2 )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( inputfeedcounter )
Call rtitem.AppendText ( ", " )
Call rtitem.AppendText ( alertthresholdinhours )
Call newDoc.Save( False, True )
newDoc.Subject = feedname
' Running from server line should be
'newDoc.SendTo = "Ecmon Feedcheck/Ecmonitor@ECMONITOR"
newDoc.SendTo = "AX1Forward Feedcheck/ACHQ@company.com"
newDoc.Send( False )
End Sub
Решение
За то, что вы не разработчик, вы можете написать много кода :)
Если вы ищете несколько уроков, чтобы начать становиться хорошим разработчиком, то воспользуйтесь советом Митча (из комментариев) и разбейте это на подпрограммы.Урок 1:Здесь определенно есть какой-то повторяющийся код, и всегда полезно поместить повторяющийся код в метод (функцию или подпрограмму), чтобы он существовал только один раз.Раздел, который подсчитывает обработанные файлы и предыдущие обработанные файлы, выглядит аналогично и, вероятно, может быть включен в процедуру, подобную:
Function GetCountFilesProcessed() As Integer
'code here
End Function
Однако, возможно, вам даже удастся избежать необходимости в этом, если я правильно понимаю ваш код.Вместо того, чтобы выполнять этот странный цикл в середине, похоже, вы пытаетесь просто получить значение из столбца viewentry.Допустим, вас заинтересовало значение столбца 4.Вы можете просто получить значение для нужного вам столбца, обратившись к нему по индексу.Например, ваша переменная files может быть установлена непосредственно в значение столбца 4 с помощью этой строки
files = Cint(entry.ColumnValues(4)) 'check this, it might be 3 if the array is zero based.
В любом случае, суть в том, что если этот код работает, то у вас хорошее начало!
Другие советы
Что касается стилевой стороны вещей, то я всегда считал, что поддерживать код других людей проще, когда у них есть
- Объявленный
Option 'Explicit'
в разделе "Декларации" - Объявленные переменные примерно от более высоких до более низких (например, сеанс перед db перед view перед doc)
- Добавленные к объектам notes префиксы с указанием их типа (docMail, dbMyDatabase, viewOutstandingInvoices)
- Поместите все объявления вверху перед (помогает найти объявление, когда вы сталкиваетесь с переменной)
- Как упоминали другие, разбейте его на функции / подразделы, где это применимо.
Ваш комментарий о копировании этого агента для других случаев той же проблемы также поднимает флаг.Попытайтесь выяснить, что общего между этими агентами, и перенесите эти функции в библиотеку сценариев.Такого рода вещи экономят много времени при поддержании кода, поскольку вам не нужно думать о том, чем отличается каждый агент (например.применяется ли мое изменение ко всем экземплярам этого агента или только к некоторым из них?)
Вы хотите разложить свой код намного больше и ... одну маленькую вещь. Вместо
while not item is nothing
что является двойным отрицанием и популярным извращением мозга .. напишите:
do until item is nothing
...
loop
Это также позволяет вам выйти из цикла с выходом do
вы можете оптимизировать оба ваших цикла ForAll. Вот как будет выглядеть первый:
Forall colval In entry.ColumnValues
Select Case (counter)
Case 1: lastdate = colval
Case 2: lasttime = colval
Case 4: files = Cint(colval)
Case 6: errors = Cint(colval)
End Select
counter = (counter + 1) Mod 10
End Forall
Вот так будет выглядеть второй:
Forall colval In entry.ColumnValues
if (counter = 4) Then files = Cint(colval)
counter = (counter + 1) Mod 10
End Forall
Просто замечание относительно этого фрагмента
While Not entry Is Nothing
files = 0
Forall colval In entry.ColumnValues
If counter = 9 Then
counter = 0
Elseif counter = 8 Then
counter = 9
....
Как говорит Кен, вы можете получить значения столбцов, используя метод entry.Значения столбцов (x), поэтому взаимодействие по значениям не требуется.Но;ты мог бы это сделать
While Not entry Is Nothing
files = 0
counter = 0
Forall colval In entry.ColumnValues
counter = counter + 1
Select case counter
case 6
errors = Cint(colval)
.....
end select
Некоторые хорошие моменты уже. Чтобы добавить к ним переменные, которые имеют общий объект, создайте класс. Добавьте ваши переменные в этот класс. Р>
Так что вместо того, чтобы сказать:
Dim userFullName as String
Dim age as Integer
Dim addressLine1 as String
' ... etc.
Вы можете иметь:
Class UserDetails
Dim fullName as String
Dim age as Integer
Dim addressLine1 as String
' ... etc
End Class
и ссылка:
Dim u as new UserDetails
u.fullName = "full name"
u.age = 22
u.addressLine1 = "1 main street"
Преимущество этого в том, что вы можете добавлять методы для манипулирования этими данными, и вы знаете, что код относится к этому объекту, а не просматривает ваше приложение. Р>