Can't add attachment to email using VBA - excel

I am having a very strange problem with this code. The general purpose is to save user data from a form in Access to a spreadsheet in Excel, and then use an email client to send an email containing the spreadsheet attachment. The code is as follows
Private Sub Send_Email_Click()
Dim MySheetPath As String
Dim Xl As Excel.Application
Dim XlBook As Excel.Workbook
Dim XlSheet As Excel.Worksheet
' Tell it location of actual Excel file
MySheetPath = "\\SERVER\Users\Public\Documents\WORK ORDERS\Blank Work Order.xlsx"
'Open Excel and the workbook
Set Xl = CreateObject("Excel.Application")
Set XlBook = GetObject(MySheetPath)
'Make sure excel is visible on the screen
Xl.Visible = True
XlBook.Windows(1).Visible = True
'Define the sheet in the Workbook as XlSheet
Set XlSheet = XlBook.Worksheets(1)
'Insert values in the excel sheet starting at specified cell
XlSheet.Range("B6") = Jobnameonform.Value
XlSheet.Range("C7") = Companynameonform.Value
XlSheet.Range("C8") = Employeename.Value
XlSheet.Range("H7") = Jobnumberonform.Value
Xl.ActiveWorkbook.Save
Xl.ActiveWorkbook.Close
Xl.Quit
'in case something goes wrong
Set Xl = Nothing
Set XlBook = Nothing
Set XlSheet = Nothing
Dim cdomsg
Set cdomsg = CreateObject("CDO.message")
With cdomsg.Configuration.Fields
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'NTLM method
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/smptserverport") = 587
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "matthewfeeney6#gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "REDACTED"
.Update
End With
' build email parts
With cdomsg
.To = "matthewfeeney6#gmail.com"
.From = "matthewfeeney6#gmail.com"
.Subject = "Test email"
.TextBody = "Did you get the attachment?"
.AddAttachment "\\SERVER\Users\Public\Documents\WORK ORDERS\Blank Work Order.xlsx"
.Send
End With
Set cdomsg = Nothing
MsgBox "Completed"
End Sub
Without the line ".AddAttachment..." The code works exactly as intended, minus sending the attachment of course. However, with that line, I get a runtime error 91, with the debugger citing the line "Xl.ActiveWorkbook.Save" as the problematic code. Also, without the code to modify the excel spreadsheet, the simple email portion does work, attachments included. If anyone can provide insight as to why I am getting this error, that would be very helpful. Thanks in advance!
EDIT: Retesting the code, it seems to consistently crash at Xl.ActiveWorkbook.Save I thought it worked before, but I must have been mistaken

You (think you) are saving and closing your workbook with:
Xl.ActiveWorkbook.Save
Xl.ActiveWorkbook.Close
but that's not the workbook you're using and manipulating, which is XlBook:
Set XlBook = GetObject(MySheetPath)
If you save and close the "real" workbook, XlBook:
XlBook.Save
XlBook.Close
then it should work.
The reason you're getting the error at the Save call probably means that the Xl.ActiveWorkbook object doesn't exist/is null or something.

Related

Graph portion of Excel table in Word with a macro

So for background, I get a excel workbook from another department that is full of a information for a specific account that I then take and use certain parts to create graphs in word. Is there a way I could create a macro what would grab the data from Ex. C22:H34, put it into a template word document and possibly auto populate the graphs as well? I want to make it a process that I can hand off to other people to do, so the simpler it is to execute, the better.
Here is what I have
Sub AutoNew()
'
' AutoNew Macro
'
'
Dim xlapp As Object
Dim xlbook As Object
Dim xlsheet As Object
Dim bstartApp As Boolean
Dim i As Long
On Error Resume Next
Set xlapp = GetObject(, "Excel.Application")
If Err Then
bstartApp = True
Set xlapp = CreateObject("Excel.Application")
End If
On Error GoTo 0
Set xlbook = xlapp.Workbooks.Open("C:\Users\MattsonC\Documents\work\Copy of
3202_2018_Renewal Rate Workbook v2 EDIT.xlsx")
Set xlsheet = xlbook.Sheets(1)
With xlsheet.Range("A1")
For i = 1 To .CurrentRegion.Rows.Count - 1
ActiveDocument.Variables(.Offset(i, 0)).Value = .Offset(i, 2)
Next i
End With
xlbook.Close
If bstartApp = True Then
xlapp.Quit
End If
Set xlapp = Nothing
Set xlbook = Nothing
Set xlsheet = Nothing
ActiveDocument.Range.Fields.Update
End Sub
I have variables done like {DOCVARIABLE LLY} in all the places I want data to go in the template, and renamed the cells in excel with the same variable name.
I can't get any output to happen in my Word document, any suggestions?
Thank you!
go back to the beginning
insert a document variable in a new word document using following sequence (word 2016)
insert tab … text … quick parts … field … categories: document automation … field names: docVariable … put in variable name xxxx
then run this code
Sub aaa()
'ActiveWindow.View.ShowFieldCodes = Not ActiveWindow.View.ShowFieldCodes ' toggle field code view
Stop
ActiveWindow.View.ShowFieldCodes = True
Stop
ActiveWindow.View.ShowFieldCodes = False
ActiveDocument.Variables("xxxx").Value = "abc123"
ActiveDocument.Range.Fields.Update
Stop
ActiveDocument.Variables("xxxx") = "xyz987"
ActiveDocument.Fields.Update
End Sub
if that works, then use the code with the document that you are having trouble with and figure out if your field names are what you think they are

How to insert a hyperlink and table into a cell in the Excel sheet?

This is the code in outlook VBA
Sub Sendmail()
Dim olItem As Outlook.MailItem
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSht As Excel.Worksheet
Dim sPath As String
Dim iRow As Long
Dim strRFIitems As String
Dim Signature As String
sPath = "**"
' // Excel
Set xlApp = CreateObject("Excel.Application")
' // Workbook
Set xlBook = xlApp.Workbooks.Open(sPath)
' // Sheet
Set xlSht = xlBook.Sheets("Sheet1")
' // Create e-mail Item
Set olItem = Application.CreateItem(olMailItem)
strRFIitems = xlSht.Range("E2")
Signature = xlSht.Range("F2")
With olItem
.To = Join(xlApp.Transpose(xlSht.Range("A2", xlSht.Range("A9999").End(xlUp))), ";")
.CC = Join(xlApp.Transpose(xlSht.Range("B2", xlSht.Range("B9999").End(xlUp))), ";")
.Subject = xlSht.Range("C2")
.Body = xlSht.Range("D2") & Signature
.Attachments.Add (strRFIitems)
.Display
End With
' // Close
xlBook.Close SaveChanges:=True
' // Quit
xlApp.Quit
Set xlApp = Nothing
Set xlBook = Nothing
Set xlSht = Nothing
Set olItem = Nothing
End Sub
The code retrieves the data from the linked Excel sheet. Now the
problem is with .Body = xlSht.Range("D2") & Signature this line
of code, where the body of the mail is retrieved from the D2 cell of
Excel sheet.
And as per my requirement, the body of the mail should contain a hyper
link and table along with the text.
Example:
Hello All,
Please update the details in the portal
portal link :http://google.com.
Please contact me for any clarifications.
Below mentioned details needs to be updated:
table has to be inserted here
Suppose above mentioned text is inserted into a cell of Excel.
List item
This portal link: http://google.com. becomes a plain text not a hyper link.
If I try to make it a hyper link the entire cell becomes hyper link. i.e even the text.
List item
How to insert table into a cell of Excel sheet and call it using Outlook VBA
Query:
How to insert a hyperlink and table along with the test
message into a cell of Excel and retrieve it as it is using the above
mentioned code and send a mail containing hyperlink and table.
For hyperlink you can use the following code:
Range("K6").Select
ActiveCell.FormulaR1C1 = "test"
Range("K6").Select
ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:= _
"http://www.google.com", TextToDisplay:="test"
Range("K6").Select
Selection.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True

Disable excel save changes prompt

I have tried all the ways I normally do this and what I can find searching. oxl.DisplayAlerts = False is not working. I still get asked if I want to save changes.
I am essentially trying to use the excel sheet as a template. The full script exports to pdf, but this is enough to re-create the problem. BTW I tried saving it as a xltx file (template) and still get the save promt.
Dim oxl As New Excel.Application
Dim apppath2 As String = My.Application.Info.DirectoryPath.ToString
Dim mywb As Excel.Workbook = oxl.Workbooks.Open(Filename:=apppath2 & "\fuse template.xlsx", [ReadOnly]:=True)
oxl.Visible = False
Dim mysheet As Excel.Worksheet = mywb.Sheets(1)
mysheet.Cells(10, 5) = l_region.Text
mysheet.Cells(11, 5) = comb_emc_name.Text
oxl.DisplayAlerts = False
mywb.Close(False)
mysheet = Nothing
mywb = Nothing
oxl = Nothing
GC.Collect()
I was missing mywb.Saved = True. I have never had to do that before.

How to retrieve data from Excel and add to Word

I have a Word template file that retrieves data from an Excel file to populate a form.
The code looks something like this:
Dim myXL As Object
Set myXL = Getobject("myfile.xls")
myXL.Application.Visible = True
myXL.Parent.Windows(1).Visible = True
This code works fine in Office 2010 and 2007, but when I try it in 2013, it gives run time error 9 which is an array subscript error. When I check the Windows array it has zero elements, so error is correct.
How do I achieve the same result in 2013?
The next bit of code attempts to access the Worksheets("mysheet") and if I skip the Visible = True line accessing the worksheet gives runtime error 1004.
Any help with fixing this would be greatly appreciated.
To make the code work on Office 2013 I added the line myXL.Activate before trying to make the Window visible. So the code becomes:
Dim myXL As Object
Set myXL = Getobject("myfile.xls")
myXL.Application.Visible = True
myXL.Activate
myXL.Parent.Windows(1).Visible = True
This fixed the run-time error, and the code went back to working well.
To retrieve data from an Excel
An Example would be...
Option Explicit
Sub ExcelData()
Dim xlApp As Object ' Application
Dim xlBook As Object ' Workbook
Dim xlSht As Object ' Worksheet
Dim FilePath As String
FilePath = "C:\Temp\Book1.xlsx"
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open(FilePath)
Set xlSht = xlBook.Sheets("Sheet1")
With ActiveDocument
.Content = xlSht.Range("A1").Value
End With
xlApp.Visible = True
Set xlApp = Nothing
Set xlBook = Nothing
End Sub

Access VBA: working with an existing excel workbook (Run-Time error 9, if file is already open)

I'm writing a macro in Access that (hopefully) will:
create an Excel worksheet
set up and format it based on information in the Access database
after user input, will feed entered data into an existing Excel master file
Opening the blank sheet etc. is working absolutely fine, but I'm stuck trying to set the existing master file up as a variable:
Sub XLData_EnterSurvey()
Dim appXL As Excel.Application
Dim wbXLnew, wbXLcore As Excel.Workbook
Dim wsXL As Excel.Worksheet
Dim wbXLname As String
Set appXL = CreateObject("Excel.Application")
appXL.Visible = True
wbXLname = "G:\[*full reference to file*].xlsm"
IsWBOpen = fnIsWBOpen(wbXLname)
'separate function (Boolean), using 'attempt to open file and lock it' method
'from Microsoft site.
If IsWBOpen = False Then
Set wbXLcore = appXL.Workbooks.Open(wbXLname, True, False)
'open file and set as variable.
ElseIf IsWBOpen = True Then
wbXLcore = appXL.Workbooks("ResultsOverall.xlsm") 'ERROR HERE.
'file is already open, so just set as variable.
End If
Debug.Print wbXLcore.Name
Debug.Print IsWBOpen
Set appXL = Nothing
End Sub
When the file is closed, this works perfectly. However, when it's open I get:
Run-Time error '9':
Subscript out of range
I'm only just starting to teach myself VBA (very trial and error!) and nothing else I've seen in answers here / Google quite seems to fit the problem, so I'm a bit lost...
Considering that it works fine when the file is closed, I suspect I've just made some silly error in referring to the file - perhaps something to do with the 'createobject' bit and different excel instances??
Any suggestions would be much appreciated! Thanks
Thank you #StevenWalker
Here's the working code:
Sub XLData_EnterSurvey()
Dim appXL As Excel.Application
Dim wbXLnew As Excel.Workbook, wbXLcore As Excel.Workbook
Dim wsXL As Excel.Worksheet
On Error GoTo Handler
Set appXL = GetObject(, "Excel.Application")
appXL.Visible = True
Dim wbXLname As String
wbXLname = "G:\ [...] .xlsm"
IsWBOpen = fnIsWBOpen(wbXLname)
If IsWBOpen = False Then
Set wbXLcore = appXL.Workbooks.Open(wbXLname, True, False)
ElseIf IsWBOpen = True Then
Set wbXLcore = appXL.Workbooks("ResultsOverall.xlsm")
End If
Set appXL = Nothing
'-------------------Error handling------------------
Exit Sub
' For if excel is not yet open.
Handler:
Set appXL = CreateObject("Excel.Application")
Err.Clear
Resume Next
End Sub
Sorry I'm on my phone so I can't go in to too much detail or do much with the code but at a glance I think you might need to add an error handler so that if the file is already open, a different line of code is executed.
Add 'On error go to handler' (before creating the excel object) and at the bottom
Of your code add 'handler:'. In the error handler, use get object rather than create object.
You will have to ensure you use exit sub before the error handler or it will run the handler every time you run the code.
You can see an example of what I mean here: How to insert chart or graph into body of Outlook mail
Although please note in this example it's the other way round (if error 'getting' outlook, then create it).
Example in link:
Set myOutlook = GetObject(, "Outlook.Application")
Set myMessage = myOutlook.CreateItem(olMailItem)
rest of code here
Exit Sub
'If Outlook is not open, open it
Handler:
Set myOutlook = CreateObject("Outlook.Application")
Err.Clear
Resume Next
End sub
If you move the appXL.Workbooks statement to the debugging window, you will find that the names of the items in that collection are without extension.
So in your case, I'm guessing the line should read:
wbXLcore = appXL.Workbooks("ResultsOverall")

Resources