2

我不知道如何仅使用公式在循环中遍历字符串。

这是我试图转换为公式的 vba 代码。我想用这个公式对各种单元格进行数据验证。

公式:

Function Test(pValue) As Boolean
    If Len(pValue) < 2 Or Len(pValue) > 99 Then
        AlphaNumeric = False
        Exit Function
    End If
    LPos = 1
    LValid_Values = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789"
    While LPos <= Len(pValue)
        LChar = Mid(pValue, LPos, 1)
        If InStr(LValid_Values, LChar) = 0 Then
            Test = False
            Exit Function
        End If
        LPos = LPos + 1
    Wend
    Test = True
End Function

我写的公式的简单部分:

=IF(AND(LEN(E4)>1,LEN(E4)<100,____Formula_Here____),TRUE,FALSE)

我假设如果我选择E4:E50000并单击DataValidationCustom从下拉列表中选择,然后输入上述公式,那么它也会自动将其应用于 E4、E5、E6.. E50000。如果我错了,请纠正我。

另外,我希望它可以在 Excel 2003 及更高版本上运行。

4

4 回答 4

6

用 填空

NOT(ISERROR(SUM(SEARCH(MID(E4,ROW($1:$99),1)," ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789"))))

这是一个数组公式,因此如果在工作表中使用,您可以使用 ctrl-shift-enter 输入它。但是,数据校验的自定义公式(至少在2003年)会自动将其视为数组公式,因此只需正常输入即可。

让我们从内到外分解它。ROW($1:$99)数组公式内部提供了循环机制。它将导致周围的数组公式在每个 处求值i = 1, 2, ..., 99,因此将依次MID取第ith 个字符。不区分大小写,所以我们可以省略,因为我们有. 它返回找到第 th 个字符的位置,否则返回错误。聚合这些位置并将传播任何错误。所以,如果没有找到任何字符,整体就会出错。E4SEARCHa..zA..ZA..Z.0..9iSUMSUM

请注意,据我所知,您可以在自定义验证公式中使用 UDF,所以我不确定我是否遵循您的反对意见。

于 2013-02-03T20:01:45.733 回答
0

使用可以在公式中使用你的函数:http: //office.microsoft.com/en-us/excel-help/creating-custom-functions-HA001111701.aspx

于 2013-02-01T07:51:32.133 回答
0

我的想法是使用一堆嵌套的替代函数将有效条目减少到“”并进行数据验证以确保这是“”。

这是嵌套替换。

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(B1," ",""),"a",""),"b",""),"c",""),"d",""),"e",""),"f",""),"g",""),"h",""),"i",""),"j",""),"k",""),"l",""),"m",""),"n",""),"o",""),"p",""),"q",""),"r",""),"s",""),"t",""),"u",""),"v",""),"w",""),"x",""),"y",""),"z",""),"A",""),"B",""),"C",""),"D",""),"E",""),"F",""),"G",""),"H",""),"I",""),"J",""),"K",""),"L",""),"M",""),"N",""),"O",""),"P",""),"Q",""),"R",""),"S",""),"T",""),"U",""),"V",""),"W",""),"X",""),"Y",""),"Z",""),".",""),"0",""),"1",""),"2",""),"3",""),"4",""),"5",""),"6",""),"7",""),"8",""),"9","")

事实证明,这对您没有多大好处,因为我无法将其复制粘贴到数据验证中,但我在 VBA 中编写的并没有丢失所有内容。

Sub jf()
Dim lValid_values As String
Dim rowcount As Long
lValid_values = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789"
Dim form As String
Dim desired_column As String
Dim desired_rowMin As Long
Dim desired_rowMax As Long
Dim InitialCell As String
Dim temp As String
desired_column = "E"
desired_rowMin = 4
desired_rowMax = 50000
InitialCell = desired_column & desired_rowMin
form = "substitute(||cell||," & """" & " " & """" & "," & """" & """" & ")"

Do While lValid_values <> ""
form = "substitute(" & form & "," & """" & Left(lValid_values, 1) & """" & "," & """" & """" & ")"
lValid_values = Right(lValid_values, Len(lValid_values) - 1)
Loop
form = "=AND(LEN(||cell||)>1,LEN(||cell||)<100," & form & "=" & """" & """" & ")"

For rowcount = desired_rowMin To desired_rowMax
temp = Replace(form, "||cell||", desired_column & rowcount)

With Range(desired_column & rowcount).Validation
    .Delete
    .Add Type:=xlValidateCustom, AlertStyle:=xlValidAlertStop, Operator:= _
    xlBetween, Formula1:=temp
    .IgnoreBlank = True
    .InCellDropdown = True
    .InputTitle = ""
    .ErrorTitle = ""
    .InputMessage = ""
    .ErrorMessage = ""
    .ShowInput = True
    .ShowError = True
End With
Next rowcount
End Sub

我开始将它运行到 50000,但它非常慢,所以我将它停在 4000 左右。它确实有效,所以希望它不是你必须多次执行的操作。您必须更改desired_column、desired_rowmin 和desired_rowmax 变量以满足您的需要。

于 2013-02-03T17:56:06.060 回答
0

我发现这样做的方法是使用辅助列。

假设你有你的数据E4:E50000

F4 会将=Test(E4)
这个值复制到最后,所以你现在有你的帮助列(如果你想检查,最后一个是=Test(E50000)

然后将是数据验证自定义公式=F4(当您在选择范围 E4:E50000 的情况下输入此公式时,它会将其复制下来,并调整引用以指向其旁边的相应单元格)。

您的代码中也有错误 - 您有AlphaNumeric = False,应该是Test = False。设置选项显式将有助于发现这些错误。


我在测试电子表格中使用的例程的略微修改版本:

Option Explicit

Function Test(pValue) As Boolean
Dim lPos As Long
Dim lValid_Values As String
Dim LChar As String

If Len(pValue) < 2 Or Len(pValue) > 99 Then
    Test = False
    Exit Function
End If
lPos = 1
lValid_Values = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789"
While lPos <= Len(pValue)
    LChar = Mid(pValue, lPos, 1)
    If InStr(lValid_Values, LChar) = 0 Then
        Test = False
        Exit Function
    End If
    lPos = lPos + 1
Wend
Test = True
End Function
于 2013-02-04T18:17:18.873 回答