• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Help on VBA Scripting

Raja Kamarthi

New Member
Hello Friends,

I am working on a employee data base file which has the details of their passport, visa, licence etc and each input has a EXPIRY DATE.


Now am looking for a script which would automatically trigger a mail when there is an expiry date which is less than or equal to 30 days (1 month).


For e.g an employee passport will expire on 23rd May 2013 which means number of days for the expiry of passport is 30 days.Now outlook should automatically send a mail to a preassigned e mail id stating that so & so employee passport or visa is getting expired, kind of an alert.Please refer to the attachment for more details


https://www.dropbox.com/s/xeuj3nwia065i89/Employee%20Database.xlsx


Any help in getting this done is highly appreciated


RK
 
Hi, Raja Kamarthi!

This question has been asked and answered a lot of times. If you haven't performed yet the search herein, try going to the topmost right zone of this page (Custom Search), type the keywords used in Tags field when creating the topic or other proper words and press Search button. You'd retrieve many links from this website, like the following one(s) -if any posted below-, maybe you find useful information and even the solution. If not please advise so as people who read it could get back to you as soon as possible.

Regards!
 
SirJB7,


Much thanks for your response. I did the custom check and found results which have been answered as per the query, something like customized solutions for each different query.


Considering my expertise on macros, I am new and find hard to understand and tweak the code to suit my requirement


I would request you to provide a solution which will help me constructing the template


RK
 
Thinking outside the box, and trying to get a nice template start, check out Chandoo's Birthday reminder here:

http://chandoo.org/wp/2010/10/26/birthday-reminder-template/


The tool uses formulas instead of macros. Granted, this is designed for birthdays, but the general idea is still the same "When date x is here (or close to here) send an email."


That said, if searching here or other places online, you could expand your search to "Excel automatic email birthday" to get a large results of various topics/workbooks that have been created.
 
Hello Luke,


Thanks for the advice.


I understood the formula used in birthday template but I am stuck how to create the auto trigger of the mail and if am not wrong this can be done only through a macro


Any input on this?


RK
 
Hi, Raja Kamarthi!


Give a look at this file:

https://dl.dropboxusercontent.com/u/60558749/Help%20on%20VBA%20Scripting%20-%20Employee%20Database%20%28for%20Raja%20Kamarthi%20at%20chandoo.org%29.xlsm


I had to add an EMail column as your worksheet didn't have that information (BTW, nice data that on hidden worksheet) and therefore it'd be a little hard to send mails.


I added a dynamic named range DataTable so as to make easier the employee additions and deletions, so take care of adjusting it when changing the number of columns. I'd use title rows to get the actual value, but neither row 1 nor 2 had all cells with data, so COUNTIF couldn't be used.


You have two buttons, cyan for viewing mails and red for sending mails.

This is the code:

-----

Option Explicit

Sub PreExpirationMails(pbSend As Boolean)
' constants
Const ksWS = "Sheet1"
Const ksData = "DataTable"
Const ksHeaderID = "Expiry date"
Const kiHeaderNumber = -1
Const kiHeaderName = -1
Const kiLimit = 30
Const ksSeparator = " - "
Const ksSubject = "Documents expiration"
Const ksText1 = "Dear sir/madame:"
Const ksText2 = "These documents have expired or expire within " & kiLimit & " days."
Const ksText3 = "Signed by XXX."
' declarations
Dim rng As Range
Dim olApp As Object, olMail As Object
Dim I As Integer, J As Integer, A As String, sMail As String, sText As String
' start
Set rng = Worksheets(ksWS).Range(ksData)
Set olApp = CreateObject("Outlook.Application")
' process
With rng
For I = 1 To .Rows.Count
A = ""
For J = 1 To .Columns.Count
If .Cells(0, J).Value = ksHeaderID Then
If .Cells(I, J).Value - Int(Now()) < kiLimit Then
If Len(A) <> 0 Then A = A & vbCrLf
A = A & .Cells(-1, J + kiHeaderName).Value & ksSeparator & _
.Cells(I, J + kiHeaderNumber).Value & ksSeparator & _
Format(.Cells(I, J).Value, "dd/mmm/yyyy")
End If
End If
Next J
If A <> "" Then
Set olMail = olApp.CreateItem(0)
sMail = .Cells(I, 5).Value
sText = ksText1 & vbCrLf & _
.Cells(I, 1).Value & vbCrLf & _
.Cells(I, 2).Value & vbCrLf & _
.Cells(I, 3).Value & vbCrLf & _
.Cells(I, 4).Value & vbCrLf & vbCrLf & _
ksText2 & vbCrLf & _
A & vbCrLf & vbCrLf & _
ksText3
'=====
'This block of code written by Ron de Bruin, copied from
'http://msdn.microsoft.com/en-us/library/ff458119(office.11).aspx#odc_office_UseExcelObjectModeltoSendMail_Introduction
On Error Resume Next
' Change the body and subject in the macro before you run it.
With olMail
.To = sMail
.CC = ""
.BCC = ""
.Subject = ksSubject
.Body = sText
'You're not sending an attachment, so I commented this out
'.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:test.txt")
' In place of the following statement, you can use ".Display" to
' display the mail.
If pbSend Then .Send Else .Display
DoEvents
End With
On Error GoTo 0
'=======
Set olMail = Nothing
End If
Next I
End With
' end
Set olApp = Nothing
Beep
End Sub

-----


Just advise if any issue.


Regards!


PS: Needing people in Dubai? I'm available...

PS2: Maybe I could play a little with one of your new police cars, not the Ferrari FF but the Lamborghini Aventador...
 
@Luke M

Hi!

BTW, there were 14 groups of 3 columns of document types with number, expiration date and a months to expire, so no templates could be used.

Regards!
 
@SirJB7


Nice coding my friend, and thanks for the explanation.


PS. If SirJB7 will let me, I'll be his partner in a new Lamborghini. Or my own...I'm not picky.
 
Hi, Raja Kamarthi!

Check the provided solution and tell us if you achieved your goal. And prepare 2 Aventador for 2 Ninjas... for 15K € (or Pounds) / month we are there in 24 hs, aren't we, Luke M?

Regards!


@Luke M

Hi!

BTW thanks for the compliment.

Regards!
 
SirJB7,


Amazing stuff, this is beyond excellence


I checked the sample file and it does exactly, in fact much more than what I wished for


Many many Thanks for your time and effort


And 15K is nothing for you, come to my place, you will get better than that


RK
 
Hi, Raja Kamarthi!

Glad you solved it. Thanks for your feedback and for your kind words too. And welcome back whenever needed or wanted.

Regards!

PS: Where do I sign? When will I be receiving the air tickets?
 
SirJB7,


Need bit more assistance from you


In the template, there are few things which are mandatory for every employee like passport, visa but not everything like few might have driving licence and few don't.


Where ever an employee is not holding the relevant card, i will mention as "N/A" in the report and the same should not reflect either in "Expiration View" or "Expiration Send"


Can you please get this in the script?


Thanks

RK
 
Hi, Raja Kamarthi!


Let me change the things a little bit:


a) Mandatory documents should have an "(*)" -unquoted- at the end of description in row 1, e.g., "Passport (*)", "Driving License".


b) Non existent document numbers should have columns "Number" and "Expiry date" in blank


c) Formula for "No.of Months for Expiry" changes from:

=(G3-HOY())/30 -----> in english: =(G3-TODAY())/30

to:

=SI(ESBLANCO(F3);SI(ESERROR(HALLAR("(*)";F$1));"";"N/A");(G3-HOY())/30) -----> in english: =IF(ISBLANK(F3),IF(ISERROR(SEARCH("(*)",F$1)),"","N/A"),(G3-TODAY())/30)

so yo have to enter anything like "N/A" and hence avoiding errors (no, I don't trust in users, neither on MIS people)


d) I added two empty columns before those weird columns "BOSIET" & "HUET" so as to standardize the column distribution, 3 for each, it doesn't follow Codd's 12 postulates but's the better I could figure out. You can hide them later if you wish.


e) That let me apply a unique formula for conditional formatting to highlight "N/A" entries (red):

=Y($A1<>"";COLUMNA()>=6;INDICE($A:$BA;FILA();COLUMNA()+2-RESIDUO(COLUMNA()-6;3))="N/A") -----> in english: =AND($A1<>"",COLUMN()>=6,INDEX($A:$BA,ROW(),COLUMN()+2-MOD(COLUMN()-6,3))="N/A")

another for mandatory within expiration limits (orange):

=Y($A1<>"";FILA()>1;COLUMNA()>=6;DERECHA(INDICE($A:$BA;1;COLUMNA()-RESIDUO(COLUMNA()-6;3));3)="(*)";INDICE($A:$BA;FILA();COLUMNA()+2-RESIDUO(COLUMNA()-6;3))<=1) -----> in english: =AND($A1<>"",ROW()>1,COLUMN()>=6,RIGHT(INDEX($A:$BA,1,COLUMN()-MOD(COLUMN()-6,3)),3)="(*)",INDEX($A:$BA,ROW(),COLUMN()+2-MOD(COLUMN()-6,3))<=1)

and another for non mandatory within period (yellow):

=Y($A1<>"";FILA()>1;COLUMNA()>=6;DERECHA(INDICE($A:$BA;1;COLUMNA()-RESIDUO(COLUMNA()-6;3));3)<>"(*)";INDICE($A:$BA;FILA();COLUMNA()+2-RESIDUO(COLUMNA()-6;3))<=1) -----> in english: =AND($A1<>"",ROW()>1,COLUMN()>=6,RIGHT(INDEX($A:$BA,1,COLUMN()-MOD(COLUMN()-6,3)),3)<>"(*)",INDEX($A:$BA,ROW(),COLUMN()+2-MOD(COLUMN()-6,3))<=1)

applied to columns $F:$BA

f) I excluded non mandatory blank (but kept those expired) documents from being included in the mail and profiting the 3 and half normal form of your database I simplified macro code as follows:

-----

Option Explicit

Sub PreExpirationMails(pbSend As Boolean)
' constants
Const ksWS = "Sheet1"
Const ksData = "DataTable"
Const ksHeaderID = "Expiry date"
Const kiHeaderNumber = -1
Const kiHeaderName = -1
Const kiLimit = 30
Const ksMandatoryInexistent = "N/A"
Const ksSeparator = " - "
Const ksSubject = "Documents expiration"
Const ksText1 = "Dear sir/madame:"
Const ksText2 = "These documents have expired or expire within " & kiLimit & " days."
Const ksText3 = "Signed by XXX."
' declarations
Dim rng As Range
Dim olApp As Object, olMail As Object
Dim I As Integer, J As Integer, bOk As Boolean
Dim A As String, sMail As String, sText As String
' start
Set rng = Worksheets(ksWS).Range(ksData)
Set olApp = CreateObject("Outlook.Application")
' process
With rng
For I = 1 To .Rows.Count
A = ""
For J = 1 To .Columns.Count
If .Cells(0, J).Value = ksHeaderID Then
bOk = False>If .Cells(I, J + 1).Value = ksMandatoryInexistent Then
bOk = True
Else
If .Cells(I, J).Value <> "" Then
If .Cells(I, J).Value - Int(Now()) < kiLimit Then bOk = True
End If
End If
If bOk Then
If Len(A) <> 0 Then A = A & vbCrLf
A = A & .Cells(-1, J + kiHeaderName).Value & ksSeparator & _
.Cells(I, J + kiHeaderNumber).Value & ksSeparator & _
Format(.Cells(I, J).Value, "dd/mmm/yyyy")
End If
End If
Next J
If A <> "" Then
Set olMail = olApp.CreateItem(0)
sMail = .Cells(I, 5).Value
sText = ksText1 & vbCrLf & _
.Cells(I, 1).Value & vbCrLf & _
.Cells(I, 2).Value & vbCrLf & _
.Cells(I, 3).Value & vbCrLf & _
.Cells(I, 4).Value & vbCrLf & vbCrLf & _
ksText2 & vbCrLf & _
A & vbCrLf & vbCrLf & _
ksText3
'=====
'This block of code written by Ron de Bruin, copied from
'http://msdn.microsoft.com/en-us/library/ff458119(office.11).aspx#odc_office_UseExcelObjectModeltoSendMail_Introduction
On Error Resume Next
' Change the body and subject in the macro before you run it.
With olMail
.To = sMail
.CC = ""
.BCC = ""
.Subject = ksSubject
.Body = sText
'You're not sending an attachment, so I commented this out
'.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:test.txt")
' In place of the following statement, you can use ".Display" to
' display the mail.
If pbSend Then .Send Else .Display
DoEvents
End With
On Error GoTo 0
'=======
Set olMail = Nothing
End If
Next I
End With
' end
Set olApp = Nothing
Beep
End Sub

-----


Download again the file from this link (same as previous):

https://dl.dropboxusercontent.com/u/60558749/Help%20on%20VBA%20Scripting%20-%20Employee%20Database%20%28for%20Raja%20Kamarthi%20at%20chandoo.org%29.xlsm


BTW, new people in original list of employees? :)


Regards!
 
SirJB7,


Mission accomplished and this happened only because of you.


Thank you so much for being so helpful and supportive


And your Lamborghini Aventador would be ready upon your arrival on my land :)


SirJB7, am working on few more templates and need your assistance in coming days as well


Hope you and the entire "NINJA TEAM" would be there for me


Regards,

RK
 
Hi, Raja Kamarthi!

Glad you solved it. Thanks for your feedback and for your kind words too. And welcome back whenever needed or wanted.

Regards!

PS: I can't speak for all the Ninja team, but please separate and prepare (service, wash, no sand) my Aventador.

PS2: BTW I haven't received the air tickets yet.

PS3: Did you check the employee list?
 
Back
Top