#cs Purpose: To analyze daily summary log generated by modem service program, generate daily summary word doc., then send out summary report to owners in Notes mail. Plus, do house keeping to move source log files to log archive path and able to send multiple receipents. Platform: Windows 7/64, AutoIT v3.3.14.5, Lotus Notes 8.5 Operation: to be executed at a given time set in cron job once a day, then generate a daily Word summary report and send it out via Notes mail Output: Home path = C:\Users\00070020\Desktop\3G_detection_automation Source path = C:\Users\00070020\Desktop\3G_detection_automation\Log\log_file.2021.06.01.txt & summary_log.2021.06.01.txt Output path = C:\Users\00070020\Desktop\3G_detection_automation\Summary\Daily summary 2021.06.09.docx Log Archive path = C:\Users\00070020\Desktop\3G_detection_automation\Archive\Log Date: 14/06/2021 Key Vairables: $dirnameHome - working directory for log and summary files $template - Word template for daily summary report $arrayLogFile - log files for raw and summary logs of 3G modem service program $nSummary - number of lines of key results in summary log file $offset - where "{Summary_Result_Begin}" located, up from bottom of file $arrayKeyWord - keyWord defined in Word template < key information of summary result in log file, all the resst derived from them > {Summary_Result_Begin} date_time = 03/15/2021, 15:16:34 c_failure = 1 c_2nd = 3 c_1st = 201 {Summary_Result_End} Date: 21/06/2021 v.2 1. change $docTitle = "Daily summary template v1 - Microsoft Word" to "Daily summary template v1" to make it able to match window on Word2010 and Word2016 2. in WordInsertObject() to add more WinActivate() before logs attachment to ensure no interruption by other messages or unexpected things, always focus on Word window to ensure hot-key works #ce #include ; necessary for _NowDate #include ; necessary for Word document manipulation #include ; necessary for array usage #include ; necessary for file handling #include ; necessary for MsgBox() #include ; necessary for _ClipBoard functions Const $tPause = 300 ; mili-seconds, for delay between operations. DO NOT shorter than this Const $tMsgShow = 3 ; seconds, for appearance duration of message box Const $aCurrsorPark[2] = [35,35] ; location at top-left area ; date variables for reports -> report to be generated based on logs in previous day ; Julian date of today Global $s_JulianDate = _DateToDayValue(@YEAR, @MON, @MDAY) ; yesterday in YYYY, MM, DD format Global $sYearAgo, $sMonthAgo, $sDateAgo Global $s_GeorgianDate = _DayValueToDate($s_JulianDate -1 , $sYearAgo, $sMonthAgo, $sDateAgo) ; last day in a given month and year --> used by monthly update only ??? => No used here ; Const $tLastDay = _DateDaysInMonth (Number($sYearAgo), Number($sMonthAgo)) Const $sReportDate = $sYearAgo & "." & $sMonthAgo & "." & $sDateAgo ; working directory Const $dirnameHome = "C:\Users\00070020\Desktop\3G_detection_automation\" Const $logDir = "Log\" Const $summaryDir = "Summary\" Const $archiveDir = "Archive\" ; Word summary template and output files Const $template = "\Source\Daily summary template v1.docx" ;Const $docTitle = "Daily summary template v1 - Microsoft Word" Const $docTitle = "Daily summary template v1" Const $srcFile = $dirnameHome & $template Const $offset = 10 ; where "{Summary_Result_Begin}" located, up from bottom of file Const $nKeyWord = 11 ; number of keywords in Word template Const $arrayKeyWord[$nKeyWord] = ["{r_date}", "{result}", "{t_count}", "{t_success}", "{t_failure}", "{t_2nd}", "{t_1st}", "{ratio_success}", "{ratio_failure}" , "{ratio_2nd}", "{ratio_1st}"] ; raw and summary log files Const $nSummary = 4 ; number of key results in summary log file Const $nLogFile = 2 ; titles and keywords in Word template for attachments Const $arrayLocation[$nLogFile] = ["{raw_logfile}", "{summary_logfile}"] Const $arrayTitle[$nLogFile] = ["[ Daily check raw data log file ]", "[ Daily check summary log file ]"] ; Notes mail ;Const $mailRecipient = "andrew_yang" Const $nReceipent = 3 Const $arrayMailRecipien[$nReceipent] = ["andrew_yang", "andrew_yang", "andrew_yang"] ;Const $mailSubject = "3G daily summary report by RPA UMC [ " & StringReplace(_NowDate(), "/", ".") & " ]" Const $mailSubject = "3G daily summary report by RPA UMC [ " & $sReportDate & " ]" Const $mailBodyText = "attachment of daily summary" ;Const $mailAttachment = $report Const $mailSaveitFlag = False ; leave a copy in send folder or not ;Const $arrayLogFile[$nLogFile] = ["\Log\testing_log_file.txt", "\Log\sample summary log v1.txt"] Const $arrayLogFile[$nLogFile] = ["log_file." & $sReportDate & ".txt", "summary_log." & $sReportDate & ".txt"] ; file name will be something like "Daily summary 2021.04.05.docx" ;Const $report = "\Summary\Daily summary " & StringReplace(_NowDate(), "/", ".") & ".docx" Const $report = "Daily summary " & $sReportDate & ".docx" ;Const $outFile = $dirnameHome & $report => changed below by month before actual usage ; set the path by month of report date ;$summaryDir = $dirnameHome & "Summary\" & MonthNumberToEnglish($sMonthAgo) & "\" ;$outFile = $summaryDir & $report ; file path for daily Word summary doc Const $outFile = $dirnameHome & $summaryDir & $report ;$attachmentSummaryLog = $dirnameHome & $arrayLogFile[1] ; set the path by month of report date ;$logDir = "Log\" & MonthNumberToEnglish($sMonthAgo) & "\" ; file path for daily summary log file Const $attachmentSummaryLog = $dirnameHome & $logDir & $arrayLogFile[1] ; ; Main program ; MouseMove($aCurrsorPark[0],$aCurrsorPark[1]) ; to park cursor in no impact area ; << Start of Part I >> -- read data from summary log file and store them in variables ; change the current working directory, return '0' if failure, return '1' if success $result = FileChangeDir($dirnameHome) If $result = 0 Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to change directory: " & $dirnameHome & " !" & @CR, $tMsgShow) Exit EndIf $nLines = _FileCountLines($attachmentSummaryLog) ; open file in read-only mode, return '-1' if failure, return file handle if success $oLog = FileOpen($attachmentSummaryLog, $FO_READ) Sleep($tPause) If $oLog = -1 Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to open file: " & $attachmentSummaryLog & " !" & @CR, $tMsgShow) Exit EndIf Local $tSummaryResult[$nSummary] $targetLine = $nLines - $offset + 1 ; 1st element of summary result, {r_date} For $i = 1 To $nSummary $sFound = FileReadLine($oLog, $targetLine) ; ConsoleWrite("A => " & $sFound &@CR) ; debug $sFinal = StringSplit( $sFound, "=") ; delimiter '=', store 1st, 2nd in array[1], [2] ; ConsoleWrite("B => " & $sFinal[2] &@CR) ; debug $tSummaryResult[$i-1] = $sFinal[2] ; assign values in array for later usage $targetLine = $targetLine + 1; next line Next ; sequence of 11x keywords: {r_date}, {result} => Good, Warning, Alert, {t_count} ; {t_success}, {t_failure}, {t_2nd}, {t_1st} ; {ratio_success}, {ratio_failure} , {ratio_2nd}, {ratio_1st} Local $tKeyWordValue[$nKeyWord] ; for all keywords in Word template ; data preparation $tKeyWordValue[0] = $tSummaryResult[0] ; variable for {r_date} $tKeyWordValue[4] = $tSummaryResult[1] ; variable for {t_failure} $tKeyWordValue[5] = $tSummaryResult[2] ; variable for {t_2nd} $tKeyWordValue[6] = $tSummaryResult[3] ; variable for {t_1st} ; status judgement if $tKeyWordValue[4] <> 0 Then; variable for {result} => Good, Warning, Alert $tKeyWordValue[1] = "Alert" ElseIf $tKeyWordValue[5] <> 0 Then $tKeyWordValue[1] = "Warning" Else $tKeyWordValue[1] = "Good" EndIf ; variable for {t_count} $tKeyWordValue[2] = $tKeyWordValue[4] + $tKeyWordValue[5] + $tKeyWordValue[6] ; variable for {t_success} $tKeyWordValue[3] = $tKeyWordValue[5] + $tKeyWordValue[6] ; variable for {ratio_success} $tKeyWordValue[7] = Round(100*($tKeyWordValue[3]/$tKeyWordValue[2]),2) ; variable for {ratio_failure} $tKeyWordValue[8] = Round(100*($tKeyWordValue[4]/$tKeyWordValue[2]),2) ; variable for {ratio_2nd} $tKeyWordValue[9] = Round(100*($tKeyWordValue[5]/$tKeyWordValue[2]),2) ; variable for {ratio_1st} $tKeyWordValue[10] = Round(100*($tKeyWordValue[6]/$tKeyWordValue[2]),2) #cs ; debug portion For $i = 1 to $nKeyWord ConsoleWrite($i & "th element is: " & $tKeyWordValue[$i-1] &@CR) Next #ce ; close file, return '0' if failure, return '1' if success $result = FileClose($oLog) If $result = 0 Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to close file: " & $attachmentSummaryLog & " !" & @CR, $tMsgShow) Exit EndIf ; << End of Part I >> ; << Start of Part II >> -- update {xx} keywords in Word template with values storead above ; _Word_xx() functions set @error to non-zero by default, whcih make if @error valid $oWord = _Word_Create() Sleep($tPause*3) If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to create Word!" & @CR, $tMsgShow) Exit EndIf $oDoc = _Word_DocOpen($oWord, $srcFile) ; template report file If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to open file: " & $srcFile & " !" & @CR, $tMsgShow) Exit EndIf Sleep($tPause) WinActivate($docTitle) WinSetState($docTitle, "", @SW_MAXIMIZE) ; maximize Word doc ; debug portion ;MsgBox($MB_SYSTEMMODAL,"Information", "value replacement", $tMsgShow) ; replace all keywords in template file with values For $i = 1 to $nKeyWord $tKeyWord = $arrayKeyWord[$i-1] $tKeyValue = $tKeyWordValue[$i-1] $oRange = _Word_DocFind($oDoc, $tKeyWord) ; locate keyword $oRange.Bold = True ; change properties of keyword $oRange.Select ; mark selected area Sleep($tPause) ; debug portion ;MsgBox($MB_SYSTEMMODAL, "Information", "Key Word: " & $tKeyWord & "; Key Value: " & $tKeyValue & @CR, $tMsgShow) _Word_DocFindReplace($oDoc, $tKeyWord, $tKeyValue) ; replace tKeyWord with new value Sleep($tPause) Next ; attachment insertion, cursor location default at start of matched string For $i = 1 to $nLogFile ;Local $attachment = $dirnameHome & $arrayLogFile[$i-1] $attachment = $dirnameHome & $logDir & $arrayLogFile[$i-1] $oRange = _Word_DocFind($oDoc, $arrayLocation[$i-1]) Sleep($tPause) $oRange.Bold = True $oRange.Select ; mark selected area Sleep($tPause) ConsoleWrite("attachment: " & $attachment & @CR) ;WordInsertObject($arrayTitle[$i-1], $attachment) <= wrong usage, should give doc. title to activate window WordInsertObject($docTitle, $attachment) ; insert attachment Sleep($tPause) WinActivate($docTitle) ; ensure target Word template activated $oRange.InsertBefore($arrayTitle[$i-1] & @CR) ; add title before attachment file ;ConsoleWrite("attachment: " & $attachment & ", DONE!" & @CR) ; debug portion Sleep($tPause) _Word_DocFindReplace($oDoc, $arrayLocation[$i-1], "") ; remove keyword Sleep($tPause) Next ; _Word_xx() functions set @error to non-zero by default, whcih make if @error valid _Word_DocSaveAs($oDoc, $outFile, $WdFormatDocumentDefault) ; save as a new file If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to save file: " & $outFile & " !" & @CR, $tMsgShow) Exit EndIf _Word_DocClose($oDoc) If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to close file: " & $outFile & " !" & @CR, $tMsgShow) Exit EndIf _Word_Quit($oWord) If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Not able to close Word!" & @CR, $tMsgShow) Exit EndIf ; << End of Part II >> ;WordSave($dirnameHome & $template, "{logfile}", $dirnameHome & $summaryLog , "[ Daily check log file ]", $dirnameHome & $report) ; send out mail with attachment $mailAttachment = $outFile ;NotesSendMail($mailRecipient, $mailSubject, $mailBodyText, $mailAttachment, $mailSaveitFlag) For $i = 1 to $nReceipent NotesSendMail($arrayMailRecipien[$i-1], $mailSubject, $mailBodyText, $mailAttachment, $mailSaveitFlag) Next ;MsgBox($MB_SYSTEMMODAL, "Information", "End of Program" & @CR, $tMsgShow) ; debug portion ; housekeeping, move log files from .\Log to .\Archive\Log Local $source_path = $dirnameHome & $logDir Local $target_path = $dirnameHome & $archiveDir & "Log\" Local $source_file = "*." & $sReportDate & ".txt" #Local $cmd = "cmd /C move /Y " & $source_path & $source_file & " " & $target_path Local $cmd = @ComSpec & " /C " & "move /Y " & $source_path & $source_file & " " & $target_path Local $iReturn = RunWait($cmd) ConsoleWrite($cmd & @CR) ConsoleWrite($iReturn & @CR) If $iReturn = 0 Then ConsoleWrite("house keeping DONE!" & @CR) Else ConsoleWrite("housekeeping Failed!" & @CR) EndIf ; ; End of Main program ; ; << Functions >> #cs To paste a long string into required field directly instead of character by character via send(), also can clean buffer in last input at the same time Variables: $t_WORD - String #ce Func ClipSend($t_WORD) _ClipBoard_Empty() _ClipBoard_SetData($t_WORD) Send("^v") ; Ctrl + v Sleep($tPause) EndFunc #cs Remember to 'activate' Word document to make it work !! Only picture and text insertsion functions provided in Word.au3, here is a 'raw' method to implement object insertion function in Word No error handling covered Hot-key to complete object insersion: Alt+N+J+J (object menu) Tab, F (create from file) tab x 1 (filed to input file name) tab x 4 (OK button) Variables: $t_objectPath - String; full-path of to-be-selected object $t_worddocTitle - String; title of source Word doc #ce Func WordInsertObject($t_worddocTitle, $t_objectPath) ; $oRange never changed, so even insert "" afterwards, attachment still at start of keyword Sleep($tPause) MsgBox(0,"Information", "test before ALT. Window to activate: " & @CR & $t_worddocTitle, $tMsgShow) Sleep($tPause) WinActivate($t_worddocTitle) Sleep($tPause) Send("{ALT}NJJ") ;Alt+N+J+J insert object Sleep($tPause*5) ; wait longer for response WinActivate("Object") ; title of object insert dialog Sleep($tPause) Send("{TAB}") ; tab one time to activate menu Sleep($tPause) ;MsgBox(0,"Information", "wait to file tab", $tMsgShow) ; debug portion WinActivate("Object") Send("F") ;F create from file tab Sleep($tPause) Send("{TAB}") ; tab one time to enter file name Sleep($tPause*5) ; wait longer for response before paste info WinActivate("Object") ; activate target before action, or clip_send() fails 1st time ;Send($t_objectPath) ; one character by one character, replaiced by ClipSend() ClipSend($t_objectPath) Sleep($tPause) ;MsgBox(0,"Information", "wait to OK", $tMsgShow) ; debug portion WinActivate("Object") Send("{TAB 4}") ; tab 4 times to OK button Sleep($tPause) Send("{ENTER}") ; press enter Sleep($tPause) ;MsgBox(0,"Information", "All windows closed", $tMsgShow) ; debug portion EndFunc #cs Author: 8AB/PIS/Apo Test Windows 7 / 64, AutoIT 3.3.14, Lotus Notes 8.5 Variablen: $recipient - String $subject - String $bodytext - String $attachment - String $saveit - Boolean #ce Func NotesSendMail($recipient, $subject, $bodytext, $attachment, $saveit) $Session = ObjCreate("Notes.NotesSession") $UserName = $Session.UserName $Maildb = $Session.GETDATABASE("", "") $Maildb.OPENMAIL() $MailDoc = $Maildb.CREATEDOCUMENT $MailDoc.Form = "Memo" $MailDoc.From = $UserName $MailDoc.sendto = $recipient $MailDoc.Subject = $subject $MailDoc.SAVEMESSAGEONSEND = $saveit $MailDoc.PostedDate = _Now() $body = $MailDoc.createRichTextItem("Body") With $body .appendText($bodytext) .addNewLine(2) EndWith If $attachment <> "" Then If FileExists($dirnameHome & "\" & $attachment) Then $filename = $attachment $fullpath = $dirnameHome & "\" & $attachment ElseIf FileExists($attachment) Then $pos = StringInStr($attachment,"\",0,-1) $filename = StringTrimLeft($attachment,$pos) $fullpath = $attachment Else Return SetError(1, 1, "attachment not found") Exit EndIf $AttachME = $MailDoc.CREATERICHTEXTITEM($filename) $EmbedObj = $AttachME.EMBEDOBJECT(1454, "", $fullpath, $filename) EndIf $MailDoc.SEND(0, $recipient) $EmbedObj = "NULL" $MailDoc = "NULL" $Maildb = "NULL" $Session = "NULL" EndFunc #cs To convert month from number to English Variables: $t_NoMonth - Int $t_EngMonth - String #ce #cs Func MonthNumberToEnglish($t_NoMonth) Local $aMonth[12] $aMonth[0] = "January" $aMonth[1] = "February" $aMonth[2] = "March" $aMonth[3] = "April" $aMonth[4] = "May" $aMonth[5] = "June" $aMonth[6] = "July" $aMonth[7] = "August" $aMonth[8] = "September" $aMonth[9] = "October" $aMonth[10] = "November" $aMonth[11] = "December" Local $t_EngMonth = $aMonth[$t_NoMonth - 1] return $t_EngMonth EndFunc #ce