Jump to content
Revelation343

Mailing from Excel/variable storing

Recommended Posts

Revelation343

Purpose of script: To send emails in Outlook based on data in an excel spreadsheet. From: fields are entered for purposes of sending on behalf of (delegate), copies A2 cell from excel for To: field, Subject field is a static value and entered, returns to excel spreadsheet to read A1 and copy the first name and insert into the body of a template at an insertion point. The From, and the body of the email change based on region, so currently I have 6 different scripts that do essentially the same thing with some minor changes and want to consolidate into one script to save time.

Question:
To expedite the process of this and cut down on the amount of scripts, 6 in total I use daily, is it possible for me to somehow add the region to column C in excel, have autoit read column C values per row, and then decide which function, within a master script, to execute and loop this until there is no value in column C field?

Example spreadsheet:

Rob | rob@annuity.com |Midwest
Annie | annie@agency.com | Midwest
Kyle | kyle@agency.com | MidAtlantic
Rick | rick@megasales.com | MidAtlantic
Blank | Blank | Blank |

Example execution:
Run Birthday.au3, execute loop part through hotkey
Reads row 1, C1, value is Midwest, calls Midwest(), script runs as Midwest Birthday.au3 does currently
Reads row 2, C2, value is Midwest, calls Midwest(), script runs as Midwest Birthday.au3 does currently
Reads row 3, C3, value is MidAtlantic, calls MidAtlantic(), script runs as MidAtlantic Birthday.au3 currently
Reads row 4, C4, value is MidAtlantic, calls MidAtlantic(), script runs as MidAtlantic Birthday.au3 currently
Reads row 5, C5, value is null or blank, ends script through Exit

 

Everything I have coded in my time in AutoIt has been based mostly on mouse based movements and I don't have variable programming knowledge so I feel like I'm close to understanding how to do this, but the reading/storing variables part is beyond my current skill set. Help is appreciated. :)

Mail Merges don't work as delegated in Outlook 07, for those that might be questioning why I just don't do that.
 

MidAtlantic Birthday.au3

Midwest Birthday.au3

Edited by Revelation343

Share this post


Link to post
Share on other sites
water

I suggest to use the Excel UDF that comes with AutoIt plus the OutlookEX UDF which you can download from my signature.
First use _Excel_RangeRead to read the whole worksheet into an array, then loop through the array and call _OL_Wrapper_SendMail to create the mail and send it.

If needed I can provide an example script.

 

 

Edited by water
  • Like 1

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
water
#include <Excel.au3>
#include "OutlookEX.au3"

Global $oExcel = _Excel_Open()
Global $oWorkbook = _Excel_BookOpen($oExcel, @ScriptDir & "\Test_Mail.xlsx", True) ; Open Excel workbook read-only
Global $aData = _Excel_RangeRead($oWorkbook)
_Excel_BookClose($oWorkbook, False)
_Excel_Close($oExcel, False)

$oOL = _OL_Open()

; Retrieve defined signatures
Global $aSignatures = _OL_MailSignatureGet()
; Deactivate signature for new emails
_OL_MailSignatureSet("", Default)

; Create, Modify and send mails
For $i = 0 To UBound($aData, 1) - 1
    $oItem = _OL_ItemCreate($oOL, $olMailItem, "", @ScriptDir & "\" & $aData[$i][2] & ".msg", "Subject=Test")
    ConsoleWrite("IC: " & @error & "-" & @extended & @CRLF)
    $aBody = _OL_ItemGet($oOL, $oItem, Default, "HTMLBody")
    ConsoleWrite("IG: " & @error & "-" & @extended & @CRLF)
    $sBody = StringReplace($aBody[1][1], "%Firstname%", $aData[$i][0])
    _OL_ItemModify($oOL, $oItem, Default, "HTMLBody=" & $sBody)
    ConsoleWrite("IM: " & @error & "-" & @extended & @CRLF)
    _OL_ItemRecipientAdd($oOL, $oItem, Default, $olTo, $aData[$i][1])
    ConsoleWrite("RA: " & @error & "-" & @extended & @CRLF)
    $oItem.Display()
Next

; Set signature for new emails to previous value
For $i = 1 To $aSignatures[0][0]
    If $aSignatures[$i][1] = True Then
        _OL_MailSignatureSet($aSignatures[$i][0], Default)
        ExitLoop
    EndIf
Next

_OL_Close($oOL)

First (quick & dirty) example. Reads all records from Test_mail.xlsx with the structure as defined by you.
Depending on the value in column C (MidWest, MidAtlantic) an email is created based on template MidWest.msg or MidAtlantic.msg.
Placeholder "%Firstname%" is replaced with the recipients name.
Then the mail is being displayed (parameter SentOnBehalf has not been set yet).

What you need to do:

  • Place above script in a directory
  • Create MidWest.Msg and MidAtlantic.msg in the same directory
  • Create Test_mail.xlsx in the same directory

Example MidAtlantic.msg:

Quote

Dear %FirstName%,

Happy Birthday from your friends at x y.

Signature MidAtlantic

 

Edited by water
  • Like 1

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
Revelation343

Ok this makes sense. Is there a way to input the From field based on column C? Or I could just make it to where the From email is in Column D if need be if that would be easier.

Edit: Nevermind, I think I got it to work here, I just added the values for the From address to the D column. :) Take a look at it and let me know if there's anything obvious I'm missing but based on my testing it looks like this is exactly the functionality I need and I have a much better understanding of how this works now.

#include <Excel.au3>
#include "OutlookEX.au3"

Global $oExcel = _Excel_Open()
Global $oWorkbook = _Excel_BookOpen($oExcel, @ScriptDir & "\" & "Birthday.xlsx", True) ; Open Excel workbook read-only
Global $aData = _Excel_RangeRead($oWorkbook)
_Excel_BookClose($oWorkbook, False)
_Excel_Close($oExcel, False)

$oOL = _OL_Open()

; Retrieve defined signatures
Global $aSignatures = _OL_MailSignatureGet()
; Deactivate signature for new emails
_OL_MailSignatureSet("", Default)

; Create, Modify and send mails
For $i = 0 To UBound($aData, 1) - 1
    $oItem = _OL_ItemCreate($oOL, $olMailItem, "", @ScriptDir & "\" & $aData[$i][2] & ".msg", "Subject=Test", "SentOnBehalfOfName="& $aData[$i][3])
    ConsoleWrite("IC: " & @error & "-" & @extended & @CRLF)
    $aBody = _OL_ItemGet($oOL, $oItem, Default, "HTMLBody")
    ConsoleWrite("IG: " & @error & "-" & @extended & @CRLF)
    $sBody = StringReplace($aBody[1][1], "%Firstname%", $aData[$i][0])
    _OL_ItemModify($oOL, $oItem, Default, "HTMLBody=" & $sBody)
    ConsoleWrite("IM: " & @error & "-" & @extended & @CRLF)
    _OL_ItemRecipientAdd($oOL, $oItem, Default, $olTo, $aData[$i][1])
    ConsoleWrite("RA: " & @error & "-" & @extended & @CRLF)
    $oItem.Display()
Next

; Set signature for new emails to previous value
For $i = 1 To $aSignatures[0][0]
    If $aSignatures[$i][1] = True Then
        _OL_MailSignatureSet($aSignatures[$i][0], Default)
        ExitLoop
    EndIf
Next

 

Edited by Revelation343

Share this post


Link to post
Share on other sites
water

Looks quite good :)
Before using the script in production you could remove the ConsoleWrite statements. I inserted them for debugging reasons.

  • Like 1

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
Revelation343

Okay. Is there a maximum of new messages outlook has? So far I'm just running in batches of about 24. I don't know if it would be dependent on RAM or if Outlook has a hard cap. I feel like I've encountered a cap before when I was doing an deliverable report.

Share this post


Link to post
Share on other sites
water

Outlook is just the frontend to a mail server like Exchange. I've never heard of a limit for Outlook. Maybe the mail server has a limit to prevent mail floods.

Next idea would be to set the date in the Excel file. This would allow to restart the script without re-sending all mails by checking the date.
Right now the created mails get displayed. If you want to send them automatically then better error checking would be needed.

What do you plan as a next step?

  • Like 1

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
Revelation343

I like the ability to review before sending. Though in my first 3 batches of 24, there were no errors. I mean, this function is to basically pat some people on the back and isn't a high influence sort of issue. I've been out of the office for a few days so I have 249 more to send, but on the daily, this functionality should be more than sufficient. I am interested in the concept of being able to check the date incase I do have a large list like this in the future though.

 

Edit: I was able to just keep hitting send and produce all 249 at once so the hard cap that I ran into before must have only been a figment of my overworked imagination. :) 

Edited by Revelation343

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • Gowrisankar
      By Gowrisankar
      Dear members,
      I'm trying to move unread mails from Inbox to a different folder using OutlookEx UDF.
      But its not working for me. I'm not sure what mistake I do.
      I get the error code 6 when the following is executed. From the UDF it is observed that  "No or an invalid item has been specified".
      Note : The UDF version is 1.3.3.1. AutoIt version (v3.3.14.2).
      #include <OutlookEX.au3> Global $oOutlook = _OL_Open() If @error <> 0 Then Exit MsgBox(16, "OutlookEX UDF", "Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended) Global $aOL_Item = _OL_ItemFind($oOutlook, "*\Inbox", $olMail, "[UnRead]=True", "", "", "Subject", "", 1) If $aOL_Item[0][0] = 0 Then Exit MsgBox(16, "OutlookEX UDF: _OL_ItemMove Example Script", "Could not find a task item in folder 'Outlook-UDF-Test\SourceFolder\Tasks'. @error = " & @error) _ArrayDisplay($aOL_Item, "OutlookEX UDF: _OL_ItemFind Example Script - Unread mails") _OL_ItemMove($oOutlook, $aOL_Item[1][0], Default, "*\Outlook-UDF-Test\TargetFolder\Mail") If @error <> 0 Then Exit MsgBox(16, "OutlookEX UDF: _OL_ItemMove Example Script", "Error moving specified task. @error = " & @error) Any help is deeply appreciated. Thanks in advance.
      Thanks and regards,
      Gowrisankar R.
    • MrCheese
      By MrCheese
      Hi guys,
      without including everything (unless you want it)
      I am copying data from a table in chrome and wanting to paste it into excel.
      Copying in Chrome works.
      I can paste it into the field i want by emulating goto -> ctrl V:
      WinActivate($dataload) WinWaitActive($dataload) Sleep(500) $oWorkbook1.Sheets("ItemReturn").Activate Sleep(500) $msg = "Measuring Sheet" conwrite() ttips2() Local Const $xlUp = -4162 With $oWorkbook1.ActiveSheet ; process active sheet $oRangeLast = .UsedRange.SpecialCells($xlCellTypeLastCell) ; get a Range that contains the last used cells $iRowCount = .Range(.Cells(1, 1), .Cells($oRangeLast.Row, "B")).Rows.Count ; get the the row count for the range starting in row/column 1 and ending at the last used row/column $iLastCell = .Cells($iRowCount + 1, "B").End($xlUp).Row ; start in the row following the last used row and move up to the first used cell in column "B" and grab this row number EndWith $NewStartCell = $iLastCell + 2 $msg = "moving to location" conwrite() ttips2() Sleep(250) Send("^g") WinWait("Go To") Sleep(100) Send("B" & $NewStartCell) Sleep(100) Send("{ENTER}") Sleep(500) Send("^v")  
      But, I want to use _excel_rangecopypaste, pasting from the clipboard
      _Excel_RangeCopyPaste($oWorkbook1.ActiveSheet, default, "B" & $NewStartCell,default,$xlPasteValuesAndNumberFormats) If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeCopy Example 2", "Error pasting cells." & @CRLF & "@error = " & @error & ", @extended = " & @extended) however, this gives me error 4 , extended@:  -2147352567
      How can i fix this or find out how to debug this error?
       
      Thanks
    • Simpel
      By Simpel
      Hi.
      I try to figure out who is using a excel workbook which I can only open "read only". I use this code:
      #include <Array.au3> #include <Excel.au3> Local $sFile = ; excel file with path on a network drive Local $oExcel = _Excel_Open(True, True) Local $oTabelle = _Excel_BookOpen($oExcel, $sFile) Local $aUsers If IsObj($oTabelle) Then $aUsers = $oTabelle.UserStatus _ArrayDisplay($aUsers) EndIf If I am the one allowed to write to the excel file (I'm the first one who opened it) then I will get an array with myself:

      If my collegue opened the excel file first and I run the code I get the following error message:
      "H:\_Conrad lokal\Downloads\AutoIt3\_COX\Tests\test.au3" (9) : ==> The requested action with this object has failed.: $aUsers = $oTabelle.UserStatus $aUsers = $oTabelle^ ERROR The excel file is on a network drive. Is that's the problem?
      Regards, Conrad
    • robertocm
      By robertocm
      change linked image paths in excel 2007 Open XML Files with AutoIt and 7-zip:
      #include <File.au3> ;Change this Local $sFind = "C:\Users\MyUserName\Documents\MyImageFolder\My%20Image1.png" Local $sReplace = "C:\Users\ANOTHERUSERNAME\Documents\AnotherImageFolder\My%20Image1.png" Local Const $sMessage = "Directory to change excel image paths" Local $sFileSelectFolder = FileSelectFolder($sMessage, "") Local $sTempDir = @ScriptDir & "\testdir" ;Required 7-zip Local $PathZipProgram = @ProgramFilesDir & "\7-Zip\" If Not(FileExists($PathZipProgram & "\7z.exe")) Then MsgBox(16, "", "7z.exe not found in path " & $PathZipProgram) Exit EndIf ;look for excel files in selected directory and all subdirectories Local $SFileList = _FileListToArrayRec($sFileSelectFolder, "*.xls.;*.xlsm", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH) If Not @error Then For $i = 1 To $SFileList[0] DirRemove($sTempDir, 1) ;use x command to keep the folder stucture, -aoa Overwrite All existing files without prompt, use -r to unzip the subfolders from the zip file RunWait('"' & $PathZipProgram & '7z.exe" x -aoa -r "' & $SFileList[$i] & '" -o"' & $sTempDir & '" -y', $PathZipProgram, @SW_HIDE) __ReplaceImagePaths($sTempDir, $sFind, $sReplace) RunWait('"' & $PathZipProgram & '7z.exe" a -r "' & $SFileList[$i] & '" "' & $sTempDir & '\*" -tzip -y', $PathZipProgram, @SW_HIDE) Next Else MsgBox(16, "Error", "No files were found in the folder specified.") EndIf DirRemove($sTempDir, 1) Func __ReplaceImagePaths($sTempDir, $sFind, $sReplace) ;List all files with .xml.rels extension in the directory \xl\drawings\_rels Local $aFileList = _FileListToArray($sTempDir & "\xl\drawings\_rels", "*.xml.rels", 1, True) If @error = 1 Then ;MsgBox (0, "", "Path was invalid") SplashTextOn("Title", "Path was invalid", -1, -1, -1, -1, 1, "", 24) Sleep(2000) SplashOff() Exit EndIf If @error = 4 Then ;MsgBox (0, "No files", "No files were found") SplashTextOn("Title", "No files were found", -1, -1, -1, -1, 1, "", 24) Sleep(2000) SplashOff() Exit EndIf Local $iRetval ;Loop through the array For $i = 1 To $aFileList[0] $iRetval = _ReplaceStringInFile($aFileList[$i], $sFind, $sReplace) Next EndFunc  
      Some references:
      https://stackoverflow.com/questions/37145369/change-path-to-picture-links-in-excel http://www.jkp-ads.com/Articles/Excel2007FileFormat.asp EDITED:
      Note: it seems that if User Account Control (UAC) is enabled then 7zip is unable to overwrite the destination file (using the same name).
      In this case, a possible solution would be to rename the original excel file before (see _PathSplit in help file).
      In my case i prefer just to disable UAC
×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.