我需要确保一个单元格以一个字符串(目前是两个之一)开头,然后是一个冒号,然后是其他任何内容(不是空白)。
IE:
IP Address:1.2.3.4
FQDN:a.b.c.d
所以,我需要确保这些字符串中的任何一个加上“:”都会启动单元格。':' 周围可能有间距。
我需要确保一个单元格以一个字符串(目前是两个之一)开头,然后是一个冒号,然后是其他任何内容(不是空白)。
IE:
IP Address:1.2.3.4
FQDN:a.b.c.d
所以,我需要确保这些字符串中的任何一个加上“:”都会启动单元格。':' 周围可能有间距。
我不确定您所说的“确保”是什么意思...
这将检查单元格以查看它是否具有 Excel 函数中的两个起始值之一:
=IF(OR(LEFT(A1,5)="FQDN:",LEFT(A1,11)="IP Address:"),TRUE,FALSE)
不过,这并没有考虑到冒号周围的间距。为此,它是正则表达式,我不太擅长。
-- 从 Tushar Mehta 的网站获取代码:http ://www.tmehta.com/regexp/add_code.htm
然后,使用这样的 Excel 函数:
=regexpfind(A1,"^FQDN\s*:\s*")
=regexpfind(A1,"^IP Address\s*:\s*")
或者您可以将它们合并成一个公式,如下所示:
=regexpfind(A1,"^(FQDN|IP Address)\s*:\s*")
如果您的单元格是 A4,请在数据/验证中尝试此操作。自定义公式:
=((COUNTIF(A4,"fqdn*")+COUNTIF(A4,"ip address*"))*COUNTIF(A4,"*:*")>0)
注意这不区分大小写。
这可能是最简单的方法。假设您正在检查单元格 A1 中的值:
=IF(ISERR(FIND(":",A1)),"Bad!",IF(FIND(":",A1)<>LEN(A1), "OK", "Bad!"))
首先,此公式检查单元格 A1 是否有冒号。如果没有,那就是坏细胞。如果是,它会检查冒号是否不是最后一个字符。如果是最后一个字符,冒号后面没有文字,所以是坏单元格。如果冒号后面有文字,那就是好单元格。希望这可以帮助!
- 编辑 -
要检查冒号是否不是第一个字符,这是公式:
=IF(ISERR(FIND(":",A1)),"Bad!",IF(OR(FIND(":",A1)=LEN(A1), FIND(":",A1) = 1), "Bad!", "OK"))"Bad!"))
使用此公式,您必须在冒号之前有一个字符串。但是,如果您只需要检查这两个字符串,最好明确地检查它们。
这是另一种解决方案(假设字符串在 中A1
):
=IFERROR(IF(AND(SEARCH(":",A1)>1,SEARCH(":",A1)<LEN(TRIM(A1))),"GOOD","BAD"),"BAD")
这将处理:
共享示例文件(使用不同的选项):https ://www.dropbox.com/s/5rxzyzgkg8biffg/StringWithColon.xlsx
如果您真的想确保没有人可以在您正在谈论的单元格中输入任何其他内容,您可以使用自定义数据验证公式。这是一步一步:
在“公式”框中,复制以下公式:
=IF(NOT(ISERR(FIND(":",A1))), AND(FIND(":",A1)<>LEN(A1),FIND(":",A1) <> 1), FALSE)
用 A1 替换您需要的任何单元格。这与我的其他答案中的公式相同;它只检查是否有文本,然后是冒号,然后是更多文本(按此顺序),而不是特定字符串。要明确检查字符串“IP 地址”和“FQDN”,请在数据验证对话框中替换其他人的公式。
如果您想要 VBA 解决方案,这里有一个函数,您可以将其用作 UDF 或来自 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
因此,作为答案之一给出的正则表达式方法构成了我的解决方案的基础。我从提供的链接复制代码并粘贴到另一个模块。然后,我为 RegExpFind 创建了一个小包装器,它基本上运行匹配并在模式成功与否时返回真或假。
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
现在,我不能直接在自定义验证中使用它,因此,鉴于我的工作表是从元数据动态生成的(没有预先创建任何内容),我最终遵循了这里给出的第二个建议。
我是如何做到的,是拥有以下 VBA 代码(摘自我必须创建数据验证规则的方法):
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
我将公式(实际工作)粘贴到未使用的单元格(EV [validationFormulaCellName] = 152 [validationFormulaCellRef],沿行很远,然后设置数据单元格的自定义验证以检查论坛单元格的值是否为 True。firstIndex value 是我要插入的第一行的编号,所以我最终得到了一个看起来像“=EV10=TRUE”的验证公式。我在验证公式中使用 INDIRECT(..) 语法生成单元格引用对于该特定行,因为固定的(即:EV10)单元格引用不会为每一行自动调整(所有都将引用 EV10)。相反,验证公式是固定的(即:=EV10=TRUE)但会调整插入时的每一行。我不明白为什么这些行为不同。
将来,将我需要验证的值(FQDN 和 IP 地址)粘贴到我们拥有的存储各种数据位(枚举等)的隐藏工作表中是有意义的。这样,它可以从列表中以编程方式构建,而不是硬编码。