如何处理UDF中的全列范围?

时间:2016-06-19 22:36:44

标签: .net vb.net excel optimization excel-dna

我使用Excel DNA为Excel开发了一个插件。我声明了一个接受范围作为输入的UDF,将ExcelReference强制转换为Range并使用GetEnumerator中的枚举器收集List中的所有单元格值以进行进一步处理,然后将输出写入另一个范围。

作为一个测试,我尝试将整个列传递给函数(A:A)并且所有内容都冻结,因为枚举器在最后一个值之后保持枚举空单元格。

是否有更快的方法来检测全列范围并获取非空的所有单元格?

目前我正在使用此代码,但在上述情况下速度非常慢。

            Dim ue = inputRange.GetEnumerator    
            Dim L As New List(Of String)

            Do
                If ue.MoveNext Then
                    Dim c As Range = ue.Current
                    Dim V As String = c.FormulaLocal
                    If String.IsNullOrWhiteSpace(V) Then Continue Do
                    L.Add(V)
                Else
                    Exit Do
                End If
            Loop

我将使用以下解决方法,但我想在根目录中阻止这种情况。

            Dim ue = inputRange.GetEnumerator
            Dim counter as integer=0
            Dim L As New List(Of String)
            Do
                If counter>10 Then Exit Do
                If ue.MoveNext Then
                    Dim c As Range = ue.Current
                    Dim V As String = c.FormulaLocal
                    If String.IsNullOrWhiteSpace(V.Trim) Then
                        counter = counter + 1
                        Continue Do
                    End If
                    L.Add(V)
                Else
                    Exit Do
                End If
            Loop

1 个答案:

答案 0 :(得分:1)

ExcelReference获取所有值,而不是获取COM Range对象会快得多。

从参数中删除AllowReference=true(然后您将直接获取值)或从ExcelReference获取值:

object value = inputRef.GetValue();

if (value is object[,])
{ 
    object[,] valueArr = (object[,])value;
    int rows = valueArr.GetLength(0);
    int cols = valueArr.GetLength(1);
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {    
            object val = valueArr[i,j];
            // Do more here...
        }
    }
}

如果单元格为空,则您获得的对象将为ExcelEmpty类型。你可以忽略这些,你对空单元格不感兴趣。

另一种方法是使用C API获取工作表的使用范围,并将其与ExcelReference相交。一个缺点是,这需要将您的函数标记为IsMacroType=true,其中(与AllowReference=true一起)会产生使函数变得不稳定的副作用。

显示如何执行此操作的代码位于:https://gist.github.com/govert/e66c5462901405dc96aab8e77abef24c