简体   繁体   中英

How do I validate a portion of a cell?

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:

  1. followed by a colon and then whatever else ( not blank ).
  2. There could be spacing around the ':'.

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:

  1. Highlight the first cell of the column you want to validate
  2. On the ribbon, click on Data, then, under Data Tools heading, click Data Validation.
  3. The Data Validation window should be open. Click on the settings tab (it should be selected by default, actually)
  4. In the "Allow" drop-down menu, click Custom.
  5. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM