My company has a database that was built for us,and suddenly the module we were using to send emails isnt working anymore. I'm told that security measures have changed, so I'm trying to figure out how to update the settings and make this work again. Unfortunately, I don't really know how half these functions work. Any ideas?
Option Compare Database
Option Explicit
Public Function EmailReceiptByGeneric( _
ByVal strReceipt As String, _
ByVal Recipient As String, _
ByVal ToAdd As String, _
ByVal strProgram As String, _
ByVal Attachment As String, _
ByVal strSubject As String, _
ByVal strMessage As String, _
ByVal strEmailFROM As String, _
ByVal strEmailPWD As String, _
Optional ByVal CC As String) As Boolean
Dim cdoConfig As Object
Dim msgOne As Object
On Error GoTo errHandler
EmailReceiptByGeneric = False
Set cdoConfig = CreateObject("CDO.Configuration")
With cdoConfig.Fields
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465 '587 '
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = strEmailFROM
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = strEmailPWD
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
.Update
End With
Set msgOne = CreateObject("CDO.Message")
Set msgOne.Configuration = cdoConfig
msgOne.To = ToAdd
msgOne.FROM = strEmailFROM
msgOne.Subject = strSubject
msgOne.htmlBody = strMessage & "<br/>" & "<br/>" & "<br/>" & "<br/>" & _
strReceipt
msgOne.send
EmailReceiptByGeneric = True
Cleanup:
On Error GoTo 0
On Error Resume Next
exitProc:
Exit Function
errHandler:
EmailReceiptByGeneric = False
MsgBox prompt:="There was an error in the attempt to send email through " & strEmailFROM & "." & vbCrLf & vbCrLf, _
buttons:=vbCritical + vbOKOnly, title:="Unable to Send Email through " & strEmailFROM
Resume Cleanup
Resume
End Function
Public Function ValidateEmailAddress(ByVal strEmailAddress As String) As Boolean
Dim objRegExp As Object
Dim blnIsValidEmail As Boolean
On Error GoTo errHandler
strEmailAddress = Trim(strEmailAddress)
Set objRegExp = CreateObject("VBScript.RegExp")
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = "^([a-zA-Z0-9_\-\.]+)#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"
blnIsValidEmail = objRegExp.Test(Trim(strEmailAddress))
ValidateEmailAddress = blnIsValidEmail
Cleanup:
On Error GoTo 0
On Error Resume Next
exitProc:
Exit Function
errHandler:
ValidateEmailAddress = False
MsgBox prompt:=Err & ": " & Err.description, buttons:=vbCritical + vbOKOnly, title:="Unable to Validate Email"
Resume Cleanup
Resume
End Function
Public Function ValidateEmailAddress(ByVal strEmailAddress As String) As Boolean
Dim objRegExp As Object
Dim blnIsValidEmail As Boolean
On Error GoTo errHandler
strEmailAddress = Trim(strEmailAddress)
Set objRegExp = CreateObject("VBScript.RegExp")
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = "^([a-zA-Z0-9_\-\.]+)#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"
blnIsValidEmail = objRegExp.Test(Trim(strEmailAddress))
ValidateEmailAddress = blnIsValidEmail
Cleanup:
On Error GoTo 0
On Error Resume Next
exitProc:
Exit Function
errHandler:
ValidateEmailAddress = False
MsgBox prompt:=Err & ": " & Err.description, buttons:=vbCritical + vbOKOnly, title:="Unable to Validate Email"
Resume Cleanup
Resume
End Function
Public Function ValidatePMT(ByVal dblPmtAmt As Double, ByVal dtPmtDate As Date) As Boolean
On Error GoTo errHandler
If dblPmtAmt = 0 Then
ValidatePMT = False
MsgBox prompt:="Payment amount is required for emailed receipt.", buttons:=vbExclamation + vbOKOnly, title:="Missing Required Payment Amount"
GoTo Cleanup
ElseIf dtPmtDate = #1/31/2099# Then
ValidatePMT = False
MsgBox prompt:="Payment date is required for emailed receipt.", buttons:=vbExclamation + vbOKOnly, title:="Missing Required Payment Date"
GoTo Cleanup
End If
ValidatePMT = True
Cleanup:
On Error GoTo 0
On Error Resume Next
exitProc:
Exit Function
errHandler:
MsgBox prompt:="Unexpected error " & Err.Number & ", " & Err.description, buttons:=vbExclamation + vbOKOnly, title:="Error"
Resume Cleanup
Resume
End Function
Sounds like you upgraded to new Windows...
Microsoft stopped including CDO with Windows, if I'm not mistaken, some 10 years ago.
You can solve this by obtaining the dll file
cdosys.dll
preferably from your previous Windows system, from the following folder.
C:\Windows\System32
Copy the dll to the same location on your new system.
Then you must register the dll on your new system. Open a COMMAND window and navigate to your C:\Windows\System32 folder and run the following command.
regsvr32 cdosys.dll
Related
I want to print all emails and attachments of an Outlook folder. I want to print excel, word and pfd files.
This works but not in the right order. Emails en printed attachments get mixed-up. So i want to synchronize the printing. The process has to wait until the print job has been send. The problem is probably that ShellExecute command works asynchronically from the VBA.
So how can I let the VBA wait until the ShellExecute has finished. I've read on the MSDN that I have to use the CreateProcess but I don't know how to use a print command on this. It only runs an application.
I also tried to use the Sleep method in VBA to give the printing some time but it doesn't seems to be the right solution or work very good. Please has anyone an advice?
Private Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
Sub SaveBijlageArgumenten()
SaveEmailAttachmentsToFolder "Postvak IN", "Account...", "xlsx", "xls", "pdf", "doc", "docx", "C:\....."
End Sub
Sub SaveEmailAttachmentsToFolder(OutlookInbox As String, OutlookAccount As String, _
ExtString As String, ExtString2 As String, ExtString6 As String, ExtString3 As String, ExtString4 As String, _
ExtString5 As String, DestFolder As String)
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim MyDocPath As String
Dim I As Integer
Dim wsh As Object
Dim fs As Object
Dim xlApp As Object
Dim myBook As Object
' Create Excel Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False 'Visible is False by default, so this isn't necessary
On Error GoTo ThisMacro_err
Set ns = GetNamespace("MAPI")
Set Inbox = ns.Folders(OutlookAccount)
Set SubFolder = Inbox.Folders(OutlookInbox)
I = 0
' Check subfolder for messages and exit of none found
If SubFolder.Items.Count = 0 Then
MsgBox "There are no messages in this folder : " & OutlookFolderInInbox, _
vbInformation, "Nothing Found"
Set SubFolder = Nothing
Set Inbox = Nothing
Set ns = Nothing
Exit Sub
End If
'Create DestFolder if DestFolder = ""
Set fs = CreateObject("Scripting.FileSystemObject")
If DestFolder = "" Then
Set wsh = CreateObject("WScript.Shell")
Set fs = CreateObject("Scripting.FileSystemObject")
MyDocPath = wsh.SpecialFolders.Item("mydocuments")
DestFolder = MyDocPath & "\" & Format(Now, "dd-mmm-yyyy hh-mm-ss")
If Not fs.FolderExists(DestFolder) Then
fs.CreateFolder DestFolder
End If
Else
DestFolder = DestFolder & "\" & Format(Now, "dd-mmm-yyyy hh-mm-ss")
If Not fs.FolderExists(DestFolder) Then
fs.CreateFolder DestFolder
End If
End If
If Right(DestFolder, 1) <> "\" Then
DestFolder = DestFolder & "\"
End If
'On Error Resume Next
' Check each message for attachments and extensions
For Each Item In SubFolder.Items
Item.PrintOut Background:=False
Item.UnRead = False
Sleep 500
For Each Atmt In Item.Attachments
If LCase(Right(Atmt.FileName, Len(ExtString))) = LCase(ExtString) Or _
LCase(Right(Atmt.FileName, Len(ExtString2))) = LCase(ExtString2) Then
FileName = DestFolder & Item.SenderName & " " & Atmt.FileName
Atmt.SaveAsFile FileName
Set myBook = xlApp.Workbooks.Open(FileName, UpdateLinks:=0)
myBook.PrintOut Background:=False
myBook.Close SaveChanges:=False
I = I + 1
ElseIf LCase(Right(Atmt.FileName, Len(ExtString3))) = LCase(ExtString3) Or LCase(Right(Atmt.FileName, Len(ExtString4))) = LCase(ExtString4) _
Or LCase(Right(Atmt.FileName, Len(ExtString5))) = LCase(ExtString5) Then
FileName = DestFolder & Item.SenderName & " " & Atmt.FileName
Atmt.SaveAsFile FileName
ShellExecute 0, "print", FileName, vbNullString, vbNullString, 0
Sleep 3000
I = I + 1
End If
Next Atmt
Next Item
On Error GoTo ThisMacro_err
' Show this message when Finished
If I > 0 Then
MsgBox "De bestanden in de bijlage zijn opgeslagen op onderstaande locatie: " _
& DestFolder, vbInformation, "Klaar!"
Else
MsgBox "Er bevonden zich geen bijlagen bij de emails", vbInformation, "Klaar!"
End If
' Clear memory
ThisMacro_exit:
Set SubFolder = Nothing
Set Inbox = Nothing
Set ns = Nothing
Set fs = Nothing
Set wsh = Nothing
Set xlApp = Nothing
Set myBook = Nothing
Set AcroExchApp = Nothing
Set AcroExchAVDoc = Nothing
Exit Sub
' Error information
ThisMacro_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveEmailAttachmentsToFolder" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume ThisMacro_exit
End Sub
The WshShell object provides the Run method which has the bWaitOnReturn optional parameter. It indicates whether the script should wait for the program to finish executing before continuing to the next statement in your script. If set to true, script execution halts until the program finishes, and Run returns any error code returned by the program. If set to false (the default), the Run method returns immediately after starting the program, automatically returning 0 (not to be interpreted as an error code).
the code below is creating an email, whilst searching through folders and attaching the relevant docs.
I have coded it to check whether the user has sent the email or closed it. I have put it so an input box gets displayed when the user closes the email. What i would like to happen is when the email gets closed, is the InputBox is set to focus, and after a reason why the email was sent have been entered then go back to the email to click on don't save draft.
Or even have the input box display after the email has been closed, after the save without changed dialog box.
Userform Code:
Dim OutApp As Object
Dim itmevt As New CMailItemEvents
Private Sub btnEMSent_Click()
Dim i, j, lastG, lastD As Long
Dim OutMail As Object
Dim sFName As String, colFiles As New Collection
Dim myDir As String, ChDir As String, attName As New Collection, attName2 As String
Dim dte As String
Dim greet As String, cntName As String, SigString As String, Signature As String
lastG = Sheets("File Locations").Cells(Rows.Count, "B").End(xlUp).Row
SigString = "H:\AppData\Roaming\Microsoft\Signatures\"
If Dir(SigString, vbDirectory) <> vbNullString Then
SigString = SigString & Dir$(SigString & "*.htm")
Else:
SigString = ""
End If
Signature = CreateObject("Scripting.FileSystemObject").GetFile(SigString).OpenAsTextStream(1, -2).readall
If Me.cmbMonth.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Payment Month Required!"
Me.cmbMonth.SetFocus
Exit Sub
ElseIf Me.txtbxYear.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Payment Year Required!"
Me.txtbxYear.SetFocus
Exit Sub
ElseIf Me.cmbSubbie.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Sub-Contractor Required!"
Me.cmbSubbie.SetFocus
Exit Sub
End If
For i = 1 To lastG
lookupVal = Sheets("File Locations").Cells(i, "B") ' value to find
If Dir(lookupVal, vbDirectory) = "" Then
Else
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set itmevt.itm = OutMail
dte = Me.cmbMonth.Value & " " & Me.txtbxYear.Text
myDir = lookupVal 'Set Dir to search
ChDir = (myDir & "\" & Me.cmbSubbie.Value & "\Remittance\") 'Change to that dir
sFName = Dir(ChDir & "*" & dte & "*") 'Set Search spec
While InStr(sFName, dte)
colFiles.Add (ChDir & sFName)
attName.Add (sFName)
sFName = Dir
Wend
End If
Next i
On Error Resume Next
With OutMail
If Me.txtbxSubNAME.Value <> "" Then
cntName = " " & Me.txtbxSubNAME.Value & ","
Else
cntName = ","
End If
If Time < TimeValue("12:00:00") Then
greet = "Good Morning" & cntName
Else
greet = "Good Afternoon" & cntName
End If
If colFiles.Count > 0 Then
For i = 1 To colFiles.Count
.Attachments.Add colFiles(i)
attName2 = attName(i) & "<br>" & attName2
Next i
End If
.To = Me.txtbxSubEMAIL.Value
.CC = ""
.BCC = ""
.Subject = Me.cmbMonth.Value & "'s Remittances"
.BodyFormat = olFormatHTML
.HTMLbody = "<HTML><BODY></BODY></HTML>" & .HTMLbody & Signature
.Display True
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
In the class module CMailItemEvents:
Option Explicit
Public WithEvents itm As Outlook.MailItem
Private Declare PtrSafe Function MessageBox _
Lib "User64" Alias "MessageBoxA" _
(ByVal hWnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As Long) _
As Long
Private Sub itm_Close(Cancel As Boolean)
Dim blnSent As Boolean
Dim lastG As Long
Dim myValue As Variant
lastG = Sheets("Report").Cells(Rows.Count, "A").End(xlUp).Row + 1
On Error Resume Next
blnSent = itm.Sent
If Err.Number = 0 Then
myValue = inputBox("Why was " & usrFrmEMAIL.cmbSubbie & " Remittance E-Mail not sent?", "Remittance Error")
Sheets("Report").Range("A" & lastG).Value = usrFrmEMAIL.cmbSubbie.Value
Sheets("Report").Range("B" & lastG).Value = usrFrmEMAIL.cmbMonth.Text & " " & usrFrmEMAIL.txtbxYear.Text
Sheets("Report").Range("C" & lastG).Value = Now
AppActivate (myValue.ActiveExplorer.CurrentItem)
Sheets("Report").Range("D" & lastG).Value = myValue
Exit Sub
Else
Sheets("Report").Range("A" & lastG).Value = usrFrmEMAIL.cmbSubbie.Value
Sheets("Report").Range("B" & lastG).Value = usrFrmEMAIL.cmbMonth.Text & " " & usrFrmEMAIL.txtbxYear.Text
Sheets("Report").Range("C" & lastG).Value = Now
End If
End Sub
sorry for taking so long to get back, i've been away on holiday.
I managed to figure out how to get this to work.
Class Module:
Option Explicit
Private Declare Function GetWindowThreadProcessId Lib _
"user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function AttachThreadInput Lib "user32" _
(ByVal idAttach As Long, ByVal idAttachTo As Long, _
ByVal fAttach As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hWnd As Long) As Long
Private Declare Function IsIconic Lib "user32" _
(ByVal hWnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName _
As Long, ByVal lpWindowName As String) As Long
Const SW_SHOW = 5
Const SW_RESTORE = 9
Public WithEvents itm As Outlook.MailItem
Function ForceForegroundWindow(ByVal hWnd As Long) As Boolean
Dim ThreadID1 As Long
Dim ThreadID2 As Long
Dim nRet As Long
If hWnd = GetForegroundWindow Then
ForceForegroundWindow = True
Else
ThreadID1 = GetWindowThreadProcessId( _
GetForegroundWindow, ByVal 0&)
ThreadID2 = GetWindowThreadProcessId(hWnd, ByVal 0&)
If ThreadID1 <> ThreadID2 Then
AttachThreadInput ThreadID1, ThreadID2, True
nRet = SetForegroundWindow(hWnd)
AttachThreadInput ThreadID1, ThreadID2, False
Else
nRet = SetForegroundWindow(hWnd)
End If
If IsIconic(hWnd) Then
ShowWindow hWnd, SW_RESTORE
Else
ShowWindow hWnd, SW_SHOW
End If
ForceForegroundWindow = CBool(nRet)
End If
End Function
Private Sub itm_Close(Cancel As Boolean)
Dim blnSent As Boolean
Dim lastG As Long, currentrow As Integer
Dim myValue As String
Dim bOK As Boolean
Dim idx As Long
idx = usrFrmEMAIL.cmbSubbie.ListIndex
lastG = Sheets("Report").Cells(Rows.Count, "A").End(xlUp).Row + 1
On Error Resume Next
blnSent = itm.Sent
If Err.Number = 0 Then
itm.Close olDiscard
ForceForegroundWindow FindWindowA(0, Application.Caption)
Do
myValue = inputBox("Why was " & usrFrmEMAIL.cmbSubbie & "'s Remittance E-Mail not sent?", "Remittance Error")
If StrPtr(myValue) = 0 Then
bOK = False
MsgBox "You cannot just press Cancel!" & vbLf & vbLf & "A reason is needed for not sending the email.", vbCritical
ElseIf myValue = "" Then
bOK = False
MsgBox "You didn't enter anything, but pressed OK" & vbLf & vbLf & "A reason is needed for not sending the email.", vbExclamation
ElseIf Len(Application.WorksheetFunction.Substitute(myValue, " ", "")) = 0 Then
bOK = False
MsgBox "You only entered spaces!" & vbLf & vbLf & "A reason is needed for not sending the email.", vbExclamation
Else
bOK = True
Exit Do
End If
Loop Until bOK = True
Sheets("Report").Range("A" & lastG).Value = usrFrmEMAIL.cmbSubbie.Value
Sheets("Report").Range("B" & lastG).Value = usrFrmEMAIL.cmbMonth.Text & " " & usrFrmEMAIL.txtbxYear.Text
Sheets("Report").Range("C" & lastG).Value = Now
Sheets("Report").Range("D" & lastG).Value = myValue
If idx <> usrFrmEMAIL.cmbSubbie.ListCount - 1 Then
usrFrmEMAIL.cmbSubbie.ListIndex = idx + 1
Else
usrFrmEMAIL.cmbSubbie.ListIndex = 0
End If
Else
For currentrow = 6 To lastG
Sheets("Report").Range("A" & lastG).Value = usrFrmEMAIL.cmbSubbie.Value
Sheets("Report").Range("B" & lastG).Value = usrFrmEMAIL.cmbMonth.Text & " " & usrFrmEMAIL.txtbxYear.Text
Sheets("Report").Range("C" & lastG).Value = Now
Sheets("Report").Range("D" & lastG).Value = "Sent"
Next
If idx <> usrFrmEMAIL.cmbSubbie.ListCount - 1 Then
usrFrmEMAIL.cmbSubbie.ListIndex = idx + 1
Else
usrFrmEMAIL.cmbSubbie.ListIndex = 0
End If
End If
End Sub
UserForm Code:
Dim OutApp As Object
Dim itmevt As New CMailItemEvents
Private Sub btnCreateEmail_Click()
Dim i, j, lastG, lastD As Long
Dim OutMail As Object
Dim sFName As String, colFiles As New Collection
Dim myDir As String, ChDir As String, attName As New Collection, attName2 As String
Dim dte As String
Dim greet As String, cntName As String, SigString As String, Signature As String
lastG = Sheets("File Locations").Cells(Rows.Count, "B").End(xlUp).Row
SigString = "H:\AppData\Roaming\Microsoft\Signatures\"
If Dir(SigString, vbDirectory) <> vbNullString Then
SigString = SigString & Dir$(SigString & "*.htm")
Else:
SigString = ""
End If
Signature = CreateObject("Scripting.FileSystemObject").GetFile(SigString).OpenAsTextStream(1, -2).readall
If Me.cmbMonth.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Required!"
Me.cmbMonth.SetFocus
Exit Sub
ElseIf Me.txtbxYear.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Required!"
Me.txtbxYear.SetFocus
Exit Sub
ElseIf Me.cmbSubbie.Value = "" Then
Me.lblErrorMsg.Visible = True
Me.lblErrorMsg.Caption = "Required!"
Me.cmbSubbie.SetFocus
Exit Sub
End If
For i = 1 To lastG
lookupVal = Sheets("File Locations").Cells(i, "B") ' value to find
If Dir(lookupVal, vbDirectory) = "" Then
Else
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set itmevt.itm = OutMail
dte = Me.cmbMonth.Value & " " & Me.txtbxYear.Text
myDir = lookupVal 'Set Dir to search
ChDir = (myDir & "\" & Me.cmbSubbie.Value & "\***\") 'Change to that dir
sFName = Dir(ChDir & "*" & dte & "*") 'Set Search spec
While InStr(sFName, dte)
colFiles.Add (ChDir & sFName)
attName.Add (sFName)
sFName = Dir
Wend
End If
Next i
On Error Resume Next
With OutMail
If Me.txtbxSubNAME.Value <> "" Then
cntName = " " & Me.txtbxSubNAME.Value & ","
Else
cntName = ","
End If
If Time < TimeValue("12:00:00") Then
greet = "Good Morning" & cntName
Else
greet = "Good Afternoon" & cntName
End If
If colFiles.Count > 0 Then
For i = 1 To colFiles.Count
.Attachments.Add colFiles(i)
attName2 = attName(i) & "<br>" & attName2
Next i
End If
.To = Me.txtbxSubEMAIL.Value
.CC = ""
.BCC = ""
.Subject = Me.cmbMonth.Value & "'s "
.BodyFormat = olFormatHTML
.HTMLbody = "<HTML><BODY STYLE='font-family:Calibri;font-size:14.5'>" & greet & "<br><br>" & "Thank for your . Please see the attached remittances." & "<br><br>" & "<b>" & attName2 & "</b>" _
& "<br>" & "Please submit if you are required to do so. In this email, could you please copy in:" & "<br><br>" & _
"" & "<br><br>" & _
"<b>" & "Please note: " & "</b>" & "If you need to supply a matching invoice and we do not receive one, your payment's will be held." & "<br><br>" & "Kind regards," & "</BODY></HTML>" & .HTMLbody & Signature
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I am using the below code to archive emails that have been marked completed. It is supposed to check all emails in our shared folder for anything marked complete prior to today's date. It works, but I must run the code multiple times to archive all of the affected quoted. Does anyone have any ideas how to get this to work in one shot?
Public Const CEpath As String = "\\s-estimating\CentralEstimating\"
Option Explicit
Public Const sArchivePath As String = Miscellaneous.CEpath + "Archives\"
Public Sub ArchiveInbox()
Dim dtDateToMove As Date
Dim iMessageCount As Integer
Dim oDestination As MAPIFolder
Dim oFileName As String
Dim oNamespace As NameSpace
Dim oMailItem As MailItem
Dim oProgress As New ProgressDialogue
Dim oSource As MAPIFolder
Dim oStore As Store
Dim oOSPsource As MAPIFolder
'Dim oOSPDestination As MAPIFolder
On Error GoTo HandleError
' Obtain a NameSpace object reference.
Set oNamespace = Application.GetNamespace("MAPI")
Set oStore = oNamespace.Stores.item("Rings")
Set oSource = oStore.GetDefaultFolder(olFolderInbox)
' try to connect to the OSP Folder
On Error Resume Next
'Debug.Print oSource.Folders("OSP Quotes").Items.count
Set oOSPsource = oSource.Folders("OSP Quotes")
On Error GoTo HandleError
' Start Progess form
oProgress.Configure title:="Archive Old RFQs", _
status:="Please stand by while the operation is being processed…", _
Min:=0, _
Max:=CDbl(oSource.Items.count), _
optShowTimeElapsed:=True, _
optShowTimeRemaining:=True
oProgress.Show vbModeless
' Open Archive (or create and open)
dtDateToMove = PreviousBusinessDay(Date)
If Month(PreviousBusinessDay(Date)) < 7 Then
oFileName = "RFQs " & Year(dtDateToMove) & " - Jan-Jun"
Else
oFileName = "RFQs " & Year(dtDateToMove) & " - Jul-Dec"
End If
' Debug.Print dtDateToMove
' Debug.Print oFileName
oNamespace.AddStoreEx Store:=sArchivePath & oFileName & ".pst", _
Type:=olStoreUnicode
Set oDestination = oNamespace.Folders.GetLast
If Not oDestination.Name = oFileName Then oDestination.Name = oFileName
' Sort through all closed emails in Rings and move them to the archive folder
For Each oMailItem In oSource.Items
iMessageCount = iMessageCount + 1
If oProgress.cancelIsPressed Then Exit For
' Debug.Print " " & oMailItem.TaskCompletedDate
If oMailItem.FlagStatus = olFlagComplete Then
If oMailItem.IsConflict Then
Err.Raise Number:=95, _
Description:="Mail Item Conflict Detected"
End If
If oMailItem.TaskCompletedDate <= dtDateToMove Then
oMailItem.Move oDestination
' Debug.Print " Moved"
End If
End If
oProgress.SetValue iMessageCount
Next oMailItem
ExitRoutine:
oProgress.Hide
If oOSPsource Is Nothing Then
Debug.Print "OSP Quotes folder was not found."
Else
If oOSPsource.Items.count > 0 Then
MsgBox "There are items in OSP Quotes.", vbInformation + vbOKOnly
End If
End If
' close the store
oNamespace.RemoveStore oDestination
Set oProgress = Nothing
Set oDestination = Nothing
' Set oOSPDestination = Nothing
Set oOSPsource = Nothing
Set oSource = Nothing
Set oStore = Nothing
Set oNamespace = Nothing
Exit Sub
HandleError:
Debug.Print Err.Number
Debug.Print Err.Description
Select Case Err.Number
Case 95
MsgBox Prompt:=oMailItem.Subject & vbCrLf & vbCrLf & "An email with the above subject line is in conflict." & _
vbCrLf & "You will need to resolve the conflict and run Export to Excel again.", _
Buttons:=vbCritical + vbOKOnly, _
title:="Conflict Resolution Required"
oProgress.Hide
GoTo ExitRoutine
Case Else
If Not ErrorHandling.ErrorLog(Err.Number, Err.Description, "Archive The Inbox") Then
Err.Clear
Resume
End If
End Select
End Sub
Do not use "for each" loop if you are modifying the collection
Change the loop
For Each oMailItem In oSource.Items
to a down "for" loop:
dim oItems = oSource.Items
for I = oItems.Count to 1 step -1
set oMailItem = oItems.Item(I)
I've set up a button in my Excel Sheet that should be able so save a picture of the sheet to my hard drive and then send an Email to a specific address with the picture attached to it, the saving of the picture works fine, but when I try and send the Email using a piece of code I found at http://www.exceltoolset.com/sending-email-with-vba/ it returns the error: -2147220975
Here is the whole sub:
Sub SendKnap_Klik()
Set Sheet = ActiveSheet
Ret = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp"))
Output = Ret & "\SkemaSend.png"
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range(Sheet.PageSetup.PrintArea)
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export Output, "png"
chartobj.Delete
ReturnValue = SendEMail("Subject", "MyMail#gmail.com", Range("J25").Value, "Body", "smtp.gmail.com", "", Output)
If ReturnValue = True Then
MsgBox "Emailen sent to " & Range("J25") & " was successfull!"
Else
MsgBox "Emailen sent to " & Range("J25") & " was not sent" & vbNewLine & "Error: " & Err.Number
End If
End Sub
Function SendEMail(Subject As String, _
FromAddress As String, _
ToAddress As String, _
MailBody As String, _
SMTP_Server As String, _
BodyFileName As String, _
Optional Attachments As Variant = Empty) As Boolean
Dim MailMessage As CDO.Message
Dim N As Long
Dim FNum As Integer
Dim S As String
Dim Body As String
Dim Recips() As String
Dim Recip As String
Dim NRecip As Long
' ensure required parameters are present and valid.
If Len(Trim(Subject)) = 0 Then
SendEMail = False
Exit Function
End If
If Len(Trim(FromAddress)) = 0 Then
SendEMail = False
Exit Function
End If
If Len(Trim(SMTP_Server)) = 0 Then
SendEMail = False
Exit Function
End If
' Clean up the addresses
Recip = Replace(ToAddress, Space(1), vbNullString)
If Right(Recip, 1) = ";" Then
Recip = Left(Recip, Len(Recip) - 1)
End If
Recips = Split(Recip, ";")
For NRecip = LBound(Recips) To UBound(Recips)
On Error Resume Next
' Create a CDO Message object.
Set MailMessage = CreateObject("CDO.Message")
If Err.Number <> 0 Then
SendEMail = False
Exit Function
End If
Err.Clear
On Error GoTo 0
With MailMessage
.Subject = Subject
.From = FromAddress
.To = Recips(NRecip)
If MailBody <> vbNullString Then
.TextBody = MailBody
Else
If BodyFileName <> vbNullString Then
If Dir(BodyFileName, vbNormal) <> vbNullString Then
' import the text of the body from file BodyFileName
FNum = FreeFile
S = vbNullString
Body = vbNullString
Open BodyFileName For Input Access Read As #FNum
Do Until EOF(FNum)
Line Input #FNum, S
Body = Body & vbNewLine & S
Loop
Close #FNum
.TextBody = Body
Else
' BodyFileName not found.
SendEMail = False
Exit Function
End If
End If ' MailBody and BodyFileName are both vbNullString.
End If
If IsArray(Attachments) = True Then
' attach all the files in the array.
For N = LBound(Attachments) To UBound(Attachments)
' ensure the attachment file exists and attach it.
If Attachments(N) <> vbNullString Then
If Dir(Attachments(N), vbNormal) <> vbNullString Then
.AddAttachment Attachments(N)
End If
End If
Next N
Else
' ensure the file exists and if so, attach it to the message.
If Attachments <> vbNullString Then
If Dir(CStr(Attachments), vbNormal) <> vbNullString Then
.AddAttachment Attachments
End If
End If
End If
With .Configuration.Fields
' set up the SMTP configuration
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = SMTP_Server
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "mymail#gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "pass"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Update
End With
On Error Resume Next
Err.Clear
' Send the message
.Send
If Err.Number = 0 Then
SendEMail = True
Else
SendEMail = False
Exit Function
End If
End With
Next NRecip
SendEMail = True
End Function
I also changed settings on my Gmail account to allow unsecured programs to access the account
What am I doing wrong, should something be changed?
//
// MessageId: CDO_E_SMTP_SEND_FAILED
//
// MessageText:
//
// The message could not be sent to the SMTP server. The transport error code was %2. The server response was %1
//
#define CDO_E_SMTP_SEND_FAILED 0x80040211L
CDO takes it's default settings from Windows Mail/Outlook Express/Microsoft Internet Mail and News.
This VBA code list your configuration:
Set emailConfig = emailObj.Configuration
On Error Resume Next
For Each fld in emailConfig.Fields
Text = Text & vbcrlf & fld.name & " = " & fld
If err.number <> 0 then
Text = Text & vbcrlf & fld.name & " = Error - probably trying to read password - not allowed"
err.clear
End If
Next
Msgbox Replace(Text, "http://schemas.microsoft.com", "")
I have this code to send mail to multiple recipients using Lotus Notes. Right now I need to mention the entire file path for the attachments. My requirement is to use FileSearch method - mention any part of the name of the attachment within * * - so that the files get attached.
Sub Send()
Dim oSess As Object
Dim oDB As Object
Dim oDoc As Object
Dim oItem As Object
Dim direct As Object
Dim Var As Variant
Dim flag As Boolean
Dim cell As Range
Dim r As Excel.Range
Dim Name As String
Dim Annex As String
Dim recp As Variant
Dim cc As Variant
Dim Resp As Long
Resp = MsgBox(prompt:="Do you wish to send to the mail?", Buttons:=vbYesNo + vbInformation + vbDefaultButton2, Title:=AppHeader)
If Resp = vbYes Then
Sheets("Sheet2").Activate
For Each cell In Columns("B").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" And _
LCase(Cells(cell.Row, "E").Value) = "yes" Then
Set oSess = CreateObject("Notes.NotesSession")
Set oDB = oSess.GETDATABASE("", "")
Call oDB.OPENMAIL
flag = True
If Not (oDB.IsOpen) Then flag = oDB.Open("", "")
If Not flag Then
MsgBox "Can't open mail file: " & oDB.SERVER & " " & oDB.FILEPATH
GoTo exit_SendAttachment
End If
On Error GoTo err_handler
'Building Message
recp = Cells(cell.Row, "B").Value
cc = Cells(cell.Row, "C").Value
Set oDoc = oDB.CREATEDOCUMENT
Set oItem = oDoc.CREATERICHTEXTITEM("BODY")
oDoc.Form = "Memo"
oDoc.Subject = "HI" & "-" & Cells(cell.Row, "D").Value
oDoc.sendto = Split(recp, ",")
oDoc.copyto = Split(cc, ",")
oDoc.body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please find attached "
oDoc.postdate = Date
oDoc.SaveMessageOnSend = True
Name = Cells(cell.Row, "F").Value
Annex = Cells(cell.Row, "G").Value
Call oItem.EmbedObject(1454, "", Name)
Call oItem.EmbedObject(1454, "", Annex)
oDoc.Send False
End If
Next cell
MsgBox prompt:="Mail Sent", Buttons:=vbOKOnly + vbInformation, Title:=AppHeader
Exit Sub
'Attaching DATABASE
For Each r In Range("Fpath") '// Change to suit
If r.Value <> vbNullString Then
Call Send
End If
Next
oDoc.visable = True
'Sending Message
exit_SendAttachment:
On Error Resume Next
Set oSess = Nothing
Set oDB = Nothing
Set oDoc = Nothing
Set oItem = Nothing
'Done
err_handler:
If Err.Number = 7225 Then
MsgBox "File doesn't exist"
Else
MsgBox Err.Number & " " & Err.Description
End If
On Error GoTo exit_SendAttachment
Else
Sheets("Sheet1").Activate
End If
End Sub
Any thoughts will be highly appreciated.
It's been years since I have worked with Lotus notes. The last question that I answered on Lotus notes was way back in July 26, 2011 So be gentle on me if I miss any syntax. :p
Application.FileSearch method is no longer supported from XL2007+
Reference: Error message when you run a macro to search for a file in an Office 2007 program: "Run-time error 5111"
In case the above link dies, here is the screenshot.
As mentioned in that link You can use the FileSystemObject object to recursively search directories and to find specific files. Here is how we do that
In case the above link dies, here is the code from that link.
'~~> COURTESY: http://support.microsoft.com/kb/185601
Option Explicit
Dim fso As New FileSystemObject
Dim fld As Folder
Private Sub Command1_Click()
Dim nDirs As Long, nFiles As Long, lSize As Currency
Dim sDir As String, sSrchString As String
sDir = InputBox("Type the directory that you want to search for", _
"FileSystemObjects example", "C:\")
sSrchString = InputBox("Type the file name that you want to search for", _
"FileSystemObjects example", "vb.ini")
MousePointer = vbHourglass
Label1.Caption = "Searching " & vbCrLf & UCase(sDir) & "..."
lSize = FindFile(sDir, sSrchString, nDirs, nFiles)
MousePointer = vbDefault
MsgBox Str(nFiles) & " files found in" & Str(nDirs) & _
" directories", vbInformation
MsgBox "Total Size = " & lSize & " bytes"
End Sub
Private Function FindFile(ByVal sFol As String, sFile As String, _
nDirs As Long, nFiles As Long) As Currency
Dim tFld As Folder, tFil As File, FileName As String
On Error GoTo Catch
Set fld = fso.GetFolder(sFol)
FileName = Dir(fso.BuildPath(fld.Path, sFile), vbNormal Or _
vbHidden Or vbSystem Or vbReadOnly)
While Len(FileName) <> 0
FindFile = FindFile + FileLen(fso.BuildPath(fld.Path, _
FileName))
nFiles = nFiles + 1
List1.AddItem fso.BuildPath(fld.Path, FileName) ' Load ListBox
FileName = Dir() ' Get next file
DoEvents
Wend
Label1 = "Searching " & vbCrLf & fld.Path & "..."
nDirs = nDirs + 1
If fld.SubFolders.Count > 0 Then
For Each tFld In fld.SubFolders
DoEvents
FindFile = FindFile + FindFile(tFld.Path, sFile, nDirs, nFiles)
Next
End If
Exit Function
Catch: FileName = ""
Resume Next
End Function
Once you are able to select the files you can use the below code in a loop to add the attachments
stAttachment = "Blah Blah.Txt"
Set obAttachment = oDoc.CreateRichTextItem("stAttachment")
Set EmbedObject = obAttachment.EmbedObject(EMBED_ATTACHMENT, "", stAttachment)