如何在不使用循环的情况下返回VBA中的单元格范围?
假设我有一个excel电子表格,如下所示: col1 col2 ------------ dog1 dog dog2 dog dog3 dog dog4 dog cat1 cat cat2 cat cat3 cat 我想返回一系列单元格dog1、dog2、dog3、dog4或基于dog或cat的cat1、cat2、cat3 我知道我可以做一个循环来逐个检查,但是VBA中是否有其他方法可以一次过滤结果 也许Range.FindXXX会有所帮助,但我只看到一个单元格的示例,而不是一系列单元格的示例 请指教如何在不使用循环的情况下返回VBA中的单元格范围?,vba,excel,range,Vba,Excel,Range,假设我有一个excel电子表格,如下所示: col1 col2 ------------ dog1 dog dog2 dog dog3 dog dog4 dog cat1 cat cat2 cat cat3 cat 我想返回一系列单元格dog1、dog2、dog3、dog4或基于dog或cat的cat1、cat2、cat3 我知道我可以做一个循环来逐个检查,但是VBA中是否有其他方法可以一次过滤结果 也许Range.FindXXX会有所帮助,但我只看到一个单元格的
这家伙有很好的FindAll功能: 谢谢,DJ FindAll解决方案仍然使用VBA循环来做事情 我试图找到一种方法,不使用用户级循环来过滤excel VBA中的范围 在这里我找到了一个解决办法。它利用excel内置的引擎来完成这项工作 1使用 worksheetfunction.CountIf,Cat获取Cat单元格的计数 2.使用.Findcat获取cat的第一行 有了行数和第一行,我就可以得到猫的范围了
此解决方案的优点在于:没有用户级循环,如果范围较大,这可能会提高性能。Excel支持ODBC协议。我知道您可以从Access数据库连接到Excel电子表格并进行查询。我还没有这样做,但也许有一种方法可以从Excel内部使用ODBC查询电子表格。除非您使用的是一台非常旧的机器,或者您有一个包含大量行的XL2007工作表,否则循环将足够快。老实说 不要相信我?看看这个。我使用以下方法用随机字母填充了一百万行范围:
=CHAR(RANDBETWEEN(65,90))
然后我编写了这个函数,并使用Control Shift Enter从26个单元格范围调用它:
=TRANSPOSE(UniqueChars(A1:A1000000))
以下是我在几分钟内破解的不是很优化的VBA函数:
Option Explicit
Public Function UniqueChars(rng As Range)
Dim dict As New Dictionary
Dim vals
Dim row As Long
Dim started As Single
started = Timer
vals = rng.Value2
For row = LBound(vals, 1) To UBound(vals, 1)
If dict.Exists(vals(row, 1)) Then
Else
dict.Add vals(row, 1), vals(row, 1)
End If
Next
UniqueChars = dict.Items
Debug.Print Timer - started
End Function
在我一岁的Core 2 Duo T7300 2GHz笔记本电脑上,花了0.58秒。忘记了XL2007的另一项功能:高级过滤。如果您想在VBA中使用它,我可以从录制的宏中获得:
Range("A1:A1000000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:= Range("F1"), Unique:=True
我在0.35秒左右计时
诚然,如果没有2007,就没有多大用处。这里有一些关于使用记录集返回范围的注释
Sub GetRange()
Dim cn As Object
Dim rs As Object
Dim strcn, strFile, strPos1, strPos2
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strFile = ActiveWorkbook.FullName
strcn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& strFile & ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"
cn.Open strcn
rs.Open "SELECT * FROM [Sheet1$]", cn, 3 'adOpenStatic'
rs.Find "Col2='cat'"
strPos1 = rs.AbsolutePosition + 1
rs.MoveLast
If Trim(rs!Col2 & "") <> "cat" Then
rs.Find "Col2='cat'", , -1 'adSearchBackward'
strPos2 = rs.AbsolutePosition + 1
Else
strPos2 = rs.AbsolutePosition + 1
End If
Range("A" & strPos1, "B" & strPos2).Select
End Sub
您发布的示例看起来很奇怪,请将其更改为可读。这不是空格键问题。他使用了一个奇怪的字符集或其他东西。它只出现在他的一些文本中?这很奇怪,但是当你试图删除额外的空格时,它也会删除字符。你可以玩他的一个旧版本,自己看看。我如何制作html表格?它在预览中有效,但在最终结果中无效?我希望它看起来像一个电子表格。我还发现在大范围内循环的性能可能非常慢。但是,如果您使用VBA并首先将范围值转换为数组,然后再进行循环,则可以获得巨大的性能提升。即使你以后必须转换回去。