识别VBA UDF的两个颈部
在我的工作表中,我有四个不同的类别。对于每个类别,都有 3~5种不同的价格。还有其他属性。因此,每个类别重复了多次,总共有30000行。工作表的第一行包含所有列名。每个类别跨越连续的行。因此,我编写了以下函数来识别“块”并计算“块”的最小值识别VBA UDF的两个颈部,vba,excel,performance,runtime,Vba,Excel,Performance,Runtime,在我的工作表中,我有四个不同的类别。对于每个类别,都有 3~5种不同的价格。还有其他属性。因此,每个类别重复了多次,总共有30000行。工作表的第一行包含所有列名。每个类别跨越连续的行。因此,我编写了以下函数来识别“块”并计算“块”的最小值 Public Function blockMin(rng_temp作为范围)作为整数 暗咖喱和长咖喱一样 currRow=rng_临时行 '查找类别列 变暗rng As范围 昏暗的小屋和长的一样 暗淡的价格 对于范围内的每个rng(“1:1”) 如果rng
Public Function blockMin(rng_temp作为范围)作为整数
暗咖喱和长咖喱一样
currRow=rng_临时行
'查找类别列
变暗rng As范围
昏暗的小屋和长的一样
暗淡的价格
对于范围内的每个rng(“1:1”)
如果rng.Value=“Cat”,则
类别列=rng.列
如果结束
如果rng.Value=“价格”,则
pric_col=标记列
如果结束
下一个rng
Dim cat_col_char,price_col作为字符串
cat\u col\u char=数字2个字母(cat\u col)
price\u col\u char=number2字母(price\u col)
'查找usedRange的最后一行
最后一排一样长
lastRow=findLastRow()
'每个猫的挡块在哪里
暗淡的起点,终点和长的一样
startRow=rng_温度行
endRow=rng_临时行
“找到顶端
开始时执行此操作>=2
如果范围(cat\u col\u char和startRow)。值范围(cat\u col\u char和currRow),则
startRow=startRow+1
退出Do
如果结束
startRow=startRow-1
环
如果startRow=1,则startRow=2'位于最顶部
"找底"
在endRow时执行类似操作会快一点:
Public Function blockMin(rng_temp As Range) As Integer 'double?
Dim sht As Worksheet, rS As Long, rE As Long, cat, v
Dim hdrs, i As Long
Dim cat_col As Long, price_col As Long
Set sht = rng_temp.Worksheet '<<< scope all references to this sheet
' or you'll get odd results when a different
' sheet is active
rS = rng_temp.Row
rE = rS
'Find headers
hdrs = sht.Range("A1").Resize(1, 100).Value 'limit your search range
For i = 1 To UBound(hdrs, 2)
v = hdrs(1, i)
If cat_col = 0 And v = "Cat" Then cat_col = i
If price_col = 0 And v = "Price" Then price_col = i
If cat_col > 0 And price_col > 0 Then
cat = rng_temp.EntireRow.Cells(cat_col).Value
If Len(cat) > 0 Then
'find start/end rows
Do While rS > 1 And sht.Cells(rS, cat_col) = cat
rS = rS - 1
Loop
Do While sht.Cells(rE, cat_col) = cat
rE = rE + 1
Loop
blockMin = Application.Min(sht.Range(sht.Cells(rS + 1, price_col), _
sht.Cells(rE - 1, price_col)))
End If
Exit For
End If
Next i
End Function
Public Function blockMin(rng_temp作为范围)作为整数“double”?
尺寸sht为工作表,rS为长,rE为长,cat为v
暗淡的HDR,我想
暗淡的颜色和颜色一样长,价格和颜色一样长
设置sht=rng_临时工作表'1和sht.单元格(rS、cat_col)=cat
rS=rS-1
环
当短单元格(rE、cat_col)=cat
rE=rE+1
环
blockMin=Application.Min(短范围(短单元格(rS+1,价格列))_
单格(rE-1,价格)
如果结束
退出
如果结束
接下来我
端函数
可能值得将Option Explicit
放在模块顶部,修复未声明/键入的变量,然后重新发布代码。对于范围内的每个rng(“1:1”)
-您正在检查约16000个单元格(两次)对于每个调用-当cat\u col
和price\u col
都大于0时,您应该退出循环。我想如果您将其转换为Sub,而不是将其用作UDF,则速度会快得多-每个调用都有大量重复。从简单的一瞥中,您对代码的描述并不是100%清楚实现(我仍然无法想象一个块是什么),通过在数据中使用透视表,您可能会受益。该块在问题主体中显示为链接。很抱歉,我刚开始使用这个帐户,所以我没有被授权发布图片,但只有URL…除了随机命名的变量之外,rS
和rE
是什么?不是随机的,只是简短:“rowStart”,“rowEnd”好的-那么为什么这么短而不是描述性的名称?因为这是我编写代码时喜欢的?它不是那么难以理解。谢谢你的评论!有没有办法让我克服这个循环部分?我想这就是瓶颈。
Public Function blockMin(rng_temp As Range) As Integer 'double?
Dim sht As Worksheet, rS As Long, rE As Long, cat, v
Dim hdrs, i As Long
Dim cat_col As Long, price_col As Long
Set sht = rng_temp.Worksheet '<<< scope all references to this sheet
' or you'll get odd results when a different
' sheet is active
rS = rng_temp.Row
rE = rS
'Find headers
hdrs = sht.Range("A1").Resize(1, 100).Value 'limit your search range
For i = 1 To UBound(hdrs, 2)
v = hdrs(1, i)
If cat_col = 0 And v = "Cat" Then cat_col = i
If price_col = 0 And v = "Price" Then price_col = i
If cat_col > 0 And price_col > 0 Then
cat = rng_temp.EntireRow.Cells(cat_col).Value
If Len(cat) > 0 Then
'find start/end rows
Do While rS > 1 And sht.Cells(rS, cat_col) = cat
rS = rS - 1
Loop
Do While sht.Cells(rE, cat_col) = cat
rE = rE + 1
Loop
blockMin = Application.Min(sht.Range(sht.Cells(rS + 1, price_col), _
sht.Cells(rE - 1, price_col)))
End If
Exit For
End If
Next i
End Function