VBA/Excel - Group by value in table and send e-mail - excel

I have a large list where I have different companies and organisations. My current VBA codes iterates through each table row, and send out an e-mail for each line.
However, what I need to achieve is that there might be companies which have the same parent organisation - in this case, I don't want to send out an e-mail for each company, but would rather send out one e-mail to the organisation, including all the associated companies.
I have tried to illustrate it in below table.
So for record #1, I would just send out an e-mail as always. However for [2-3], I would like to send out one e-mail, which includes company name 2 and 3.
Same goes for record [4-6], which should also send out one e-mail, but include company name #4, #5 and #6.
Example:
Hi Organisation B
Please check below companies in your organisation:
Company 2
Company 3
My current code:
Below is my current code, which iterates through all table rows and send out mails:
'Count table rows
Set tbl = oWorksheet.ListObjects("DataTable")
TableRows = tbl.ListRows.Count
TableRows = TableRows + 1 'Skips the header
iRow = 2 'Skip the header
Do While iRow <= TableRows
Set oNotesMail = oMailDB.CreateDocument
oNotesMail.Form = "Memo"
oNotesMail.SendTo = oWorksheet.Cells(iRow, 5).Value
oNotesMail.Subject = "Company check"
oNotesMail.Body = "Hi " & oWorksheet.Cells(iRow, 2) & "Please check"
oNotesMail.SaveMessageOnSend = True
oNotesMail.PostedDate = Now()
oNotesMail.Send 0, oWorksheet.Cells(iRow, 5).Value
Set oNotesMail = Nothing
Loop
So above code send out an email (in Lotus Notes) for each line.
How can I achieve my example above?
Please note
The table will always be sorted by 'Organisation' - hopefully this will help when the code is iterating through the rows.

Related

Vba to break up text within a cell? Text to columns not working

How can I break up text within a cell with vba? I exported emails to an excel file using a vba and the information exported in one of the cells is formatted as seen below:
Name * xxxxxx
Country of residence * xxxxxx Email * xxxxx#gmail.com mailto:xxxxxxx#gmail.com
Mobile phone number * 0xxxxxx
Do you want to become a member of Assoc? Yes Check all that apply *
Members
Education
Ethical Conduct
Events
Regulation
I tried the solution below and it’s not working.
From article: If you need to build a formula to remove these line breaks all you need to know is that this ‘character’ is character 10 in Excel. You can create this character in an Excel cell with the formula =CHAR(10).
So to remove it we can use the SUBSTITUTE formula and replace CHAR(10) with nothing ( shown as “”).
https://www.auditexcel.co.za/blog/removing-line-breaks-from-cells-the-alt-enters/#:~:text=Building%20a%20formula%20to%20remove%20the%20ALT%20ENTER%20line%20breaks,-If%20you%20need&text=You%20can%20create%20this%20character,cell%20with%20no%20line%20breaks.
My understanding is that you dump an email into 1 excel cell and are hoping to separate a series of strings [Country, Email, Etc.] that are separated by a line break?
I suggest using the split function to separate the strings into an array, then loop through that array to put the information in the desired cells. Mind you this will only work if the items are in the same order everytime, if the order can change then you will need to add a data verification step. i.e. if inStr("#",[Range]) then its an email...
Split([string to split], [delimiter])
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/split-function
Dim strEmail as String 'Email dump
Dim arrEmail() as String 'Array for looping
Dim ItemsInArray as Integer 'Used to hold array count
Dim i as Integer 'Counter
strEmail = ActiveSheet.Cells("[Column,Row]") 'Cell your email dumps to
arrEmail = Split(strEmail, char(10)) 'Populate array
ItemsInArray = UBound(arrEmail) 'Get upper bound of array (total item count)
For i = 0 to ItemsInArray
ActiveSheet.Cells("[Column,Row]") = arrEmail(i)
Column + 1
Next i
when i = 0 its a country code
when i = 1 its an email
when i = 2 its a phone #
etc....

Multiple Listboxes showing ranges from active sheets - Excel VBA

This is my First Ever Post:
I am creating a user form that will function similarly to a school management system.
One of the elements that are part of it is a Pupil Profile, which shows all information relating to the specific child.
Currently, each pupil has its own sheet. When searching for the child, the sheet matching the name of the child will be set as the active sheet.
This sheet contains sets of columns that store data about Parents meetings, rewards and sanctions, concerns and meetings with key staff members.
Example Pupil Sheet
I have a multipage setup with 4 tabs, each tab has a list box that I want to show the data from the set of columns on the active sheet.
I don't know a great deal about VBA, so I followed some tutorials and managed to make one of the sets of columns work perfectly. But to be honest, I don't understand how the code works, and I can't make it work for the other rows:
Private Sub cmdSearch_Click()
Dim X As Long
Dim Y As Long
Dim i As Long, G As Integer
Dim C As Integer, M As Integer
For G = 2 To Sheets.Count
If Sheets(G).Name = txtSearch Then
For i = 2 To Sheets(G).Range("A2000").End(xlUp).Row
Me.ListBox1.AddItem
For C = 0 To 6
Me.ListBox1.List(ListBox1.ListCount - 1, C) = Sheets(G).Cells(i, C + 1)
Next C
Next i
End If
Next G
Private Sub AddParentMeeting_Click()
TgtSheet = txtSearch.Value
If TgtSheet = "" Then
Exit Sub
End If
Worksheets(TgtSheet).Activate
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Cells(LastRow + 1, 1).Value = PM1.Value
ActiveSheet.Cells(LastRow + 1, 2).Value = PM2.Value
ActiveSheet.Cells(LastRow + 1, 3).Value = PM3.Value
ActiveSheet.Cells(LastRow + 1, 4).Value = PM4.Value
ActiveSheet.Cells(LastRow + 1, 5).Value = PM5.Value
ActiveSheet.Cells(LastRow + 1, 6).Value = PM6.Value
End Sub
Basically, my two key issues are:
How do I populate list boxes from a range of data on the active sheet so that it changes with each new profile search? E.g
ListBox1 shows A2:F2000 on active sheet
ListBox2 shows H2:K2000 on active sheet
ListBox3 shows M2:Q2000 on active sheet
ListBox4 shows S2:X2000 on active sheet
How do I add information to just those columns without it adding the information to the next fully clear row? e.g)
I don't want this to happen:
Picture
I want it to look like this:
Picture
Sorry for the lengthy post, and any questions or help in the right direction would be really appreciated
You may not like this reply and for that I apologize but your approach ignores all database basics. It will give you more work than need be and fail before the project is finished. The first mistake is to have a separate sheet for each pupil.
You need one sheet with a row for each pupil, columns like name, first name, middle name, birthday (not age because you can calculate the age from the birthday any time you need it), address, parent's phone etc. The first column is the most important. In db parlance it's call the "Key". It contains a unique identifier for everything in the row, a pupil number, if you like or an ID code. The point of the "key" is to be unique. By this ID you can retrieve the entire row and all information in it.
Then you need 4 more similar data bases: Parent Meetings, Staff Meetings, Concerns, Rewards/Consequences. Each of these has the columns you already designed plus one more which is called the "Foreign Key". In each row of these tables you enter the "Key" from the Pupils sheet, linking each entry - Meeting, Concern or Reward - to one particular pupil. Perhaps you have a validation drop-down with the pupils' names to avoid typos in the Keys. But that is already step 2.
You would be able to work with this setup immediately. Simply filter any of the lists on a pupil's ID to get a list of all meetings, concerns or rewards for any one pupil. With the help of the "Key" you would be able to easily and quickly create a sheet with the pupil's details at the top, meetings, concerns, rewards listed - much like your existing pupil sheets but with changing data as you select a pupil from a validation drop-down. All done with VLOOKUP and worksheet functions. No user form yet. That would be the de-luxe version but you would have 80% of the functionality while you work on it.

Excel VBA - Change tab colours based on user

I'm setting up a spreadsheet for multiple users on my team for testing purposes.
The idea is that a spreadsheet gets passed around and any feedback whether it be a pass or fail is noted on the spreadsheet.
I've currently added validation on certain cells which are red until something is filled in by, let's call them the primary tester.
I've added further validation via VBA to check that all red cells have something entered, otherwise the tab colour will turn red.
My problem is that the spreadsheet then gets accessed by the secondary tester then I want the tab to stay red until they have passed or failed the work (again based on cell validation).
So I think I've found a solution whereby the
In a module I've got:
Public Function UserName()
UserName = Environ$("UserName")
End Function
Range("M5").Value = Environ("username")
In another worksheet I've got:
Set myRange3 = ActiveSheet.Range("P21")
If UserName <> Range("M5").Value Then
If UserName = Range("E15").Value Then
If Application.WorksheetFunction.CountA(myRange3) = 0 Then
ActiveWorkbook.ActiveSheet.Tab.Color = vbRed
Else
ActiveWorkbook.ActiveSheet.Tab.Color = xlColorIndexNone
End If
End If
End If
'M5 = Primary tester
'E15 = Secondary tester
I expect the primary tester to have filled in all their requirements, making the tab turn from Red to neutral.
I would then expect the secondary tester to open up the spreadsheet and notice that a tab has been flagged as Red, meaning they need to add their validation of pass/fail for the tab to go neutral.

Using if statements in the body of email Excel to Outlook

I am lost on how to tackle this part of the project I have undertaken for my company. I have created thus far, code that will filter, search for count of times an item is mentioned, and store it into a variable.
I have 20 of these items and I need to send an email out with the amount of times an item was mentioned.
I would rather just send an email that shows only the items that were mentioned and leave the rest out.
Doing this in Excel is the hard part as I am unsure how to code it in the body. Any help on sending me in the right direction would be greatly appreciated.
EX.
Item 1,
Item 1,
Item 2,
Item 3.
VarForItem1 = 2
VarForItem2 = 1
VarForItem3 = 1
VarForItem4 = 0
VarForItem5 = 0
etc.
I want the email to only show the Vars that have greater than 0.
I figured it out, with a combination of if statements underneath the calculation and a strmessage string. I just added the line with the amount if it was above 0.
If item1 > 0 then
strmessage = strmessage & "Item 1 - " & strmessage & vbnewline
End if

AppleScript for sending emails from a list in Excel

I don’t know AppleScript at all so thanks in advance for any help offered on this question.
I’m on my Macbook Pro laptop with the latest version of OSX installed. I have an Excel spreadsheet (I could use numbers if that makes it easier) with two columns.
FirstName Email
------------ -----------------
Ken blah#blah.com
Mike blahblah#blahblah.com
This is my customer list and I want to send them an email. Unfortunately I don’t have this list in an autoresponder so I have to send the emails one by one.
I know that I could whip up a PHP script to send the emails, however there are issues with email deliverability when doing it this way.
I want to write an AppleScript that processes my spreadsheet one row at a time and sends a message.
The message would be something like this:
Subject: How’s it going?
Hi Ken
It’s been a while since I sold you that defective widget from China.
If you need more defective elctronics I’m here for you. Just give me
a call at xxx-xxx-xxxx.
Sincerely
Ken
The AppleScript would read the name and email address from one row of the spreadsheet and send this email, filling in name and email address, using the standard apple mail program.
After sending the message I want the script to wait 60 seconds. Then send another email.
This needs to happen until a blank row is encountered.
My first question… Is this possible? If possible how do I do it?
Also is there a better way to do what I’m trying to do?
Thanks
There's probably a better way to do this, but couldn't you just copy the addresses as TSV or CSV?
set addresses to "Ken;blah#blah.com
Mike;blahblah#blahblah.com"
set text item delimiters to ";"
repeat with l in paragraphs of addresses
tell application "Mail"
tell (make new outgoing message)
set subject to "subject"
set content to "Hi " & text item 1 of l & linefeed & linefeed & "..."
make new to recipient at end of to recipients with properties {name:text item 1 of l, address:text item 2 of l}
send
delay (random number) * 100
end tell
end tell
end repeat
Try:
set {firstName, eAddress} to getData()
repeat with i from 1 to count firstName
tell application "Mail"
activate
set mymail to make new outgoing message at the beginning of outgoing messages with properties {subject:"How’s it going?"}
tell mymail
make new to recipient at beginning of to recipients with properties {address:item i of eAddress}
set content to "Hi " & item i of firstName & "
It’s been a while since I sold you that defective widget from China.
If you need more defective elctronics I’m here for you. Just give me
a call at xxx-xxx-xxxx.
Sincerely
Ken"
end tell
--show message window (otherwise it's hidden)
set visible of mymail to true
--bring Mail to front
activate
send mymail
end tell
end repeat
on getData()
set colA to {}
set colB to {}
tell application "Microsoft Excel"
activate
tell active sheet
set lastRow to first row index of (get end (last cell of column 1) direction toward the top)
repeat with i from 3 to lastRow
set end of colA to (value of range ("A" & i))
set end of colB to (value of range ("B" & i))
end repeat
end tell
end tell
return {colA, colB}
end getData

Resources