如何不挂Excel?

时间:2016-06-23 19:49:52

标签: .net excel visual-studio excel-dna

我有这个问题,我的volatile,宏类型UDF设置调用单元格旁边的几个单元格的值,除非在工作表中使用两次(或更多),否则工作正常:Excel状态栏开始闪烁&#34 ;计算..."

我不是一个真正的挂起,而是一大堆重新计算:示例函数中的计数器被绘制而没有实际挂起的紊乱。

我也不确定是否使用易失性UDF,因为我需要自动重新计算,但仅限于输入更改,而不是常量轮询。

我确实生成了一个包含三个函数的示例模块:

  • VolatileNyanCat - 与我的UDF类似:一次SetValue来电。如果两次使用, Excel会挂起
  • NonVolatileOneNyanCat - 如上所述,但不易变。不会挂起,但我需要自动重新计算。
  • HangNyanCat - 在两个不同的范围内调用SetValue两次。 Excel挂起。

我认为这与ExcelAsyncUtil.QueueAsMacro的工作方式和线程安全有关,但我在这里感到困惑。

Imports ExcelDna.Integration
Imports ExcelDna.Integration.XlCall

Public Module Example

    <ExcelFunction(IsMacroType:=True, IsVolatile:=True)>
    Public Function VolatileNyanCat() As String

        Dim caller = CType(XlCall.Excel(XlCall.xlfCaller), ExcelReference)
        Dim NyanCat(,) As String = {{"Nyan", "Cat"}}

        Dim nc As New ExcelReference(caller.RowFirst + 1, caller.RowLast + 1,
                                     caller.ColumnFirst, caller.ColumnLast + 1,
                                     caller.SheetId)

        Static nyy As Integer = 1

        ExcelAsyncUtil.QueueAsMacro(Sub()
                                        nyy += 1
                                        nc.SetValue(NyanCat)
                                    End Sub)
        Return "NYA! x " + CStr(nyy)
    End Function

    <ExcelFunction(IsMacroType:=True)>
    Public Function NonVolatileOneNyanCat() As String

        Dim caller = CType(XlCall.Excel(XlCall.xlfCaller), ExcelReference)
        Dim NyanCat(,) As String = {{"Nyan", "Cat"}}

        Dim nc As New ExcelReference(caller.RowFirst + 1, caller.RowLast + 1,
                                     caller.ColumnFirst, caller.ColumnLast + 1,
                                     caller.SheetId)

        Static nyy As Integer = 1

        ExcelAsyncUtil.QueueAsMacro(Sub()
                                        nyy += 1
                                        nc.SetValue(NyanCat)
                                    End Sub)
        Return "NYA! x " + CStr(nyy)
    End Function

    <ExcelFunction(IsMacroType:=True, IsVolatile:=True)>
    Public Function HangNyanCat() As String

        Dim caller = CType(XlCall.Excel(XlCall.xlfCaller), ExcelReference)
        Dim nyan(,) As String = {{"Nyan"}} : Dim cat(,) As String = {{"Cat"}}

        Dim n As New ExcelReference(caller.RowFirst + 1, caller.RowLast + 1,
                                    caller.ColumnFirst, caller.ColumnLast,
                                    caller.SheetId)

        Dim c As New ExcelReference(caller.RowFirst + 1, caller.RowLast + 1,
                                    caller.ColumnFirst + 1, caller.ColumnLast + 1,
                                    caller.SheetId)

        Static nyy As Integer = 1

        ExcelAsyncUtil.QueueAsMacro(Sub()
                                        n.SetValue(nyan)
                                        c.SetValue(cat)
                                        nyy += 1
                                    End Sub)
        Return "NYA! x " + CStr(nyy)
    End Function
End Module

1 个答案:

答案 0 :(得分:1)

ExcelAsyncUtil.QueueAsMacro会尽快运行代码 - 在这种情况下计算完成时。但是您运行的宏在工作表上设置了一些值,因此易失性函数将再次计算。其中一个新宏排队设置一些单元格...等等所以一切似乎按预期工作。

建议不要在UDF中设置其他单元格并使用Excel阻止 - 这就是为什么你必须经历奇怪的宏路由。如果您可以将您的功能重组为没有这些副作用,Excel将变得更加快乐。