在非活动工作表中更新 Excel 中的 UDF 时出错

Error in updating UDF in Excel in non active sheets

我创建了一些 UDF 来自动化我和一些同事经常使用的一些微积分。 为了简单起见,我粘贴了一个我遇到问题的 MWE,我的实际代码更长,但采用相同的输入,一系列单元格,其中一个维度等于一个(所以一行或一列)

Public Function Test(Donnees As Range)

Dim Nombre_Cellules, Temp As Double
Dim Format_Donnees As String

Temp = 0


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'                                                                                   '
'       Parametres utiles generaux                                                  '
'                                                                                   '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Nb_Lignes = Donnees.Rows.Count
Nb_Colonnes = Donnees.Columns.Count
Premiere_Ligne = Donnees.Row
Premiere_Colonne = Donnees.Column
Derniere_Ligne = Donnees.Row + Nb_Lignes - 1
Derniere_Colonne = Donnees.Column + Nb_Colonnes - 1



'On definit la frequence et la taille associee
If Nb_Lignes = 1 Then
    Format_Donnees = "Colonnes"
    Nombre_Cellules = Nb_Colonnes
End If
If Nb_Colonnes = 1 Then
    Format_Donnees = "Lignes"
    Nombre_Cellules = Nb_Lignes
End If


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'                                                                                   '
'       Verifications des parametres et messages d'erreurs                          '
'                                                                                   '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'On verifie que la plage renseignée est soit sur une seule ligne soit sur une seule colonne
If (Nb_Lignes <> 1 And Nb_Colonnes <> 1) Then
        MsgBox _
            "La plage de données considérée est incorrecte, il ne peut s'agir que " & vbNewLine & _
            Chr(149) & " de données sur une seule ligne ou " & vbNewLine & _
            Chr(149) & " de données sur une seule colonne" _
            , , "Parametres incorrects"
        Test = CVErr(xlErrRef)
        Exit Function
End If


'On verifie que toute la période qui sert au calcul contient bien des valeurs numériques et ne contient pas de valeurs vides
If Format_Donnees = "Lignes" Then
    For i = 0 To Nombre_Cellules - 1
        If Not IsNumeric(Cells(Premiere_Ligne + i, Premiere_Colonne).Value) Then
            MsgBox _
            "La plage de donnée considérée est incorrecte" & vbNewLine & _
            "Toutes les cellules nécessaires au calcul dans la colonne ne sont pas numériques" _
            , , "Parametres incorrects"
            Test = CVErr(xlErrRef)
            Exit Function
        End If
        If (Cells(Premiere_Ligne + i, Premiere_Colonne).Value = "") Then
            MsgBox _
            "La plage de donnée considérée est incorrecte" & vbNewLine & _
            "Une cellule de la colonne considérée est vide et semble avoir une valeur manquante" _
            , , "Parametres incorrects"
            Test = CVErr(xlErrRef)
            Exit Function
        End If
    Next
End If
If Format_Donnees = "Colonnes" Then
    For i = 0 To Nombre_Cellules - 1
        If Not IsNumeric(Cells(Premiere_Ligne, Premiere_Colonne + i).Value) Then
            MsgBox _
            "La plage de donnée considérée est incorrecte" & vbNewLine & _
            "Toutes les cellules nécessaires au calcul dans la ligne ne sont pas numériques" _
            , , "Parametres incorrects"
            Test = CVErr(xlErrRef)
            Exit Function
        End If
        If (Cells(Premiere_Ligne, Premiere_Colonne + i).Value = "") Then
            MsgBox _
            "La plage de donnée considérée est incorrecte" & vbNewLine & _
            "Une cellule de la ligne considérée est vide et semble avoir une valeur manquante" _
            , , "Parametres incorrects"
            Test = CVErr(xlErrRef)
            Exit Function
        End If
    Next
End If


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'                                                                                   '
'                           Calculs a proprement parler                             '
'                                                                                   '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


If Format_Donnees = "Lignes" Then
    For i = 0 To Nombre_Cellules - 1
        Temp = Temp + Cells(Premiere_Ligne + i, Premiere_Colonne).Value
    Next
End If
If Format_Donnees = "Colonnes" Then
    For i = 0 To Nombre_Cellules - 1
        Temp = Temp + Cells(Premiere_Ligne, Premiere_Colonne + i).Value
    Next
End If

Test = Temp
End Function

因此,由于我不会是此功能的唯一用户,因此我尝试包含一些检查和错误消息。 一是检查所选范围是否有空值和非数值。

现在我的函数可以工作了(至少它们可以计算出我希望它们计算的东西),但是我对它们的更新方式有些疑惑。 请注意,我已经反对用户偏好,以便所有使用的值都包含在输入中传递的范围内。

我能够用这段代码重现的问题之一是,如果我在一个工作簿的几个 sheet 上使用这个函数(所以一个 Test() 在 worksheet1,还有一个 Test() 在工作 sheet2,出于一个原因尝试更新整个工作簿(例如通过 Ctrl + alt + shift + F9),然后我将收到一个我在非活动 sheet 中设置的警告 ("Une cellule de la ligne considérée est vide et semble avoir une valeur manquante")。

谁能给我解释一下?

您正在使用没有 sheet 资格的 Cells()。这意味着它指的是活动 sheet 碰巧是什么。因此,除非对您的 UDF 的所有调用都在当前活动的 sheet

上,否则它将无法正常工作

您需要将其更改为 Donnees.Cells( ) 并更改单元格索引以引用 Donnees 中的单元格而不是整个 sheet

中的单元格