如何在不使用循环的情况下返回VBA中的单元格范围?

如何在不使用循环的情况下返回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会有所帮助,但我只看到一个单元格的

假设我有一个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并首先将范围值转换为数组,然后再进行循环,则可以获得巨大的性能提升。即使你以后必须转换回去。