我使用VBA将以下INDEX MATCH公式插入到一组单元格中。
cell2.FormulaArray = _
"=INDEX('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!AK:AK, _
MATCH(1,('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$A:$A = A " & value & ")* _
('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$B:$B=""Total""),0))*1000"
当它运行时,我遇到错误1004 - “无法设置Range类的FormulaArray属性”
我很确定它与引用当前工作簿之间有关,因为它在同一工作簿中的INDEX MATCH时工作正常。
公式的浓缩版本(为了清晰起见)如下 -
=INDEX(Sheet2!AK:AK, MATCH(1,(Sheet2!A:A = A5)*(Sheet2!B:B="Total"),0))
然后在vba -
cell2.FormulaArray = "=INDEX(Sheet2!C:C, MATCH(1,(Sheet2!A:A = A5)*(Sheet2!B:B=""Total""),0))"
答案 0 :(得分:2)
如何使用VBA输入超过255个字符的FormulaArray
在这种情况下,似乎有一个符合原始FormulaArray
要求的备用标准公式。但是,可能存在没有替代公式的情况。
对于这些情况,我使用以下方法使用VBA 输入超过255个字符的FormulaArray
。
大多数情况下,FormulaArray
长度超过255个字符是由于它包含的references
的长度,因为它们可能与长常量数组有关,外部工作簿的名称大于(就像在这种情况下)或具有大名称(在这种情况下也是)的工作表。该方法包括用较短的字符串替换这些长字符串,但是为了使FormulaArray
(替换后)被接受为FormulaArray
,这些较短的字符串也需要表示有效references
。
根据上述情况,至少有三种情况可能有references
长
Defined Names
Workbooks
名称较大且Worksheets
名字很大对于案例2和3,同样适用的方法:使用短references
指向临时 Worksheet
作为临时替代。
将此方法应用于此案例:
原始 FormulaArray
:使用变量sFmlArray
来保存公式
Dim sFmlArray As String
sFmlArray = "=INDEX('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!AK:AK," & _
"MATCH(1,('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$A:$A = A" & bVal & ") * " & _
"('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$B:$B=""Total""),0)) * 1000"
我建议使用变量来保存工作簿和工作表的名称,以避免多次写入。
Dim sFmlRng as string
sFmlRng = "'[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!"
将FormulaArray
中的工作簿和工作表的名称替换为相应的变量:
sFmlAry = "=INDEX(" & sFmlRng & "AK:AK," & _
"MATCH(1,(" & sFmlRng & "$A:$A = A" & bVal & ") * " & _
"(" & sFmlRng & "$B:$B=""Total""),0)) * 1000"
假设我们想要在FormulaArray
范围内输入这个长D7:D10
,让我们将其分配给变量
Dim rFmlAry as Range
Set rFmlAry = ActiveSheet.Range("D7:D10")
使用以下功能添加临时工作表。此功能还提供临时 reference
作为FormulaArray
Function WshTmp_Add(rFmlAry As Range, sFmlRngTmp As String) As Worksheet
sFmlRngTmp = "@Tmp"
With rFmlAry.Worksheet.Parent
On Error Resume Next
.Worksheets(sFmlRngTmp).Delete
On Error GoTo 0
Set WshTmp_Add = .Worksheets.Add(Before:=.Worksheets(1))
End With
WshTmp_Add.Name = sFmlRngTmp
WshTmp_Add.Tab.Color = 255
sFmlRngTmp = "'" & sFmlRngTmp & "'!"
Application.Goto rFmlAry
End Function
在FormulaArray
中将长引用替换为较短引用,并在FormulaArray
范围内输入临时 rFmlAry
sFmlAryTmp = WorksheetFunction.Substitute(sFmlAry, sFmlRng, sFmlRngTmp)
rFmlAry.FormulaArray = sFmlAryTmp
在FormulaArray
到位的情况下,将临时短references
替换为原来的长
rFmlAry.Replace What:=sFmlRngTmp, Replacement:=sFmlRng, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
最后删除 temporary Worksheet
这是整个过程(作为测试,在最后添加几行以验证结果)
Sub FormulaArray_Over255Chr()
Dim rFmlAry As Range, sFmlAry As String, bVal As Byte
Dim WshTmp As Worksheet, sFmlAryTmp As String
Dim sFmlRng As String, sFmlRngTmp As String
Dim blAppDisplayAlerts As Boolean
blAppDisplayAlerts = Application.DisplayAlerts
Rem Set Ranges & Values
bVal = 5
Set rFmlAry = ActiveSheet.Range("D2:D5")
Rem Define External Reference Variable
sFmlRng = "'[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!"
Rem Define FormulaArray (Original) - with References as Variables
sFmlAry = "=INDEX(" & sFmlRng & "AK:AK," & _
"MATCH(1,(" & sFmlRng & "$A:$A = A" & bVal & ") * " & _
"(" & sFmlRng & "$B:$B=""Total""),0)) * 1000"
Rem Set Range to Enter FormulaArray
Set rFmlAry = ActiveSheet.Range("D7:D10")
Rem Add Temporary Worksheet
Application.DisplayAlerts = False
Set WshTmp = WshTmp_Add(rFmlAry, sFmlRngTmp)
Rem Set Temporary FormulaArray - Replace long references
sFmlAryTmp = WorksheetFunction.Substitute(sFmlAry, sFmlRng, sFmlRngTmp)
Rem Enter Temporary FormulaArray
rFmlAry.FormulaArray = sFmlAryTmp
Rem Set FormulaArray (Original) - Replace short references in situ
rFmlAry.Replace What:=sFmlRngTmp, Replacement:=sFmlRng, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Rem Delete Temporary Worksheet
WshTmp.Delete
Application.DisplayAlerts = blAppDisplayAlerts
' ****************************************************************
' Lines for TESTING - Resulting FormulaArray - REMOVED when final
' ****************************************************************
Rem Validate FormulaArray
Debug.Print String(3, vbLf)
Debug.Print "FormulaArray in Range: "
Debug.Print rFmlAry.Cells(1).FormulaArray
Debug.Print "FormulaArray VBA: "
Debug.Print sFmlAry
If rFmlAry.Cells(1).FormulaArray = sFmlAry Then
MsgBox "FormulaArray with +255 entered successfully" & vbLf & _
vbLf & rFmlAry.Cells(1).FormulaArray
Else
MsgBox "Something did not worked!" & vbLf & _
vbLf & "Review formulas printed in the Immediate Window"
SendKeys "^g": Stop
End If
' ****************************************************************
End Sub
答案 1 :(得分:1)
根据我的评论,这取决于您可以在FormulaArray
的VBA中使用的公式长度的限制。在这里,您可以简单地使用非数组版本:
cell2.Formula = _
"=LOOKUP(2,1/('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$A:$A=A" & Value & _
")*('[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!$B:$B=""Total"")," & _
"'[08 Debt Comparison & Provision Report.xlsx]Details by Bus Area & Location'!AK:AK)*1000"
虽然这会返回最后一个匹配项而不是第一个匹配项,但是如果您有多个符合条件的行。