在非活动工作表中更新 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
中的单元格
我创建了一些 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
中的单元格