Inserting a table into Outlook email using VBScript - email

I have a table in a Microsoft Word document that I want to insert into the middle of a message in an Outlook email. When I manually copy the table into an email draft, it preserves the formatting, but when I don't, the formatting changes into a list-style. For example, this is what the table would look like:
9898 Apple color
1394 Banana blue
with borders, but in the email that gets sent, it shows up as
9898
Apple
Color
1394
Banana
Blue
I had to add in extra lines above because Stack Overflow wasn't showing it as each element on an separate line.
Within my code, I've taken the table and concatenated it within the string that forms the message of the email. I think this may be the problem, but I'm not sure how to change this to separately include the table. Here is my code:
message = "Dear " & owner & ", " & vbCrLf & vbCrLf
message = message & "Here is the data we have: " & vbCrLf
message = message & vbCrLf & vbCrLf & textToTable(fileName, file)
message = message & "Can you please email us back with the updated data?"
message = message & vbCrLf & vbCrLf & "Thank you."
Set MyItem = ol.CreateItem(0)
With MyItem
.To = me
.CC = ""
.BCC = ""
.Subject = "Table"
.BodyFormat = 3
.Body = message
.Send
End With
I used a lot of the code here in my textToTable function, which seems to work as intended. The only problem is getting Outlook to preserve formatting of the table; does anyone have any suggestions as to how to do this? Thank you so much!

You are setting the plain text Body property. Create an HTML table and assign the HTMLBody property to a property formatted HTML string.

Related

MS Access - Report to PDF - Data fields not populating in controls on PDF

I am trying to generate a pdf file, based on the contents of an Access Form or a Report (either is fine for me but understand it should be done via a report).
I can generate/populate the form itself, and the report itself, but when I create the pdf with this code, the fields in the pdf are blank. The controls are all there, like seen in my form, but the fields that should have data don't get copied over.
This works as-is for me, and makes a pdf that looks just like my report, except the data from the report does not carry over to the saved pdf
Private Sub pdfBtn_Click()
Dim fileName As String, fldrPath As String, filePath As String
Dim answer As Integer
fileName = "File_Test1" 'filename for PDF file*
fldrPath = "C:\Users\myname\Desktop" 'folder path where pdf file will be saved *
filePath = fldrPath & "\" & fileName & ".pdf"
'check if file already exists
If FileExist(filePath) Then
answer = MsgBox(prompt:="PDF file already exists: " & vbNewLine & filePath & vbNewLine & vbNewLine & _
"Would you like to replace existing file?", buttons:=vbYesNo, Title:="Existing PDF File")
If answer = vbNo Then Exit Sub
End If
On Error GoTo invalidFolderPath
DoCmd.OutputTo acOutputReport, "Report2", acFormatPDF, filePath
MsgBox prompt:="PDF File exported to: " & vbNewLine & filePath, buttons:=vbInformation, Title:="Report Exported as PDF"
Exit Sub
invalidFolderPath:
MsgBox prompt:="Error: Invalid folder path. Please update code.", buttons:=vbCritical
End Sub
Function FileExist(FileFullPath As String) As Boolean
Dim value As Boolean
value = False
If Dir(FileFullPath) <> "" Then
value = True
End If
FileExist = value
End Function
I've spent a few hours searching, so I'd be upset if it is something overly simple and available. But is anyone able to point me in the right direction with this?
It looks like I had some logic wrong. Yes the code provided does work, thanks again #June7. I was over complicating things by trying to generate the pdf off the form itself, versus off a report. I ended up making the button pop up the report instead of another form, and the data does now flow as expected.
Silly, like I said :(

Limiting RowSource in ComboBox (Access)

I have a form which has a ComboBox on it that pulls all DISTINCT colleague names from a huge table that includes all of our sales (50k+ records). It works perfectly fine, but it takes 3-4 minutes to open the form because it takes so long for Access to find all unique colleague names in the table.
I've been trying to research this and found something that looks useful, but can't seem to get it right.
The code I have at the moment:
Private Sub CollName_Change()
Dim strText As String
strText = Nz(Me.CollName.Text, "")
If Len(strText) > 2 Then
Me.CollName.RowSource = "SELECT CollPerf.Colleague FROM CollPerf WHERE CollPerf.Colleague LIKE ""*"" & strText & ""*""; "
Me.CollName.Dropdown
End If
End Sub
I found this code on two forums, this is supposed to do the following: "the key is to not have a Row Source defined for the Combo Box. The row source will be defined as the user starts typing letters. Once they get to 3 letters then the row source of the combo box will be defined and the combo box will be told to dropdown."
When I get to 3 letters, a dropdown appears, but it's blank, it doesn't display any results.
I'm relatively new to Access, although already built two databases, but they all have relatively basic SQL queries, so I have no idea what I'm not doing right here.
Any advice? Or alternatively a different solution as to how take my combo box faster and still keep values unique?
You only have some double-quote mixup there. It is much easier to use single quotes instead of double double-quotes.
Me.CollName.RowSource = _
"SELECT CollPerf.Colleague FROM CollPerf WHERE CollPerf.Colleague LIKE '*" & strText & "*';"
But your query would be way faster if you would only use the starting letters, i.e. remove the leading *
Me.CollName.RowSource = _
"SELECT CollPerf.Colleague FROM CollPerf WHERE CollPerf.Colleague LIKE '" & strText & "*';"
But that depends on your requirements.
EDIT to debug:
Dim strText As String
Dim strSelect As String
strText = Nz(Me.CollName.Text, "")
If Len(strText) > 2 Then
strSelect = "SELECT CollPerf.Colleague FROM CollPerf WHERE CollPerf.Colleague LIKE '*" & strText & "*';"
Debug.Print strSelect
Me.CollName.RowSource = strSelect
Me.CollName.Dropdown
End If
Copy strSelect from the Immediate Window into a query, and try it out. It should help resolve the problem.
See How to debug dynamic SQL in VBA

Some questions about coding ActiveX Script/VBScript in SQL Server Agent Jobs/DTS packages

I use SQL Server Agent Jobs/DTS packages, coded in ActiveX Script/VBScript.
It works fine.
But there are some issues I would need help at the moment:
First: Is there a possibility to send an html email out of the ActiveX Script code in the DTS Step?
My company doesn't want to buy a separate commercial DLL for sending smtp email .. like JMail for example.
I know there are many such DLLs I could buy which can be used to send an email using VB or other languages.
But we don't have the money for such external components.
Could I use SQL Server Database Mail?
... but it is necessary to send the mails in html ...
Is there a possibility to create a new *.txt, *.csv or *.xlsx file from the ActiveX Script/VBScript code in the DTS Step?
I would like to copy the html email body code (a string which I built in the ActiveX Script code) into these files and attach them to the email I send out of the script code. So the user/recipient gets the html content embedded in the email body and separate in files too.
Thanks in advance for your help.
Tommy
This code works. PLUS it displays any errors which tell you why it didn't work.
Set emailObj = CreateObject("CDO.Message")
emailObj.From = "dc#gmail.com"
emailObj.To = "dc#gmail.com"
emailObj.Subject = "Test CDO"
emailObj.TextBody = "Test CDO"
emailObj.AddAttachment "C:/Users/User/Desktop/err.fff"
Set emailConfig = emailObj.Configuration
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "dc"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "Ss"
emailConfig.Fields.Update
On Error Resume Next
emailObj.Send
If err.number = 0 then
Msgbox "Done"
Else
Msgbox err.number & " " & err.description
err.clear
End If
Also your account at www.gmail.com needs to be set to allow SMTP access (if using gmail as many are who do this).
The configuration info comes from Outlook Express (last in WinXP, renamed to Windows Mail in Vista, and dropped from Win7 and later). This shows default configuration on your computer. You may need to install Windows Live Mail. You also have to turn on the SMTP service in Windows Features.
Set emailConfig = emailObj.Configuration
On Error Resume Next
For Each fld in emailConfig.Fields
Text = Text & vbcrlf & fld.name & " = " & fld
If err.number <> 0 then
Text = Text & vbcrlf & fld.name & " = Error - probably trying to read password - not allowed"
err.clear
End If
Next
Msgbox Replace(Text, "http://schemas.microsoft.com", "")
Also CDO for Windows 2000 is not always included in all editions/versions of windows. See http://support.microsoft.com/en-au/kb/171440.
.

Use Applescript to send mail without mail.app

I'm new to Applescript and working on an app that runs in the background, and I want it to send email updates every so often WITHOUT mail.app.
I've tried googling this numerous times, and while this is the closest I've found, I don't know how to use a Python script. This app needs to work no matter what Mac OSX it is installed in, including Computers without Python. Is that possible?
I have often wanted to do the same thing and struggled myself. I ultimately landed on a python option. Python is supported back to OS X 10.5 and comes preinstalled on many of the newer versions of OS X. Is there some reason you don't feel you can use it? Are you supporting OS 10.4.x or older machines?
If they python option is still a possible option, I've included an example of how to use it here.
property PyMail : "/Users/TBD/Documents/Sample_Python_Email/PyMail.py" -- PATH TO PYTHON MAIL SCRIPT
on run
set emailTo to "youraddress#somedomain.com" -- MULTIPLE ADDRESS SHOULD BE A COMMA DELIMITED STRING LIKE THIS -- "address1#gmail.com, address2#hotmail.com"
set emailFrom to "Your Name <your.name#somedomain.com>"
set subject to "Demo Email"
set message to "Hi user,
I hope things are going well"
set pathToAttchment to "/Users/TBD/Desktop/prof.jpg" -- POSIX PATH TO FILE, LEAVE AS EMPTY STRING FOR NO ATTACHMENT
set username to "smtpusername" -- MAY OR MAY NOT BE REQUIRED IN YOUR CASE
sendPyMail(emailTo, emailFrom, subject, message, pathToAttchment, username)
end run
on sendPyMail(emailTo, emailFrom, subject, message, attachment, username)
try
do shell script "python " & quoted form of PyMail & " " & quoted form of emailTo & " " & quoted form of emailFrom & " " & quoted form of subject & " " & quoted form of message & " " & quoted form of attachment & " " & quoted form of username
return true
on error
return false
end try
end sendPyMail
Here is the python script (just copy and past it into a text editor and save as PyMail.py. You'll need to change the smtp server and possibly add the password that goes with the username you're supplying...
import sys
SMTP_TO = sys.argv[1]
SMTP_TO = SMTP_TO.split(',')
SMTP_FROM = sys.argv[2]
SUBJECT = sys.argv[3]
MESSAGE = sys.argv[4]
TEXT_FILENAME = sys.argv[5]
SMTP_USERNAME = sys.argv[6]
SMTP_SERVER = 'smtp.domainx.com'
SMTP_PORT = 25
SMTP_PASSWORD = ''
# now construct the message
import smtplib, email
from email import encoders
import os
msg = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(MESSAGE)
if TEXT_FILENAME != "":
attachment = email.MIMEBase.MIMEBase('text', 'plain')
attachment.set_payload(open(TEXT_FILENAME).read())
attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(TEXT_FILENAME))
encoders.encode_base64(attachment)
msg.attach(body)
if TEXT_FILENAME != "":
msg.attach(attachment)
msg.add_header('From', SMTP_FROM)
msg.add_header('To', ';'.join(SMTP_TO))
msg.add_header('Subject', SUBJECT)
mailer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
mailer.sendmail(SMTP_FROM, SMTP_TO, msg.as_string())
mailer.close()
Run this in Terminal
echo "this is the body" | mail -s "this is the subject" "to#address"
Note: This assumes you have a locally installed MTA
Your AppleScript would be:
do shell script "echo 'this is the body' | mail -s 'this is the subject' 'to#address'"
Knowing nothing about python, I used TextWrangler and cut and paste the two scripts above.
The second one crashes at line 1, returning a syntax error, as follows:
line 1
property PyMail : "/Users/.../PyMail.py" -- PATH TO PYTHON MAIL SCRIPT
^
SyntaxError: invalid syntax
The carrot pointer is under the 'l' in 'PyMail'.
I commented out line 1, and it returned the same message for line 3.

Applescript freezes when extracting email from mail

I'm running an applescript to extract all the email adress from all the messages in my boss's inbox and it freezes on his computer and works fine on mine.
my computer is running Snow leopard with mail 4.6 and his is running Lion with mail 5.3 if that makes any difference.
Also my inbox only has around 400 mails since i don't usually use mail and only got those messages to test the script and his has over 60 000.
The script ran through my email in around 20 seconds and on his took 2 minutes to do 40 then froze.
I was wondering if there was anything wrong with the code that could cause it to freeze in his higher version or due to the increase in email present.
On another note i know that writing them all one by one is probably counter-productive because the script i adapted this from was sorting the adresses and removing duplicates before writing them to the file but i thought that due to the large number of mails that it would speed the process and use less memory to just write them. PLus the counters helps to know where the script is at.
here is the code :
tell application "Finder" to set ptd to path to documents folder as string
set theFile to ptd & "extracted3.txt"
set theFileID to open for access theFile with write permission
set counter to 0
tell application "Mail"
set selectionMessage to selection -- just select the first message in the folder
set thisMessage to item 1 of selectionMessage
set theseMessages to (every message in (mailbox of thisMessage))
repeat with eachMessage in theseMessages
try
set counter to counter + 1
set theFrom to (extract address from sender of eachMessage)
set theFromName to (extract name from sender of eachMessage)
set theFromTemp to theFrom & "," & theFromName & "," & counter
write theFromTemp & return to theFileID as «class utf8»
if (address of to recipient) of eachMessage is not {} then
repeat with i from 1 to count of to recipient of eachMessage
set theTo to (address of to recipient i) of eachMessage as string
set theToName to (name of to recipient i) of eachMessage as string
set theToTemp to theTo & "," & theToName & "," & counter
write theToTemp & return to theFileID as «class utf8»
end repeat
end if
if (address of cc recipient) of eachMessage is not {} then
repeat with i from 1 to count of cc recipient of eachMessage
set theCC to (address of cc recipient i) of eachMessage as string
set theCCName to (name of cc recipient i) of eachMessage as string
set theCCTemp to theCC & "," & theCCName & "," & counter
write theCCTemp & return to theFileID as «class utf8»
end repeat
end if
end try
end repeat
end tell
close access theFileID
EDIT: after further thought, I removed the first script I posted. My thought is the problem you are seeing is because you are getting 60,000+ emails at once in this line...
set theseMessages to (every message in (mailbox of thisMessage))
So the idea is to just get a bunch at a time. I use the variable writeEveryXMessages to specify that you should get 500 messages at a time, and on each loop we get the next 500 until finished.
NOTE: I modified your code to be a little more efficient and fixed a few possible bugs, for example the write command is no longer in the Mail tell block of code. Also it now writes those 500 messages to file at one time. This script works on Mountain Lion and Mail v6.2. It should work for you too.
I hope this fixes your problem! Good luck.
set theFile to (path to documents folder as text) & "extracted3.txt"
set writeEveryXMessages to 500
set counter to 1
try
set theFileID to open for access file theFile with write permission
tell application "Mail"
set selectedMessage to item 1 of (get selection)
set theMailbox to mailbox of selectedMessage
set messageCount to count of messages in theMailbox
end tell
repeat
set endCount to counter + writeEveryXMessages
if endCount is greater than messageCount then set endCount to messageCount
set theString to ""
tell application "Mail"
set theseMessages to messages counter thru endCount of theMailbox
end tell
repeat with eachMessage in theseMessages
set theFromTemp to ""
set theToTemp to ""
set theCCTemp to ""
try
tell application "Mail"
tell eachMessage
set theSender to sender
set toRecipients to to recipients
set ccRecipients to cc recipients
end tell
set theFrom to extract address from theSender
set theFromName to extract name from theSender
set theFromTemp to "From: " & theFrom & "," & theFromName & "," & counter & return
if toRecipients is not {} then
repeat with toRecipient in toRecipients
try
set theTo to address of toRecipient
set theToName to name of toRecipient
set theToTemp to theToTemp & " To: " & theTo & "," & theToName & "," & counter & return
end try
end repeat
end if
if ccRecipients is not {} then
repeat with ccRecipient in ccRecipients
try
set theCC to address of ccRecipient
set theCCName to name of ccRecipient
set theCCTemp to theCCTemp & " CC: " & theCC & "," & theCCName & "," & counter & return
end try
end repeat
end if
end tell
set theString to theString & theFromTemp & theToTemp & theCCTemp & return
end try
set counter to counter + 1
end repeat
write theString to theFileID as «class utf8»
if counter is greater than or equal to messageCount then
set theString to ""
exit repeat
end if
end repeat
close access theFileID
on error theError
log theError
try
close access file theFile
end try
end try