2016-06-23 4 views
0

У меня есть эта проблема, когда мой изменчивый тип макроса UDF, который устанавливает значение пары ячеек рядом с вызывающей ячейкой, отлично работает, если не используется дважды (или больше) в листе: строка состояния Excel начинает мигать. «Расчет .. . ".Как не повесить Excel?

Я не являюсь реальным, но тяжелым грузом перерасчетов: счетчик в примерной функции рисуется без изменчивости фактических зависаний.

Также я не уверен в использовании изменчивого UDF, так как мне нужно иметь автоматический пересчет, но только при изменении ввода, а не при постоянном опросе.

я сделал произвести примерный модуль с тремя функциями:

  • VolatileNyanCat - по аналогии с моей UDF: один SetValue вызова. Excel стоит если используется 2 раз.
  • 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

Отправьте код как часть своего вопроса: http://stackoverflow.com/help/mcve – ManoDestra

+0

@ManoDestra Я работаю над этим: P – beppe9000

ответ

1

ExcelAsyncUtil.QueueAsMacro запускает код как можно скорее - в этом случае, когда вычисление завершается. Но макрос, который вы запускаете, задает некоторые значения на листе, поэтому изменчивые функции будут вычисляться снова. Какая очередь создает новый макрос для установки некоторых ячеек ... И т. Д. Итак, все работает так, как ожидалось.

Установка других ячеек изнутри UDF не рекомендуется и блокируется Excel - вот почему вам нужно пройти через странный маршрут макроса. Если вы можете реструктурировать свои функции без таких побочных эффектов, Excel станет намного счастливее.

+0

Есть ли альтернатива тому, что он изменчив, что все еще позволяет автоматически пересчитывать? – beppe9000