• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ExcelVBA Filter関数について)

ExcelVBA Filter関数について

x0000xの回答

  • ベストアンサー
  • x0000x
  • ベストアンサー率52% (67/127)
回答No.1

ヘルプでは Filter(sourcesrray, match[, include[, compare]]) sourcearray 必ず指定します。検索先の 1 次元配列の文字列を指定します。 match 必ず指定します。検索する文字列を指定します。 include (True) の場合、配列の各要素の文字列の中で、match が含まれる配列のサブセットを返します。     (False) の場合、配列の各要素の文字列の中で、match が含まれない配列のサブセットを返します。 つまり、sourcesrrayは1次元配列です。rangeは直接利用できません。 例示頂いたコードでやりたい事が読み切れませんが、 近い処理としては以下でしょうか? Sub TEST() Dim ランゲ() As String Dim カウンターI As Long Dim 項目() As String Dim 項目数 As Integer カウンターI = 0 With Sheets("Sheet1") '1次元配列のサイズを決定 ReDim ランゲ(.Range("A1:A40").rows.Count) 'Rangeを1次元配列にコピー Dim i As Long For i = 1 To .Range("A1:A40").rows.Count ランゲ(i) = .Range("A1:A40").Cells(i, 1) Next Do カウンターI = カウンターI + 1 項目 = Filter(ランゲ, .Range("A1:A40").Cells(カウンターI, 1), False) 項目数 = UBound(項目) Debug.Print "行="; カウンターI; ",項目数="; 項目数 Loop Until 項目数 = -1 End With End Sub .Range("A1:J40")の場合は2次元配列になるので そのままでは利用できませし、sourcearray が1次元であれば、戻り値も1次元の配列になります。 ヘルプでは、 引数 sourcearray 内で引数 match に一致する文字列がなかった場合は、Filter 関数は空の配列を返します。 引数 sourcearray が Null 値であるか、1 次元配列でない場合は、エラーになります。 Range.AutoFilter を使う場合は以下 Option Explicit Option Base 1 Public Sub TestFilter() 'CellのFilterを利用する場合 Dim rng As Range Dim ランゲ() As String Dim cnt As Long Dim row As Long Set rng = ActiveSheet.Range("A1:J41") row = 1 '2行目からFilter Do row = row + 1 'A列の1行目の値から順にFilterを設定する Dim match As String match = rng.Cells(row, 1).Value rng.AutoFilter Field:=1, Criteria1:=match 'Filterの対象Cellを取得 cnt = 0 Dim i As Integer For i = 2 To rng.rows.Count If rng.rows(i).Height > 0 And _ rng.Cells(i, 1) <> Empty Then 'Filterで選択されてる場合 '空白Cellは除く cnt = cnt + 1 ReDim ランゲ(cnt) ランゲ(cnt) = rng.Cells(i, 1) End If Next '結果の確認 Debug.Print "行="; row; ",項目数="; UBound(ランゲ) Loop Until cnt = 0 End Sub 例示のコードが読み切れないのでやりたい事と相違する可能性があります。 意図しない回答であれば、スルーでお願いします。

Nouble
質問者

お礼

有り難うございます。

Nouble
質問者

補足

失礼しました、 誤記があります。 With文の直下 ランゲに値を入れているところですが、 入れる値が.VALUEになってますが間違いです。 これにともない 行頭にSET文を追加してお読みくだされば幸いです。 済みません、 あと、説明も不足ですよね 例文は目録を作る目的のものです。 で、前提として レンジ範囲の全てに 何らか、任意の文字列が入っていて、 これらは全くバラバラな訳ではない。 と、します。 (※注:カレントレギオンなどで 範囲内、空セルなしにできますね。) この時、 何種類あるかは、解らない訳ですが 少なくとも、1つデータが入っていれば それが1つ目の種類を形成するので、 読み替えると「空データがない」 と、なる前提より、 最初に読めるデータは、必ず1種類の種目に含まれる と、断定できます。 そこでこれを「第1種類目」とし、 同種のものをFilterで削除 この事により、 オブジェクトが空になってない限り 「更に種類が含まれる」 と、言うことなので、 再度行う。 と、こう言う考えで書いたものです。 幾段ものふしだらをお詫びします。

関連するQ&A

  • ExcelVBA 非連続域の扱い(01)

    お世話になります。 添付映像の、ような 非連続域の、扱いに 困って、います 下記に、記載の コードに、おいて 2回目、以降に Function 最小値域(… に、 制御が、回た 際の >フィールド.Rows.Count が、 1に、成り 困って、います。 と、言うか 抑も、 非連続域の、扱い方が 全く 解って、いません どう、取得し、 どう、扱い、 どう、指定し、 どう、渡す、 のか… 等、 なので >Evaluate("MIN(" & フィ… や、 >For Each カウンター In フィールド.Range(Cells(… 等の、 Range指定、等も 間違えて、いる と、思います 其処で、 非連続域の、扱い に、ついて どうぞ、ご指南を 宜しく、お願いします。                記 Option Base 1 Option Explicit Type ランゲポイント形式   左 As Long   右 As Long   上 As Long   下 As Long End Type Function 最小値域(ByVal フィールド As Range, ByVal 列 As Long, Optional ByVal 指標値 As Variant) As Range Dim ポイント As ランゲポイント形式, ランゲ As Range, カウンター As Range, 注目行 As Long  Let ポイント.上 = 1  Let ポイント.左 = 1  Let ポイント.下 = フィールド.Rows.Count  Let ポイント.右 = フィールド.Columns.Count  Set ランゲ = Nothing  Set カウンター = Nothing  If IsMissing(指標値) _  Then   Set 指標値 = Evaluate("MIN(" & フィールド.Range(Cells(列, ポイント.上), Cells(列, ポイント.下)).Value & ")")  End If  For Each カウンター In フィールド.Range(Cells(列, ポイント.上), Cells(列, ポイント.下))   If カウンター.Value = 指標値 _   Then    Let 注目行 = カウンター.Row    If ランゲ Is Nothing _    Then     Set ランゲ = フィールド.Range(Cells(注目行, ポイント.左), Cells(注目行, ポイント.右))    Else     Set ランゲ = Union(ランゲ, フィールド.Range(Cells(注目行, ポイント.左), Cells(注目行, ポイント.右)))    End If   End If  Next  Set 最小値域 = ランゲ End Function Sub main() Dim ダミー As Range  Set ダミー = 最小値域(最小値域(最小値域(Range("sheet2!B2:e9"), 2, "A"), 3), 4) End Sub                               以上

  • ExcelVBA マクロの数値を2ケタに変更したい

    http://www.exvba.com/blog/?p=3974 こちらの百ます計算のシートをダウンロードし活用させて頂こうと思っていますが、2ケタのものが作れるかを試してみたいと思っています。例えば26+57とか、81-32とかです。掛け算だけは、2ケタ×1ケタにしたいです。 当方プログラムが初心者でスキル不足のため、VBAがよく分かりません。以下がスクリプトのようですが、色々数値を変えてみましたがダメでした。 <--ここから--> Option Explicit '100マス計算ジェネレータ by 達人養成塾 http://www.exvba.com/ Sub main() Dim calc As Long With Application calc = .Calculation .Calculation = xlCalculationManual InputBase Range("B5"), "+", False InputBase Range("B18"), "-", True InputBase Range("B31"), "×", False .Calculation = calc ' .Calculation = xlAutomatic End With End Sub Sub InputBase(bs As Range, op As String, bType As Boolean) With bs If Not IsEmpty(bs) Then .CurrentRegion.ClearContents End If If Not IsEmpty(.Offset(, 12)) Then .Offset(, 12).CurrentRegion.ClearContents End If SetLine bs, op, True, False SetLine bs, op, False, bType .CurrentRegion.Copy Destination:=.Offset(, 12) ExeCalc bs, op End With End Sub Private Sub SetLine(base As Range, ope As String, bRow As Boolean, add10 As Boolean) '起点セル、演算子、行か列か、値に10を足すか Dim c As Long, ar(9) As Long With base .Value = ope Application.Calculate With Worksheets("rnd") .Range("A2:B12").Sort key1:=.Range("B2"), order1:=xlAscending, Header:=xlYes For c = 3 To 12 ar(c - 3) = .Range("A" & c).Value Next End With If bRow Then For c = 1 To 10 .Offset(c).Value = ar(c - 1) Next ElseIf Not add10 Then For c = 1 To 10 .Offset(, c).Value = ar(c - 1) Next Else For c = 1 To 10 .Offset(, c).Value = ar(c - 1) + 10 Next End If End With End Sub Private Sub ExeCalc(base As Range, ope As String) Dim r As Long, c As Long With base.Offset(, 12) Select Case ope Case "+" For r = 1 To 10 For c = 1 To 10 .Offset(r, c).Value = .Offset(r).Value + .Offset(, c).Value Next Next Case "-" For r = 1 To 10 For c = 1 To 10 .Offset(r, c).Value = .Offset(, c).Value - .Offset(r).Value Next Next Case Else For r = 1 To 10 For c = 1 To 10 .Offset(r, c).Value = .Offset(r).Value * .Offset(, c).Value Next Next End Select End With End Sub <--ここまで--> こちら他者様の著作物になりますので、もしこうした質問が不適切でしたら削除させて頂きます。 もしよろしければアドバイスを頂けましたら幸いに思います。

  • Excelでシート名と最終更新日を自動表示したい

    Excelを使って (1)セルA1に入れた名目をシート名にし (2)セルH1には、最終更新日を自動で入れたいです。 調べた結果、 シート名を右クリックして「コードの表示」から (1)は Private Sub Worksheet_Change(ByVal Target As Range) Sheets(1).Name = Range("B1") End Sub を入れてうまくいきましたが、 (2)は Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  If ThisWorkbook.Saved = False Then   Worksheets("Sheet1").Range("H1").Value = Date  End If End Sub を入れてみましたが(←調べましたもの) うまくいきませんでした。 単純に、 Private Sub Worksheet_Change(ByVal Target As Range) Sheets(1).Name = Range("B1") End Sub Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  If ThisWorkbook.Saved = False Then   Worksheets("Sheet1").Range("H1").Value = Date  End If End Sub とつなげて入れるのではだめなんでしょうか? それとも、(2)の何かが間違っていますか? ご教授願います。

  • ExcelVBAで行と列の検索

       A  B  C  D  E 1  コード あ  い  う  え 2  10  ○    ○ 3  20     ○  ○ 4  30          ○ 上記の表が5000件あります。Textbox1に入力し検索ボタンを押すと A列のコードを検索して一致する列の○のあるところの1行目の項目 をtextbox2に表示したいのですがうまく行きません。 よろしくお願い致します。 Private Sub CommandButton1_Click() '検索フォームボタン Dim i As Long Dim 最終行 As String Dim サーチ行 As Long Sheets(1).Activate 最終行 = Range("A1").End(xlDown).Row サーチ行 = 0 For i = 2 To 最終行 If TextBox1.Value = Range("A" & i) Then If Range("B" & i, "N" & i) = "" Then TextBox2.Text = Range("B1", "N1") サーチ行 = i Exit For End If End If Next If サーチ行 = 0 Then MsgBox TextBox1.Value & "データはありません。", vbInformation, "無し" End If TextBox1.SetFocus End Sub エラーはでません。データはありませんとなります。  

  • 【ExcelVBA】 既にあるマクロの間で実行させたいのです。

    こんにちは 下のマクロを・・・ Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Const RangeName As String = "●入力" If Not Intersect(Range(RangeName), Target) Is Nothing Then Cancel = True If Target = "●" Then Target = "" Else Target = "●" End If End If End Sub このマクロの■ここで実行■で実行させたいのですが、どのようにしたらよいでしょう。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Target.Address <> "$D$1" Then Exit Sub Cancel = True Columns("A:U").Select Range("T1").Activate Selection.Sort Key1:=Range("D2"), Order1:=xlAscending, Header:=xlYes, _ OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _ :=xlPinYin, DataOption1:=xlSortNormal Selection.Replace What:="ああ", Replacement:="", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Range("D1").Select End Sub ■ここで実行■ Private Sub Worksheet_Change(ByVal Target As Range) strAddress = "A1:A2000" On Error GoTo ErrorHandler If Target.Count > 1 Then GoTo ErrorHandler If Not Intersect(Target, Range(strAddress)) Is Nothing Then Application.EnableEvents = False Range(strAddress).ClearContents Target.Value = "●" End If ErrorHandler: Application.EnableEvents = True End Sub

  • エクセル ダブルクリックで処理日の入力

    お世話になります。 先般、お教え頂きました別のダブルクリックイベントプロシージャと 下記の当日の日付を入力するという処理を同じシート上で行いたいのですが、VBエディターにどのように記述したら良いかわかりません。 当方、かなりの初心者です。 よろしくご教授くださいませ。 【新しく加えたい処理】 Option Explicit Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("b4:C999")) Is Nothing Then Exit Sub If ActiveCell = "" Then ActiveCell = Date Cancel = True End If End Sub 【もともと使っている処理】 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Not Intersect(Target, Range("h1:h999")) Is Nothing Then With Target If .Value = "" Then .Value = "有" ElseIf .Value = "有" Then .Value = "無" ElseIf .Value = "無" Then .Value = "" End If End With ElseIf Not Intersect(Target, Range("i1:i999")) Is Nothing Then With Target If .Value = "" Then .Value = "要" ElseIf .Value = "要" Then .Value = "不要" ElseIf .Value = "不要" Then .Value = "" End If End With End If End Sub よろしくお願いします。

  • Objectで宣言するのとObject型で宣言する

    Objectで宣言するのとObject型で宣言するのではどちらがいいでしょうか? エクセルです。 VBAでコードを作るにおいて、どちらのほうがいいのでしょうか? どちらも同じ動きをします。 Sub Sample1() Dim buf As Range Set buf = Range("A1") MsgBox buf.Value End Sub Sub Sample2() Dim buf As Object Set buf = Range("A1") MsgBox buf.Value End Sub ご回答よろしくお願いします。

  • エクセルVBAのイベントで質問です。

    ダブルクリックイベントで、G12:G31の範囲の文字列をB10:B27の範囲(最下行)に入れていくものを使っていますが、新たにH12:H31にある文字列もダブルクリックするとC10:C27の範囲(最下行)に入れていけるようにしたいと思います。 どのようにすればいいでしょうか。 ご存知の方いらっしゃればお教えいただけると助かります。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, _ Cancel As Boolean) Dim i As Long Dim flg As Boolean If Intersect(Target, Range("G12:G31")) Is Nothing Then Exit Sub If IsEmpty(Target.Value) Then Exit Sub With Worksheets("シートA") For i = 10 To 27 If .Range("B" & i).Value = "" Then .Range("B" & i).Value = Target.Value flg = True Exit For End If Next i If flg = False Then MsgBox .Name & " がいっぱいです。" End If End With Cancel = True End Sub

  • ExcelVBAのFind関数について質問です。

    Find関数を使用して検索を行う際に、検索対象のシートに"ヶ月"、"ヵ月"という文字が記載されていると 処理が遅くなってしまします。 解決方法をご存知の方いらっしゃいますでしょうか? 以下、読みにくいプログラムかもしれませんが、ご教授願います。 Sub ボタン1_Click() Dim value As String Dim pass As String Dim template As Workbook Dim object As Object '検索対象文字 value = "A" 'テンプレートのパス pass = "C:\template.xls" 'テンプレートを開く Set template = Workbooks.Open(pass) 'テンプレートをコピー ActiveWorkbook.Sheets.Copy 'テンプレートを閉じる template.Close saveChanges:=False With ActiveWorkbook.ActiveSheet.Range(Cells(1, 1), Cells(10000, 256)) 'テンプレートにAという文字が存在するかのチェック Set object = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) Do '存在しない場合は処理を終了 If object Is Nothing Then End '存在する場合はA→Bに置き換える Else object = Replace(object, value, "B") End If '引き続きSheet2にAという文字が存在するかのチェック Set object = .Find(What:=value, LookAt:=xlPart, SearchOrder:=xlByRows) Loop While Not object Is Nothing End With End Sub

  • Filter関数を用いた結果、何も検索されなかった場合

    Filter関数を用いた結果、何も検索されなかった場合 以下のプログラムを実行したところ、セルはまっさらのまま。   Sub Macro3()     Dim a As Variant     a = Array(1, 2, 3, 4, 5)     ActiveCell.Value = Filter(a, 8)   End Sub そこで   If Filter(A,8) = "" Then ・・・(1)     ActiveCell.Offset(1, 0).value = False   Else表示     ActiveCell.Offset(1, 0).value = True   endif を書き加えてみましたところ、   実行時エラー'13':   型が一致しません とのエラーが出ます。 (1)を   If ActiveCell.value = "" Then と書く分には問題ないのですが、だからと言って、Filter(A,8)の値は""で表せないのですね。 とりあえずこの五行はエラーが出ているので削除しました。 次に   ActiveCell.Offset(1, 0).Value = IsEmpty(Filter(A, 8)) を書き加えると、アクティブセルの一つ下は「False」となります。Filter(A,8)では何も抽出されないのですから、空か否かを問われたら「True」のはずなのですが・・・やはり何か戻り値があるのですね・・・ ではエラー値が戻っているのかと   ActiveCell.Offset(2, 0).Value = IsError(Filter(A, 8)) を書き加えると、「False」ですからエラー値ではありません。   If Filter(A,8) = Null Then ・・・(2)     ActiveCell.Offset(3, 0).value = False   Else表示     ActiveCell.Offset(3, 0).value = True   endif を書き加えたところ、またも   実行時エラー'13':   型が一致しません とのエラーが出ます。 (2)を   If Filter(A,8) = Error Then と書き換えてみても同じです。 試しに(2)を   If Cvar(Filter(A,8)) = Null Then としてみたり   If Filter(A,8) = Cvar(Null) Then としてみたり   If Cvar(Filter(A,8)) = Cvar(Null) Then としてみたりしましたが、同じエラーが出ます。 Ubound(Filter(A,8)の値は-1です。これをもってこの場合の戻り値とするしかないのでしょうか。filter関数の戻り値が分からないからUbound関数を使っていることがモロばれで、嫌なんです。   If Filter(A,8) = なんとか Then のなんとかに入る戻り値をどなたか教えてください。