I have emails in my Outbox in Outlook and I'd like to run a vb script to change the from field of these emails to some other email
I managed to do the following but it doesn't work as I'd like to and therefore I am missing the main piece. I'd appreciate if someone could help.
intFolderOutbox = 4
msoFileDialogOpen = 1
' Load requied objects
Set WshShell = WScript.CreateObject("WScript.Shell") ' Windows Shell
Set ObjOlApp = CreateObject("Outlook.Application") ' Outlook
Set ns = ObjOlApp.GetNamespace("MAPI") ' Outlook
Set box = ns.GetDefaultFolder(intFolderOutbox) ' Outlook
For Each Item In box.Items
*** HERE IS WHAT I NEED TO REPLACE THE FROM FIELD ****
Item.sender = "email2#gmail.com"
Item.Update
Item.Save
Next
Something like the following works adding a recipient but I couldn't find the equivalent to the from field.
Item.Recipients.Add "email2#gmail.com"
Here is something that could help but it doesn't work in my case
Set oAddrEntry = CreateObject("MAPI.AddressEntry")
oAddrEntry.Name = SYSTEM_ADDRESS
oAddrEntry.resolve
Set oNewMsg.sender = oAddrEntry
oNewMsg.Update
oNewMsg.Send
Thanks
Firstly, once a message is submitted (and moved to Outbox) it cannot be touched - it belongs to the spooler.
Secondly, you cannot send on behalf of an arbitrary user. In case of Exchange, set the MailItem.SentOnBehalfOfName property to the name of the Exchange mailbox on whose behalf the current user can send. In case of POP3/SMTP accounts, set the MailItem.SendUsingAccount property to one of the accounts from the Namespace.Accounts collection.
Related
This SO answer explains how to refresh a Microsoft Outlook mailbox in Powershell using $mapi.SendAndReceive()
I would like to extend the question with:
How can I use Powershell to refresh a specific mailbox in Outlook? For example, if there are 5 mailboxes and I only wish to refresh one.
How can I get Powershell to wait for SendAndReceive() to complete? According to the documentation it is an asynchronous method.
Accepted solution must be in Powershell script.
How can I get Powershell to wait for SendAndReceive() to complete
The SyncEnd event of the SyncObject class is fired immediately after Microsoft Outlook finishes synchronizing a user's folders using the specified Send/Receive group.
Dim WithEvents mySync As Outlook.SyncObject
Sub Initialize_handler()
Set mySync = Application.Session.SyncObjects.Item(1)
mySync.Start
End Sub
Private Sub mySync_SyncEnd()
MsgBox "Synchronization is complete."
End Sub
How can I refresh a specific mailbox in Outlook?
A Send\Receive group lets users configure different synchronization scenarios, selecting which folders and which filters apply.
Use the Item method to retrieve the SyncObject object from a SyncObjects object. Because the Name property is the default property of the SyncObject object, you can identify the group by name.
The SyncObject object is read-only; you cannot change its properties or create new ones. However, note that you can add one Send/Receive group using the SyncObjects.AppFolders property which will create a Send/Receive group called Application Folders.
The Start method of the SyncObject class begins synchronizing a user's folders using the specified Send\Receive group.
Public Sub Sync()
Dim nsp As Outlook.NameSpace
Dim sycs As Outlook.SyncObjects
Dim syc As Outlook.SyncObject
Dim i As Integer
Dim strPrompt As Integer
Set nsp = Application.GetNamespace("MAPI")
Set sycs = nsp.SyncObjects
For i = 1 To sycs.Count
Set syc = sycs.Item(i)
strPrompt = MsgBox( _
"Do you wish to synchronize " & syc.Name &"?", vbYesNo)
If strPrompt = vbYes Then
syc.Start
End If
Next
End Sub
I am trying to add the field FROM in my matlab function to send an email with outlook.
This function works (without the from):
function sendolmail(to,subject,body,attachments, from)
%Sends email using MS Outlook. The format of the function is
%Similar to the SENDMAIL command.
% Create object and set parameters.
h = actxserver('outlook.Application');
mail = h.CreateItem('olMail');
mail.Subject = subject;
mail.To = to;
mail.BodyFormat = 'olFormatHTML';
mail.HTMLBody = body;
% THIS PART DOES NOT WORK
if nargin ==5
mail.From = from;
end
% Add attachments, if specified.
if nargin == 4
for i = 1:length(attachments)
mail.attachments.Add(attachments{i});
end
end
% Send message and release object.
mail.Send;
h.release;
However, when I add from then I get the error:
No public property From exists for class
Interface.00063034_0000_0000_C000_000000000046.
As already stated, there is no From attribute in MailItem objects. There are many attributes referring to the sender: Sender, SenderEmailAddress, SenderEmailType, SenderName... but all of them, except Sender, are read-only. This means they cannot be set, and you must rely uniquely on the Sender property, which accept object instances of type AddressEntry.
I'm not sure that this will work, because such mechanic would be easily abused by malicious users... but you can try the following:
if (nargin == 5)
recipient = h.Session.CreateRecipient(from);
mail.Sender = recipient.AddressEntry;
end
Here are all the properties of the MailItem class, which is what you are creating through this interface: https://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.mailitem_members.aspx
It looks like you need to set either Sender or SendUsingAccount. However, since neither of these take strings, you'll have to retrieve an object of the appropriate type using the matlab interface. It seems to me that you should be able to use
mail.SendUsingAccount= h.Session.Accounts.Item(3); %Select the third account
to set this property; however, it seems like there may be some issues with that, according to this source. Unfortunately, I don't have outlook setup, some I'm not able to try it myself.
I've posted here before under a different account name and thanks all for previous help.
I have a spreadsheet which extracts information from a Data Historian, to generate a report on the status of the factory which is then automatically emailed out via Lotus Notes to recipients at fixed time intervals.
Sometimes there may be network issues affecting either the factory DCS, Data Historian (Aspen), or Lotus Notes. This gives a run time error when the script runs. Usually all that is required is to end the script, wait a period of time, recalculate the sheet, and then re-run the script.
Was hoping somebody could advise what code to add to achieve this. All I really need to know is what code to write and where to insert it to end the script in the event of a run-time error, and then to trigger another sub-routine in which I can add an application.wait and application.calculate before re-running the script. I need the script to end and run a separate sub as it causes issues with multiple scheduled events otherwise which then ultimately sends out multiple emails.
I've marked the part of the script that usually fails.
Sub Macro6()
Windows("Silo report 2 hourly.xlsm").Activate
' Range("A1").Select
'Calculate all workbooks
Application.Calculate
'Set up the objects required for Automation into lotus notes
Dim Maildb As Object 'The mail database
Dim UserName As String 'The current users notes name
Dim MailDbName As String 'THe current users notes mail database name
Dim MailDoc As Object 'The mail document itself
Dim AttachME As Object 'The attachment richtextfile object
Dim Session As Object 'The notes session
Dim EmbedObj As Object 'The embedded object (Attachment)
'Start a session to notes
Set Session = CreateObject("Notes.NotesSession")
'Next line only works with 5.x and above. Replace password with your password
'Get the sessions username and then calculate the mail file name
'You may or may not need this as for MailDBname with some systems you
'can pass an empty string or using above password you can use other mailboxes.
UserName = Session.UserName
MailDbName = Left$(UserName, 1) & Right$(UserName, (Len(UserName) - InStr(1, UserName, " "))) & ".nsf"
'Open the mail database in notes
Set Maildb = Session.GETDATABASE("", MailDbName)
If Maildb.IsOpen = True Then
'Already open for mail
Else
Maildb.OPENMAIL
End If
'Set up the new mail document
Set MailDoc = Maildb.CreateDocument
MailDoc.Form = "Memo"
vaRecipient = VBA.Array("xxx.xxx#xxx.com", "yyy.yyy#yyy.com", "zzz.zzz#zzz.com")
MailDoc.SendTo = vaRecipient
MailDoc.Subject = Range("B1").Value
Set workspace = CreateObject("Notes.NotesUIWorkspace")
'**THE RUNTIME ERROR USUALLY OCCURS WITHIN THE NEXT 5 LINES OF SCRIPT**
Dim notesUIDoc As Object
Set notesUIDoc = workspace.EditDocument(True, MailDoc)
Call notesUIDoc.GOTOFIELD("Body")
Call notesUIDoc.FieldClear("Body")
Call notesUIDoc.FieldAppendText("Body", Range("B9").Value & vbCrLf & vbCrLf & Range("b10").Value & Range("I10").Value & Range("D10").Value & vbCrLf & Range("b11").Value & Range("I11").Value & Range("D11").Value & vbCrLf & Range("b12").Value & Range("I12").Value & Range("D12").Value & vbCrLf & vbCrLf & Range("b13").Value & Range("I13").Value & Range("D13").Value & vbCrLf & vbCrLf & Range("b14").Value & Range("C14").Value & Range("D14").Value & vbCrLf & vbCrLf & Range("b15").Value & Range("I15").Value & Range("D15").Value & vbCrLf)
notesUIDoc.Send
notesUIDoc.Close
MailDoc.PostedDate = Now() 'Gets the mail to appear in the sent items folder
'MailDoc.Send 0, vaRecipient
'Clean Up
Set Maildb = Nothing
Set MailDoc = Nothing
Set AttachME = Nothing
Set Session = Nothing
Set EmbedObj = Nothing
End Sub
In LotusScript as well as in Visual Basic / VBA the error handling works exact the same. At the beginning of your Script you define where to go if an error occurs:
On Error Goto ErrorHandler
Place a Jump- Mark above the line, where you want to start over, when the error occurs:
TryAgain:
At the very end of your sub you define the errorhandler itself:
EndSub:
'- prohibit that error handler is called without an error
Exit Sub
ErrorHandler:
'- here you can react on the error, e.g. check for the err (Error number)
If err = NumberOfErrorThatOccursWhenNetworkErrorOccurs then
'- wait some time to give the network time to recover
Sleep x '- put in x as best for your problem
'- jump back
Resume TryAgain
Else
'- another error occured: inform user
Messagebox err & ", " & Error & " in line " & Erl
'- now jump to the end of the sub
Resume EndSub
End If
Of course this is a minimal errorhandling, and probably you would not want to jump around without further checks, but the idea should be clear with this example.
Just one more thing from the comments: you don't need the ui- stuff at all! Just omit it, as it is totally unneccessary and makes your code unstable.
Replace the whole paragraph starting with Set workspace... ending with notesUIDoc.close with two lines of code:
Call Maildoc.ReplaceItemValue( "Body", Range("B9").Value ..... )
Call Maildoc.Send( False )
Then you don't have to take care if something goes wrong - the document will just be discarded when the code runs again or ends, and it will be much more stable than handling ui windows and the screen will not flicker...
I know Access can setup an Outlook Task to auto-export query to Excel, but it requires the Outlook to be always open on the user's computer.
Is there an easy way to setup a schedule that can automatically export a query to Excel and this schedule will then auto-email the exported Excel file to an email address every Monday at 5AM for example?
If this can only be done in VBA, any reference I may start with?
Thanks.
I do not think you can do this with Access. You can use a tool like these:
http://www.r-tag.com
http://www.hybing.com/Report-Genie.html
They are able to get data from a database, export it to excel and email it. Report genie is cheap although it is pretty old software and I don't know if it has any support. I don't think there is a way to schedule tasks too. R-Tag has paid and free version. Both versions will allow you to schedule a task to export data from any database to excel and email the file. There are some restrictions for the free version.
I don't know how to schedule it, but this may give you a good start:
If Weekday(Now(), 2) = 1 Then
If Forms![Head Form]![Once subform].Form![ID] = 0 Then
DoCmd.OpenQuery "UpdateOnce1", acViewNormal, acEdit
DoCmd.SetWarnings False
DoCmd.OpenReport "Report1", acViewPreview
DoCmd.RunSavedImportExport "Export-Report 1"
Dim strSql
Dim db As Database
Set db = CurrentDb()
Dim Outlook
Dim rng
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "number of mail adresses"
.CC = ""
.BCC = ""
.Subject = "Report 1"
.HTMLBody = ""
.Attachments.Add ("T:\.....\Report1.pdf")
.Send
End With
DoCmd.Close acReport, "Report1"
End If
End If
So if it is monday, and the code hasn't run yet (it checks if the ID equals 0), Report 1 is openend, exported to PDF, added as an attachment and then mailed via outlook.
I see scheduler like feature in salesforce but it is somewhat tied with existing features that salesforce provide and no sample source code is provided as far as my research goes.
What I want to do is to create my own scheduler that sends simple email based on date.
Goal:
Custom Object Player has fields
startDate : date like '2010-11-01'
email : text field like foo#bar.com
name : player's name like John.
If today's date is one day before the startDate, I want to send email to the Player.
For instance, Player's name is John and if today is 2010-12-10 and one Player's startDate is set to 2010-12-11, email saying "hello John" is sent.
Unfortunately I cannot find good example or tutorial online or salesforce doc how to do this using Apex.
Could anyone point out where to get started?
UPDATE
I want to extend the answer from eyescream.
After setting scheduler, you can set what follow up action to take like sending email using template or set custom object fields to some values.
Below I found useful for people using email template in Visualforce format.
I have custom object 'alertTester' which has reference to other object 'custom' and even this object 'custom' has reference to another object 'custom1GrandChild' and all the relationship (up to 3 or 5 layers I think) can be accessed like below.
I've tested below and works fine. Now I'm receiving email with my condition set :)
<messaging:emailTemplate subject="Hello" recipientType="User" relatedToType="alertTester__c" >
<messaging:plainTextEmailBody >
{!relatedTo.name}
{!relatedTo.custom__r.name}
{!relatedTo.custom__r.custom1GrandChild__r.name}
</messaging:plainTextEmailBody>
</messaging:emailTemplate>
Check out solutions that don't involve code before you'll dive deeply to Apex...
Email Alert + Workflow Rule should provide you with all functionality you need in this scenario and involve just clicking without any code.
I'm answering to my own question again..
Below link, search for schedule
http://www.salesforce.com/us/developer/docs/apexcode/index.htm
Looks like Apex has Schedulable interface that I can implements and set up cron task.
Below is sample code provided in the doc:
global class TestScheduledApexFromTestMethod implements Schedulable {
// This test runs a scheduled job at midnight Sept. 3rd. 2022
public static String CRON_EXP = '0 0 0 3 9 ? 2022';
global void execute(SchedulableContext ctx) {
CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime
FROM CronTrigger WHERE id = :ctx.getTriggerId()];
System.assertEquals(CRON_EXP, ct.CronExpression);
System.assertEquals(0, ct.TimesTriggered);
System.assertEquals('2022-09-03 00:00:00', String.valueOf(ct.NextFireTime));
Account a = [SELECT id, name FROM Account WHERE name =
'testScheduledApexFromTestMethod'];
a.name = 'testScheduledApexFromTestMethodUpdated';
update a;
}
}