Alpha Numeric Validation in Microsoft Excel - excel

1- I'd like to use a validation rule for an input cell where the entry must be 7 or 8 alphanumeric characters long
2- at the start of the string Alphas used must be 1 or 2 characters and uppercase.
3- at the end of the string Numerics will always be 6 characters long.
4- The following type of entries are required to be validated
FD456789
X256325
Z899666
DQ985421
FD000052
5-I have created a validation formula. it works fine except it cannot validate 2nd character as alphabate in the string. i used AP656569 and A5656569 for testing. it should allow only AP656569, but on the contrary it is allowing both strings.
Formula: =AND(OR(LEN(A3)=7,LEN(A3)=8),ISNUMBER(VALUE(RIGHT(A3,6))),IF(LEN(A3)=7,NOT(ISNUMBER(VALUE(LEFT(A3,1)))),ISTEXT(MID(A3,2,1))))

You may try:
=AND(AND(LEN(A1)>6,LEN(A1)<9,ISNUMBER(RIGHT(A1,6)*1),CODE(A1)>64,CODE(A1)<91),IF(LEN(A1)=8,AND(CODE(MID(A1,2,1))>64,CODE(MID(A1,2,1))<91),1))
=AND( - Let's check two things:
AND( - Check if multiple conditions are TRUE:
LEN(A1)>6 - Check if string is over 6 char.
LEN(A1)<9 - Check if string in under 9 chars.
ISNUMBER(RIGHT(A1,6)*1 - Check if 6 rightmost characters make up a numeric value.
CODE(A1)>64,CODE(A1)<91 - Check if leftmost characters is in class [A-Z].
IF( - Check the following:
LEN(A1)=8 - Check if the lengths is actually 8.
AND( - If TRUE then check the following:
CODE(MID(A1,2,1))>64,CODE(MID(A1,2,1))<91 - Check if 2nd char is in class [A-Z].
1 - If the length is not false, it will still be 7, therefor we return a 1 (equal to TRUE), to not mess with our parent AND().
You can apply this to your custom validation rule as a formula if you want to avoid false data, or as mentioned in the comments to conditional formatting if you want to be able to show false data after it being entered.
Alternatively, if you have Excel 2019 or higher, and you like code-golf you could use:
=AND(ISNUMBER(RIGHT(A1,6)*1),CODE(A1)>64,CODE(A1)<91,SWITCH(LEN(A1),7,1,8,AND(CODE(MID(A1,2,1))>64,CODE(MID(A1,2,1))<91),0))

Your conditions do not exclude a string like A1234567 (1 capital letter, 7 digits). According to your conditions and assuming your string is in cell A1, this formula should work:
=AND(OR(LEN(A1)=7,LEN(A1)=8),OR(IFERROR(LEFT(A1,1)*1,0)=0,AND(IFERROR(LEFT(A1,1)*1,0)=0,IFERROR(LEFT(A1,2)*1,0)=0)),UNICODE(A1)=UNICODE(UPPER(A1)),UNICODE(MID(A1,2,1))=UNICODE(UPPER(MID(A1,2,1))),IFERROR(MID(RIGHT(A1,6),1,1)*1,0),IFERROR(MID(RIGHT(A1,6),2,1)*1,0),IFERROR(MID(RIGHT(A1,6),3,1)*1,0),IFERROR(MID(RIGHT(A1,6),4,1)*1,0),IFERROR(MID(RIGHT(A1,6),5,1)*1,0),IFERROR(MID(RIGHT(A1,6),6,1)*1,0))
It's basically an AND function that contains:
a condition to check for the lenght of the string: OR(LEN(A1)=7,LEN(A1)=8)
a condition to check if first 2 characters of the string are letters (only the first or both): OR(IFERROR(LEFT(A1,1)*1,0)=0,AND(IFERROR(LEFT(A1,1)*1,0)=0,IFERROR(LEFT(A1,2)*1,0)=0))
a condition to check if the first character is capital: UNICODE(A1)=UNICODE(UPPER(A1))
a condition to check if the second character is capital: UNICODE(MID(A1,2,1))=UNICODE(UPPER(MID(A1,2,1)))
a condition for each last 6 characters to check if they are numeric (example refers to the first one): IFERROR(MID(RIGHT(A1,6),1,1)*1,0)
EDIT: Improvements
The formula can be improved like this:
=AND(OR(LEN(A1)=7,LEN(A1)=8),OR(IFERROR(LEFT(A1,1)*1,0)=0,AND(IFERROR(LEFT(A1,1)*1,0)=0,IFERROR(LEFT(A1,2)*1,0)=0)),EXACT(LEFT(A1,2),UPPER(LEFT(A1,2))),ISNUMBER(RIGHT(A1,6)*1))
It's still an AND function. This the changes:
it contains a single condition to check if the first 2 characters are capital (previously there were 1 for each character that used the UNICODE function): EXACT(LEFT(A1,2),UPPER(LEFT(A1,2))) [CREDIT: JvdV]
it contains a single condition for the last 6 characters to check if they are numeric (previously there were 1 for each character that used the IFERROR function): ISNUMBER(RIGHT(A1,6)*1)
EDIT: correction
In order to exclude special character, i've edited the formula:
=AND(OR(LEN(A1)=7,LEN(A1)=8),OR(AND(UNICODE(A1)>64,UNICODE(A1)<91,ISNUMBER(MID(A1,2,1)*1)),AND(UNICODE(A1)>64,UNICODE(A1)<91,UNICODE(MID(A1,2,1))>64,UNICODE(MID(A1,2,1))<91)),EXACT(LEFT(A1,2),UPPER(LEFT(A1,2))),ISNUMBER(RIGHT(A1,6)*1))

Related

Excel customer data validation for chars and numbers

I am trying to validate a combination of char and numbers that looks like this XXXX0000000.
I have tried this formula; =OR((LEFT(B2,3)="XXXX",LEN(B2)=11),AND(LEFT(B2,3)="XXXX",LEN(B2)=11).
The error message I receive is as follows:
excel error message
Title: "Excel customer data validation for chars and numbers"
...I have the feeling it's not just about validating XXXX0000000 but it's about the pattern of characters and numbers. Therefor try:
Formula in B1:
=IF(ISERROR(FILTERXML("<t><s>"&A1&"</s></t>","//s[translate(substring(.,1,4), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','')=''][string-length()=11][substring(.,5)*0=0]")),"Invalid","Valid")
Where:
//s[translate(substring(.,1,4), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','')=''] - Check if when we translate the first 4 characters to nothing this also equals empty string;
[string-length()=11] - Check that node is 11 characters long;
[substring(.,5)*0=0] - Check that substring from 5th position onwards equals zero when multiplied by zero.
Note: FILTERXML() is case sensitive and is currently checking for uppercase alpha-chars.
EDIT:
To use this in data-validation; Ditch the IF() since you don't need that in validation and nest the remainder in NOT():
=NOT(ISERROR(FILTERXML("<t><s>"&A1&"</s></t>","//s[translate(substring(.,1,4), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','')=''][string-length()=11][substring(.,5)*0=0]")))
When you select your range, make sure the validation rule has the topleft cell in the reference.
You have two formulas but no joining of them
IE you have an OR formula
=OR((LEFT(B2,3)="XXXX",LEN(B2)=11)
Which will return a true/false answer
You also have an AND formula
=AND(LEFT(B2,3)="XXXX",LEN(B2)=11)
Which will return a true/false answer
when you work through it you are being given a return of:
=True(or false), true (or false)
That isn't a formula and is causing the error output
I think you want to use an IF statement to join them and get an output as desired:
E.g.
=If(OR(LEFT(B2,3)="XXXX",LEN(B2)=11),AND(LEFT(B2,3)="XXXX",LEN(B2)=11), DO SOEMTHING IF TRUE, DO SOMETHING IF FALSE)
I suggest this:
OR(LEFT(B2,3)="XXX",LEN(B2)=11,AND(LEFT(B2,3)="XXX",LEN(B2)=11))
It corrects the number of characters error and sorts the logic.

Data validation on number of numerical characters in a string

Trying to add formula to data validation that checks whether a string is either 6 numerical digits, or 6 numerical digits with hyphens or spaces. E.g.
123456
Or
12-34-56
Or
12 34 56
The string could also contain leading zeros.
The user should not be able to input a string that differs from the above formats, so
123-456
Or
1234567
....for example
Would prefer not to use VBA, but am struggling to make this into a data validation formula.
Any ideas would be appreciated
Try this:
=AND(SUBSTITUTE(SUBSTITUTE(A1," ",""),"-","")*1<=999999,SUBSTITUTE(SUBSTITUTE(A1," ",""),"-","")*1>=1,LEN(SUBSTITUTE(SUBSTITUTE(A1," ",""),"-",""))=6)
This formula removes hyphens and spaces, then checks if the number is 6 digits and that it falls between 1 and 999999. If there are any letters/symbols, the *1 part will cause an error.
Edit:
#JvdV id right. I misread your requirements. Here is my second attempt:
=AND(OR(ISNUMBER(MATCH("??-??-??",A1,0)),ISNUMBER(MATCH("?? ?? ??",A1,0)),AND(IFERROR(A1*1,0)<=999999,IFERROR(A1*1,0)>=1)),ISNUMBER(SUBSTITUTE(SUBSTITUTE(A1,"-","")," ","")*1))
Here is what it allows and doesn't allow:

PowerQuery M Conditional Column 'count' argument is out of range

I have a sheet with dates as MMDDYYY with no leading 0's if month number is single digit. For example, 1012018 or 12312018. Each record has a date, and each date is either 7 or 8 characters in length.
Here is the code I am using to convert the numbers to dates:
if Text.Length([ContractDate]) = 7
then
Text.Range([ContractDate],0,1)&"/"&Text.Range([ContractDate],1,2)&"/"&Text.Range([ContractDate],4,4)
else
Text.Range([ContractDate],0,2)&"/"&Text.Range([ContractDate],2,2)&"/"&Text.Range([ContractDate],4,4)
The code works fine for the "else" condition but I am getting error "Expression.Error: The 'count' argument is out of range. Details: 4" for all records where Text.Length() = 7. I verified this by adding a second column to get Length of ContractDate.
What am I missing?
EDIT: Problem Solved - I'm an idiot. I was getting an error because in the "then" condition, I am extracting a substring of (4,4) from a value that only has Len=7. I can't get 4 characters out of a 7 character string when starting at index of 4.
I know you found the issue with your code, but worth pointing out some things that might be good to know.
Text.Range with no character count will pull in all characters past the start point (so Text.Range([ContractDate], 4) would work for both).
Text.Middle operates like Text.Range but will not cause an error if you select a range that expands past the size of the string. This can be useful if for some reason you were dealing with variable size strings where you need a specific number of characters up to a limit past a certain position.
You could also use Text.PadStart([ContractDate], 8, "0") to pad the 7 length strings with a 0 at the start, and avoid the need for a conditional check all together.

Remove all text and characters except some

I have here some text strings
"16cg-301 -request","16cg-3368 - for review","16cg-3684 - for process"
what i would like to do is to remove all the text and characters except the number and the letters "cg" and - which is within the reference code.
If the string you want to extract is always before the first space in the full string then you can use SEARCH and LEFT to extract your reference code:
=LEFT(A1,SEARCH(" ",A1)-1)
This formula would take 16cg-3368 from 16cg-3368 - for review.
I suggest using something like suggested here
How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops
With a replace regex similar to this
[^\dcg]*
or a match regex like this
^([0-9cg- ]+).*
else you could also work with a strange formule similar to this
=CONCATENATE(IF(NOT(ISERROR(SEARCH(MID(A2;1;1);"01234567890cg-")>0));MID(A2;1;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;2;1);"01234567890cg-")>0));MID(A2;2;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;3;1);"01234567890cg-")>0));MID(A2;3;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;4;1);"01234567890cg-")>0));MID(A2;4;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;5;1);"01234567890cg-")>0));MID(A2;5;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;6;1);"01234567890cg-")>0));MID(A2;6;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;7;1);"01234567890cg-")>0));MID(A2;7;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;8;1);"01234567890cg-")>0));MID(A2;8;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;9;1);"01234567890cg-")>0));MID(A2;9;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;10;1);"01234567890cg-")>0));MID(A2;10;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;11;1);"01234567890cg-")>0));MID(A2;11;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;12;1);"01234567890cg-")>0));MID(A2;12;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;13;1);"01234567890cg-")>0));MID(A2;13;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;14;1);"01234567890cg-")>0));MID(A2;14;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;15;1);"01234567890cg-")>0));MID(A2;15;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;16;1);"01234567890cg-")>0));MID(A2;16;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;17;1);"01234567890cg-")>0));MID(A2;17;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;18;1);"01234567890cg-")>0));MID(A2;18;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;19;1);"01234567890cg-")>0));MID(A2;19;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;20;1);"01234567890cg-")>0));MID(A2;20;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;21;1);"01234567890cg-")>0));MID(A2;21;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;22;1);"01234567890cg-")>0));MID(A2;22;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;23;1);"01234567890cg-")>0));MID(A2;23;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;24;1);"01234567890cg-")>0));MID(A2;24;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;25;1);"01234567890cg-")>0));MID(A2;25;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;26;1);"01234567890cg-")>0));MID(A2;26;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;27;1);"01234567890cg-")>0));MID(A2;27;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;28;1);"01234567890cg-")>0));MID(A2;28;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;29;1);"01234567890cg-")>0));MID(A2;29;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;30;1);"01234567890cg-")>0));MID(A2;30;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;31;1);"01234567890cg-")>0));MID(A2;31;1);"");IF(NOT(ISERROR(SEARCH(MID(A2;32;1);"01234567890cg-")>0));MID(A2;32;1);""))
only works by now for less than 33 signs.
problem here will be that you will get unexpected behavior like this:
123cg-123 - Process => 123cg-123-c
after rereading , I think you should try an other approach than described in the question ;-)
If you want to return everything up to and including the last digit, then try:
=LEFT(A1,LOOKUP(2,1/ISNUMBER(-MID(A1,seq,1)),seq))
seq is a named formula: Formula ► Define Name
Name: seq
Refers to: =ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))
seq returns an array of sequential numbers from 1 to 255.
mid(a1,seq,1)
returns an array consisting of the individual characters in the string in A1. The leading minus sign converts the digits from strings to numbers.
The lookup function will then return the position of the last digit

IFERROR with 3 values

I have a VLOOKUP for postcodes and currently it works when searching for both 3 and 4 character postcodes
e.g.
TW13 - Feltham
UB3 - Uxbridge
=IFERROR(VLOOKUP(LEFT(F2,4)&"*",Postcodes!A:C,3,FALSE),VLOOKUP(LEFT(F2,3)&"*",Postcodes!A:C,3,FALSE))
But I forgot that there are 2 character postcodes and both VLOOKUP and IFERROR only allow two checks to be made.
So where should I be looking to first check for 4 characters, then 3 characters or worst case 2 characters? If it helps all my postcodes are in the correct format with the space e.g. TW13 9XX, UB3 4XJ, W3 4EE.
Just nest in another IFERROR() in the value_if_error clause of the first:
=
IFERROR(VLOOKUP(LEFT(F2,4)&"*",Postcodes!A:C,3,FALSE),
IFERROR(VLOOKUP(LEFT(F2,3)&"*",Postcodes!A:C,3,FALSE),
VLOOKUP(LEFT(F2,2)&"*",Postcodes!A:C,3,FALSE)))
How about just extracting the part prior to the breaking space in postcodes
=IFERROR(VLOOKUP(LEFT(F2,FIND(" ",F2)-1)&"*",Postcodes!A:C,3,FALSE),"")

Resources