I've got an issue with some code when I've tried to install some code on a colleagues machine. The machine and version of Outlook are exactly the same and reference the same libraries. However, when I try and run the script on her machine, it throws up an error 91 on the 'Set xlWB = xlApp.Workbooks.Open(strPath)'.
The intention is to export necessary data from a selected email message into an Excel spreadsheet located in a specified directory.
Any clues as to what I should be trying in order to eliminate the error? First half of the code below.
Many thanks!
Option Explicit
Sub ServiceRequestTool()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim olItem As Outlook.MailItem
Dim obj As Object
Dim strColA, strColB, strColC As String
strPath = "H:\My Documents\General Docs\Govtnz-Service-Request.xlsm"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
If Dir$("H:\My Documents\General Docs\Govtnz-Service-Request.xlsm") = "" Then
MsgBox "Contact the spreadsheet administrator for assistance.", vbOKOnly + vbCritical, "File not found!"
Exit Sub
End If
End If
On Error GoTo 0
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("requestAssignment")
On Error Resume Next
rCount = xlSheet.Range("C" & xlSheet.Rows.Count).End(-4162).Row + 1
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each obj In Selection
Set olItem = obj
strColA = olItem.SenderName
strColB = olItem.SenderEmailAddress
strColC = olItem.ReceivedTime
xlSheet.Range("B" & rCount) = strColC
xlSheet.Range("C" & rCount) = strColA
xlSheet.Range("D" & rCount) = strColB
rCount = rCount + 1
Next
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set olItem = Nothing
Set obj = Nothing
Set currentExplorer = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
You are most probably getting that error because there is no instance of Excel which is running.
You need to create a new instance when GetObject doesn't find one.
You are checking for the existence of the file if Err <> 0? i.e when no Excel instance is found? That doesn't make sense. Check for the existence of the file first and then check for Excel.
Is this what you are trying? (untested)
Change your code
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
If Dir$("H:\My Documents\General Docs\Govtnz-Service-Request.xlsm") = "" Then
MsgBox "Contact the spreadsheet administrator for assistance.", _
vbOKOnly + vbCritical, "File not found!"
Exit Sub
End If
End If
On Error GoTo 0
to
'~~> Move ths out of that IF/EndIf
If Dir$("H:\My Documents\General Docs\Govtnz-Service-Request.xlsm") = "" Then
MsgBox "Contact the spreadsheet administrator for assistance.", _
vbOKOnly + vbCritical, "File not found!"
Exit Sub
End If
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Set xlApp = CreateObject("Excel.Application") '<~~ Add this line
End If
On Error GoTo 0
If xlApp Is Nothing Then
MsgBox "Excel is not installed"
Exit Sub
End If
Related
What I am trying to do.
I highlight some text in an email then run my macro.
It 'copies' the highlighted text and stores it in variable strText.
Then it creates a file called Artwork List.xlsx if it does not exist and if it exists it opens it.
After that it copies the text into the file in column A row 1 if the lastrow is 1, and if not, it appends to lastrow + 1
My code throws
'Run-time error 424, Object required'
To narrow down, the error should be coming from:
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
or anything related to this line.
Sub copyArts2File()
MsgBox "ok"
Dim OutApp As Object
Dim OutMail As Object
Dim olInsp As Object
Dim wdDoc As Object
Dim strText As String
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
Dim strTextArr As Variant
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
'Outlook wasn't running, so cancel
If Err <> 0 Then
MsgBox "Outlook is not running so nothing can be selected!"
GoTo lbl_Exit
End If
On Error GoTo 0
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = wdDoc.Application.Selection.Range.Text
End With
'MsgBox strText
lbl_Exit:
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
FileName = "Artwork List.xlsx"
fileDoesExist = Dir("C:\Users\quaer\Desktop\DL Arts\" & FileName) > ""
' Check for existing file
If fileDoesExist Then
' Open Excel file
Set xlBook = xlApp.Workbooks.Open("C:\Users\quaer\Desktop\DL Arts\" & FileName)
Set xlSheet = xlBook.Sheets(1)
Else
' Add Excel file
Set xlBook = xlApp.Workbooks.Add
With xlBook
.SaveAs FileName:="C:\Users\quaer\Desktop\DL Arts\" & FileName
End With
Set xlSheet = xlBook.Sheets(1)
End If
' Do stuff with Excel workbook
Dim i As Integer
Dim lastrow As Long
With xlApp
With xlBook
With xlSheet
strTextArr = Split(strText, "Adding file")
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
MsgBox lastrow
If lastrow = 1 Then
For i = 1 To UBound(strTextArr)
.Range("A" & i).Value = strTextArr(i)
Next i
Else
For i = 1 To UBound(strTextArr)
.Range("A" & (i + lastrow)).Value = strTextArr(i)
Next i
End If
.Close SaveChanges:=True
End With
End With
End With
xlApp.Visible = True
Exit Sub
End Sub
Try replacing this line, lastrow = .Cells(Rows.Count, 1).End(xlUp).Row, with:
lastrow = .Cells(1048576, 1).End(xlUp).Row
or
lastrow = .Cells(Rows.Count +1, 1).End(xlUp).Row
Jeeez this is crazy. I have found the problem finally and got a working code for anyone wanting similar usage. 1st off, I need to add the Microsoft excel add in. So in Outlook VBA, Tools -> references -> check Microsoft Excel 16.0 Object Library. This is to get rid of the 424 object required error, as I was trying to a call a excel built in method I guess. this is the line:
lastrow = .Cells(Rows.Count, 1).End(xlUp).Row
Pls note that I am calling this macro from Outlook.
After this I faced a couple of other issues.
1. errors such as 424 run time, remote server machine does not exist or is not available.
first time running, it throws this error, 2nd time I click, the problem goes away. This is an issue with non specific use of the app, book and worksheet and so leaves VBA to assign on its own. Lesson learnt, be explicit about every thing.
leaves a copy of excel process even after program ends. This can be seen in task manager. This causes issues because then my excel file is linked to this process and not able to open without either read only or notify. Its locked with the process. So I cannot run again next time.
Anyway. Here is the final code. And I have also changed it to .Range instead of .Cells. I believe it does not matter if I used either but the key culprit is : xlSheet.Rows.Count. Instead of just Rows.Count, explicitly use xlSheet.Rows.Count.
Option Explicit
Sub copyArts2File()
MsgBox "ok"
Dim OutApp As Object, OutMail As Object, olInsp As Object, wdDoc As Object
Dim xlApp As Excel.Application, xlBook As Excel.Workbook, xlSheet As Object
Dim strText As String
Dim strTextArr As Variant
Dim fName As String
Dim fileDoesExist As Boolean
Dim i As Integer
Dim lastrow As Long
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
'Outlook wasn't running, so cancel
If Err <> 0 Then
MsgBox "Outlook is not running so nothing can be selected!"
GoTo lbl_Exit
End If
On Error GoTo 0
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = wdDoc.Application.Selection.Range.Text
End With
'MsgBox strText
'Close out all shit
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
lbl_Exit:
Set OutMail = Nothing
Set OutApp = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
On Error Resume Next 'Create or use a Excel Application
Set xlApp = GetObject(, "Excel.Application")
If Err.Number > 0 Then Set xlApp = CreateObject("Excel.Application")
On Error GoTo 0
xlApp.Visible = False
xlApp.DisplayAlerts = False
fName = "Artwork List.xlsx"
fileDoesExist = Dir("C:\Users\quaer\Desktop\DL Arts\" & fName) > ""
' Check for existing file
If fileDoesExist Then
' Open Excel file if present
Set xlBook = xlApp.Workbooks.Open("C:\Users\quaer\Desktop\DL Arts\" & fName)
Else
' Add Excel file if not present
Set xlBook = xlApp.Workbooks.Add
xlBook.SaveAs fileName:="C:\Users\quaer\Desktop\DL Arts\" & fName
End If
Set xlSheet = xlBook.Worksheets(1)
' Do stuff with Excel workbook
strTextArr = Split(strText, "Adding file")
lastrow = xlSheet.Range("A" & xlSheet.Rows.Count).End(xlUp).Row
If lastrow = 1 Then
For i = 1 To UBound(strTextArr)
xlSheet.Range("A" & i).Value = strTextArr(i)
Next i
Else
For i = 1 To UBound(strTextArr)
xlSheet.Range("A" & (i + lastrow)).Value = strTextArr(i)
Next i
End If
xlBook.SaveAs fileName:="C:\Users\quaer\Desktop\DL Arts\" & fName, AccessMode:=xlExclusive, ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges
xlBook.Close (True)
Set xlBook = Nothing
Set xlSheet = Nothing
xlApp.Visible = True
xlApp.Quit
Set xlApp = Nothing
MsgBox "Done!"
Exit Sub
End Sub
Thanks for the help and suggestions nonetheless.
This question already has answers here:
Test or check if sheet exists
(23 answers)
Closed 3 years ago.
I have set macro for test mails & move them. But if i get an another excel file, where are another sheet names then I get VBA error: subscript out of range.
The error is in this line: Set xlSheet = xlWB.sheets("MySheet1")
Option Explicit
Sub CheckAttachments(olItem As MailItem)
Const strPath As String = "C:\Users\PC2\Documents\Temp_attachs\"
Const strFindText As String = "Completed"
Dim strFilename As String
Dim olAttach As Attachment
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim bXStarted As Boolean
Dim bFound As Boolean
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = myInbox.Folders("MyFolder1")
If olItem.Attachments.Count > 0 Then
For Each olAttach In olItem.Attachments
If Right(LCase(olAttach.FileName), 4) = "xlsx" Then
strFilename = strPath & Format(olItem.ReceivedTime, "yyyymmdd-HHMMSS") & _
Chr(32) & olAttach.FileName
olAttach.SaveAsFile strFilename
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 read the data
Set xlWB = xlApp.workbooks.Open(strFilename)
Set xlSheet = xlWB.sheets("MySheet1")
If FindValue(strFindText, xlSheet) Then
olItem.Move myDestFolder
'MsgBox "Value found in " & strFilename
bFound = True
End If
xlWB.Close 0
If bXStarted Then xlApp.Quit
If Not bFound Then Kill strFilename
'Exit For
End If
Next olAttach
End If
End Sub
How can i test the sheet and if it's not exists then exit sub (errorhandling: exit sub) ?
To check if the Sheet exists, you can use a code like this:
On Error Resume Next
Set xlSheet = xlWB.Sheets("MySheet1")
If xlSheet Is Nothing Then
MsgBox "Sheet not found!", vbCritical
Exit Sub
End If
On Error GoTo 0
Hope this helps.
You can adjust your code as follows:
Sub foo()
Dim xlSheet As Object
Dim xlWB As Object
On Error Resume Next
Set xlWB = ThisWorkbook
Set xlSheet = xlWB.Sheets("MySheet2")
On Error GoTo 0
If xlSheet Is Nothing Then
Debug.Print "sheet is missing"
Else
Debug.Print "sheet is not missing"
End If
End Sub
Simply shift your "On Error GoTo 0" statement after you set your xlSheet value, and then add another "If" statement to check if you should continue with the rest of your code.
This should Work for you:
Sub CheckAttachments(olItem As MailItem)
Const strPath As String = "C:\Users\PC2\Documents\Temp_attachs\"
Const strFindText As String = "Completed"
Dim strFilename As String
Dim olAttach As Attachment
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim bXStarted As Boolean
Dim bFound As Boolean
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = myInbox.Folders("MyFolder1")
If olItem.Attachments.Count > 0 Then
For Each olAttach In olItem.Attachments
If Right(LCase(olAttach.FileName), 4) = "xlsx" Then
strFilename = strPath & Format(olItem.ReceivedTime, "yyyymmdd-HHMMSS") & _
Chr(32) & olAttach.FileName
olAttach.SaveAsFile strFilename
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 read the data
Set xlWB = xlApp.Workbooks.Open(strFilename)
For Each xlSheet In xlWB.Worksheets
If xlSheet.Name = "MySheet1" Then
Set xlSheet = xlWB.sheets("MySheet1")
Exit For
End If
Next
If xlSheet Is Nothing Then
Exit Sub
End If
If FindValue(strFindText, xlSheet) Then
olItem.Move myDestFolder
'MsgBox "Value found in " & strFilename
bFound = True
End If
xlWB.Close 0
If bXStarted Then xlApp.Quit
If Not bFound Then Kill strFilename
'Exit For
End If
Next olAttach
End If
End Sub
You could use a simple function to check if a sheet name exits:
Function CheckIfSheetExists(Sheetname As String, wb As Workbook) As Boolean
On Error Resume Next
Debug.Print wb.Sheets(Sheetname)
If err.Number <> 0 Then CheckIfSheetExists = False Else CheckIfSheetExists = True
err.clear
End Function
You can call it like so
Sub test()
Dim wbook As Workbook
Dim result As Boolean
Set wbook = Workbooks("Book1")
result = CheckIfSheetExists("Sheet4", wbook)
If result = True Then Msgbox "Sheet exists!"
End Sub
The function will try to print out the name of the specified worksheet within the specified workbook. If this fails, it could not find the worksheet so the function will return False, otherwise it will return True.
I wish to extract the filenames of the attachments I have received into the public folder and extract ( paste ) them into the excel file for easy analysis.
I have the below code however it is only selecting details of 1 email.
I wish to understand where it does wrong.
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim olItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Dim j As Long
Dim i As Integer
Dim Report As String
Dim attachment As attachment
Dim obj As Object
Dim strColB, strColC, strColD, strColE, strColF As String
' Get Excel set up
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "\Documents\test.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
'Find the next empty line of the worksheet
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row
' get the values from outlook
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each obj In Selection
Set olItem = obj
Set myAttachments = olItem.Attachments
'collect the fields
Next
For Each Selection In Selection
If Selection.Class = olMail Then
End If
For Each attachment In olItem.Attachments
Report = strColC & GetAttachmentInfo(attachment)
strColB = olItem.Attachments.Count
strColD = olItem.SenderEmailAddress
strColE = olItem.Categories
strColF = olItem.ReceivedTime
'write them in the excel sheet
xlSheet.Range("B" & rCount) = strColB
xlSheet.Range("c" & rCount) = Report
xlSheet.Range("d" & rCount) = strColD
xlSheet.Range("e" & rCount) = strColE
xlSheet.Range("f" & rCount) = strColF
'Next row
rCount = rCount + 1
Next
Next
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set olItem = Nothing
Set obj = Nothing
Set currentExplorer = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
Public Function GetAttachmentInfo(attachment As attachment)
On Error GoTo On_Error
Dim Report
Dim strColA, strColB, strColC, strColD, strColE, strColF As String
GetAttachmentInfo = ""
Report = strColA & "Display Name: " & attachment.DisplayName
Report = strColC & "File Name: " & attachment.filename
GetAttachmentInfo = Report
Exiting:
Exit Function
On_Error:
MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Function
I do not have access to Outlook at the moment so the following is from studying the macro rather than trying to run it.
Public Function GetAttachmentInfo(attachment As attachment)
You need As String at the end if you want a value returned. You are using attachment both as a keyword and as the name of a parameter. Please rename the parameter.
Report = strColA & "Display Name: " & attachment.DisplayName
Report = strColC & "File Name: " & attachment.filename
strColA and strColA have be declared with a Dim statement but have not been given values so are blank. The second statement overwrites the value of Report set by the first.
I see examples of your use of On Error repeatedly. I did the same until I realised it was totally unhelpful. During development, you want the interpreter to stop on the statement giving the error so you know what to correct. In a production macro, released to non-technical users, you need something more friendly. I suggest you delete this code.
I cannot see why you are getting the name of the first attachment but not the other attachments. I suggest you correct these errors and then repost your revised code.
I want to export messages to Excel. However, when I try running the macro, I don't see it in the list.
I just copied the code below from http://www.slipstick.com/developer/vba-copy-outlook-email-excel-workbook
Option Explicit
Const xlUp As Long = -4162
Sub CopyToExcel(olItem As Outlook.MailItem)
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim strPath As String
Dim M1 As Object
Dim M As Object
Dim lgLastRow As Long 'specify the last data row
lgLastRow = Range("A1048576").End(xlUp).Row 'Take Note: very useful!!
enviro = CStr(Environ("username"))
'the path of the workbook
strPath = enviro & "C:\Desktop\Project\SR History File.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")
'Find the next empty line of the worksheet
rCount = lgLastRow = Range("A1048576").End(xlUp).Row + 1
xlSheet.Range("A" & rCount) = olItem.SentOn
xlSheet.Range("B" & rCount) = olItem.SenderEmailAddress
xlSheet.Range("C" & rCount) = olItem.Subject
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set M = Nothing
Set M1 = Nothing
Set Reg1 = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
The code cannot run without a parameter, olItem.
Open a mailitem then run this, which will be in the list.
Option Explicit
Sub CopyToExcel_Test
Dim currItem as mailitem
Set currItem = ActiveInspector.currentitem
CopyToExcel currItem
ExitRoutine:
Set currItem = Nothing
End Sub
I am trying to export all data related to a specific folder in my Outlook 2010 to Excel. I need the To, From, Body, All date fields, Has Attachement, etc.. Is there a way where I can include all the fields without defining field by field?
When I run the below code, I have a Compile Error: Next without For.
I believe all the IFs are closed.
Sub ExportToExcel()
On Error GoTo ErrHandler
Dim appExcel As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Dim rng As Excel.Range
Dim strSheet As String
Dim strPath As String
Dim intRowCounter As Integer
Dim intColumnCounter As Integer
Dim msg As Outlook.MailItem
Dim nms As Outlook.NameSpace
Dim fld As Outlook.MAPIFolder
Dim itm As Object
strSheet = "OutlookItems.xls"
strPath = "C:\"
strSheet = strPath & strSheet
Debug.Print strSheet
'Select export folder Set nms = Application.GetNamespace("MAPI")
Set fld = nms.PickFolder
'Handle potential errors with Select Folder dialog box.
If fld Is Nothing Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.DefaultItemType <> olMailItem Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.Items.Count = 0 Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
End If
'Open and activate Excel workbook.
Set appExcel = CreateObject("Excel.Application")
appExcel.Workbooks.Open (strSheet)
Set wkb = appExcel.ActiveWorkbook
Set wks = wkb.Sheets(1)
wks.Activate
appExcel.Application.Visible = True
'Copy field items in mail folder. For Each itm In fld.Items
intColumnCounter = 1
Set msg = itm
intRowCounter = intRowCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.To
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.SenderEmailAddress
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.Subject
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.Body
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.SentOn
intColumnCounter = intColumnCounter + 1
Set rng = wks.Cells(intRowCounter, intColumnCounter)
rng.Value = msg.ReceivedTime
Next itm
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler: If Err.Number = 1004 Then
MsgBox strSheet & " doesn't exist", vbOKOnly, "Error"
Else
MsgBox Err.Number & "; Description: ", vbOKOnly, "Error"
End If
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
End Sub
It is not the problem of For/Next Loop.
Change the line
ErrHandler: If Err.Number = 1004 Then
to
ErrHandler:
If Err.Number = 1004 Then
TIP: Always indent your code :) You might also want to see this (point 4)?
EDIT: See Point 6 in the above link as well :) To illustrate that in your code, see this part
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler:
If Err.Number = 1004 Then
MsgBox strSheet & " doesn't exist", vbOKOnly, "Error"
Else
MsgBox Err.Number & "; Description: ", vbOKOnly, "Error"
End If
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
End Sub
This can be also written as
LetsContinue:
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler:
If Err.Number = 1004 Then
MsgBox strSheet & " doesn't exist", vbOKOnly, "Error"
Else
MsgBox Err.Number & "; Description: ", vbOKOnly, "Error"
End If
Resume LetsContinue
End Sub
Another example
If fld Is Nothing Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.DefaultItemType <> olMailItem Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.Items.Count = 0 Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
End If 'Open and activate Excel workbook. Set appExcel = CreateObject("Excel.Application")
Set wkb = appExcel.Workbooks.Open(strSheet)
Set wks = wkb.Sheets(1)
wks.Activate
You don't need to use Exit Sub so many times
You can put the rest of the code in the Else part of the IF
In fact DO NOT use Exit Sub at all in your code. Reason being, your code will exit the sub without destroying and cleaning up the objects that you created. Exit the procedure gracefully :)
FOLLOWUP
Try this code. (UNTESTED)
Sub ExportToExcel()
On Error GoTo ErrHandler
'~~> Excel Objects / Variables
Dim appExcel As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Dim strSheet As String, strPath As String
Dim intRowCounter As Long, intColumnCounter As Long
'~~> Outlook Objects
Dim msg As Outlook.MailItem
Dim nms As Outlook.Namespace
Dim fld As Outlook.MAPIFolder
Dim itm As Object
strSheet = "OutlookItems.xls"
strPath = "C:\"
strSheet = strPath & strSheet
Set nms = Application.GetNamespace("MAPI")
Set fld = nms.PickFolder
If fld Is Nothing Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
ElseIf fld.DefaultItemType <> olMailItem Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
ElseIf fld.Items.Count = 0 Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Else
'Open and activate Excel workbook.
Set appExcel = CreateObject("Excel.Application")
Set wkb = appExcel.Workbooks.Open(strSheet)
Set wks = wkb.Sheets(1)
appExcel.Visible = True
'Copy field items in mail folder.
For Each itm In fld.Items
Set msg = itm
With wks
intRowCounter = intRowCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.To
intColumnCounter = intColumnCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.SenderEmailAddress
intColumnCounter = intColumnCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.Subject
intColumnCounter = intColumnCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.Body
intColumnCounter = intColumnCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.SentOn
intColumnCounter = intColumnCounter + 1
.Cells(intRowCounter, intColumnCounter) = msg.ReceivedTime
End With
Next itm
End If
LetsContinue:
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler:
If Err.Number = 1004 Then
MsgBox strSheet & " doesn't exist", vbOKOnly, "Error"
Else
MsgBox "Error Number: " & Err.Number & vbNewLine & _
"Error Description: " & Err.Description, vbOKOnly, "Error"
End If
Resume LetsContinue
End Sub
Assuming your code looks like what you pasted, the reason you are getting the error is this line:
'Copy field items in mail folder. For Each itm In fld.Items
Notice that the for part of your loop is part of your comment?
Siddharth gave you a lot of good tips to help avoid these kind of problems, but to get your code to compile just replace the line I showed you with this:
'Copy field items in mail folder.
For Each itm In fld.Items
You also commented out another line:
'Select export folder Set nms = Application.GetNamespace("MAPI")
Should be:
'Select export folder
Set nms = Application.GetNamespace("MAPI")