Excel formula to distinguish multiple alphanumeric formats needed!

sst0189

New Member
Joined
Aug 11, 2016
Messages
2
Hello!

I have a list of manually entered postcodes in excel which I am trying to work with. What I am trying to achieve is a formula that recognises when these postcodes are entered with an incorrect alphanumeric format.

So all post codes I am working with should begin with an alphanumeric string of either "ANNAA", "ANNNAA", "AANNAA", "AANNNAA", "ANANAA" or "AANANAA".

Where "A" indicates an alphabetic character and "N" indicates a numeric
character (Note, I have already removed any spaces in the string).

So a formula which returns 'true' if the cell contains a string with one of the above alphanumeric formats and 'false' for any other format.

for example;
A cell with 'DN551PT' would return true
A cell with 'CR26XH' would return true
A cell with 'DN55647PL4' would return false

I do not know VBA. Any help would be very gratefully received! Also this is my first post so please bare with me and/or let me know if I have described the situation poorly and left any vital info out.

Many thanks in advance,
Sam
 

Excel Facts

Copy PDF to Excel
Select data in PDF. Paste to Microsoft Word. Copy from Word and paste to Excel.
PQ7T9ZZ7AANANAACORRECT POSTCODESAALPHABETIC
R55WW5ANNAA567NNUMERIC
R777W5ANNNAANNAAAANNAAAANANAA
BC5V6FK7AANANAAANANAAAANNNAA
B55V6FK7ANNANAAANNNAA
A65
B66
C67
D68
this macro turns your postcode into an ANANANANNA TYPE stringE69
F70
For j = 1 To 5G71
For k = 1 To Cells(j, 2)H72
If Asc(Mid(Cells(j, 1), k, 1)) < 65 Then GoTo 100I73
If Asc(Mid(Cells(j, 1), k, 1)) > 90 Then GoTo 100J74
temp = "A": GoTo 200K75
100 temp = "N"L76
200 temp1 = temp1 & tempM77
Next kN78
Cells(j, 3) = temp1O79
temp1 = ""P80
Next jQ81
End SubR82
S83
T84
U85
see column CV86
W87
X88
Y89
Z90
my difficulty is
if you have a 5 digit postcode ANNAA which is correct
if the next character is an A making it ANNAAA
HOW DO WE TEST IF IT IS CORRECT
TESTING FIRST 5 AGAINST ANNAA
OR
FIRST 6 AGAINST AANNAA OR ANANAA OR ANNNAA ETC ETC SEEMS A BIT CRUDE

<colgroup><col span="2"><col><col span="7"><col><col span="5"></colgroup><tbody>
</tbody>
 
Upvote 0
Welcome to the forum.

Here's a formula solution:

AB
1A12BCTRUE
2A123BCTRUE
3AB12CDTRUE
4AB123CDTRUE
5A1B2CDTRUE
6AB1C2DETRUE
71AB2C3FALSE
822ABC12FALSE
9DN551PTTRUE
10CR26XHTRUE
11DN55647PL4FALSE

<colgroup><col style="width: 25pxpx"><col><col></colgroup><thead>
</thead><tbody>
</tbody>
Sheet2

Worksheet Formulas
CellFormula
B1=IF(ISNUMBER(MATCH(SUM(IF(ISNUMBER(MID(A1,{1,2,3,4,5,6,7},1)+0),{1,2,4,8,16,32,64})),{6,10,12,14,20,28},0)),TRUE)

<thead>
</thead><tbody>
</tbody>

<tbody>
</tbody>



Like oldbrewere, I also had questions about what to do about positions 6-7. I basically noticed that all the numeric values are in positions 1-5, so assumed that 6-7 would be characters.

Let me know if this helps, or if there's more to the story.
 
Upvote 0
I used Regular Expressions. While I could post the code, here is a link to a file with my code.

Hi Kenneth

Just a remark:

I think it's better to post code than to post a link.

Some things to consider
- many members are not allowed to download external files because of company policy
- many members will not download external files for security reasons

This board is a very rich solutions database.
Solutions will be read years after they were posted. My experience with external links is that one year from now (or less) they will be dead, making this post useless, not helping those who need it.

... and I think it's quicker if you are searching a solution for a problem, to just look at solutions directly and decide whether they are interesting for you or not than to download for each one an external file and then open it.
 
Last edited:
Upvote 0
Sometimes yes, sometimes no pgc01. It depends on the original poster (op) to my mind. The best solution is both as more experienced users do prefer code as it is less risky while less experienced should like a file as code and libraries will be set properly. Not allowing file attachments is the main reason that I don't visit here as much as some other forums.

I had already done the work so I just posted the link. The only reason I did not do both as I usually do is because Eric's solution worked fine and the only thing special about the regular expression is the pattern string. In any case, I do see your point so here it is so that it might help someone sometime which is why I even do a followup post after a solution was posted.

I am not a regular expression guru. The pattern string was fairly easy though. The comments show some more involved pattern strings for various international zip code formats.

In the Main module:
Code:
'RegExp cheat sheet, http://regexlib.com/CheatSheet.aspx

Const sRE As String = "([A-Z]\d{2}[A-Z]{2}|[A-Z]\d{3}[A-Z]{2}|[A-Z]{2}\d{2}[A-Z]{2}|[A-Z]{2}\d{3}[A-Z]{2}|[A-Z]{2}\d[A-Z]\d[A-Z]{2})$"

'As a UDF:
'=rgxValidate(A2,"([A-Z]\d{2}[A-Z]{2}|[A-Z]\d{3}[A-Z]{2}|[A-Z]{2}\d{2}[A-Z]{2}|[A-Z]{2}\d{3}[A-Z]{2}|[A-Z]{2}\d[A-Z]\d[A-Z]{2})$")
Sub Main()
  Dim s As String
  
  s = "^([A-Z]\d{2}[A-Z]{2}"
  s = s & "|" & "[A-Z]\d{3}[A-Z]{2}"
  s = s & "|" & "[A-Z]{2}\d{2}[A-Z]{2}"
  s = s & "|" & "[A-Z]{2}\d{3}[A-Z]{2}"
  s = s & "|" & "[A-Z]{2}\d[A-Z]\d[A-Z]{2}" & ")$"
  'or
  's="^([A-Z]\d{2}[A-Z]{2}|[A-Z]\d{3}[A-Z]{2}|[A-Z]{2}\d{2}[A-Z]{2}|[A-Z]\d[A-Z]\d[A-Z]{2}|[A-Z]{2}\d[A-Z]\d[A-Z]{2})$"
  'or
  's=sre
  
  's = "^[A-Z]{2}[0-9]{3}[A-Z]{2}$", '3rd case
  's = "^[A-Z]{2}\d{3}[A-Z]{2}$", '2nd method for 3rd case
  
  Debug.Print s
  Debug.Print rgxValidate(Range("A2").Value2, s)
  Debug.Print sRE
  Debug.Print rgxValidate(Range("A2").Value2, sRE)
End Sub

In another module though the above could be added:
Code:
Option Explicit
'John Nurick, http://www.mvps.org/access/modules/mdl0063.htm
'Some useful regular expressions:
                'Notes:
                'Each of these regular expressions is wrapped in a (?: )
                'grouping pattern. This means that they can be OR'd by
                'concatenating them with the pipe character "|". Thus
                ' rgxZIP_US & "|" & rgxZIP_CA
                'will match either US or Canadian postal codes.
                '
                'Official formatting of postcodes and the like may change
                'over time. Some of these expressions may need adjustment
                ' to bring them up to date.
                'UK Postcode
                Public Const rgxZIP_UK = "(?:(?:A[BL]|B[ABDHLNRST]?|" _
                & "C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|" _
                & "H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|" _
                & "N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|" _
                & "T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)" _
                & "\d(?:\d|[A-Z])? \d[A-Z]{2})"
                'A simpler expression that does not check for valid postcode areas:
                ' "(?:[A-Z]{1,2}\d(?:\d|[A-Z])? \d[A-Z]{2})"
                
                'Zip or Zip+4
                Public Const rgxZIP_US = "(?:\d{5}(?:-\d{4})?)"
                'Canadian postal codes
                Public Const rgxZip_CA = "(?:[A-Z]\d[A-Z] \d[A-Z]\d)"
                
                'Most European postal codes:
                Public Const rgxZIP_EU = "(?:NL-\d{4}(?: [A-Z][A-Z])|" _
                & "(?:IS|FO)\d{3}|" _
                & "(?:A|B|CH|CY|DK|EE|H|L|LT|LV|N)-\d{4}|" _
                & "(?:BA|DE?|E|FR?|FIN?|HR|I|SI|YU)-\d{5}|" _
                & "(?:CZ|GR|S|SK)-\d{3} \d{2}|PL-\d\d-\d{3}|" _
                & "PT-\d{4}(?:-\d{3})?" _
                & ")"
                'A simpler expression that doesn't check the postcode
                'format against the country code
                ' "(?:NL[- ]\d{4} [A-Z][A-Z]|" _
                ' & "(?:[A-Z]{1,2}[- ])?\d{2,3}(?:\d\d?| \d\d|\d-\d{3}))"
                'US States
                Public Const rgxSTATES_US = "(:?A[KLRZ]|C[AOT]|D[CE]|FL|" _
                & "GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|" _
                & "O[HKR]|P[AR]|RI|S[CD]|T[NX]|" _
                & "UT|V[AIT]|W[AIVY])"
                'Australian States
                Public Const rgxSTATES_AU = "(?:ACT|NSW|NT|QLD|SA|TAS|VIC|WA)"
                'Canadian Provinces
                Public Const rgxPROVINCES_CA = "(?:AB|BC|MB|N[BLTSU]|ON|PE|QC|SK|YT)"
                'Canonical phone number
                Public Const rgxPHONE_INTL = "(?:\+\d{1,4} ?(?:\(\d{0,5}\))?(?:\d+[-. ])*\d{2,})"
                

Function rgxValidate( _
                target As Variant, _
                Pattern As String, _
                Optional CaseSensitive As Boolean = False, _
                Optional MatchWholeString As Boolean = True, _
                Optional FailOnError As Boolean = True) _
                As Boolean
                'Returns True if Target matches the regular
                'expression Pattern.
                'By John Nurick, October 2002 - January 2003
                '©2003 John Nurick
                'NOTES:
                'Target will normally be a String. If Target is Null,
                'rgxValidate returns False. Otherwise if Target cannot be
                'converted to a string with CStr(), rgxValidate fails
                'with Error 13, Type Mismatch.
                'Pattern should be a VBScript regular expression. See VBScript
                'help file and other documentation for information.
                'CaseSensitive does the expected.

                'MatchWholeString: if False, rgxValidate returns True if any
                'substring of Target matches Pattern. If True or omitted,
                'the function only returns True if the whole of Target
                'matches Pattern.
                ' E.g. Target "12345" only matches Pattern "234" if
                ' MatchWholeString is False.
                'FailOnError: if this is True or omitted, rgxValidate passes
                'any run time error to the calling procedure. If it is False,
                'the function returns True on a successful match and False if
                'the match fails for any reason including a run time error.
                'rgxValidate is suitable for use in data entry forms and the
                'like. It can also be used in queries and in looping through
                'recordsets, but because it creates a RegExp object and compiles
                'the regular expression (Pattern) every time it is called,
                'it is rather inefficient for repetitive operations.
                'Constants for messages:
                Const rgxPROC_NAME = "rgxValidate"
                Const rgxERRMSG_CREATE = "Could not create VBScript.RegExp object: "
                Const rgxERRMSG_UNEXPECTED = "Unexpected error: "
                'VBScript.Regexp error messages:
                Const rgxERRMSG_5017 = "Syntax error in regular expression"
                Const rgxERRMSG_5019 = "Expected ']' in regular expression"
                Const rgxERRMSG_5020 = "Expected ')' in regular expression"
                Dim oRE As Object
                On Error GoTo ERRHANDLER
                rgxValidate = False 'Set default return value
                If IsNull(target) Then Exit Function
                Set oRE = CreateObject("VBScript.RegExp")
                'If we're here, the object has been created
                oRE.Global = False
                oRE.IgnoreCase = Not CaseSensitive
                oRE.MultiLine = False
                If MatchWholeString Then
                'Add anchors at ends of Pattern
                '(doesn't matter if Pattern already has them)
                  oRE.Pattern = "^" & Pattern & "$"
                Else
                  oRE.Pattern = Pattern
                End If
                'Do it!
                rgxValidate = oRE.test(CStr(target))
                'If we're here, the match executed OK. Normal termination
                Set oRE = Nothing
                Exit Function
                
ERRHANDLER:
                If FailOnError Then
                  With Err
                  Select Case .Number
                    Case 5017: .Description = rgxERRMSG_5017
                    Case 5019: .Description = rgxERRMSG_5019
                    Case 5020: .Description = rgxERRMSG_5020
                  Case Else
                    If oRE Is Nothing Then
                    .Description = rgxERRMSG_CREATE & Err.Description
                    Else
                    .Description = rgxERRMSG_UNEXPECTED & Err.Description
                    End If
                  End Select

                  Set oRE = Nothing
                  Err.Raise Err.Number, , rgxPROC_NAME & "(): " & .Description
                  End With
                  Else 'Fail silently
                  Err.Clear
                  Set oRE = Nothing
                End If
                End Function
 
Last edited:
Upvote 0
Thanks all for your help.

I have used Eric's formula solution and it works perfectly, thanks Eric.

As a follow on, could anyone recommend a good resource to begin learning VBA online?

thanks again!
 
Upvote 0
I have used Eric's formula solution and it works perfectly, thanks Eric.
Eric's formula incorrectly returns TRUE for values shaped like these (there may be others, I just found these right away)...

ANANA

AANANA

I think you will have trouble finding a formula that will handle all those patterns properly; however, I am pretty sure the following UDF (user defined function) will work correctly...
Code:
[table="width: 500"]
[tr]
	[td]Function IsPattern(S As String) As Boolean
  Select Case Len(S)
    Case 5: IsPattern = S Like "[A-Z]##[A-Z][A-Z]"
    Case 6: IsPattern = S Like "[A-Z]??#[A-Z][A-Z]" And Not S Like "??[A-Z][A-Z]???"
    Case 7: IsPattern = S Like "[A-Z][A-Z]#[0-9A-Z]#[A-Z][A-Z]"
  End Select
End Function[/td]
[/tr]
[/table]

HOW TO INSTALL UDFs
------------------------------------
If you are new to UDFs, they are easy to install and use. To install it, simply press ALT+F11 to go into the VB editor and, once there, click Insert/Module on its menu bar, then copy/paste the above code into the code window that just opened up. That's it.... you are done. You can now use IsPattern just like it was a built-in Excel function. For example,

=IsPattern(A1)

If you are using XL2007 or above, make sure you save your file as an "Excel Macro-Enabled Workbook (*.xlsm) and answer the "do you want to enable macros" question as "yes" or "OK" (depending on the button label for your version of Excel) the next time you open your workbook.
 
Last edited:
Upvote 0
Eric's formula incorrectly returns TRUE for values shaped like these (there may be others, I just found these right away)...

ANANA

AANANA

I think you will have trouble finding a formula that will handle all those patterns properly; however, I am pretty sure the following UDF (user defined function) will work correctly...
Code:
[table="width: 500"]
[tr]
	[td]Function IsPattern(S As String) As Boolean
  Select Case Len(S)
    Case 5: IsPattern = S Like "[A-Z]##[A-Z][A-Z]"
    [B][COLOR="#FF0000"]Case 6: IsPattern = S Like "[A-Z]??#[A-Z][A-Z]" And Not S Like "??[A-Z][A-Z]???"[/COLOR][/B]
    Case 7: IsPattern = S Like "[A-Z][A-Z]#[0-9A-Z]#[A-Z][A-Z]"
  End Select
End Function[/td]
[/tr]
[/table]

HOW TO INSTALL UDFs
------------------------------------
If you are new to UDFs, they are easy to install and use. To install it, simply press ALT+F11 to go into the VB editor and, once there, click Insert/Module on its menu bar, then copy/paste the above code into the code window that just opened up. That's it.... you are done. You can now use IsPattern just like it was a built-in Excel function. For example,

=IsPattern(A1)

If you are using XL2007 or above, make sure you save your file as an "Excel Macro-Enabled Workbook (*.xlsm) and answer the "do you want to enable macros" question as "yes" or "OK" (depending on the button label for your version of Excel) the next time you open your workbook.
One line of code needs an adjustment as it permits non-alphanumerics to be accepted. Replace the red highlighted line of code with this one...
Code:
[table="width: 500"]
[tr]
	[td]Case 6: IsPattern = S Like "[A-Z][0-9A-Z][0-9A-Z]#[A-Z][A-Z]" And Not S Like "??[A-Z][A-Z]???"[/td]
[/tr]
[/table]
 
Last edited:
Upvote 0

Forum statistics

Threads
1,215,829
Messages
6,127,129
Members
449,361
Latest member
VBquery757

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top