Click here to Skip to main content
15,884,237 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a list of reports in Column A that go to a list of emails in Column B. Column B has anywhere between 1 email and 10 separated by a comma ",". I need a Vlookup or VBA code to help me sort the list in a new sheet as Column A being each individual email (already done) and then the report(s) each email receives in Column B. The problem I run into is that there is roughly 250 reports, some with the same name and roughly 125 emails in Column B but mainly of the emails repeating in different rows. I need it as Column A: Emails Column C: Reports so that I can start to see what email is getting what report so I can start trimming reports/merging similar, etc. Column B is taken by another VBA function verifying that emails still exist in the domain contact group. How can I achieve this list of emails getting reports?
The current sheets names are Original Data: "ReportsQuery" and where I am putting data: "Emails".

Example of excel sheet:

Report Title | Emails
Report One | Emailone@email.com,Emailtwo@email.com
Report Two | Emailone@email.com,Emailthree@email.com,emailfour@email.com
Report Three | Emailfive@email.com,Emailone@email.com,emailsix@email.com
Report Four  | Emailseven@email.com


What I have tried:

I tried just Vlookup formulas but it would report one report and not multiple. Also tried
=INDEX(ReportValues!$A$2:$Q$1000,QUOTIENT(ROW(A2)-2,16)+1,MOD(ROW(A2)-2,16)+1)
which also gives me one report.

Tried:
VB
=IFERROR(INDEX(return_range, SMALL(IF(lookup_value = lookup_range, ROW(return_range) - m, ""), COLUMN() - n)), "")

WITH VALUES:
VB
=IFERROR(INDEX(ReportQuery!$A$2:$A$1000, SMALL(IF($A2 = ReportQuery!$B$2:$B$1000, ROW(ReportQuery!$A$2:$A$1000) - 1, ""), COLUMN() - 3)), "")

but it returns blank due to the Lookup email value having more than just that one email.
Posted
Updated 14-Mar-19 1:12am
v6
Comments
Maciej Los 13-Mar-19 14:59pm    
Please, share sample data...
Trogers96 13-Mar-19 15:35pm    
Report Title | Emails
Report One | Emailone@email.com,Emailtwo@email.com
Report Two | Emailone@email.com,Emailthree@email.com,emailfour@email.com
Report Three | Emailfive@email.com,Emailone@email.com,emailsix@email.com
Report Four | Emailseven@email.com

Will this work?
Patrice T 13-Mar-19 15:52pm    
Use Improve question to update your question.
So that everyone can pay attention to this information.

Quote:
Excel VBA vlookup with multiple results

VLookup with "multiple results" does not exist. I think you need to create appropriate VBA program.
As far as I understand what you want, you have a list:
Report Title | Emails
Report One | Emailone@email.com,Emailtwo@email.com
Report Two | Emailone@email.com,Emailthree@email.com,emailfour@email.com
Report Three | Emailfive@email.com,Emailone@email.com,emailsix@email.com
Report Four | Emailseven@email.com

and want to, in 1 way or another, transform it to:
Report Title | Email
Report One | Emailone@email.com
Report One | Emailtwo@email.com
Report Two | Emailone@email.com
Report Two | Emailthree@email.com
Report Two | emailfour@email.com
Report Three | Emailfive@email.com
Report Three | Emailone@email.com
Report Three | emailsix@email.com
Report Four | Emailseven@email.com

and then, send reports from this expended list.

As far as I know XL, there is no standard functionality to do this transform, You need to make a program like:
VB
' get number of rows
' loop on each row
  ' split emails with RegEx
  ' loop on email list
    ' write the new couple report/email
 
Share this answer
 
Comments
Maciej Los 14-Mar-19 3:59am    
5ed!
Patrice T 14-Mar-19 7:28am    
Thank you
Try this:

VB
Option Explicit

Sub SplitEmails()
    Dim srcWsh As Worksheet, dstWsh As Worksheet
    Dim i As Long, j As Long, k As Long
    Dim emails() As String

On Error GoTo Err_SplitEmails

    Set srcWsh = ThisWorkbook.Worksheets(1) 'replace 1 with corresponding sheet name, for ex.: ThisWorkbook.Worksheets("ReportQuery")
    Set dstWsh = ThisWorkbook.Worksheets(2) 'replace 2 with corresponding sheet name, for ex.: ThisWorkbook.Worksheets("FinalData")

    With dstWsh
        .Range("A1") = "Report"
        .Range("B1") = "Email"
        .Range("A1:B1").Font.Bold = True
        .Range("A1:B1").Interior.Color = vbGreen
        .Range("A1:B1").Borders.LineStyle = xlContinuous
    End With

    i = 2
    k = 2
       
    Do While srcWsh.Range("A" & i) <> ""
        emails = Split(CStr(srcWsh.Range("B" & i)), ",")
        For j = LBound(emails()) To UBound(emails())
            With dstWsh
                .Range("A" & k + j) = srcWsh.Range("A" & i)
                .Range("B" & k + j) = Trim(emails(j))
                .Range("A" & k + j & ":B" & k + j).Borders.LineStyle = xlContinuous
            End With
        Next
        k = k + j
        i = i + 1
    Loop


Exit_SplitEmails:
    On Error Resume Next
    Set srcWsh = Nothing
    Set dstWsh = Nothing
    
    Exit Sub

Err_SplitEmails:
    MsgBox Err.Description, vbExclamation, Err.Number
    Resume Exit_SplitEmails

End Sub


How to use it?
1. Open a file containing the data
2. Press CTR+F11 to switch to and open Visual Basic for Applications Code pane
3. Go to Insert menu and click Module
4. Copy above macro and paste it into newly added module
5. Move cursor to SplitEmails and click wherever inside a body of that procedure then run it (F5).

That's all. Good luck!
 
Share this answer
 
v2
Comments
Trogers96 15-Mar-19 13:21pm    
I am marking this as the solution. One small problem I am having is that it is making empty rows at the end of the emails for reports because in my data I have a , after the last email as well. Anyway to get around this for efficiency purposes? Thank you!
Maciej Los 15-Mar-19 14:31pm    
Great!
Yes, there is a way to avoid empty rows.
...
k = k + j
If Trim(dstWsh.Range("B" & k-1))="" Then k = k - 1 'here!
i = i + 1
...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900