如何不挂Excel?
How to not hang Excel?
我遇到这个问题,我的易失性宏类型 UDF 设置调用单元格旁边的几个单元格的值,除非在 sheet 中使用两次(或更多次),否则工作正常:Excel 状态栏开始闪烁 "Calculating...".
我不是真正的挂起,而是大量的重新计算:示例函数中的计数器是在没有实际挂起的情况下绘制的。
此外,我不确定是否使用可变 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
ExcelAsyncUtil.QueueAsMacro 运行 尽快输入代码 - 在本例中为计算完成时。但是你 运行 的宏在 sheet 上设置了一些值,所以 volatile 函数将再次计算。它排队一个新的宏来设置一些单元格......等等所以一切似乎都按预期工作。
不建议从 UDF 内部设置其他单元格,Excel 会阻止 - 这就是为什么您必须通过奇怪的宏路径。如果你能重组你的函数,使其没有这些副作用,Excel 会变得更快乐。
我遇到这个问题,我的易失性宏类型 UDF 设置调用单元格旁边的几个单元格的值,除非在 sheet 中使用两次(或更多次),否则工作正常:Excel 状态栏开始闪烁 "Calculating...".
我不是真正的挂起,而是大量的重新计算:示例函数中的计数器是在没有实际挂起的情况下绘制的。
此外,我不确定是否使用可变 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
ExcelAsyncUtil.QueueAsMacro 运行 尽快输入代码 - 在本例中为计算完成时。但是你 运行 的宏在 sheet 上设置了一些值,所以 volatile 函数将再次计算。它排队一个新的宏来设置一些单元格......等等所以一切似乎都按预期工作。
不建议从 UDF 内部设置其他单元格,Excel 会阻止 - 这就是为什么您必须通过奇怪的宏路径。如果你能重组你的函数,使其没有这些副作用,Excel 会变得更快乐。