简体   繁体   English

添加或删除不相关的工作表时,Excel VBA UDF 返回#VALUE 错误

[英]Excel VBA UDF Returns #VALUE Error When Adding Or Deleting Unrelated Sheet

First time posting, apologies if I make any mistakes!第一次发帖,如有错误请见谅!

So, I'm having a pretty strange problem with my UDF.所以,我的 UDF 有一个很奇怪的问题。 In my workbook, I have an invisible 'template' sheet named "Standard Phase Sheet", and a subroutine that a user can activate which copies that template sheet into a new, visible sheet that the user can then work with.在我的工作簿中,我有一个名为“标准阶段表”的不可见“模板”表,以及一个用户可以激活的子例程,该子例程将该模板表复制到用户可以使用的新的可见表中。 There will be many copies of that template sheet throughout the workbook, but they will all have unique names.整个工作簿中将有该模板表的许多副本,但它们都有唯一的名称。

My UDF is on that template sheet in several spots, and thus on every copy of the template sheet that a user makes.我的 UDF 位于该模板表的多个位置,因此位于用户制作的模板表的每个副本上。 When working within one of these sheets, the UDF works just fine, and returns the values I'd expect.在其中一张工作表中工作时,UDF 工作得很好,并返回我期望的值。

However, when a user ADDS a new copy of the template sheet, SOMETIMES the UDF goes haywire and returns #VALUE errors in every place the UDF is being used.但是,当用户添加模板表的新副本时,有时 UDF 会失控并在使用 UDF 的每个地方返回 #VALUE 错误。

Also, when a user DELETES one of the copies of the template sheet, the UDF ALWAYS goes haywire and returns #VALUE errors in every place the UDF is being used.此外,当用户删除模板表的一个副本时,UDF 总是会出问题并在使用 UDF 的每个地方返回 #VALUE 错误。

I'm not using ActiveSheet or anything like that, and I believe I'm correctly giving full references to the ranges I'm working with within the UDF.我没有使用 ActiveSheet 或类似的东西,我相信我正确地给出了我在 UDF 中使用的范围的完整引用。 Any help will be appreciated, I'm in a bind here!任何帮助将不胜感激,我在这里受困! Code for the UDF is below. UDF 的代码如下。

Also, because I'm sure I'll be asked the question, the neColumn variable within my code is a public variable that I use in several subroutines and UDFs.另外,因为我确定我会被问到这个问题,所以我的代码中的 neColumn 变量是我在几个子例程和 UDF 中使用的公共变量。 It is defined at the beginning of my module.它在我的模块的开头定义。 Also, I am using Option Explicit at the beginning of my module as well.此外,我也在模块的开头使用了 Option Explicit。

Thank you!谢谢!

Public Function fSum(ByVal Target As Range, bExtended As Boolean) As Single

'This function returns a sum, based on a range provided in the cell that holds the function.
'It checks to see if that line item has been marked as Non-Extended, based on the NE column
'that can be check marked. If that line item is marked NE, then only the NE sum columns can
'use that line item as part of their sum, and those values are removed from the E columns.

Dim sSum As Single
Dim i As Integer
Dim n As Integer

'This small section is used to determine complete references to the cell calling the function.

Dim sheetName As String
sheetName = Application.Caller.Parent.Name

'Loop through provided range, and sum up the contents based on whether they have been marked NE or not.

i = 1
n = Target.row
sSum = 0

If Sheets(sheetName).Visible = True Then

While i < Target.Rows.Count

    If (bExtended = True) Then

        If Sheets(sheetName).Range(neColumn.Address).Cells(n, 1) = vbNullString Then

            sSum = sSum + Sheets(sheetName).Range(Target.Address).Cells(i, 1).Value

        End If

    Else

        If Sheets(sheetName).Range(neColumn.Address).Cells(n, 1) <> vbNullString Then

            sSum = sSum + Sheets(sheetName).Range(Target.Address).Cells(i, 1).Value

        End If

    End If

i = i + 1
n = n + 1

Wend

End If

fSum = sSum

End Function

Summarizing the comment thread in an answer for posterity:在子孙的答案中总结评论线程:

  • I'm not sure why exactly you see this behavior.我不确定为什么你会看到这种行为。
  • There would be ways to better this UDF (including using Long instead of Integer , preferring a Do While...Loop to While...Wend , removing the .Visible check...有办法改善这个 UDF(包括使用Long而不是Integer ,更喜欢Do While...LoopWhile...Wend ,删除.Visible检查...
  • But in any case, it does feel like this is just replicating the functionality of SUMIFS so you might just consider going that route.但无论如何,感觉这只是复制SUMIFS的功能,因此您可能会考虑走这条路。

The reason is that your neColumn variable has become Nothing , because Excel is Volatile.原因是你的neColumn变量变成了Nothing ,因为 Excel 是 Volatile。

I assume that the start of your module looks something like this:我假设你的模块的开头看起来像这样:

Option Explicit

Public neColumn As Range

Sub Auto_Open()
    Set neColumn = Sheet1.Range("A1:B2")
End Sub

When you open the Workbook, you call the Auto_Open Sub to Set the neColumn variable.当您打开工作簿时,您调用Auto_Open Sub 来Set neColumn变量。 However - when certain actions occur, Excel rebuilds the VBA, which resets the Public Variables (such as neColumn ) to their defaults (which, for an Object such as a Range , is Nothing ).但是 - 当某些操作发生时,Excel 会重建 VBA,这会将公共变量(例如neColumn )重置为其默认值(对于诸如Range类的Object ,它是Nothing )。 An easy way to trigger this is by deliberately throwing an error, such as attempting to run this:触发它的一种简单方法是故意抛出错误,例如尝试运行:

Sub ThrowErr()
    NotDefined = 1
End Sub

You can make it more visible to you by adding the following line to your fSum code:您可以通过在fSum代码中添加以下行来使其更明显:

If neColumn Is Nothing Then Stop

You either need a way to restore neColumn when it has been reset to Nothing , OR find a non-volatile way to store it.neColumn被重置为Nothing ,您要么需要一种方法来恢复它,要么找到一种非易失性的方法来存储它。

I am assuming that this is not suitable to become a Const , because otherwise it already would be but you could turn it into a Named Range, or store the Address in a hidden worksheet / CustomDocumentProperty .我假设这不适合成为Const ,因为否则它已经是,但您可以将其转换为命名范围,或将Address存储在隐藏的工作表/ CustomDocumentProperty These options would also allow you to store neColumn when the Workbook is saved for when you reopen it这些选项允许您在重新打开工作簿时保存工作簿时存储neColumn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM