I have an excel userform a screen shot of which I would like to include in an outlook email. It works fine on my main programming computer, but when I run the same program on other computers I get the above error. The excel workbook is in the cloud and is run from the cloud (google drive) on various computers. the code is:
Function outlookEmail()
Dim doc As Object, rng As Range
Application.SendKeys "(%{1068})"
DoEvents
'ActiveSheet.Paste
With CreateObject("Outlook.Application").CreateItem(0)
.display
Set doc = .GetInspector.WordEditor
doc.Range(0, 0).Paste
.To = sDetail.Cells(myRow, headerDict.item("email"))
.Subject = "documents for you"
End With
End Function
the error is on the set doc line, if I mark it out, the error moves the the next line: doc.range...
Outlook is a singleton. That means you can't run two instances of the application at the same time. If the Outlook Application is already running under the different security context you may get into troubles. So, I'd suggest checking whether Outlook is already running and make sure it is running under the same security context, so you could reach the instance.
You can use the Visual Basic GetObject function to return a reference to the Application object that represents a session that is already running. Note that because there can be only one instance of Outlook running at any given time, GetObject usually serves little purpose when used with Outlook. CreateObject can always be used to access the current instance of Outlook or to create a new instance if one does not exist. However, you can use error trapping with the GetObject method to determine whether Outlook is currently running.
Read more about that in the Automating Outlook from Other Office Applications article.
Related
I created an Excel VBA that check for data in the cells and send email with WorkBook_Open().
Option Explicit
Private Sub Workbook_Open()
'Declaring variables
Dim notifyEmailApplication As Object
Dim notifyEmailContent As Object
Dim triggerEmailApplication As Object
Dim triggerEmailContent As Object
'Create email object
Set notifyEmailApplication = CreateObject("Outlook.Application")
Set notifyEmailContent = notifyEmailApplication.CreateItem(0)
Set triggerEmailApplication = CreateObject("Outlook.Application")
Set triggerEmailContent = triggerEmailApplication.CreateItem(0)
...
I then created a VBScript to run the Excel file.
Call ExcelMacro
Sub ExcelMacro()
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open("....\Email Automation.xlsm", 0, False)
xlBook.Close
Set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
End Sub
I also created a cmd file to run the VBScript on cscript.exe
cscript.exe "....\vbscript.vbs"
exit
Whenever I trigger the cmd file manually (double clicking it), the Excel Macro runs perfectly and successfully send email to the designated person.
But when I use Task Scheduler to run the cmd file, the Excel Macro does not run successfully and this line was highlighted.
Set notifyEmailApplication = CreateObject("Outlook.Application")
Notes: I already viewed a lot of forums and didn't find a fix:
In 'dcomcnfg' I already set Outlook Message Attachment to Interactive User
I tried changing Dim notifyEmailApplication As Object to Dim notifyEmailApplication As Outlook.Application, same line is highlighted
I already added Outlook Object Library as reference in Excel VBA
But when I use Task Scheduler to run the cmd file, the Excel Macro does not run successfully
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
Read more about that in the Considerations for server-side Automation of Office article.
If you deal with open XML documents you may consider using the Open XML SDK instead, see Welcome to the Open XML SDK 2.5 for Office for more information. Also take a look at any third-party components designed for the server-side execution (they don't require Office installed on the system).
I haven't touched this topic for many years, but as I remember, from a long time ago, the Task Scheduler allows, or requires, you to enter your Windows password and if the password is incorrect it won't notify you of the error, so it seems like it's working, but with the incorrect password, it won't work. Can you double-check that your Windows password is entered correctly?
That's basically my question. Doing googling didn't return anything that I am looking for, but basically I am running SOLIDWORKS from Excel and for that I need "sldworks 2016 Type Library" and "SOLDIWORKS 2016 Constant Type Library" to be enabled. Of course you'd say to do it manually, BUT my program is being run both, by people with and without Solidworks installed and if a user doesn't have SOLDIWORKS on their PC - the entire thing won't even run. So I am looking to enable and disable those two type libraries upon necessity in the code.
Could, someone, please help me?
P.S. I am not looking for any workarounds etc.
BUT my program is being run both, by people with and without Solidworks installed and if a user doesn't have SOLDIWORKS on their PC - the entire thing won't even run.
Is this what you are trying? The below code will first try to bind with an open instance of SOLIDWORKS. If it is not open, then it will try to create a new instance. Obviously if SOLIDWORKS is not installed then the CreateObject will fail but the code will not crash because of On Error Resume Next. Finally check if objSolid is not nothing. This is late binding and you do not have to set any references.
Dim objSolid As Object
'~~> Establish an SOLIDWORKS application object
On Error Resume Next
Set objSolid = GetObject(, "SldWorks.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then Set objSolid = CreateObject("SldWorks.Application")
Err.Clear
On Error GoTo 0
If objSolid Is Nothing Then
MsgBox "SOLIDWORKS not installed"
Exit Sub
End If
'
'~~> Rest of your code
'
EDIT
You cannot say Solidworks is not properly documented without putting in the right efforts to search. It took me less than 30 seconds to find this SOLIDWORKS Example of Late Binding. Of course their code will fail if the user doesn't have SOLIDWORKS and that is because they have not done proper error handling. My answer above does that for you.
Their website has all the information that you need. You just need to put in the right efforts to search. As I mentioned in the chat below, when you convert the code into late binding, you will have to search for the value of those constants. No one will give them to you in a platter. :) You can either search Google with swDocPART Constant value or as #FunThomas pointed out, type ?swDocPART in Immediate Window to get the value when the reference to SOLIDWORKS has been established.
System Details.
Windows 10
Excel 365 64-bit V16.0 (Apps for Enterprise)
Issue.
I have a macro that opens a file, checks if the user has allowed programmatic access to the VBA Project in the trust center and raises an alert if they have not. This works fine on windows 7 machines with both 32bit and 64bit Excel from 2013 onwards.
The specific problem I am having on the Windows 10 machine is that when workbooks.open(path) is executed the file opens but in the VBA Project explorer window the VBAProject object for that file does not appear. I also get a popup saying that code cannot be run in break mode when I try this while stepping through the code. When run on Win 7 with this version of Excel and others both 32 and 64-bit the VBAProject object appears and no popup is generated.
This lack of the VBA Project causes an issue later when I run set vbproj = ActiveWorkbook.VBProject. At this point when stepping through the code execution halts with no messages at all. The Project pops up in the Project explorer window and it takes me to a module in the opened workbook. This gets opened with Design Mode turned on and when you click to turn it off I get an error message saying 'Macros have been disabled'
Notes
set vbproj = ActiveWorkbook.VBProject works fine if the file is open and the VBAProject is visible in the Project explorer window.
If the file being opened does not contain a macro then it works correctly.
I have made sure that the files are in a Trusted Location.
I have set Enable all macros in the Macro Settings of the Trust Center.
When opening the files manually I do not get any alerts that macros have been disabled by an administrator and I do not get any message asking if I want to enable macros.
I have looked at W10 group policies to see if there is one that would block VBAProjects / Macros from files opened via VBA and there does not appear to be one as far as I can see.
The Trust Center setting for programmatic access to the VBA Project does not matter to this test case. It will return True if it is allowed and False if it is not allowed.
This has been tested on another Windows 10 laptop with the same version of Excel 64-bit and it has the same result so is not an issue with a specific users laptop.
I removed the folder from the Trusted Location on the Windows 7 machine and the code still executes correctly and returns True/False.
In the actual macro this check is done for each opened file in a loop and the variant vbproj is used to remove data from the modules within that project. I have considered working around the issue by using Application.onTime and that may be a solution but have not spent much time on that and with how it halts it may not be viable.
Attempted Solutions
I have tried set wb = workbooks.open(path) to open the workbook and then using set vbproj = wb.VBProject but it has the same behavior as above.
I have tried doing ActiveWorkbook.Activate and similar actions to see if that will make the VBA project appear, it does not.
I have tried setting Application.FileValidation = msoFileValidationSkip before opening the file, this does not change the behavior.
I have tried setting Application.EnableEvents=False before opening the file, this does not change the behavior.
I have tried making vbproj a variant, an object and a VBProject, this does not change the behavior.
Steps to Recreate
Create a new workbook.
Put the below code into Module 1.
Function projectAccess()
Dim vbproj As Variant
On Error GoTo noaccess
Set vbproj = ActiveWorkbook.VBProject 'If access is denied an error is raised.
projectAccess = True
Exit Function
noaccess:
projectAccess = False
End Function
Sub openfile()
Dim filepath As String
filepath = Application.ThisWorkbook.Path
Workbooks.Open (filepath & "\openfile.xlsm")
Debug.Print projectAccess
End Sub
Save the workbook
Create a 2nd workbook, in my case it was called openfile.xlsm and put some code into Module 1.
put both workbooks in the same location and make sure it is a Trusted Location in Excel.
run openfile().
If successful the immediate window will display True / False depending on the Trust Center setting.
I am out of ideas. Any suggestions for some setting that I may have overlooked to make the Win 10 machines behave the same as the Win 7 machines or suggestions for a possible work around?
Even if it is a group policy setting that would be something I can raise with IT as long as I know what to ask for.
Many Thanks
Andrew
EDIT: Thanks to Rory in the comments the issue was making sure that the automation security was set like so Application.AutomationSecurity = msoAutomationSecurityLow as the way the new Win 10 + Office 64 systems have been set up by my IT dept is to have it default to msoAutomationForceDisable
I'm trying to implement a bootstrap installer for my add-ins workbook, such that I can easily install the add-in for new users and send out updates. It works fine on my machine, but when having others test it, I get a runtime error when I try to call Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True). Specifically, the error is "1004: Unable to get the Add property of the AddIns class". I thought this was because the user needed to have "Trust access to the VBA project object model" enabled, but the error seems to occur even after they've toggled that box.
Other things I've checked:
The fullPath to the add-in is valid and the user can access the directory and the file
The user has the folder located at Application.UserLibraryPath
Any ideas?
Figured it out. It appears that the issue isn't one of permissions, but rather of whether a workbook is already open. Opening any workbook before running the Addins.Add prevented the error from occurring so I've simply added that into the program:
If Application.Workbooks.Count = 0 then Set wb = Application.Workbooks.Add()
Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True)
If not wb is nothing then wb.Close
Duke, perhaps it's the Trust Center settings on the recipients' machines. I have found this and may be helpful.
Best,
Danny
Check out VBA videos on ExcelVBADude on YouTube.
I have the following code, that should save a specific Excel file attached to an email. The code is combined with a rule, that trigger this script when an emai lwith a specific subject is received.
The code is triggered, but here comes the strangest error I saw lately: itm.Attachments.Count appear to be zero and obviously the file is not saved! But... if I put a breakpoint on "For each..." line and add itm.Attachments.Count to watch window, it is shown as zero. If I add itm only, then browse to Attachments property, then to Count property it shows 1 for Count (as it should) and the code is executed fine. I spent half a day trying to understand what's going on, but I can't figure it out.
The behaviour is the same both on a Outlook 2010 x64 on a Windows 7 x64 and on a Outlook 2010 x86 on a Windows 7 x86. Macros are enabled in Trust Center. I have attached some screenshot with the code and rule settings and also a movie showing the watch windows strangeness.
The script was built some time ago and it worked well on a couple of PCs and it was based on the steps from here: iterrors.com/outlook-automatically-save-an-outlook-attachment-to-disk/.
Any ideas?
Rule screen here
1 min. movie here
Public Sub Kona(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "C:\test"
For Each objAtt In itm.Attachments
If InStr(objAtt.DisplayName, "Kona Preferred Fixed Price Matrix (ALL)") Then
objAtt.SaveAsFile saveFolder & "\" & objAtt.DisplayName
End If
Set objAtt = Nothing
Next
End Sub
In case if you have an IMAP account configured in Outlook: your Offline Settings might be set to only store up to 1 month, 3 months, 12 month worth of emails on your local disk.
If you’ve got enough space on your disk and want to cache more emails locally, you can set the sync slider in the following way:
File-> Account Settings-> Account Settings…-> double click on your IMAP account.
Try to increase the offline storage in Outlook. See Empty Inbox and other IMAP synching issues in Outlook 2013 for more information.
My best understanding of this behavior is that Microsoft Outlook (at least the versions of 2010 that I tested) has a bug. There may be other factors that I'm not aware of contributing to this, but I was able to reproduce the error using different service pack levels / builds of Outlook 2010 on Windows Vista. Office 2013 does not appear to be affected.
I managed to create a workaround.
I found that by displaying the message while stepping through the code in debug mode using
objMailItem.GetInspector.Activate
the number of attachments was subsequently correctly detected (without having to do strange things like setting up a watch for the object variable and then clicking on it in the IDE).
However, this only worked while stepping through the code, not during normal execution.
For this reason, I suspected the message might not be displaying long enough during normal code execution for Outlook to get the twist out of its knickers. I reasoned that it might be possible to insert a delay to allow sufficient time for this.
I tried out several methods of inserting a delay. Here is the one that worked for me. I created a form called
frmTimer
and added the freeware RSTimer OCX control (http://www.softpedia.com/get/Programming/Components-Libraries/RS-Timer.shtml) to it.
I set the
Interval
property of the OCX to 1000 ms.
The form is loaded right after displaying the message like this:
objMailItem.GetInspector.Activate
frmTimer.Show ' <-- form is loaded and displayed (it is not sufficient to just 'load' it)
objMailItem.Close OlInspectorClose.olDiscard
The form has one single event handler:
Private Sub RSTimer1_Timer()
Unload frmTimer
End Sub
When the event fires, the form is unloaded and code execution continues with
objMailItem.GetInspector.Activate
frmTimer.Show
objMailItem.Close OlInspectorClose.olDiscard ' <-- code execution continues here
Here is a complete function that allows the attachment to be detected correctly.
Function EmailHasAttachments(ByVal objMailItem As Outlook.MailItem) As Boolean
On Error GoTo ErrHandler
objMailItem.GetInspector.Activate
frmTimer.Show
objMailItem.Close OlInspectorClose.olDiscard
If objMailItem.Attachments.Count > 0 Then
EmailHasAttachments = True
Else
EmailHasAttachments = False
End If
ExitHere:
Exit Function
ErrHandler:
Debug.Print Err.Number, Err.Description
Select Case Err.Number
Case 12345
' handle the error
Case Else
MsgBox "An unknown error has occurred."
Exit Function
End Select
End Function