Sending images by email
The Cardbox help file gives various examples of macros that can be used to send emails from Cardbox databases. Here is an example that shows how you can send emails that incorporate images from your Cardbox records. It is quite a big and complex macro. You can adapt it for your own purposes or use the ideas in this macro to construct macros of your own.
What the sample macro does
The macro works with Microsoft Outlook Express. It looks at the current selection in a window called PICTURES. It collects together the images from each record, and creates an email with all those images attached.
If you want to do the same thing by sending email directly from Cardbox, rather than using Outlook Express, see Sending a single record directly from Cardbox, which (despite its name) gives you macros for single records and multiple records, with and without images attached.
The sample macro
Here is the complete text of the sample macro. When you see numbers in square brackets, like this [6], they refer to notes in the description that follows the macro.
Option Explicit ' [1] const senderEmail="myself@here.com" ' [2] const subject="Selected images" ' [3] Dim img,rec,recs,fso,out Set recs=Records Dim tempFolder,tempFilenameEML const emailSeparator="2349wecdwf3" ' [4] Set fso=CreateObject("Scripting.FileSystemObject") tempFolder=fso.GetSpecialFolder(2) ' [5] tempFilenameEML=tempFolder & "\fromCardbox.eml" Set out=fso.CreateTextFile(tempFilenameEML,True) StartEmailFile out out.WriteLine "Here are the selected images." ' [6] For Each rec in recs ' [7] For Each img in rec.Images AddImageToEmailFile out,img Next Next CompleteEmailFile out out.Close Launch tempFilenameEML ' [8] Sub StartEmailFile(out) ' [9] out.WriteLine "From: " & senderEmail out.WriteLine "Subject: " & subject out.WriteLine "X-Unsent: 1" out.WriteLine "MIME-Version: 1.0" out.WriteLine "Content-Type: multipart/mixed; boundary=""" & emailSeparator & """;" out.WriteLine "Content-Transfer-Encoding: 7bit" out.WriteLine "" out.WriteLine "--" & emailSeparator out.WriteLine "Content-Type: text/plain; charset=""iso-8859-1""" out.WriteLine "Content-Transfer-Encoding: 8bit" out.WriteLine "" End Sub Sub AddImageToEmailFile(out,img) ' [10] Dim filext,filtype If img.Type=cbxImageDocument Then ' [11] filext="gif" : filtype="gif" Else filext="jpg" : filtype="jpeg" End If Dim imgFilename imgFilename=tempFolder & "\fromCardbox." & filext img.WriteToFile imgFilename,cbxImageNonBMP ' [12] out.WriteLine "--" & emailSeparator ' [13] out.WriteLine "Content-Type: image/" & filtype & ";" ' [14] out.WriteLine "Content-Transfer-Encoding: base64" out.WriteLine "Content-Disposition: attachment" out.WriteLine "" out.WriteLine ReadFileIntoBase64(imgFilename) ' [15] fso.DeleteFile imgFilename End Sub Sub CompleteEmailFile(out) ' [16] out.WriteLine "--" & emailSeparator & "--" End Sub
Notes
- Because this is a big and complicated macro, we have used Option Explicit to ensure that no variable names are misspelt (Macros and Programming book, page 53).
- Set senderEmail to the address that you are sending this email from.
- Set subject to the subject line of your email.
- You can set emailSeparator to any sequence of characters that can be guaranteed not to appear in the text of your email. The recipient never sees these characters.
- tempFolder is the name of the folder in which this macro will create its temporary files. tempFilenameEML is the name of the temporary file that is used to construct the email.
- You can have a much longer and more descriptive email message here. You could even extract text from the individual records that you are sending, and include it in the text of your email.
- Under some circumstances Outlook Express seems to have a tendency to attach
images to an outgoing email in the reverse order to the order in which they
were written, so that the image that you attach first appears last in the
list of attachments. If this happens to you, and it causes inconvenience,
then replace the For Each rec and For
Each img statements with the following:
Dim iRec For iRec=recs.Count To 1 Step -1 Set rec=recs(iRec) Dim iImg For iImg=rec.Images.Count To 1 Step -1 Set img=rec.Images(iImg)
This will attach the last image first, so that (after Outlook Express's reversal) the last image will appear last in the list of attached images. - Launch opens Outlook Express and gives it the newly created .eml file. You can then make any changes you want to the email before transmitting it. Note that this macro does not delete the .eml file. This is because Outlook Express starts running as soon as the Launch command is executed. You will not find that very much of your disk space is wasted, because the same filename will be reused the next time you run this macro.
- StartEmailFile writes the necessary headers to the beginning of the email file. If you are adapting the macro so that it fills in the recipient's address for you, put a "To:" line immediately after the "From:" line, using the same layout.
- AddImageToEmailFile adds an attached image to the email.
- The image will be in GIF or JPEG format, depending on the type of the Cardbox image.
- WriteToFile writes the image to a temporary file. The cbxImageNonBMP option tells Cardbox to convert the image to GIF or JPEG.
- A separator is output, to tell Outlook Express that one part of the email has finished and another part is about to begin.
- In this example we do not give a name to the attached image, which means
that Outlook Express will assign a name for itself. If you want to specify
a name, and you have put the name into a variable called imgName,
then modify the Content-Type line as follows:
out.Write "Content-Type: image/" & filtype & ";" out.WriteLine " name=""" & imgName & """;"
- ReadFileAsBase64 takes the file that has just been written, translates it to the Base64 encoding that is used in emails, and adds it to the email file. After doing this, the macro deletes the temporary file that contained the image.
- CompleteEmailFile writes a final marker to indicate that the last part of the email (usually, the last image) has finished and that there is nothing more in the email.
Possible modifications
You could use the information stored in each record to build up the text of the email that you are sending. To do this, you would replace the single line at note [6] with a For Each rec loop that extracted the necessary data from the relevant fields in each record.
You could make the macro send images for tagged records only, by replacing Set recs=Records (near the beginning of this macro) with Set recs=Records.SelectTagged.
You could have a separate database with one record for each recipient. The macro could perform a search for appropriate images and pause to allow you to fine-tune the selection; the macro could then extract the recipient's email address from his record (see note [9]), and even write into the recipient's record the details of the date of the email and what images were sent.