I have code that splits a workbook based on a condition. I want to email each of those new workbooks to different people.
When I run the macro, it splits the workbook and puts all the worksheets where I want them. When I try to send I only send 1 email.
Sub savesheetsSend()
Dim ws As Worksheet
Dim Filetype As String
Dim Filenum As Long
Dim wb As Workbook
Dim FolderName As String
Dim open_book As Workbook
Set outmail = CreateObject("outlook.application")
Set outmsg = outmail.createitem(0)
Set wb = Application.ThisWorkbook
'create directory to save each sheet in
FolderName = "C:\Users\jpenn\Desktop" & "\" & wb.Name
MkDir FolderName
On Error Resume Next
'save each sheet as workbook in directory
For Each ws In wb.Worksheets
If ws.Range("A1") = 1 Then
Filetype = ".xlsm": Filenum = 52
ws.Copy
xFile = FolderName & "\" & Application.ActiveWorkbook.Sheets(1).Name & Filetype
Application.ActiveWorkbook.SaveAs xFile, FileFormat:=Filenum
End If
Next
'send all new workbooks to email address in CELL("B1")
For Each open_book In Application.Workbooks
If open_book.Name <> ThisWorkbook.Name Then
With outmsg
.Subject = ActiveWorkbook.Name & " payroll data"
.To = ActiveWorkbook.ActiveSheet.Range("b1").Value
.body = "I will get to this later"
.Attachments.Add Application.ActiveWorkbook.FullName
.send
End With
open_book.Close
End If
Next
End Sub
Try it this way... Tested
Option Explicit
Sub savesheetsSend()
Dim Ws As Worksheet
Dim Filetype As String
Dim xFile As String
Dim Filenum As Long
Dim Wb As Workbook
Dim FolderName As String
Dim Open_Book As Workbook
Dim OutMsg As Object
Dim OutMail As Object
Set OutMail = CreateObject("outlook.application")
Set Wb = Application.ThisWorkbook
'create directory to save each sheet in
FolderName = "C:\Users\jpenn\Desktop" & "\" & Wb.Name
MkDir FolderName
'save each sheet as workbook in directory
For Each Ws In Wb.Worksheets
If Ws.Range("A1") = 1 Then
Filetype = ".xlsm": Filenum = 52
Ws.Copy
xFile = FolderName & "\" & Application.ActiveWorkbook.Sheets(1).Name & Filetype
Application.ActiveWorkbook.SaveAs xFile, FileFormat:=Filenum
Set OutMsg = OutMail.createitem(0)
With OutMsg
.Subject = Ws.Name & " payroll data"
.To = ActiveSheet.Range("b1").Value
.Body = "I will get to this later"
.Attachments.Add (xFile)
.Display
End With
ActiveWorkbook.Close
End If
Next
End Sub
Related
Trying to reference a dynamic range in the body of an email (this will change based on the user's input into the sheet). The email outputs just fine, but there is nothing in the email where "AFund" is supposed to be. Code is below, any help is appreciated!
Dim BlasEmail As Workbook
Dim OutApp As Object
Dim OutMail As Object
Dim FundAdd, FundRem, Broker As Range
Dim AFund As String
Set BlastEmail = ActiveWorkbook
Set Cover = ThisWorkbook.Sheets("Cover")
Set CDEA = ThisWorkbook.Sheets("CDEA")
LastRow = Cells(Rows.Count, 5).End(xlUp).Row
LRow = Cells(Rows.Count, 7).End(xlUp).Row
LasRow = Cells(Rows.Count, 2).End(xlUp).Row
FundAdd = AFund
Set FundAdd = Range("E2:E" & LastRow)
Set FundRem = Range("G2:G" & LRow)
Set Broker = Range("C6:C" & LasRow)
If Range("ISDAMRA") = "ISDA" And Range("G2") = "" Then
Application.ReferenceStyle = xlA1
SigString = Environ("appdata") & _
"\Microsoft\Signatures\My Signature.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
Set OutApp = CreateObject("Outlook.Application")
Dim EmBody As String
EmBody = "Hello," & "<br><br>" & _
"Body goes here " & "<br>" & "<br>" & AFund
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "myemail"
.CC = ""
.BCC = ""
.Subject = "Here is the subject " & Range("B6") & " "
.HTMLBody = EmBody & Signature
'You can add files like this
'.Attachments.Add ("C:\test.txt")
'.Send
.Display 'This will display the emails for the user to review CXH
End With
On Error GoTo 0
Set OutMail = Nothing
End If
'
End Sub
From:
Sending a range of cells...
2 Methods to Quickly Send Selected Cells in an Excel Worksheet as an Outlook Email
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub SendRange()
' https://www.datanumen.com/blogs/2-methods-quickly-send-selected-cells-excel-worksheet-outlook-email/
' https://stackoverflow.com/questions/73136067
Application.Calculation = xlCalculationManual
' Application is Excel. No influence in Outlook.
Application.ScreenUpdating = False
' Reference Microsoft Outlook nn.n Object Library
Dim olApp As Outlook.Application
Dim olEmail As Outlook.MailItem
Dim olInsp As Outlook.Inspector
' Reference Microsoft Word nn.n Object Library
Dim wdDoc As Word.Document
Dim strGreeting As String
Dim lastRow As Long
lastRow = Cells(Rows.Count, 5).End(xlUp).Row
Debug.Print lastRow
Dim fundAdd As Range
Dim objSelection As Range
Set fundAdd = Range("E2:E" & lastRow)
fundAdd.Select
Set objSelection = Selection
objSelection.Copy
Dim objTempWorkbook As Workbook
Set objTempWorkbook = Workbooks.Add(1)
Dim objTempWorksheet As Worksheet
Set objTempWorksheet = objTempWorkbook.Sheets(1)
Dim strTempHTMLFile As String, Strbody As String
Dim objTempHTMLFile As Object, objTextStream As Object
Dim objFileSystem As Object
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
'Pasting into a Temp Worksheet
With objTempWorksheet.Cells(1)
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
'Save the Temp Worksheet as a HTML File
strTempHTMLFile = objFileSystem.GetSpecialFolder(2).Path & _
"\Temp for Excel" & Format(Now, "YYYY-MM-DD hh-mm-ss") & ".htm"
Set objTempHTMLFile = objTempWorkbook.PublishObjects.Add(xlSourceRange, _
strTempHTMLFile, objTempWorksheet.Name, objTempWorksheet.UsedRange.Address)
objTempHTMLFile.Publish (True)
strGreeting = "Hello," & vbNewLine & vbNewLine & _
"Body goes here " & vbNewLine & vbNewLine
Set olApp = New Outlook.Application
Set olEmail = olApp.CreateItem(olMailItem)
With olEmail
Set olInsp = .GetInspector ' A side effect is to get the signature
Set wdDoc = olInsp.WordEditor
wdDoc.Range.InsertBefore strGreeting
wdDoc.Paragraphs(5).Range.Paste
'Insert the Temp Worksheet into the Email Body
Dim wb1 As Workbook
Set wb1 = ActiveWorkbook
Dim TempFilePath As String
TempFilePath = Environ$("temp") & "\"
Dim TempFileName As String
TempFileName = "Output Data"
Dim FileExtStr As String
FileExtStr = ".xlsx"
Debug.Print TempFilePath & TempFileName
wb1.SaveAs TempFilePath & TempFileName, FileFormat:=xlOpenXMLWorkbook
.Display
End With
objTempWorkbook.Close (False)
objFileSystem.DeleteFile (strTempHTMLFile)
Kill TempFilePath & TempFileName & FileExtStr 'Delete the temp Excel File
Set olApp = Nothing
Set olEmail = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
I wanted to export the images on the word doc to local drive how can I do it from excel using vba.
Sub gen_Files()
Dim WdApp As Word.Application, Doc As Word.Document, fPath As String
Dim i As Long
fPath = ThisWorkbook.Path & Application.PathSeparator & "Test.docx"
If fPath = "" Or Dir(fPath) = "" Then MsgBox "Invalid file path.": Exit Sub
Set WdApp = New Word.Application
WdApp.Visible = True
Set Doc = WdApp.Documents.Open(fPath)
Doc.SaveAs2 ThisWorkbook.Path & "\New.docx", FileFormat:=12
For i = 1 To Doc.InlineShapes.Count
'Doc.InlineShapes(i).Range.ExportAsFixedFormat(ThisWorkbook.Path & Application.PathSeparator & i & ".jpg",wdExportFormatXPS,False,,,,,,,,,,)
Next i
'Save the file and done
Doc.Save
Doc.Close
WdApp.Quit
End Sub
The code would be like this.
Sub gen_Files()
Dim WdApp As Word.Application, Doc As Word.Document, fPath As String
Dim i As Long
Dim cht As Chart, obj As ChartObject
Dim Ws As Worksheet
Dim myFn As String
Dim shp As InlineShape
Set Ws = ActiveSheet
fPath = ThisWorkbook.Path & Application.PathSeparator & "Test.docx"
If fPath = "" Or Dir(fPath) = "" Then MsgBox "Invalid file path.": Exit Sub
Set WdApp = New Word.Application
WdApp.Visible = True
Set Doc = WdApp.Documents.Open(fPath)
Doc.SaveAs2 ThisWorkbook.Path & "\New.docx", FileFormat:=12
For i = 1 To Doc.InlineShapes.Count
Set shp = Doc.InlineShapes(i)
shp.Range.CopyAsPicture
Set obj = Ws.ChartObjects.Add(Range("i1").Left, 0, shp.Width, shp.Height)
myFn = ThisWorkbook.Path & Application.PathSeparator & i & ".jpg"
With obj.Chart
.Paste
.Export myFn
End With
obj.Delete
Next i
'Save the file and done
Doc.Save
Doc.Close
WdApp.Quit
End Sub
I have an Excel 2016 worksheet with a "Send Worksheet" button purposed to email the worksheet to all the designated recipients. When I run the following code (most of which came from another program and tweaked), I receive the following errors:
Runtime Error 429: ActiveX component can't create object.
at Set OutlookApp = CreateObject("Outlook.Application")
as well as
Runtime Error 91: Object variable or With block variable not set.
in the With block at .To = "email address".
Option Explicit
Private Sub cmdSendWorksheet_Click()
Dim xFile As String
Dim xFormat As Long
Dim Wb As Workbook
Dim Wb2 As Workbook
Dim FilePath As String
Dim FileName As String
Dim OutlookApp As Object
Dim OutlookMail As Object
'On Error Resume Next
Application.ScreenUpdating = False
Set Wb = Application.ActiveWorkbook
ActiveSheet.Copy
Set Wb2 = Application.ActiveWorkbook
Select Case Wb.FileFormat
Case xlOpenXMLWorkbook:
xFile = ".xlsx"
xFormat = xlOpenXMLWorkbook
Case xlOpenXMLWorkbookMacroEnabled:
If Wb2.HasVBProject Then
xFile = ".xlsm"
xFormat = xlOpenXMLWorkbookMacroEnabled
Else
xFile = ".xlsm"
xFormat = xlOpenXMLWorkbook
End If
End Select
FilePath = Environ$("temp") & "\"
FileName = Wb.Name & Format(Now, "dd-mmm-yy h-mm-ss")
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.CreateItem(0)
Wb2.SaveAs FilePath & FileName & xFile, FileFormat:=xFormat
With OutlookMail
.To = "email address"
.CC = ""
.BCC = ""
.Subject = "Worksheet Attached"
.Body = "Please see attached worksheet"
.cmdSendWorksheet.Enabled = True
.Attachments.Add Wb2.FullName
.Send
End With
Wb2.Close
Kill FilePath & FileName & xFile
Set OutlookMail = Nothing
Set OutlookApp = Nothing
Application.ScreenUpdating = True
End Sub
this code should do the job you need. But you need to go in Tools / References and check the following reference :
Microsoft Scripting Runtime
Microsoft Outlook 14.0 Object Library
Private Sub cmdSendWorksheet_Click()
Dim Wb As Workbook
Dim FilePath As String
Dim FileName As String
Dim FileExtensionName As String
Dim FileFullPath As String
Dim OutlookApp As New Outlook.Application
Dim OutlookMail As Outlook.MailItem
Dim fso As New FileSystemObject
'On Error Resume Next
Application.ScreenUpdating = False
Set Wb = ThisWorkbook
FilePath = Environ$("temp") & "\"
FileName = fso.GetBaseName(Wb.Path & "\" & Wb.Name) & Format(Now, "dd-mmm-yy h-mm-ss")
FileExtensionName = fso.GetExtensionName(Wb.Path & "\" & Wb.Name)
FileFullPath = FilePath & FileName & "." & FileExtensionName
fso.CopyFile Wb.Path & "\" & Wb.Name, FileFullPath
'Sending the email
Set OutlookMail = OutlookApp.CreateItem(olMailItem)
With OutlookMail
.To = "email address"
.CC = ""
.BCC = ""
.Subject = "Worksheet Attached"
.Body = "Please see attached worksheet"
.Attachments.Add FileFullPath
.Display
'.Send You can chose .Send or .Display, as you wish
End With
Kill FileFullPath
'Free the memory
Set OutlookMail = Nothing
Set OutlookApp = Nothing
Set fso = Nothing
Application.ScreenUpdating = True
Application.Quit
End Sub
I am having problems with my code since it only works in the specific folders but not in all subfolders inside the particular folder.
Could someone please helps to make the code works to all subfolders inside that specific folder? :)
These are my code:
Sub Execute1()
Dim monthstr As String
Dim year As String
Dim monthtext As String
Dim prevmonth As String
Dim prevmonthtext As String
year = Range("D8").Text
monthstr = Trim(Range("D9").Text)
monthtext = Trim(Range("D10").Text)
prevmonth = Trim(Range("D11").Text)
prevmonthtext = Trim(Range("D12").Text)
prevyear = Trim(Range("D13").Text)
'confirmation box before running macro//////////////////////////////////////////////////////////////////////////////////////
response = MsgBox("Are you sure the settings are correct?", vbYesNo, "Confirmation")
If response = vbNo Then
Exit Sub
End If
'optimize macro speed///////////////////////////////////////////////////////////////////////////////////////////////////////////
Call Optimize
'finding the correct path (month)//////////////////////////////////////////////////////////////////////////////////////////
Dim myfile As String
Dim mypath As String
Dim newpath As String
mypath = "C:\Users\praseirw\Desktop\Tes CC\" & prevyear & "\SC\" & prevmonth & " " & prevmonthtext & "\"
myfile = Dir(mypath & "*.xlsx")
newpath = "C:\Users\praseirw\Desktop\Tes CC\" & year & "\SC\" & monthstr & " " & monthtext & "\"
'loop through all files in specified month//////////////////////////////////////////////////////////////////////////////////
Dim root As Workbook
Dim rng As Range
Dim wb As Workbook
Dim ws As Worksheet
Set root = Workbooks("CC Reports Center.xlsm")
Set rng = root.Worksheets("Settings").Range("H7:H14")
Do While myfile <> ""
Set wb = Workbooks.Open(mypath & myfile)
For Each ws In wb.Worksheets
rng.Copy
With ws.Range("D1")
.PasteSpecial xlPasteFormulas
End With
Next ws
Dim oldname As String
Dim newname As String
Dim wbname As String
oldname = wb.Name
wbname = Mid(oldname, 9)
newname = year & "_" & monthstr & "_" & wbname
wb.SaveAs Filename:=newpath & newname
wb.Close
Set wb = Nothing
myfile = Dir
Loop
Application.CutCopyMode = False
MsgBox "Task Complete!"
'reset macro optimization settings//////////////////////////////////////////////////////////////////////////////////////////////
Call ResetOptimize
End Sub
Here's one way to do it with the Dir function. If you want something a little more elegant you may want to consider using a FileSystemObject. (Note that to view Debug.Print output you have to enable the immediate window from under view.)
Sub test()
Dim root As String
root = "C:\"
Dim DC As New Collection
s = Dir(root & "*", vbDirectory)
Do Until s = ""
DC.Add s
s = Dir
Loop
For Each D In DC
Debug.Print D
On Error Resume Next: s = Dir(root & D & "\*.xl*"): On Error GoTo 0
Do Until s = ""
Debug.Print " " & s
s = Dir
Loop
Next
End Sub
Here's an example of how to do this with a FileSystemObject. Note that my code is a little sloppy with "On error resume next" to protect against access denied or other errors. Realistically you may want to consider incorporating better error handling, but that's another topic. Using a FileSystemObject is more powerful than Dir because Dir only returns a string, while FileSystemObject lets you work with files and folders as actual objects, which are much more powerful.
Sub test()
'You can use "CreateObject..." to add a FileSystemObject from the Scipting Library
'Alternatively, you can add a reference to "Microsoft Scripting Runtime"
'allowing you to directly declare a filesystemobject and access related intellisense
Set fso = CreateObject("Scripting.FileSystemObject")
Set Folder = fso.GetFolder("C:\")
For Each SubFolder In Folder.SubFolders
Debug.Print SubFolder.Name
On Error Resume Next
For Each File In SubFolder.Files
Debug.Print " " & File.Name
Next
On Error GoTo 0
Next
End Sub
My workbook has 5 different sheets and I need to copy the five sheets and paste it into 5 different mails. Preferably as HTML.
The below written code only attaches the different sheets to outlook. I need the HTML below the body of the email. Please note that my range in the sheets varies from workbook to workbook but the sheet names remain the same.
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
'Function purpose: To Browser for a user selected folder.
'If the "OpenAt" path is provided, open the browser at that directory
'NOTE: If invalid, it will open at the Desktop level
'BrowseForFolder was a code originally written by Ron De Bruin, I love this function!
Dim ShellApp As Object
'Create a file browser window at the default folder
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Set the folder to that selected. (On error in case cancelled)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroy the Shell Application
Set ShellApp = Nothing
'Check for invalid or non-entries and send to the Invalid error
'handler if found
'Valid selections can begin L: (where L is a letter) or
'\\ (as in \\servername\sharename. All others are invalid
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'If it was determined that the selection was invalid, set to False
BrowseForFolder = False
End Function
Sub SaveWorksheets()
'saves each worksheet as a separate file in a specific folder.
Dim ThisFolder As String
Dim NameOfFile As String
Dim Period As String
Dim RecipName As String
ThisFolder = BrowseForFolder()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim wsName As String
For Each ws In ActiveWorkbook.Worksheets
wsName = ws.Name
If wsName <> "Data" Then
Period = ws.Cells(4, 1).Value 'put the row and column numbers of the report date here.
RecipName = ws.Cells(1, 29).Value 'put the row and column numbers of the email address here
NameOfFile = ThisFolder & "\" & "Termination Report " & wsName & " " & Period & ".xlsx"
ws.Select
ws.Copy
ActiveWorkbook.SaveAs Filename:= _
NameOfFile, FileFormat:= _
xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
Call EmailWorkbooks(RecipName, NameOfFile)
End If
Next ws
End Sub
Sub EmailWorkbooks(RecipName, NameOfFile)
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.createItem(0)
Msg = "Attached is the xyz report for your review. Please let me know if you have any questions" & vbCrLf & vbCrLf _
& "Thanks," & vbCrLf & vbCrLf _
& "Your Name Here" & vbCrLf _
& "Your Title" & vbCrLf _
& "Your contact info"
Subj = "XYZ Report" & " " & Period
On Error Resume Next
With OutMail
.To = RecipName
'.CC =
.Subject = Subj
.Body = Msg
.Attachments.Add (NameOfFile)
.Save
End With
On Error GoTo 0
End Sub
U can use Add method of PublishObjects collection, short example:
Sub InsertSheetContent()
Dim onePublishObject As PublishObject
Dim oneSheet As Worksheet
Dim scriptingObject As Object
Dim outlookApplication As Object
Dim outlookMail As Object
Dim htmlBody As String
Dim htmlFile As String
Dim textStream
Set scriptingObject = CreateObject("Scripting.FileSystemObject")
Set outlookApplication = CreateObject("Outlook.Application")
For Each oneSheet In ThisWorkbook.Worksheets
htmlFile = ThisWorkbook.Path & "\" & ThisWorkbook.Name & "_" & oneSheet.Name & ".html"
Set onePublishObject = ThisWorkbook.PublishObjects.Add(SourceType:=xlSourceRange, _
Filename:=htmlFile, _
Sheet:=oneSheet.Name, _
Source:=oneSheet.UsedRange.Address, _
HtmlType:=xlHtmlStatic, _
DivID:=oneSheet.Name)
onePublishObject.Publish Create:=True
Set textStream = scriptingObject.OpenTextFile(htmlFile)
htmlBody = textStream.ReadAll
Set outlookMail = outlookApplication.CreateItem(0)
With outlookMail
.htmlBody = htmlBody
.Display
End With
Next oneSheet
End Sub