I have an Excel workbook, with several worksheets in it. Each worksheet is a document I would like to email separately.
I have the workbook on a Windows XP SP3 machine running Office 2007. The VBA code works perfectly, and I can email each individual worksheet.
I need to run this on a Windows 7 or Windows 10 PC, again with Office 2007. This is where I get the error:
Sub EmailWithOutlook()
Dim oApp As Object
Dim oMail As Object
Dim WB As Workbook
Dim FileName As String
Dim wSht As Worksheet
Dim shtName As String
Application.ScreenUpdating = False
' Make a copy of the active worksheet
' and save it to a temporary file
ActiveSheet.Copy
Set WB = ActiveWorkbook
FileName = WB.Worksheets(1).Name
On Error Resume Next
Kill "C:\" & FileName
On Error GoTo 0
WB.SaveAs FileName:="C:\" & FileName
'Create and show the Outlook mail item
Set oApp = CreateObject("Outlook.Application")
Set oMail = oApp.CreateItem(0)
With oMail
'Uncomment the line below to hard code a recipient
'.To = "testuser#test.com"
'Uncomment the line below to hard code a subject
'.Subject = "Subject Line"
'Uncomment the lines below to hard code a body
'.body = "Dear John" & vbCrLf & vbCrLf & _
'"Here is the file you asked for"
.Attachments.Add WB.FullName
.Display
End With
'Delete the temporary file
WB.ChangeFileAccess Mode:=xlReadOnly
Kill WB.FullName
WB.Close SaveChanges:=False
'Restore screen updating and release Outlook
Application.ScreenUpdating = True
Set oMail = Nothing
Set oApp = Nothing
End Sub
The routine stops on the line containing the following:
WB.SaveAs FileName:="C:\" & FileName
What am I missing?
Windows users by default do not have permission to write at C:\ root directory.
Solutions:
Use a sub directory where the user has permission to write
Change user permission to gain write access at C:\ (not recommended)
Related
I have a workbook that I am trying to email with macros. This way the recipient will also be able to use the macros that are included with the workbook. This will make office life easier for my company. I have tried setting the saved file name to .xlsm, but that causes an error.
This is my code (which is adapted from sources online)
Sub MailGo()
'Variable declaration
Dim oApp As Object, _
oMail As Object, _
WB As Workbook, _
FileName As String, MailSub As String, MailTxt As String
'Turns off screen updating
Application.ScreenUpdating = False
'Makes a copy of the active sheet and save it to
'a temporary file
ActiveSheet.Copy
Set WB = ActiveWorkbook
FileName = "Text.xls"
On Error Resume Next
Kill "C:\" & FileName
On Error GoTo 0
WB.SaveAs FileName:="C:\Users\Public\Documents" & FileName
'Creates and shows the outlook mail item
Set oApp = CreateObject("Outlook.Application")
Set oMail = oApp.CreateItem(0)
With oMail
.To = "wesley.x.sherow#us.tel.com"
.Cc = ""
.Bcc = ""
.Subject = "LotInput"
.Body = "LotInput"
.Attachments.Add WB.FullName
.Display
.send
End With
'Deletes the temporary file
WB.ChangeFileAccess Mode:=xlReadOnly
Kill WB.FullName
WB.Close SaveChanges:=False
'Restores screen updating and release Outlook
Application.ScreenUpdating = True
Set oMail = Nothing
Set oApp = Nothing
End Sub
you need to also include this argument in your .SaveAs line.
FileFormat:=xlOpenXMLWorkbookMacroEnabled
Note: I am not interested in finding the path towards the worksheet, I intend to write the path to the worksheet in a text file that is located in the same folder as the .OTM file.
I need to transform this code from hardcoded path to a path read from a text file located in the same folder as the macro.
How do I obtain the path towards the macro using the macro (vba code) itself?
Public xlApp As Object
Public xlWB As Object
Public xlSheet As Object
Sub OpenXl()
Dim enviro As String
Dim strPath As String
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "\Documents\test2.xlsx"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("Sheet1")
' Process the message record
On Error Resume Next
End Sub
The OTM file is stored here on my PC (Windows 7/Outlook 2010):
strPath = Environ("userprofile") & "\AppData\Roaming\Microsoft\Outlook\"
Simply use:
ThisWorkbook.Path
This returns the path of the workbook containing the code.
I have already created a macro that creates individual files for me. Now having those files I have created another VBA job in outlook that will add the contact information to the e-mail, locate the needed file, and attach it to an e-mail. I need to do this to a list of about 50 different companies that I send these audits to. Currently I need to add a certain parameter to select what company I am using "V003" for example after this job is ran I go to the next one "V004" and so on.
I am looking for a way to provide VBA the list of 50 companies codes into which I have all as folders in a certain directory path. So when i kick off the job it will reference the folder named V003 in the directory path and use that as the VendorID variable I have created then loop back to the beginning and grab the next folder name V004 in the directory path and filter though until it gets to the last one.
Unless someone else has an idea that won't make me kick of the VBA job 50 times and pass in each variable. (Currently that's what I've been doing since I created these jobs and it's still a bit time consuming)
Dim GlobalVarEmail As String
Dim GlobalVarVendorName As String
Dim GlobalVendorId As String
Dim GlobalMonth As String
Dim GlobalYear As String
Dim GlobalAuditDate As String
Sub SendFilesbyEmail()
'the calling method of all sub methods.
GlobalVendorId = InputBox("What Vendor Letter are you trying to send out? (V Code: ex - V012)", "Vendor Code", "Type Here", 7500, 5000)
GlobalMonth = InputBox("What Month are you auditing for?(ex - Jan. Feb. Mar.)", "Month", "Type Here", 7500, 5000)
GlobalYear = InputBox("What year are you auditing for?(ex - 2016)", "Quarter", "Type Here", 7500, 5000)
GlobalAuditDate = InputBox("What is the audit date?(ex - 20160930)", "Quarter", "Type Here", 7500, 5000)
Call openExcel(GlobalVendorId)
Call SendAuditReport
End Sub
Public Function openExcel(UserReponse) As String
'this function is used to retrieve the vendor contact e-mail
Dim xlApp As Object
Dim sourceWB As Workbook
Dim sourceWS As Worksheet
Set xlApp = CreateObject("Excel.Application")
With xlApp
.Visible = False
.EnableEvents = True
End With
strFile = "G:\403(b)\User Folders\Chris W\SPARK Info\Contacts.xlsx"
Set sourceWB = Workbooks.Open(strFile, , False, , , , , , , True)
Set sourceWH = sourceWB.Worksheets("SPARK")
sourceWB.Activate
Rows("1:1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$H$100").AutoFilter Field:=1, Criteria1:=UserReponse
Range("F1").Select
GlobalVarEmail = Selection.End(xlDown).Value
Range("B1").Select
GlobalVarVendorName = Selection.End(xlDown).Value
ActiveWorkbook.Close SaveChanges:=False
End Function
Function SendAuditReport()
'this function will create a e-mail, (subjectline & body), attach the needed audit letter, and insert the needed vendor contact e-mail.
Dim Fname As String
Dim sAttName As String
Dim olApp As Outlook.Application
Dim olMsg As Outlook.MailItem
Dim olAtt As Outlook.Attachments
Set olApp = Outlook.Application
Set olMsg = olApp.CreateItem(0) ' email
Set olAtt = olMsg.Attachments
' send message
With olMsg
.Subject = GlobalVarVendorName & " " & GlobalMonth & " " & GlobalYear & " SPARK Audit"
.To = GlobalVarEmail
.CC = "SPARK#AXA.com"
.Attachments.Add "G:\403(b)\User Folders\Chris W\Spark Audit\" & GlobalAuditDate & "\00-Ran Reports\" & GlobalVendorId & "\SPARK Audit Report " & GlobalVarVendorName & ".xlsx"
'you can add attachments here just type .Attachments.Add "folder path"
.HTMLBody = "Hello, <br /><br /> Attached is the file
'.Send
.Display
End With
End Function
You can enumerate folder names as such:
Dim objFSO As Object
Dim objFolder As Object
Dim objSubFolder As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\pathtoyourparentfolder")
For Each objSubFolder In objFolder.subfolders
MsgBox objSubFolder.Name
Next objSubFolder
objSubFolder.Name will be the name of the folder and you can just pass this to GlobalVendorID.
I have 200 folders all with different names in a folder. Now, each folder with a different name has a macro excel file (.xlsm). I'm trying to edit all the files at once with a separate file. The code goes like this:
Sub Button1_Click()
Dim wb As Workbook
Dim ws As Excel.Worksheet
Dim strPath As String
Dim strFile As String
'Get the directories
strPath = "C:\Users\generaluser\Desktop\testing main folder\"
strFile = Dir(strPath)
'Loop through the dirs
Do While strFile <> ""
'Open the workbook.
strFileName = Dir(strPath & strFile & "*.xlsm")
'Open the workbook.
Set wb = Workbooks.Open(Filename:=strPath & strFile & "\" & strFileName , ReadOnly:=False)
'Loop through the sheets.
Set ws = Application.Worksheets(1)
'Do whatever
ws.Range("A1").Interior.ColorIndex = 0
'Close the workbook
wb.Close SaveChanges:=True
'Move to the next dir.
strFile = Dir
Loop
End Sub
But this doesn't work. I have tried tweaking it but whatever i do either does nothing or causes an error. Can someone please help me get this code to work.
(also: "testing main folder" is the folder on my desktop which holds the 200 other folders which hold the .xlsm files.)
Put Option Explicit at the top of the module. You'll get some compiler errors, one of them being that strFileName isn't declared. This would have been a great clue as to where to look, because the problem is that you're using two variable names that have roughly the same meaning when you read them, and they're getting mixed up.
After you're done fixing the variables, take a look at the documentation for the Dir function. The second issue is that you're also calling Dir multiple times in the loop, which means that you're skipping results.
It should look something more like this:
Dim wb As Workbook
Dim ws As Excel.Worksheet
Dim file As String
'path never changes, so make it a Const
Const path = "C:\Users\generaluser\Desktop\testing main folder\"
'This returns the first result.
file = Dir$(path & "*.xlsm")
Do While file <> vbNullString
Set wb = Workbooks.Open(Filename:=path & file, ReadOnly:=False)
Set ws = Application.Worksheets(1)
'Do whatever
wb.Close SaveChanges:=True
'This returns the next result, or vbNullString if none.
file = Dir$
Loop
My department uses Access to create PDFs and sends out documents in a generic e-mail template. They currently do this by opening the template, attaching the PDF manually, and then send it off. After the e-mail is sent, they then drag the .msg file from the Outlook Sent folder into each client folder individually.
I wrote an Excel VBA to read the e-mail addresses in each cell, attach the PDF through a path, send the e-mail, and then save the .msg automatically.
The problem: The .SaveAs function will not work for me as I get runtime error 287. Everything else works (Attachments, .Display, .Send, etc.) if I leave the .SaveAs out.
Things I have done: I have the Microsoft Outlook 12.0 Objects referenced, and I have tried both early and late binding. This is on a workstation and they use Excel 2010, but when I try on my home computer with Excel 2013 (Outlook 15.0 Objects) it DOES work.
I am baffled... Also, here's a link to a screen shot of the error and the line:
Sub CreateNewMessage()
Dim OutApp As Object
Dim objOutlookMsg As Object
Dim Pth As String
Dim cell As Range
Pth = "some\path\" 'Path to PDF folder
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application") 'Set Outlook application
On Error GoTo Cleanup
'For Loop to find each cell of e-mails
For Each cell In Columns("E").Cells.SpecialCells(xlCellTypeConstants)
'Finds e-mail values # and . for cell value
If cell.Value Like "?*#?*.?*" Then
Set objOutlookMsg = OutApp.CreateItem(0)
On Error GoTo Cleanup
With objOutlookMsg
.To = cell.Value
.Subject = Cells(cell.Row, "C").Value & " - Approval Letter"
.body = "Pre-worded e-mail template"
.Attachments.Add Pth & Dir(Pth & Cells(cell.Row, "C") & "\" & .Subject & ".msg" 'Attach PDF
'This next SaveAs line throws the error, or if I keep the error handler in, it goes to Cleanup and nothing happens
.SaveAs "Path\To\Save\Folder" & Cells(cell.Row "C") & _
"\" & .Subject & ".msg" 'Save MailItem to folder
.Display '.Send
End With
On Error GoTo 0
Set objOutlookMsg = Nothing
End If
Next cell
Cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
I see your code has the "," in the Cells(cell.Row, "C") so that's just a typo above,
but you haven't changed the default line to match your path (in your image either)
"Path\To\Save\Folder"