I need to ensure that a cell starts with a string (one of two, at the moment), followed by a colon and then whatever else (not blank).
ie:
IP Address:1.2.3.4
FQDN:a.b.c.d
So, I need to ensure that either of those strings plus ':' starts the cell. There could be spacing around the ':'.
I'm not sure what you mean by "ensure"...
This will check the cell to see if it has either of the two starting values in an Excel function:
=IF(OR(LEFT(A1,5)="FQDN:",LEFT(A1,11)="IP Address:"),TRUE,FALSE)
That doesn't take into account spacing around the colon though. For that, it's Regular Expressions, which I am not very good with.
-- Take the code from Tushar Mehta's site: http://www.tmehta.com/regexp/add_code.htm
Then, use an Excel function like this:
=regexpfind(A1,"^FQDN\s*:\s*")
=regexpfind(A1,"^IP Address\s*:\s*")
or you could merge these into a single formula like this:
=regexpfind(A1,"^(FQDN|IP Address)\s*:\s*")
If your cell is A4, then try this in Data/Validation.. Custom formula:
=((COUNTIF(A4,"fqdn*")+COUNTIF(A4,"ip address*"))*COUNTIF(A4,"*:*")>0)
NB this is not case-sensitive.
This might be the simplest way to do it. Assuming you are checking the value in cell A1:
=IF(ISERR(FIND(":",A1)),"Bad!",IF(FIND(":",A1)<>LEN(A1), "OK", "Bad!"))
First, this formula checks that the cell A1 has a colon. If it doesn't, it is a bad cell. If it does, it checks that the colon is not the last character. If it is the last character, there is no text after the colon, so it is a bad cell. If there is text after the colon, it is a good cell. Hope this helps!
--Edit--
To check that the colon is not the first character, this is the formula:
=IF(ISERR(FIND(":",A1)),"Bad!",IF(OR(FIND(":",A1)=LEN(A1), FIND(":",A1) = 1), "Bad!", "OK"))"Bad!"))
With this formula, you have to have a string before the colon. But if you only need to check for the two strings, it's probably better to check for them explicitly.
Here's one more solution (assuming string is in A1
):
=IFERROR(IF(AND(SEARCH(":",A1)>1,SEARCH(":",A1)<LEN(TRIM(A1))),"GOOD","BAD"),"BAD")
This will handle:
Sample file is shared (with different options): https://www.dropbox.com/s/5rxzyzgkg8biffg/StringWithColon.xlsx
If you really want to ensure that no one can enter anything else in the cells you're talking about, you can use a custom Data Validation formula. Here's a step-by-step:
In the "formula" box, copy this formula:
=IF(NOT(ISERR(FIND(":",A1))), AND(FIND(":",A1)<>LEN(A1),FIND(":",A1) <> 1), FALSE)
Substitute A1 for whatever cell you need. This is the same formula as in my other answer; it checks only that there is text, then a colon, them more text (in that order), not for specific strings. To explicitly check for the strings "IP Address" and "FQDN", substitute someone else's formula for this one in the data validation dialog.
If you want a VBA solution here is a function you can use either as a UDF or from VBA
Option Explicit
Option Base 1
Function CorrectColonPlace(StringtoCheck As String, StartStrings As Variant) As Variant
Dim iPos As Long
Dim j As Long
Dim StrStart As String
'
' return 0 if stringtocheck fails, else the position of the colon
CorrectColonPlace = 0
On Error GoTo FuncFail
iPos = InStr(StringtoCheck, ":")
If iPos > 1 Then
If iPos < Len(Trim(StringtoCheck)) Then
'' assume that StartStrings is either a Range or a 2-dimension single-column array
'' containing the strings to be found at the start of stringtocheck
If IsObject(StartStrings) Then StartStrings = StartStrings.Value2
StrStart = Trim(Left(StringtoCheck, iPos - 1))
For j = 1 To UBound(StartStrings)
If StrStart = Trim(StartStrings(j, 1)) Then
CorrectColonPlace = iPos
Exit For
End If
Next j
End If
End If
FuncFail:
End Function
So, the regex approach given as one of the answers formed the basis for my solution. I copied the code from the supplied link and pasted to another module. I then created a little wrapper for RegExpFind that basically ran the match and returned a true or false if the pattern was successful or not.
Function RegExpTest(FindIn, FindWhat As String, _
Optional IgnoreCase As Boolean = False)
Dim n As Long
Dim resultsArray As Variant ' Defined as single variant for the benefit of excel 97
Dim result As Boolean
' Don't break on errors. Easier to check if Err<>0
On Error Resume Next
Err.Clear
result = False
resultsArray = RegExpFind(FindIn, FindWhat, IgnoreCase)
' Check if the returned data is an array before proceeding.
If IsArray(resultsArray) = True Then
n = UBound(resultsArray)
If Err.Number = 0 Then
If LBound(resultsArray) <= UBound(resultsArray) Then
result = True
End If
End If
End If
RegExpTest = result
End Function
Now, I cannot use that directly in a custom validation so, given that my worksheets are generated on the fly from metadata (nothing is created beforehand), I ended up following the second suggestion given here .
How I did that, was to have the following VBA code (excerpted from the method I have to create my data validation rules):
Range(Cells(firstIndex, validationFormulaCellRef), Cells(lastIndex, validationFormulaCellRef)).Formula = _
"=RegExpTest(INDIRECT(""D""&ROW()), ""^(FQDN|IP Address)\s*:\s*([\w\d\.]+)$"", TRUE)"
Dim validationFormula As String
validationFormula = "=" & validationFormulaCellName & firstIndex & "=TRUE"
' Now, setup custom validation to check that the referenced cell's value is True
With fieldRange.Validation
.Delete
.add Type:=xlValidateCustom, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, _
Formula1:=validationFormula
.IgnoreBlank = False
.InCellDropdown = False
.InputTitle = ""
.ErrorTitle = "Input Error"
.InputMessage = "This field must start with either 'FQDN' or 'IP Address', plus a colon ':'."
.ErrorMessage = "This field must start with either 'FQDN' or 'IP Address', plus a colon ':'."
.ShowInput = True
.ShowError = True
End With
I stick the formula (that actually does the work) into an unused cell (EV [validationFormulaCellName] = 152 [validationFormulaCellRef], far along the row, then set the data cell's custom validation to check if the forumula cell's value is True. The firstIndex value is the number of the first row I'm inserting, so I end up with a validation formula that looks like "=EV10=TRUE". I use the INDIRECT(..) syntax in the validation formula soas to generate a cell reference for that particular row, since a fixed (ie: EV10) cell ref would not be automatically adjusted for each row (all would reference EV10). On the contrary, the validation formula is fixed (ie: =EV10=TRUE) but is adjusted for each row when inserted. I don't understand why those behaviours differ.
In the future, it would make sense to stick the values I need to verify (FQDN and IP Address) into a hidden worksheet we have that stores various bits of data - enums and the like. That way, it can be programatically built up from a list and not hardcoded.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.