William Matsuoka
  • Introduction
  • Topics
  • Stata
  • Teaching
    • ECON 641L
    • ECON 640L >
      • Econ-Data
  • Blog
  • About

W=M/Stata

Welcome

Sending an Email with Stata (Outlook Edition)

12/17/2015

6 Comments

 

For Use with Windows

After about a month using Stata, most early programmers start asking questions about how to expand Stata's functionalities beyond generate and replace.  A common workplace question is: "how can I get Stata to send out automatic emails for me?"

A quick Google search yields many answers – most of which requires you to know a thing or two about email servers.  After hours of collecting material and trying to send out emails, you'll realize that your work's firewall disallows you to do anything of the sort!  Well, if you use Outlook (which is pretty common), you can easily automate sending emails using the following VBScript:
Set Outlook = CreateObject("Outlook.Application")
Set Mail = Outlook.CreateItem(0)
Mail.To = "email@somedomain.com"
Mail.Subject = "Automated Email"
Mail.Body = "Hello Recipient"
Mail.Send
Set Mail = Nothing
Set Outlook = Nothing
​
​But how do we send this out?  It's really quite simple.  Open up any text editor (though I recommend using Notepad++), copy this code into the text editor, and save this file as "whatever.vbs", and either double click the file or run it by using Stata's shell command.
yourdirectory + "whatever.vbs"

CRLF

​This is great for simple emails, but what if we want to make our body a little more complex and less "robotic?"  Let me (re)introduce you to ASCII characters 10 and 13.  Since we're dealing with Windows for this post, let's switch them around and show char(13)+char(10) which corresponds to \r\n or translated: carriage return + line feed (CRLF).  What the heck is a carriage you say?  (Likely if you're under 50)  Well, it all relates back to typewriters.
Picture
​The carriage is the tray thing that moves along as you type, and by asking it to "return", you usually will get it shooting back with that distinctive PING sound.  Line feed tells the typewriter to move the paper up one line.  A carriage return without a line feed would overwrite anything you've typed, and a line feed without a carriage return could start a newline in the middle of a page.  Of course, things don't work that way anymore, but hopefully that makes a little more sense!

Anyway, this combination is useful to you if you want to send multiple paragraphs in an email.  Even more useful, write out your email body in a text file and let Stata pick up the file for you, and write the body by itself.  But more on that in a little bit.  For now, let’s talk about writing the actual script.

In Stata, in order to write a script, we must first familiarize ourselves with the file processing commands: file open, file write, and file close.  The secret here is that we can use locals to fill out any missing information in the file such as an email recipient, a subject line, or an attachment location.  Boom!  We have a program.
program define outlook_email
        syntax , to(string) [subject(string) body(string) attachment(string)]
end

​Since we always need a recipient for an email "to" is a must, but everything else should remain optional.  We want to allow our users to do whatever they want, which might include sending out 10,000 blank emails to a specific person.  Why?  They probably have their reasons.

File Processing

Want to write a file using Stata?  It's very easy to write the VBScript which runs the entire process.  For those who are unfamiliar with the file command, it follows three basic steps: open that file (even if it doesn't exist yet), write stuff to that file, and close that file!  Let's take a look at some basic syntax below:
Picture
The blue denotes these steps, the green is the name that we gave our program to point to which file to write to, and the red denotes the options.  Notice that our green "name" is myfile, but it could be anything, yet our physical file name is "testfile.txt".  Think of myfile as an id for which file we're writing to (or reading from).

Notice that we just need to put a string followed by _n to write a single line to the file.  We then do that again for line two, and for lines three and four.  We're able to write lines three and four on the same line, because they contain that _n which calls for an end of line character (in this case CRLF) to be written.

The Body

There are four steps to a making a text file work with VBS:
  1. Get rid of quotes: from " to "+Chr(34)+"
  2. Get rid of apostrophes: from ' to "+Chr(39)+"
  3. Replace CRL characters: from \013d\010d to "+ Chr(13)+Chr(10)+"
  4. Get rid of useless stuff: from +""+ to +

​You’ll see that we use filefilter to take care of these four scenarios, creating a single string that contains the entire body of our email (line breaks included).  Putting all of this together, we arrive at the final code:

Final Program

********************************************************************************
* Will Matsuoka: 2015-12-17 version 2.0.0 - for demonstrative purposes
********************************************************************************

program define outlook_email
        syntax , to(string) [subject(string) body(string) attachment(string)]
        
* Allow for the subject to contain quotes and apostrophes
        if `"`subject'"' != "" {
                sta_2_vbs `"`subject'"'
                local subject = r(vbstring)
        }
        
        if `"`body'"' != "" {
                preserve
                tempfile f1 f2
                filefilter "`body'" `f1', from(`"""') to(`""+Chr(34)+""')
                filefilter `f1' `f2', from(`"'"') to(`""+Chr(39)+""')
                filefilter `f2' `f1', from(\013d\010d) to(`""+Chr(13)+Chr(10)+""') replace
                filefilter `f1' `f2', from(`"+""+"') to("+") replace
                
                clear
                set obs 1
                gen file = fileread("`f2'")
                local body = file[1]
                restore
        }
        
        tempname myfile
        file open `myfile' using sendemail.vbs, write replace
        file write `myfile' ///
                `"Set Outlook = CreateObject("Outlook.Application")"' _n ///
                `"Set Mail = Outlook.CreateItem(0)"' _n ///
                `"Mail.To = "`to'""' _n ///
                `"Mail.Subject = "`subject'""' _n ///
                `"Mail.Body = "`body'""' _n
        if "`attachment'" != "" {
                file write `myfile' `"Mail.Attachments.Add("`attachment'")"' _n
        }
        file write `myfile' ///
                `"Mail.Send"' _n ///
                `"Set Mail = Nothing"' _n ///
                `"Set Outlook = Nothing"' _n
        file close `myfile'
        
        shell sendemail.vbs
end

program define sta_2_vbs, rclass
        local string = subinstr(`"`1'"', `"""', `""+Chr(34)+""', .)
        local string = subinstr(`"`string'"', `"'"', `""+Chr(39)+""', .)
        local string = subinstr(`"`string'"', `"+""+"', "+", .)
        return local vbstring `"`string'"'
end


​Not too terrible, although I do have a few things to note:
  • For troubleshooting, if your VBScript works, your Stata script should work - in other words, start at your VBScript
  • There are times where it helps to keep Outlook open, to make sure that your email doesn't just sit in the outbox
  • If you're trying to run this in batch mode, omit the shell command.  Just call the script on the next line of your batch file (since shell doesn't work in batch mode)
6 Comments
William Buchanan link
4/7/2016 04:34:50 am

It makes calls directly to the JVM (assuming Java is on the path) at the moment, but as long as the user knows their host information they can send email, embed images, send HTML formatted emails, etc... all from within Stata. I put together something several years ago that used Python, but didn't set up any connection (e.g., would send the email as localhost to the recipient) and ended up breaking after a not too long amount of time.

Reply
Carlos
10/6/2016 02:25:13 pm

Let me ask you something. It is possible sent a symbol at the end of the email?

Reply
Cam McDermaid
1/16/2017 07:54:10 am

Nicely done Will. This is very handy for letting our teams know when key files have been updated.

Reply
Hurchins Nyakwara
2/27/2017 01:43:24 am

nice staff

Reply
is best essays good link
2/1/2020 06:08:11 am

To tell you honestly, this is the very first time I have heard about Stata. I was really curious about it that's why I downloaded right away to see what it can do for me. I reeled that it was a software designed for people who deal with numbers a lot! At the same time, it is for the computer programmers; so that they their jobs will be easier to handle. I am happy to see that a lot of softwares are being invented for people's convenience. This is indeed a good thing!

Reply
Surge Mail link
2/27/2020 04:43:08 am

This wmatsuoka blog has been giving us and making the wonderful techniques and methods about free mail software. Thanks for updating and generating the great objectives with us.

Reply



Leave a Reply.

    Author

    Will Matsuoka is the creator of W=M/Stata - he likes creativity and simplicity, taking pictures of food, competition, and anything that can be analyzed.

    For more information about this site, check out the teaser above!

    Archives

    July 2016
    June 2016
    March 2016
    February 2016
    January 2016
    December 2015
    November 2015
    October 2015
    September 2015

    Categories

    All
    3ds Max
    Adobe
    API
    Base16
    Base2
    Base64
    Binary
    Bitmap
    Color
    Crawldir
    Email
    Encryption
    Excel
    Exif
    File
    Fileread
    Filewrite
    Fitbit
    Formulas
    Gcmap
    GIMP
    GIS
    Google
    History
    JavaScript
    Location
    Maps
    Mata
    Music
    NFL
    Numtobase26
    Parsing
    Pictures
    Plugins
    Privacy
    Putexcel
    Summary
    Taylor Swift
    Twitter
    Vbscript
    Work
    Xlsx
    XML

    RSS Feed

Proudly powered by Weebly
  • Introduction
  • Topics
  • Stata
  • Teaching
    • ECON 641L
    • ECON 640L >
      • Econ-Data
  • Blog
  • About