优化使用大型数组的Excel公式
我使用了下面提到的excel公式优化使用大型数组的Excel公式,excel,excel-formula,excel-2010,Excel,Excel Formula,Excel 2010,我使用了下面提到的excel公式 =INDEX(TABL,SMALL(IF(COUNTIF(H2,$A$1:$A$325779)*COUNTIF(I2,"<="&$B$1:$B$325779),ROW(TABL)-MIN(ROW(TABL))+1),1),3) 这是你需要的吗 Sub subFindValue() 'Speed up Application.ScreenUpdating = False Application.DisplayStatusBa
=INDEX(TABL,SMALL(IF(COUNTIF(H2,$A$1:$A$325779)*COUNTIF(I2,"<="&$B$1:$B$325779),ROW(TABL)-MIN(ROW(TABL))+1),1),3)
这是你需要的吗
Sub subFindValue()
'Speed up
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim strNamedValue As String: strNamedValue = Range("E3")
Dim curHigherThanValue As Currency: curHigherThanValue = Range("F3")
Dim varRow As Variant
varRow = 1
Do Until IsEmpty(Cells(varRow, 1))
If Cells(varRow, 1) = strNamedValue And Cells(varRow, 2) > curHigherThanValue Then
Range("G3") = Cells(varRow, 3)
Exit Do
End If
varRow = varRow + 1
Loop
'Slow down
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
这是你需要的吗
Sub subFindValue()
'Speed up
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Dim strNamedValue As String: strNamedValue = Range("E3")
Dim curHigherThanValue As Currency: curHigherThanValue = Range("F3")
Dim varRow As Variant
varRow = 1
Do Until IsEmpty(Cells(varRow, 1))
If Cells(varRow, 1) = strNamedValue And Cells(varRow, 2) > curHigherThanValue Then
Range("G3") = Cells(varRow, 3)
Exit Do
End If
varRow = varRow + 1
Loop
'Slow down
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
如果您的数据在第1列的第2列进行排序,则SpeedTools Filter.Ifs函数将比您的公式快很多(至少快50倍)
免责声明:我是商业Excel加载项产品SpeedTools的作者
您可以从以下位置下载完整的试用版:
如果您的数据在第1列的第2列进行排序,则SpeedTools筛选器。Ifs函数将比您的公式快很多(至少快50倍)
免责声明:我是商业Excel加载项产品SpeedTools的作者
您可以从以下位置下载完整的试用版:
这应该有效,并且比任何需要循环每行的VBA解决方案快得多,只要您可以将B列中的日期按降序排序: 以数组形式输入以下公式(使用Ctrl+Shift+Enter代替Enter
=INDEX($C$1:$C$15,MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1))
你应该以这样的方式结束:
说明:
IF($A$1:$A$15=F2,$B$1:$B$15)
正在构建一个值数组,该数组等于测试字位于同一行A列的B列中的行
MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1)
这是使用从Id语句构建的数组来从测试数据中查找大于或等于查找值的最小值
=INDEX($C$1:$C$15,MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1))
一旦所有这些都在一起,“索引”将返回C列中与匹配值位于同一位置的值
更新:如果您正在查找tigeravatar的答案返回的内容,那么下面是另一个将返回所有值的VBA函数:
Sub GetValues()
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
Dim strMetalName As String: strMetalName = [E3]
Dim dbMinimumValue As Double: dbMinimumValue = [F3]
Range("G3:G" & Rows.Count).ClearContents
With Range("TABL")
.AutoFilter Field:=1, Criteria1:=strMetalName
.AutoFilter Field:=2, Criteria1:=">=" & dbMinimumValue, Operator:=xlAnd
Range("C2", [C2].End(xlDown)).Copy [G3]
.AutoFilter
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
对我来说,运行his需要5-7分钟,而这需要1.5秒,其中我的第一个答案返回包含最接近匹配结果的一行,该sub将返回大于或等于的所有值。这应该有效,并且比任何VBA解决方案快得多,只要您可以对日期进行排序,该解决方案就需要循环每行B列降序: 以数组形式输入以下公式(使用Ctrl+Shift+Enter代替Enter
=INDEX($C$1:$C$15,MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1))
你应该以这样的方式结束:
说明:
IF($A$1:$A$15=F2,$B$1:$B$15)
正在构建一个值数组,该数组等于测试字位于同一行A列的B列中的行
MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1)
这是使用从Id语句构建的数组来从测试数据中查找大于或等于查找值的最小值
=INDEX($C$1:$C$15,MATCH(G2,IF($A$1:$A$15=F2,$B$1:$B$15),-1))
一旦所有这些都在一起,“索引”将返回C列中与匹配值位于同一位置的值
更新:如果您正在查找tigeravatar的答案返回的内容,那么下面是另一个将返回所有值的VBA函数:
Sub GetValues()
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
Dim strMetalName As String: strMetalName = [E3]
Dim dbMinimumValue As Double: dbMinimumValue = [F3]
Range("G3:G" & Rows.Count).ClearContents
With Range("TABL")
.AutoFilter Field:=1, Criteria1:=strMetalName
.AutoFilter Field:=2, Criteria1:=">=" & dbMinimumValue, Operator:=xlAnd
Range("C2", [C2].End(xlDown)).Copy [G3]
.AutoFilter
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
对我来说,his运行需要5-7分钟,而这需要1.5秒,其中我的第一个答案返回包含最接近匹配结果的一行。此sub也将返回大于或等于的所有值。您可能需要调整输出的位置(假设结果应在单元格G3和下一个单元格中输出),但这应该运行得很快:
Sub subFindValue()
Dim rngFound As Range
Dim arrResults() As Variant
Dim varFind As Variant
Dim dCompare As Double
Dim ResultIndex As Long
Dim strFirst As String
varFind = Range("E3").Text
dCompare = Range("F3").Value2
Range("G3:G" & Rows.Count).ClearContents
With Range("TABL").Resize(, 1)
Set rngFound = .Find(varFind, .Cells(.Cells.Count), xlValues, xlWhole)
If Not rngFound Is Nothing Then
ReDim arrResults(1 To WorksheetFunction.CountIf(.Cells, varFind), 1 To 1)
strFirst = rngFound.Address
Do
If rngFound.Offset(, 1).Value > dCompare Then
ResultIndex = ResultIndex + 1
arrResults(ResultIndex, 1) = rngFound.Offset(, 2).Text
End If
Set rngFound = .Find(varFind, rngFound, xlValues, xlWhole)
Loop While rngFound.Address <> strFirst
End If
End With
If ResultIndex > 0 Then Range("G3").Resize(ResultIndex).Value = arrResults
End Sub
子子索引值()
暗淡的rngFound As范围
Dim arresults()作为变量
Dim varFind作为变体
将Dim数据比较为双精度
Dim ResultIndex尽可能长
Dim strFirst作为字符串
varFind=范围(“E3”)。文本
D比较=范围(“F3”)。值2
范围(“G3:G”和Rows.Count)。ClearContent
带范围(“TABL”)。调整大小(,1)
设置rngFound=.Find(varFind、.Cells(.Cells.Count)、xlValues、xlWhole)
如果不是,那么rngFound什么都不是
ReDim arrResults(1到WorksheetFunction.CountIf(.Cells,varFind),1到1)
strFirst=rngFound.Address
做
如果rngFound.Offset(,1).Value>dCompare,则
ResultIndex=ResultIndex+1
arrResults(ResultIndex,1)=rngFound.Offset(,2).Text
如果结束
设置rngFound=.Find(varFind、rngFound、xlValues、xlWhole)
在rngFound.Address strFirst时循环
如果结束
以
如果ResultIndex>0,则范围(“G3”).Resize(ResultIndex).Value=arrResults
端接头
您可能需要调整输出的位置(它假设结果应在单元格G3和向下输出),但这应该运行得非常快:
Sub subFindValue()
Dim rngFound As Range
Dim arrResults() As Variant
Dim varFind As Variant
Dim dCompare As Double
Dim ResultIndex As Long
Dim strFirst As String
varFind = Range("E3").Text
dCompare = Range("F3").Value2
Range("G3:G" & Rows.Count).ClearContents
With Range("TABL").Resize(, 1)
Set rngFound = .Find(varFind, .Cells(.Cells.Count), xlValues, xlWhole)
If Not rngFound Is Nothing Then
ReDim arrResults(1 To WorksheetFunction.CountIf(.Cells, varFind), 1 To 1)
strFirst = rngFound.Address
Do
If rngFound.Offset(, 1).Value > dCompare Then
ResultIndex = ResultIndex + 1
arrResults(ResultIndex, 1) = rngFound.Offset(, 2).Text
End If
Set rngFound = .Find(varFind, rngFound, xlValues, xlWhole)
Loop While rngFound.Address <> strFirst
End If
End With
If ResultIndex > 0 Then Range("G3").Resize(ResultIndex).Value = arrResults
End Sub
子子索引值()
暗淡的rngFound As范围
Dim arresults()作为变量
Dim varFind作为变体
将Dim数据比较为双精度
Dim ResultIndex尽可能长
Dim strFirst作为字符串
varFind=范围(“E3”)。文本
D比较=范围(“F3”)。值2
范围(“G3:G”和Rows.Count)。ClearContent
带范围(“TABL”)。调整大小(,1)
设置rngFound=.Find(varFind、.Cells(.Cells.Count)、xlValues、xlWhole)
如果不是,那么rngFound什么都不是
ReDim arrResults(1到WorksheetFunction.CountIf(.Cells,varFind),1到1)
strFirst=rngFound.Address
做
如果rngFound.Offset(,1).Value>dCompare,则
ResultIndex=ResultIndex+1
arrResults(ResultIndex,1)=rngFound.Offset(,2).Text
如果结束
设置rngFound=.Find(varFind、rngFound、xlValues、xlWhole)
在rngFound.Address strFirst时循环
如果结束
以
如果ResultIndex>0,则范围(“G3”).Resize(ResultIndex).Value=arrResults
端接头
计算公式,然后将结果粘贴到单元格中?您考虑过吗?当计算公式后出现值时,复制粘贴。问题是在任何情况下,每个单元格的公式计算都需要48小时以上(每个单元格更新至少需要1秒)因此,在上面粘贴的图像中,只有一个测试数据(金,2.5),在实际中有400000个这样的记录要从300000个查找表中搜索出来。考虑VBA解决方案而不是数组函数,或者任何内置函数。