5

以下のような Excel スプレッドシートがあるとします。

col1 col2
------------
犬1匹
犬2犬
犬3犬
犬4犬
ねこ1ねこ
ねこ2ねこ
ねこ3ねこ

「犬」または「猫」に基づいて、セル範囲 (dog1,dog2,dog3,dog4) または (cat1,cat2,cat3) を返したい

ループを実行して 1 つずつチェックできることはわかっていますが、VBA に他の方法があり、結果を 1 回で「フィルタリング」できますか?

Range.Find(XXX) が役立つかもしれませんが、セルの範囲ではなく、1 つのセルの例しか表示されません。

ご意見をお聞かせください

よろしく

4

6 に答える 6

2

レコードセットを使用して範囲を返す場合の注意事項を次に示します。

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
于 2008-11-11T22:24:11.553 に答える
1

この男は素晴らしい FindAll 関数を持っています:

http://www.cpearson.com/excel/findall.aspx

于 2008-11-11T19:54:01.170 に答える
1

XL2007 のもう 1 つの機能、高度なフィルタリングを忘れていました。あなたがVBAでそれを望むなら、私は記録されたマクロからこれを得ました:

Range("A1:A1000000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:= Range("F1"), Unique:=True

私はそれを約0.35秒で計った...

確かに、2007 がなければあまり役に立ちません。

于 2008-11-11T21:15:51.380 に答える
0

非常に古いマシンを使用している場合や、大量の行を含む XL2007 ワークシートを使用している場合を除き、ループは十分に高速です。本音!

私を信用しない?これを見てください。これを使用して、100万行の範囲をランダムな文字で埋めました:

=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

私の 1 年前の Core 2 Duo T7300 (2GHz) ラップトップでは、0.58 秒かかりました。

于 2008-11-11T21:07:15.233 に答える
0

ありがとうDJ。

その FindAll ソリューションは、まだ VBA ループを使用して処理を行っています。

ユーザーレベルループを使用せずに、Excel VBA で範囲をフィルター処理する方法を見つけようとしています。

ここで解決策を見つけました。それは仕事をするためにExcel組み込みエンジンを利用します。

(1) worksheetfunction.CountIf(,"Cat") を使用して、"cat" セルの数を取得します

(2) .Find("cat") を使用して、"cat" の最初の行を取得します

行数と最初の行で、すでに「猫」の範囲を取得できます。

このソリューションの良い点は、ユーザーレベルのループがないことです。これにより、範囲が大きい場合にパフォーマンスが向上する可能性があります。

于 2008-11-11T20:10:44.503 に答える
0

Excel は ODBC プロトコルをサポートしています。Access データベースから Excel スプレッドシートに接続してクエリを実行できることは知っています。まだ行っていませんが、Excel 内から ODBC を使用してスプレッドシートにクエリを実行する方法があるかもしれません。

于 2008-11-11T20:33:03.757 に答える