Automatically export HTML Table from Outlook to Excel w/ VBA - html

I'd like to export an email that contains many tables in HTML format.
Each table is something like this:
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;background:green">...</table>
I've added a New Rule in Outlook, so everytime I receive an email with 'specific word' in the Subject, the macro runs and saves all the tables from this email to a .xlsm file. The rule itself seems to work fine, but i'm having issues to make the macro work.
I've found many topics about exporting data from Outlook to Excel and I managed to copy email's TextBody using split (in rows), but it only worked with text, not with tables.
So I started searching the web for topics about exporting Tables, and I did find one. Although, it talks about importing Tables from Outlook using Excel VBA, not exactly what i'm trying to do. I tried to edit this code in order to work when running from Outlook, but it didn't work.
References:
Here's the code:
Option Explicit
Public Sub SalvaExcel()
'This macro writes an Outlook email's body to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
'Dim TextBody As String
'Dim iArr() As String
Dim eRow As Integer
Dim xlUp As Integer
Dim i As Long
Dim j As Long
xlUp = -4162
'set email to be saved
Set olApp = Outlook.Application
Set olNameSpace = Application.GetNamespace("MAPI")
Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
Set olMail = olItems(olItems.Count)
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = olMail.HtmlBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "C:\Users\rafael.kobayashi\Desktop\projeto_licitacoes\Palavras-Chave.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'this slows down the macro, but helps during debugging
.ScreenUpdating = False 'reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("email")
'find first empty row
'eRow = .Range("B" & .Rows.Count).End(xlUp).Row + 1
'write table in excel
Debug.Print olEleColl(0)
For i = 0 To olEleColl(0).Rows.Length - 1
For j = 0 To olEleColl(0).Rows(i).Cells.Length - 1
.Range("A1").Offset(i, j).Value = olEleColl(0).Rows(i).Cells(j).innerText
Next j
Next i
'resize columns (DO NOT)
'.Columns("B:C").AutoFit
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub
EDIT: There was a typo in the code, now it seems to be running, I can see that Excel opens then closes very quickly when I run the macro. However, when I open the workbook, the sheet where the tables were supposed to be is blank :(
EDIT2: I have tested the macro in an mail item where i inserted a random table and it worked, but it won't work with the tables in the mail that i showed.
EDIT3: I've found out that it wasn't working because the first table found didn't have any text in innerText, so I tested a macro that gets all the tables and it worked!

Change that line to this instead
For i = 0 To olEleColl(0).Rows.Length - 1
(You spelled Length wrong)

I've found out that it wasn't working because the first table found didn't have any text in innerText, so I tested a macro that gets all the tables and it worked!
Here's the code:
Public Sub SalvaExcel(item As Outlook.MailItem)
'This macro writes an Outlook email's tables to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
Dim eRow As Long
Dim i As Long
Dim j As Long
Dim t
Dim posicao As String
'set email to be saved
'Set olApp = Outlook.Application
'Set olNameSpace = Application.GetNamespace("MAPI")
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
'Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
'the most recent one
'Set olMail = olItems(olItems.Count)
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = item.HtmlBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "C:\Users\rafael.kobayashi\Desktop\projeto_licitacoes\Palavras-Chave.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'if True, this slows down the macro, but helps during debugging
.ScreenUpdating = False 'if False, this reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("email")
'which row to start
eRow = 1
posicao = "A" & eRow
'write each table in excel
For Each t In olEleColl
For i = 0 To t.Rows.Length - 1
For j = 0 To t.Rows(i).Cells.Length - 1
'ignore any problems with merged cells etc
On Error Resume Next
.Range(posicao).Offset(i, j).Value = t.Rows(i).Cells(j).innerText
On Error GoTo 0
Next j
Next i
'define from which row the next table will be written
eRow = eRow + t.Rows.Length + 1
posicao = "A" & eRow
Next t
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
'Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub
It exports all the tables from the last received email in the Outlook Inbox to an Excel file. It skips 1 row between one table and the next. Since it gets the most recent email and it runs from Outlook, it's useful to use in a New Rule, so it will be automatic, according to a defined criteria. I hope it helps other people!
edit: in order to run this macro in an Outlook Rule, it's necessary to give the following argument to the Sub, otherwise the macro won't be shown in the list of macros to be chosen for the Rule:
Public Sub SalvaExcel(item As Outlook.MailItem)
I have updated the code in this answer.

Thanks for sharing the code.
Have rectified your code to make it finally work ;)
Public Sub SalvaExcel()
'Public Sub SalvaExcel(item As Outlook.MailItem)
'This macro writes an Outlook email's tables to an Excel workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olFoldersDefault As Outlook.Folders
Dim olFolder As Outlook.Folder
Dim olItems As Outlook.Items
Dim olNameSpace As Outlook.NameSpace
Dim olHTML As MSHTML.HTMLDocument: Set olHTML = New MSHTML.HTMLDocument
Dim olEleColl As MSHTML.IHTMLElementCollection
Dim xlApp As Excel.Application
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
Dim eRow As Long
Dim i As Long
Dim j As Long
Dim t
Dim posicao As String
'set email to be saved
'Set olApp = Outlook.Application
'Set olNameSpace = Application.GetNamespace("MAPI")
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
'Set olItems = olFolder.Items
'olItems.Sort ("[ReceivedTime]")
'Set olApp = Outlook.Application
Set olNameSpace = Application.GetNamespace("MAPI")
Set newFolder = olNameSpace.GetDefaultFolder(olFolderInbox)
Set olFolder = newFolder.Folders("Projects").Folders("Management").Folders("Notifications")
Set olItems = olFolder.Items
olItems.Sort ("[ReceivedTime]")
'the most recent one
Set olMail = olItems(olItems.Count)
'MsgBox olMail
'MsgBox olMail.HTMLBody
'save Outlook email's html body (tables)
With olHTML
.Body.innerHTML = olMail.HTMLBody
Set olEleColl = .getElementsByTagName("table")
End With
'set excel file to be opened
FileName = "D:\OutlookEmails.xlsm"
'create an Excel instance
Set xlApp = Application.CreateObject("Excel.Application")
'in this instance
With xlApp
.Visible = True 'if True, this slows down the macro, but helps during debugging
.ScreenUpdating = False 'if False, this reduces flash and increases speed
'open workbook
Set ExcelWkBk = xlApp.Workbooks.Open(FileName)
'in this workbook
With ExcelWkBk
'in [email] worksheet
With .Worksheets("emails")
'which row to start
eRow = 1
posicao = "A" & eRow
'write each table in excel
For Each t In olEleColl
For i = 0 To t.Rows.Length - 1
For j = 0 To t.Rows(i).Cells.Length - 1
'ignore any problems with merged cells etc
On Error Resume Next
.Range(posicao).Offset(i, j).Value = t.Rows(i).Cells(j).innerText
On Error GoTo 0
Next j
Next i
'define from which row the next table will be written
eRow = eRow + t.Rows.Length + 1
posicao = "A" & eRow
Next t
End With
'close Workbook and save changes
.Close SaveChanges:=True
End With
'quit excel
.Quit
End With
Set xlApp = Nothing
Set ExcelWkBk = Nothing
'Set olMail = Nothing
Set olHTML = Nothing
Set olEleColl = Nothing
End Sub

Related

Column Headers to the last line of data entered to the HTMLBody

I've included the last line of data entered to my HTML body. However the column headers are not showing, what am I doing wrong?
Private Sub cmdEmail_Click()
'Declare Outlook Variables
Dim OLApp As Outlook.Application
Dim OLMail As Object
Dim MyData As Object
'Open the Outlook Application and Start a new mail
Set OLApp = New Outlook.Application
Set OLMail = OLApp.CreateItem(0)
Set MyData = ThisWorkbook.Worksheets("Database").Cells(Rows.count, 1).End(xlUp).Resize(, 13)
OLApp.Session.Logon
With OLMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Quality Alert"
.HTMLBody = "<P><font size='6' face='Calibri' color='black'>Quality Issue Found<br><br> Please reply back with what adjustments have been made to correct this issue. </font></P>" & ConvertRangeToHTMLTable(ThisWorkbook.Worksheets("Database").Cells(Rows.count, 1).End(xlUp).Resize(, 13))
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Database")
Dim wb As Workbook
ws.Copy
Set wb = ActiveWorkbook
wb.SaveAs "C:\Temp\Database.xlsx" 'Change Path
.Display
' .Send
wb.Close SaveChanges:=False
Kill "C:\Temp\Database.xlsx"
End With
'Clearing Memory
Set OLMail = Nothing
Set OLApp = Nothing
End Sub
Only the 1st 13 columns of the last row are being targeted.
ThisWorkbook.Worksheets("Database").Cells(Rows.count, 1).End(xlUp).Resize(, 13)
I order to include all the data, you'll have to extend the range from the first cell to the last row.
With ThisWorkbook.Worksheets("Database")
Set MyData = .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp).Resize(, 13))
End With
Breaking up the code into smaller bites will allow you to easily isolate and test your code.
Extracting the code that targets the data range into its own function (in a public module) allows use Application.Goto to visibly inspect the range.
Application.Goto EmailData
Private Sub cmdEmail_Click()
Dim HTMLBody As String
HTMLBody = EmailHTMLFirstAndLastRow
SendEmail HTMLBody
CreateACopyOfTheDatabaseSaveItCloseKillItButNeverDoAnythingWithit
End Sub
Place this code in a public module:
Sub SendEmail(HTMLBody As String)
'Declare Outlook Variables
Dim OLApp As Outlook.Application
Dim OLMail As Object
Dim MyData As Object
'Open the Outlook Application and Start a new mail
Set OLApp = New Outlook.Application
Set OLMail = OLApp.CreateItem(0)
OLApp.Session.Logon
With OLMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Quality Alert"
.HTMLBody = "<P><font size='6' face='Calibri' color='black'>Quality Issue Found<br><br> Please reply back with what adjustments have been made to correct this issue. </font></P>" & HTMLBody
.Display
' .Send
End With
'Clearing Memory
Set OLMail = Nothing
Set OLApp = Nothing
End Sub
Function EmailHTMLFirstAndLastRow() As String
Dim Target As Range
Set Target = EmailData
With Target
.EntireRow.Hidden = msoTrue
.Rows(1).Hidden = msoFalse
.Rows(.Rows.Count).Hidden = msoFalse
.EntireRow.Hidden = msoFalse
End With
EmailHTMLFirstAndLastRow = RangetoHTML(Target.Rows(Target.Rows.Count))
End Function
Function EmailData() As Range
With ThisWorkbook.Worksheets("Database")
Set EmailData = .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp).Resize(, 13))
End With
End Function
Sub CreateACopyOfTheDatabaseSaveItCloseKillItButNeverDoAnythingWithit()
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Database")
Dim wb As Workbook
ws.Copy
Set wb = ActiveWorkbook
wb.SaveAs "C:\Temp\Database.xlsx" 'Change Path
wb.Close SaveChanges:=False
Kill "C:\Temp\Database.xlsx"
End Sub
Edit
I edited the code to create html for only the header and last rows, as per the OP's request. Since RangetoHTML() ignores hidden rows, I define the range of data, hid all but the fist and last rows, the passed the range to RangetoHTML() and assigned its value to a variable, the unhid the range.

Parse Saved HTML File VBA

I have a HTML file that is saved locally on the desktop which contains a table of statistics from which I need to pull specific data, paste it into a excel workbook table and then email it.
I've got the rest of the process working, I'm just struggling to figure out how to parse the html file and all other examples I've seen are parsing a website rather than a locally saved html file.
Apologies if this is a bit of beginner question but I'm finding it hard to make sense of the other examples I've seen.
thank you for any assistance.
Thank you to everyone for your examples and pointing me in the right direction ! The example posted below copies the data from a HTML file stored on the users desktop and pastes it into a new worksheet in Excel.
Option Explicit
Sub ParseHTML()
Dim URL As String
Dim IE As InternetExplorer
Dim htmldoc As MSHTML.IHTMLDocument 'Document object
Dim eleColtr As MSHTML.IHTMLElementCollection 'Element collection for tr tags
Dim eleColtd As MSHTML.IHTMLElementCollection 'Element collection for td tags
Dim htmlTables As MSHTML.IHTMLElementCollection 'Element collection for table tags
Dim eleRow As MSHTML.IHTMLElement 'Row elements
Dim eleCol As MSHTML.IHTMLElement 'Column elements
Dim wksOut As Worksheet
Dim rngOut As Range
Dim intTableIndex As Integer
Dim intRowIndex As Integer
Dim intColIndex As Integer
URL = Environ("userProfile") & "\desktop\FileName.HTML"
'Open InternetExplorer.
Set IE = New InternetExplorer
'Navigate to URL.
With IE
.navigate URL
.Visible = False
'Extract html information to objects.
Set htmldoc = IE.document
Set htmlTables = htmldoc.getElementsByTagName("table")
Set eleColtr = htmlTables(intTableIndex).getElementsByTagName("tr")
'Extract table to a new blank worksheet.
On Error Resume Next
Set wksOut = ThisWorkbook.Worksheets("WorksheetName")
If Err.Number <> 0 Then
Set wksOut = ThisWorkbook.Worksheets.Add(After:=Worksheets(Worksheets.Count))
wksOut.Name = "WorksheetName"
End If
With wksOut
.Cells.Clear
.Cells.NumberFormat = "General"
.Cells.ColumnWidth = 2
End With
On Error GoTo 0
'This section populates Excel
intRowIndex = 0
For Each eleRow In eleColtr
Set eleColtd = htmlTables(intTableIndex).getElementsByTagName("tr")(intRowIndex).getElementsByTagName("td") 'get all the td elements in that specific tr
Set rngOut = wksOut.Range("A1000000").End(xlUp).Offset(1, 0)
intColIndex = 0
For Each eleCol In eleColtd
rngOut.Offset(0, intColIndex) = eleCol.innerText
intColIndex = intColIndex + 1
Next eleCol
intRowIndex = intRowIndex + 1
Next eleRow
wksOut.Cells.EntireColumn.AutoFit
'Cleanup
IE.Quit
Set IE = Nothing
Set htmldoc = Nothing
Set htmlTables = Nothing
Set eleColtr = Nothing
Set eleColtd = Nothing
Set wksOut = Nothing
Set rngOut = Nothing
End With
End Sub
Please note that excel may throw a Runtime Error Automation Error on line:
Set IE = New InternetExplorer
If this happens try setting InternetExplorer integrity to Medium:
Set IE = New InternetExplorerMedium
If you need more information regarding InternetExplorer Integrity please see
https://blogs.msdn.microsoft.com/ieinternals/2011/08/03/default-integrity-level-and-automation/
As Tim mentioned I could open the file in excel and copy and paste the values which runs a lot faster:
Sub CopyHTML()
dim Wb as Workbook
dim Ws as Worksheet
Set Wb = ActiveWorkbook
Set Ws = Wb.Sheets("Sheet1")
'Opens html file and copies range
Workbooks.Open (Environ("userProfile") & "\desktop\FileName.html")
Range("A1:AJ21").Select
Selection.Copy
'pastes range in cell B5 on active workbook
Wb.Activate
Range("B5").Select
Ws.Paste
Application.CutCopyMode = False
Workbooks("FileName.html").Close
Thanks for the advice Tim !

Download unique data into ms access table

I am using this code to download certain outlook mail fields into access. This works well however the code is keep on downloading duplicate mails. Is there a way to check for existing records and download records which are not in the table? Your answers would help a lot in my project
Private Sub getml()
Dim rst As DAO.Recordset
Dim OlApp As Outlook.Application
Dim inbox As Outlook.MAPIFolder
Dim inboxItems As Outlook.Items
Dim Mailobject As Object
Dim db As DAO.Database
Dim dealer As Integer
Set db = CurrentDb
Set OlApp = CreateObject("Outlook.Application")
Set inbox = OlApp.GetNamespace("Mapi").GetDefaultFolder(olFolderInbox)
Set rst= CurrentDb.OpenRecordset("mls")
Set inboxItems = inbox.Items
For Each Mailobject In inboxItems
With rst
.AddNew
!task= Mailobject.UserProperties.Find("taskID")
!tsktml= Mailobject.UserProperties.Find("timeline")
.Update
Mailobject.UnRead = False
End With
End If
Next
Set OlApp = Nothing
Set inbox = Nothing
Set inboxItems = Nothing
Set Mailobject = Nothi
End Sub
I am assuming that TaskID is a numeric unique identifier for tasks, not that familiar with Outlook objects. If so, you can use the following code to first check the task hasn't been imported already.
Private Sub getml()
Dim rst As DAO.Recordset
Dim OlApp As Outlook.Application
Dim inbox As Outlook.MAPIFolder
Dim inboxItems As Outlook.Items
Dim Mailobject As Object
Dim db As DAO.Database
Dim dealer As Integer
Set db = CurrentDb
Set OlApp = CreateObject("Outlook.Application")
Set inbox = OlApp.GetNamespace("Mapi").GetDefaultFolder(olFolderInbox)
Set rst= CurrentDb.OpenRecordset("mls")
Set inboxItems = inbox.Items
For Each Mailobject In inboxItems
With rst
.FindFirst "task =""" & Mailobject.UserProperties.Find("taskID") & """"
If .NoMatch
.AddNew
!task= Mailobject.UserProperties.Find("taskID")
!tsktml= Mailobject.UserProperties.Find("timeline")
.Update
Mailobject.UnRead = False
End If
End With
End If
Next
Set OlApp = Nothing
Set inbox = Nothing
Set inboxItems = Nothing
Set Mailobject = Nothing
End Sub

Add new sheets to the exported excel using vba and do a lookup between two sheets using access VBA [duplicate]

I am running a few modules of code in access and am writing data into
Excel. When I write the first time, data gets written properly. But again
when I try, the new data is written on top of the old data. What should I do to
insert a new sheet?
My existing code is
Dim objexcel As Excel.Application
Dim wbexcel As Excel.Workbook
Dim wbExists As Boolean
Dim objSht As Excel.Worksheet
Dim objRange As Excel.Range
Set objexcel = CreateObject("excel.Application")
On Error GoTo Openwb
wbExists = False
Set wbexcel = objexcel.Workbooks.Open("C:\REPORT1.xls")
Set objSht = wbexcel.Worksheets("Sheet1")
objSht.Activate
wbExists = True
Openwb:
On Error GoTo 0
If Not wbExists Then
objexcel.Workbooks.Add
Set wbexcel = objexcel.ActiveWorkbook
Set objSht = wbexcel.Worksheets("Sheet1")
End If
I think that the following code should do what you want. It's very similar to yours, except it uses the return values from the .Add methods to get the objects you want.
Public Sub YourSub()
Dim objexcel As Excel.Application
Dim wbexcel As Excel.Workbook
Dim wbExists As Boolean
Set objexcel = CreateObject("excel.Application")
'This is a bad way of handling errors. We should'
'instead check for the file existing, having correct'
'permissions, and so on, and actually stop the process'
'if an unexpected error occurs.'
On Error GoTo Openwb
wbExists = False
Set wbexcel = objexcel.Workbooks.Open("C:\REPORT1.xls")
wbExists = True
Openwb:
On Error GoTo 0
If Not wbExists Then
Set wbexcel = objexcel.Workbooks.Add()
End If
CopyToWorkbook wbexcel
EndSub
Private Sub CopyToWorkbook(objWorkbook As Excel.Workbook)
Dim newWorksheet As Excel.Worksheet
set newWorksheet = objWorkbook.Worksheets.Add()
'Copy stuff to the worksheet here'
End Sub

Trying to copy an Excel sheet to another workbook from within Access

I'm trying to copy an excel worksheet to another workbook from within Access and keep getting the subscript out of range error. I've tried a few different things but can't seem to nail it. Any help would be appreciated. Using Access and Excel 2010 and my code is as follows:
Dim strTaxMonth As String
Dim strTaxYear As String
Dim strTabName As String
Dim objExcel As Excel.Application
Dim objWB As Workbook
Dim objWS As Worksheet
Dim strExcelFile0 As String
Dim strExcelFile1 As String
Dim strExcelFile2 As String
strTaxMonth = Forms!frm_PayrollTax_Report!ReportMonth
strTaxYear = Forms!frm_PayrollTax_Report!ReportYear
strTabName = strTaxMonth & strTaxYear & "_PTAX"
strExcelFile0 = "C:\File0.xlsm"
strExcelFile1 = "C:\File1.xlsx"
strExcelFile2 = "C:\File2.xlsm"
'Copy Worksheet to Yearly File
Set objExcel = New Excel.Application
objExcel.Visible = True
objExcel.DisplayAlerts = False
If Len(Dir(strExcelFile1)) > 0 Then Kill strExcelFile1
Set objWB = objExcel.Workbooks.Open(strExcelFile0)
objWB.Activate
Set objWS = objExcel.Sheets("PTAX")
objWS.Activate
objWS.Unprotect
objWS.Select
objWS.Name = strTabName
objWS.Range("A1:I16").Select
objWS.Range("A1:I16").Copy
objWS.Range("A1:I16").PasteSpecial xlPasteValues, xlPasteSpecialOperationNone
objWS.Range("B19:I28").Select
objWS.Range("B19:I28").Copy
objWS.Range("B19:I28").PasteSpecial xlPasteValues, xlPasteSpecialOperationNone
objWS.Protect
objWS.Select
objExcel.Workbooks.Open(strExcelFile0).Sheets(strTabName).Copy After:=objExcel.Workbooks.Open(strExcelFile2).Sheets("YTD PTAX")
objExcel.Workbooks(strExcelFile0).Activate
objExcel.ActiveWorkbook.SaveAs strExcelFile1
objExcel.ActiveWorkbook.Close False
objExcel.Quit
Set objExcel = Nothing
Set objWB = Nothing
Set objWS = Nothing
End Sub
Just use this piece of code
Sub test()
Dim xlapp as New Excel.Application
Dim xlwkb as Workbook
Dim xlsht as Worksheet
Dim xlwkb2 as Workbook
Dim xlsht2 as Worksheet
xlapp.DisplayAlerts=False
'First workbook and Sheet
Set xlwkb=xlapp.Workbooks.Open(strExcelFile0)
Set xlsht=xlwkb.Worksheets(1)
'Second workbook and Sheet
Set xlwkb2=xlapp.Workbooks.Open(strExcelFile0)
Set xlsht2=xlwkb.Worksheets(1)
xlsht.Range("A1:B16").Copy Destination:=xlsht2.Range("A1")
Set xlsht=Nothing
xlwkb.Close
Set xlwkb=Nothing
xlwkb2.Saveas "C:\File.xls"
Set xlsht2=Nothing
xlwkb2.Close
xlapp.DisplayAlerts=True
Set xlapp=Nothing
xlapp.Quit
End Sub