用户定义的功能不会更新

时间:2018-02-24 15:44:29

标签: excel vba excel-vba

我使用Excel 2007并创建了下面的函数来消除字符串中的某些字符。

Public Function CleanString(sUser As String) As String
Dim lStringSize As Long, lCounter As Long
Dim iCode As Integer
Dim sChar As String

Application.Volatile

On Error GoTo ErrorHandler
lStringSize = Len(sUser)
For lCounter = 1 To lStringSize
    sChar = Mid(sUser, lCounter, 1)
    iCode = Asc(sChar)
    If ((iCode < 65) Or (iCode > 90 And iCode < 97) Or (iCode > 122)) And (iCode <> 45) Then
        sUser = Replace(sUser, sChar, Chr(32))
    End If
Next lCounter



CleanString = sUser
    Exit Function

ErrorHandler:
    CleanString = ""
    Exit Function

End Function

当我在电子表格中使用如下函数时,B1包含字符串&#34; Samyn; Filiep&#34; C1 = CleanString(B1)中的结果产生预期的结果&#34; Samyn Filiep&#34; 问题是保存并重新打开工作表后C1包含&#34; Samyn; Filiep&#34;即,没有任何功能的B1应用类似于C1将包含公式= B1。我尝试过application.calculate,application.calculatefull和selection.calculate(其中选择是C1),但结果不会更新。返回结果的唯一方法是编辑C1,输入后结果是正确的。然而,重新开放后,结果再次消失。 除列出的功能外,我没有其他代码。 Excel设置为自动重新计算。 我的第一个问题是为什么执行功能的结果在保存时会消失。 我的第二个问题是为什么在进行完全重新计算时使用该函数的单元格不会更新。

2 个答案:

答案 0 :(得分:0)

您在UDF调用中使用所需范围(Application.Volatile)时不需要B1。您当前的设置意味着UDF会触发工作表中的每个更改,而不仅仅是所需的单元格 - 删除这意味着它只会在B1更改时触发。

您将字符串sUser作为输入,希望更改它,然后返回sUser作为结果。为了安全起见,我总是操纵一个临时字符串然后返回它。在您的情况下,如果循环或替换不能按预期工作,您将返回原始字符串。但是,在这种情况下,我不认为这是问题的根源。

使用Replace效率低下,你逐个字符循环,然后调用Replace,它对整个字符串起作用。同样,你的情况也令人困惑,Goodcode[Boolean] = (icode > 64 And icode < 91) or (icode > 96 and icode < 123) or icode = 45 or icode = 32)更能描述你真正想要的东西。然后,您可以使用If Not GoodCode Then等。但是,使用Regex会更有效率,您不需要循环或If

另外考虑使用Trim (...),因为这会在更改后删除多余的空格。

但是,要检查的两个主要方面是:Application.Volatile并且UDF是在标准模块中定义的。

答案 1 :(得分:0)

这是我做了什么,最终工作但我无能为力。我用下面的代码替换了上面的代码

Public Function CLSTR(sUser As String) As String
Dim lStringSize As Long, lCounter As Long
Dim iCode As Integer
Dim sChar As String

On Error GoTo ErrorHandler

    lStringSize = Len(sUser)
    For lCounter = 1 To lStringSize
        sChar = Mid(sUser, lCounter, 1)
        iCode = Asc(sChar)
        If ((iCode < 65) Or (iCode > 90 And iCode < 97) Or (iCode > 122)) And (iCode <> 45) Then
            sUser = Replace(sUser, sChar, Chr(32))
        End If
    Next lCounter

CLSTR = sUser
    Exit Function

ErrorHandler:
    CLSTR = ""
    Exit Function

End Function

正如您将注意到,除了我已删除application.volatile之外,代码中没有任何变化;虽然在原始代码中留下或删除它没有效果。

唯一的区别是该函数的名称在所有大写字母中,现在称为CLSTR而不是ClearString

这可以按预期工作。