In our company .xlsm, I'm using "standard" macro to send e-mails via Outlook:
Dim olApp As Object, olMail As Object
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If olApp Is Nothing Then
Set olApp = CreateObject("Outlook.Application")
End If
On Error GoTo 0
Set olMail = olApp.CreateItem(0)
With olMail
'properties, methods, events
End With
The thing is, it works on all company computers except for one. On this one:
If Outlook client is closed when running macro, everything works fine;
If Outlook client is opened when running macro, it returns Error '91' (Object variable not set) on Set olMail = olApp.CreateItem(0).
What could be the cause?
Your Excel Application must be run under the same security context with Outlook running to be able to get the running instance.
If Outlook client is opened when running macro, it returns Error '91' (Object variable not set) on Set olMail = olApp.CreateItem(0).
If you run Excel with admin privileges you need to run Outlook as well with admin privileges to be able to connect them together.
Also you may try to use the early-binding technology instead of late-binding one. For that you need to add an Outlook COM reference in the Excel COM References dialog (see the VBA editor). Read more about that in the Using early binding and late binding in Automation article.
Related
I wrote a script on excel vba for SAP GUI and used to work fined but currently I'm getting
Run time error'91': object variable or with block variable not set
This error happens on the below bolded set objConn = objgui.children(0) line.
I always have the page logon to proceed but its keep giving me error.
Additionally, the scripting function does not work on SAP either. It used to work but not anymore. When I record it and play it back it says it can't find the file.
Scripting is enabled. I can press the red record button and finish record by yellow square button but nothing is getting recorded and no files are saved. However, it says:
SAP frontend server: Scripting support is disabled on the server
Option Explicit
Public SapGuiAuto
Public objGui As GuiApplication
Public objConn As GuiConnection
Public session As GuiSession
Sub dd()
Dim i As Integer
Dim lastrow As Long
Set SapGuiAuto = GetObject("SAPGUI")
Set objGui = SapGuiAuto.GetScriptingEngine
# Set objConn = objGui.Children(0)
Set session = objConn.Children(0)
lastrow = ThisWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row 'Define where is last row
On Error Resume Next
For i = 2 To lastrow 'Row 2 to lastrow will be inputted
If ActiveSheet.Cells(i, 1) = "Z2" Then
session.findById("wnd[0]/tbar[0]/okcd").Text = "niw21" 'Input niw21 t-code in SAP
End If
Next i
End Sub
I tried remove and install the SAP Logon 770.
I made sure the reference is added on the VBA (SAP GUI Scripting API).
You should make sure that you have installed your SAP GUI software with the component "SAP GUI Scripting" selected, otherwise you can't use SAP GUI Scripting from your laptop.
NB: to enable Server-Side Scripting (source: this question):
Start the SAP Logon and log in to the SAP server.
Run the ‘RZ11’ transaction (type ‘RZ11 ‘and click the green tick button)
Type ‘sapgui/user_scripting’ in the Maintain Profile Parameters window.
Click the ‘Display’ button
Click ‘Change Value’ in the Display Profile Parameter Attributes window.
Type ‘TRUE’ in the ‘New value’ field.
Save the settings and log out from SAP Logon.
Exit from the SAP Logon program (click the red cross button in the toolbar, or click the ‘X’ window button to close the window and the application). You may be prompted to save any unsaved changes, if you haven’t done so already.
If you're not authorized, please ask the SAP system administrator.
I'm working with VBA and GuiXT separated and now I'm trying to use the SAP GUI VBA integration instead, but i think it's not working because I'm missing a permission.
I tried the code I've found in this thread:
Sub test()
Dim SapGuiAuto As Object
Dim SAPApp As Object
Dim SAPCon As Object
Dim session As Object
Set SapGuiAuto = GetObject("SAPGUI")
Set SAPApp = SapGuiAuto.GetScriptingEngine
Set SAPCon = SAPApp.Children(0)
Set session = SAPCon.Children.ElementAt(0)
SAPCon.FindById("wnd[0]").Maximize
End Sub
It runs and SAP informs me that a script tries to connect to SAP, but the line Set session = SAPCon.Children.ElementAt(0) gives me error 614: "The enumerator of the collection cannot find en element with the specified index".
So I googled and found out, that I'm missing the option "Script recording and playback" in SAP, it's greyed out. And i googled further and I found out, that I'm missing the permission to record or playback a script.
Because of that I'd like to know: if I don't have the permission in SAP to record or playback a script, then that's the reason for my not working VBA code, right?
The following Excel VBA code stopped working after upgrading from Office 2010 on Windows 7 to Office 365 on Windows 10.
Sub readbodytest()
Dim OL As Outlook.Application
Dim DIB As Outlook.Folder
Dim i As Object 'Outlook.ReportItem
Dim Filter As String
Set OL = CreateObject("Outlook.Application")
Set DIB = OL.Session.GetDefaultFolder(olFolderInbox)
Const PR_SENT_REPRESENTING_EMAIL_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x0065001E"
Filter = "#SQL=" & _
"""" & PR_SENT_REPRESENTING_EMAIL_ADDRESS & """ ci_phrasematch 'mailer-daemon' OR " & _
"""" & PR_SENT_REPRESENTING_EMAIL_ADDRESS & """ ci_phrasematch 'postmaster' OR " & _
"urn:schemas:httpmail:subject ci_phrasematch 'undeliverable' OR " & _
"urn:schemas:httpmail:subject ci_phrasematch 'returned'"
For Each i In DIB.Items.Restrict(Filter)
Debug.Print i.Body '<< Code fails here
Next
Set i = Nothing
Set DIB = Nothing
Set OL = Nothing
End Sub
In Excel, it returns
runtime error -2147467259 “Method 'Body' of object '_MailItem' failed”
The code will work when run directly in Outlook VBA, but not when run externally.
The purpose of the code is to do a bulk review of returned mail items, match information in the body of the email to a record on a database, and update the database to record the failure.
Looking to see if anyone has any suggestions before I re-write the code to run in reverse (from Outlook VBA to Excel; instead of Excel trying to retrieve from Outlook).
It makes sense to use the Logon method of the Application class which logs the user on to MAPI, obtaining a MAPI session. Here is what MSDN says:
Use the Logon method only to log on to a specific profile when Outlook is not already running. This is because only one Outlook process can run at a time, and that Outlook process uses only one profile and supports only one MAPI session. When users start Outlook a second time, that instance of Outlook runs within the same Outlook process, does not create a new process, and uses the same profile.
If Outlook is not running and you only want to start Outlook with the default profile, do not use the Logon method. A better alternative is shown in the following code example, InitializeMAPI: first, instantiate the Outlook Application object, then reference a default folder such as the Inbox. This has the side effect of initializing MAPI to use the default profile and to make the object model fully functional.
Second, I'd suggest checking the item type before accessing any properties. Not all items may contain such properties.
Another possible pitfall and most probably that is a security issue when dealing with the Outlook object model. When you try to access any sensitive property Outlook may trigger a security issue (it may be an error in the code or UI guard/prompt). "Security" in this context refers to the so-called "object model guard" that triggers security prompts and blocks access to certain features in an effort to prevent malicious programs from harvesting email addresses from Outlook data and using Outlook to propagate viruses and spam. You can use the following ways to bridge the gap:
The Security Manager for Outlook component allows to turn prompts off/on at runtime.
Use the low-level code which doesn't generate security prompts. Or any other third-party wrappers around that API (for example, Redemption).
Deploy a group policy to avoid security prompts.
Running an up-to-date antivirus software.
This question already has answers here:
Suppress dialog warning that a program is trying to access my mails
(3 answers)
Closed 4 years ago.
How to stop OutLook Security Message :
A program is trying to access e-mail addresses, Allow access for 1 Minutes
I want to stop this alert programatically and want to allow vba to access inbox of outlook,, since I dont have admin access for the outlook, I cant solve this manually going to trust center settings in outlook
My code works perfectly fine but op up security msgs need to check access for 10min again and again
Using excel vba I'm accessing outlook mails and downloading attachments from mail
Dim sa, ba As Date
Dim spa As Date
Set ObjO = CreateObject("Outlook.Application")
Set olNs = ObjO.GetNamespace("MAPI")
Set objFolder = olNs.GetDefaultFolder(6)
Debug.Print objFolder
spa = Date
Dim j
j = 0
For Each item1 In objFolder.Items
sa = Format(item1.ReceivedTime, "dd-MM-yyyy")
If sa <= spa Then
If sa > spa - 30 And item1.SenderName = "PUJARY, SHRIKANTH" Then
At execution of item1.senderName line that security alert is popping up
Ran into the same thing, there is no simple solution. In essence, the popup is there to prevent the exact thing you are trying to do: Controlling Outlook remotely. It was build as a defence against VBA/Macro viruses. So no, you cannot prevent this.
Solutions are to use the Extended Messaging API (MAPI) instead, but thats no easy task. Helper libraries can be bought, for example vbMAPI or Outlook Redemption
What's the difference? While the VBA method allows you to grab into a running instance of Outlook, MAPI requires you to log into the MAPI profile using username/password. This hasn't the security problems that tapping into Outlook has and is thus safe.
If using Redemption (I am its author) is an option, modifying your script in a couple places would make it run without security prompts:
dim sItem
set sItem = CreateObject("Redemption.SafeMailItem")
For Each item1 In objFolder.Items
sItem.Item = item1
sa = Format(item1.ReceivedTime, "dd-MM-yyyy")
If sa <= spa Then
If sa > spa - 30 And sItem.SenderName = "PUJARY, SHRIKANTH" Then
We have a lot of emails saved to a folder on the file system to be processed by extracting text from the message bodies. Office 2010.
Dim app As Object
Dim msg As Object
dim msg_body as string
Set app = New Outlook.Application
Set msg = app.CreateItemFromTemplate("c:\path\to\message.msg")
msg_body = msg.body
This code works fine on my laptop however when I use it on the work network it gives error '287'.
While debugging I noticed that I can view msg msg.display and even change the body with msg.body = "some text". However I cannot read the message body. Also tried msg.HTMLbody which could not be read.
The most probable cause is your company's policies.
Check this registry key to solve the SaveAs (change the 16 to your office version).
hkcu\software\policies\microsoft\office\16.0\outlook\security\promptoomsaveas
You can change the value to 2, or ask your system administrator to create a new GPO.
More information on this and other security configurations in:
https://support.microsoft.com/en-za/help/926512/information-for-administrators-about-e-mail-security-settings-in-outlo