Peter has a worksheet that contains a client list. In column D is the email address for each client. He would like to get a list of unique domains from those addresses (the part after the @ sign), along with a count of how many email addresses use each domain. There are several thousand clients in the worksheet.
The answer to this problem depends, largely, on the version of Excel you are using. If you are using Excel 2024 or later (including Microsoft 365), you could put the following formula into cell F2:
=UNIQUE(TEXTAFTER(D2:D3751, "@"))
The formula assumes that the first row of your data is used for column headings and that your data doesn't extend beyond row 3751. You can then place the following formula in cell G2:
=COUNTIF(D$2:D$3751, "*"&F2)
Copy it down as many cells as necessary and you then have your counts for each domain.
If you are using Microsoft 365, then you could replace the above formulas with a single formula in cell F2:
=GROUPBY(TEXTAFTER(TRIMRANGE(D2:D9999), "@"), TRIMRANGE(D2:D9999), COUNTA, 0, 0, -2)
A shorter variation on this formula is the following:
=LET(d,TEXTAFTER(TRIMRANGE(D2:D9999),"@"),GROUPBY(d,d,COUNTA,,0))
Another approach if you have Excel 2024 or later is to use the following single formula in F2:
=LET(r, D2:D9999, u, TOCOL(UNIQUE(TEXTAFTER(r, "@")), 3), HSTACK(u, COUNTIF(r, "*" & u)))
The purpose of the TOCOL function is to remove blanks and errors from the array gyrations used by the formula. You can get rid of the TOCOL function if you, instead, use the TRIMRANGE function. This formula requires Microsoft 365:
=LET(r, TRIMRANGE(D2:D9999), u, UNIQUE(TEXTAFTER(r, "@")), HSTACK(u, COUNTIF(r, "*" & u)))
There is one nuance of email addresses that someone is bound to bring up—it is technically permissible to have more than one @ sign in an address. The following, for example, is a valid email address:
"john@office"@mydomain.com
This is valid because the local part of the address can contain a quoted string, and just about anything can be included in the string, include an @ sign. This is described in section 3.2.4 of RFC 5322 which, among other things, defines formats used when addressing email messages. If you enjoy geek speak, you can find more information about this RFC here:
https://www.rfc-editor.org/rfc/rfc5322
The quoting can only be done in the local portion of email addresses, so the logical solution to deal with such situations is to modify the TEXTAFTER function so it looks for the first @ sign starting from the end of the address. Here, for example, is the last formula with the adjustment to TEXTAFTER:
=LET(r, TRIMRANGE(D2:D9999), u, UNIQUE(TEXTAFTER(r, "@",-1)), HSTACK(u, COUNTIF(r, "*" & u)))
Everything so far has focused on using Excel 2024 or later versions. If you are using an older version of the program, then your best bet is going to be to use a macro. The following steps through the addresses in column D and creates two collections, one for domain names and one for counts of each domain name. The output is then added to columns H and I.
Sub ListDomains()
Dim ws As Worksheet
Dim lastRow As Long
Dim r As Long
Dim emailAddr As String
Dim domain As String
Dim atPos As Long
Dim Domains As New Collection
Dim Counts As New Collection
Dim i As Long
Dim Found As Boolean
Dim outRow As Long
Dim newCount As Long
Set ws = ActiveSheet
lastRow = ws.Cells(ws.Rows.Count, "D").End(xlUp).Row
For r = 2 To lastRow
emailAddr = Trim(ws.Cells(r, "D").Value)
If Len(emailAddr) > 0 Then
atPos = InStrRev(emailAddr, "@")
If atPos > 0 And atPos < Len(emailAddr) Then
domain = LCase(Mid(emailAddr, atPos + 1))
Found = False
For i = 1 To Domains.Count
If Domains(i) = domain Then
newCount = Counts(i) + 1
Counts.Remove i
If i > Counts.Count Then
Counts.Add newCount
Else
Counts.Add newCount, , i
End If
Found = True
Exit For
End If
Next i
If Not Found Then
Domains.Add domain
Counts.Add 1
End If
End If
End If
Next r
' The following lines erase whatever is in columns H and I.
' Modify column references if output should go to a different
' set of columns.
ws.Range("H:I").ClearContents
ws.Range("H1").Value = "Domain"
ws.Range("I1").Value = "Count"
outRow = 2
For i = 1 To Domains.Count
ws.Cells(outRow, "H").Value = Domains(i)
ws.Cells(outRow, "I").Value = Counts(i)
outRow = outRow + 1
Next i
End Sub
When you run the macro, anything in columns H and I is deleted. If you want the output in a different set of columns, you should modify the column references indicted near the end of the macro.
Note:
ExcelTips is your source for cost-effective Microsoft Excel training. This tip (953) applies to Microsoft Excel 2007, 2010, 2013, 2016, 2019, 2021, 2024, and Excel in Microsoft 365.
Dive Deep into Macros! Make Excel do things you thought were impossible, discover techniques you won't find anywhere else, and create powerful automated reports. Bill Jelen and Tracy Syrstad help you instantly visualize information to make it actionable. You’ll find step-by-step instructions, real-world case studies, and 50 workbooks packed with examples and solutions. Check out Microsoft Excel 2019 VBA and Macros today!
Want to know how to move pieces of information contained in one cell into individual cells? This option exists if using ...
Discover MoreWhen working with large amounts of data, it can be tricky to figure out how to extract just the information you need. ...
Discover MoreExcel provides a variety of tools that allow you to perform operations on your data based upon the characteristics of ...
Discover MoreFREE SERVICE: Get tips like this every week in ExcelTips, a free productivity newsletter. Enter your address and click "Subscribe."
2026-06-07 09:54:37
J. Woolley
As you can see, there was a problem with the Submit Comment form after "updating" Tips.net.
My most recent comment below was prepared using Notepad, then copy/pasted into the form.
Each End-of-Line (LF) character was ignored. This text was entered manually as a test.
The following text was copy/pasted from Notepad as a test:
Line 1
Line 2
Line 3
2026-06-06 11:20:05
J. Woolley
The Tip's macro can be simplified, and its expression for lastRow ignores possible hidden rows. Here's an alternate version:
Sub ListDomains2()
    Const DATA_COL = "D", OUTPUT_COLS = "H:I"
    Dim Domains As New Collection, Counts As New Collection
    Dim emailAddr As String, domain As String, item As Variant
    Dim lastRow As Long, atPos As Long, newCount As Long, n As Long
    'include possible hidden rows
    lastRow = Columns(DATA_COL).Find(What:="*", _
        After:=Columns(DATA_COL).Cells(1), LookIn:=xlFormulas, _
        LookAt:=xlPart, MatchCase:=False, SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious).Row
    For n = 1 To lastRow
        emailAddr = Trim(Cells(n, DATA_COL).Value)
        atPos = InStrRev(emailAddr, "@")
        If atPos > 0 Then
            domain = LCase(Mid(emailAddr, atPos + 1))
            On Error Resume Next
                Domains.Add domain, domain
                If Err = 0 Then 'new domain
                    newCount = 1
                Else 'must increment indirectly
                    newCount = Counts(domain) + 1
                    Counts.Remove domain
                End If
                Counts.Add newCount, domain
            On Error GoTo 0
        End If
    Next n
    'the following replaces everything in OUTPUT_COLS
    With Range(OUTPUT_COLS)
        .ClearContents
        Application.ScreenUpdating = False
        On Error GoTo EH
        .Cells(1, 1).Value = "Domain"
        .Cells(1, 2).Value = "Count"
        n = 1
        For Each item In Domains
            n = n + 1
            .Cells(n, 1).Value = item
            .Cells(n, 2).Value = Counts(item)
        Next item
EH:
        Application.ScreenUpdating = True
        .Show
    End With
End Sub
ListDomains and ListDomains2 illustrate limitations of the Collection object:
1. You can't directly modify its value (item).
2. You can't directly determine if a key exists.
3. You can't determine any of its keys.
The Dictionary object doesn't have these limitations, but it isn't included in the VBA library; you must use VB Editor's Tools menu to include a Reference to the Microsoft Scripting Runtime library. Here's a version that uses Dictionary:
Sub ListDomains3()
    Const DATA_COL = "D", OUTPUT_COLS = "H:I"
    'check Tools > References > Microsoft Scripting Runtime
    Dim Domains As New Dictionary
    Dim emailAddr As String, domain As String, key As Variant
    Dim lastRow As Long, atPos As Long, n As Long
    'include possible hidden rows
    lastRow = Columns(DATA_COL).Find(What:="*", _
        After:=Columns(DATA_COL).Cells(1), LookIn:=xlFormulas, _
        LookAt:=xlPart, MatchCase:=False, SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious).Row
    For n = 1 To lastRow
        emailAddr = Trim(Cells(n, DATA_COL).Value)
        atPos = InStrRev(emailAddr, "@")
        If atPos > 0 Then
            domain = LCase(Mid(emailAddr, atPos + 1))
            If Domains.Exists(domain) Then
                Domains(domain) = Domains(domain) + 1
            Else
                Domains.Add domain, 1
            End If
        End If
    Next n
    'the following replaces everything in OUTPUT_COLS
    With Range(OUTPUT_COLS)
        .ClearContents
        Application.ScreenUpdating = False
        On Error GoTo EH
        .Cells(1, 1).Value = "Domain"
        .Cells(1, 2).Value = "Count"
        n = 1
        For Each key In Domains.Keys
            n = n + 1
            .Cells(n, 1).Value = key
            .Cells(n, 2).Value = Domains(key)
        Next key
EH:
        Application.ScreenUpdating = True
        .Show
    End With
End Sub
2026-05-27 11:33:04
J. Woolley
The Tip begins with this Excel 2024 formula in cell F2n=UNIQUE(TEXTAFTER(D2:D3751, "@"))nbut this Excel 2021 formula gives a similar resultn=UNIQUE(MID(D2:D3751, FIND("@", D2:D3751) + 1, 999))nThe Tip says, "You can then place the following formula in cell G2:n=COUNTIF(D$2:D$3751, "*"&F2)nCopy it down as many cells as necessary and you then have your counts for each domain." If the formula in G2 references the array at F2 like thisn=COUNTIF(D$2:D$3751, "*"&F2#)nthen it is not necessary to "Copy it down...."nIf your version is earlier than Excel 2021, you can put this formula in cell F2 and "Copy it down..."n=MID(D2, FIND("@", D2) + 1, 999)nThen select column F, press Ctrl+C, choose Paste Special > Values, and use Data > Data Tools > Remove Duplicates to return the list of unique domains. Finally put this formula in cell G2 and "Copy it down..."n=COUNTIF(D$2:D$3751, "*"&F2)nto return the count for each unique domain.nNotice FIND("@", ...) returns a #VALUE! error if @ does not appear in the referenced cell; in this case, the previous formula suggested for cell F2 can be modified as follows:n=IFERROR(MID(D2, FIND("@", D2) + 1, 999), "")nRe. the Excel 2024 formulas, since TEXTAFTER(..., "@") returns a #N/A error if @ does not appear in the referenced cell, each expression that includes TEXTAFTER(..., "@") should be wrapped with TOCOL(..., 3), which removes blanks and errors. In this case, the range does not need to be qualified like D2:D9999; you can use D:D instead. The Tip says, "You can get rid of the TOCOL function if you, instead, use the TRIMRANGE function." This is correct only if @ appears in every cell within the TRIMRANGE result.
2026-05-23 07:23:24
fred potter
When I read this problem last week, I thought '=MID(D2, FIND("@",D2, LEN(D2) - LEN(SUBSTITUTE(D2, "@", "")) + 1) + 1, 255) would do the trick if you were using excel 2019 or earlier. nI ended up using an old excel trick where you replace each @ with 50 spaces, take the rightmost 50 characters and Trim the spaces , leaving the domain.nSo I used '=TRIM(RIGHT(SUBSTITUTE(D2,"@",REPT(" ",50)),50)) nfilled it down col E then selected columns D & E inserted a pivot table, draged Domain to Rows, Draged Domain to Values (count) and there I had a count of unique domains.
Got a version of Excel that uses the ribbon interface (Excel 2007 or later)? This site is for you! If you use an earlier version of Excel, visit our ExcelTips site focusing on the menu interface.
FREE SERVICE: Get tips like this every week in ExcelTips, a free productivity newsletter. Enter your address and click "Subscribe."
Copyright © 2026 Sharon Parq Associates, Inc.
Comments