質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

4879閲覧

ExcelVBAでオートフィルした結果のセルをタイトル行(見出し)を除いて取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/07/09 07:31

編集2019/07/09 08:01

オートフィル後のセル値をメッセージににオートフィル結果だけを出したい

はじめまして。ExcelVBAは今年の5月から始めました。
15年ほど前にプログラマーだった時期がありその時はVBやVBA専門で開発していたのですが、今はほとんど忘れてしまい、復習の意味で勉強しています。

そして、業務で多いと予想される「ExcelVBAでのオートフィル操作」について勉強しているのですが分からないところがあり、ここで相談させていただきました。

オートフィル後、結果だけを取得したいのにタイトル行も取得されてしまう

現在、Excelではこのようなデータを作っています。
イメージ説明

ここから、Aの果物で「パイナップル」「リンゴ」「みかん」をキーにフィルターをかけます。
するとこう表示されます。

イメージ説明

その後、フィルターした結果のC列から担当者名をメッセージボックスで表示させたいです。
つまり、この場合は動かすと、

ループ1回目 → 「山田」
ループ2回目 → 「直原」
ループ3回目 → 「浅井」
ループ4回目 → 「弥中」

が表示されることになります。

しかし、現状のプログラムだと、

ループ1回目 → 「担当者」
ループ2回目 → 「山田」
ループ3回目 → 「直原」
ループ4回目 → 「浅井」
ループ5回目 → 「弥中」

と表示されてしまいます。

これを、1回目は「担当者」ではなく「山下」が表示されるようにしたいです。

該当のソースコード

ExcelVBA

1 2 3Option Explicit 4 5Private Sub cmd_start_Click() 6 7Dim wbinput As Workbook 'インプットファイル格納 8Dim wbinput_Sheet As Worksheet 'インプットファイルのシート 9Dim wboutput As Workbook 'アウトプットファイル格納 10Dim wboutput_Sheet As Worksheet 'アウトプットファイルのシート 11 12Dim stroutput_FName As String 13Dim strSheetName As String 14Dim endcol As Long 'エンド列名 15 16Dim strcolor As String 17 18Dim p As Long, n As Long 'カウンタ変数 19Dim r As Range, rr As Range, rs As Range 'Visibleセルを取得する変数 20 21 22'+++++++++定義+++++++ 23 24p = 0 25n = 2 26strSheetName = "sheet1" 27 28'+++++++++++++++++++ 29 30 'アウトプットファイルのファイル名取得 31 stroutput_FName = ActiveWorkbook.Name 32 33 'アウトプットファイルのファイルパスを取得 34 Workbooks.Open ThisWorkbook.Path & "\" & stroutput_FName 35 Set wboutput = ActiveWorkbook 'アクティブなワークブック 36 37 38 'ほしいデータのあるシートをアクティブにする 39 Set wboutput_Sheet = wboutput.Worksheets(strSheetName) 40 wboutput_Sheet.Activate 41 42 43 With wboutput 44 45 'オートフィルタをセット 46 Rows("1:1").Select 47 Selection.AutoFilter 48 ActiveSheet.Range("A1").AutoFilter Field:=1, Criteria1:=Array( _ 49 "パイナップル", "みかん", "リンゴ"), Operator:=xlFilterValues 50 51 52 'オートフィルタの結果から担当者の名前をメッセージボックスで表示 53 Set r = Range("C1", Range("C" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible) 54 55 56 'r:A1~データの存在する最大行セルまでの範囲(表示されているセルのみ) 57 'rr:A1~データの存在する最大行セルまで、A1から1つずつ格納される 58 For Each rr In r 59 60 'rsへ選択セルの値を格納 61 For Each rs In rr.Areas 62 63 '選択セルの行数を取得 64 p = (rs.Row) 65 66 'メッセージボックスに担当者名出力 67 MsgBox (rr) 68 69 70 n = n + 1 71 72 Next 73 74 Next 75 76 Application.DisplayAlerts = False 77 78 .Close 79 80 Application.DisplayAlerts = True 81 82 End With 83 84End Sub 85 86

試したこと

上記ソースが私が考えて書いたロジックです。
このままだと担当者名はちゃんとMsgboxで表示されるのですが、余計な「担当者」(C1セル)もメッセージされてしまっています。

そうではなくて、タイトル行を除いたデータだけを表示させるようにするには
どうしたらよいのでしょうか?

最初は、スタート時はタイトル行を除いてC2セルから固定でスタートさせようかと思ったのですが、オートフィルなので、もしかしたらオートフィル結果の最初の行はC4かもしれないしC5かもしれないこともあるので・・・
3日間色々と調べながら考えてやっと上記のソースまで来ましたが、タイトル行を除いてというところがどうしても分からず。

本来、
SpecialCells
があればオートフィルで可視化されたセルのみが表示されると思っていたのですが、どこが違うのでしょうか?

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torisan

2019/07/09 07:51

参照先のソースでは動きませんでした。現在のソースとその結果を載せて下さい。
退会済みユーザー

退会済みユーザー

2019/07/09 08:02 編集

こちらでは問題なく動いております。 念のためもう一度貼り付けておきますね。 Option Explicit Private Sub cmd_start_Click() Dim wbinput As Workbook 'インプットファイル格納 Dim wbinput_Sheet As Worksheet 'インプットファイルのシート Dim wboutput As Workbook 'アウトプットファイル格納 Dim wboutput_Sheet As Worksheet 'アウトプットファイルのシート Dim stroutput_FName As String Dim strSheetName As String Dim endcol As Long 'エンド列名 Dim strcolor As String Dim p As Long, n As Long 'カウンタ変数 Dim r As Range, rr As Range, rs As Range 'Visibleセルを取得する変数 '+++++++++定義+++++++ p = 0 n = 2 strSheetName = "sheet1" '+++++++++++++++++++ 'アウトプットファイルのファイル名取得 stroutput_FName = ActiveWorkbook.Name 'アウトプットファイルのファイルパスを取得 Workbooks.Open ThisWorkbook.Path & "\" & stroutput_FName Set wboutput = ActiveWorkbook 'アクティブなワークブック 'ほしいデータのあるシートをアクティブにする Set wboutput_Sheet = wboutput.Worksheets(strSheetName) wboutput_Sheet.Activate With wboutput 'オートフィルタをセット Rows("1:1").Select Selection.AutoFilter ActiveSheet.Range("A1").AutoFilter Field:=1, Criteria1:=Array( _ "パイナップル", "みかん", "リンゴ"), Operator:=xlFilterValues 'オートフィルタの結果から担当者の名前をメッセージボックスで表示 Set r = Range("C1", Range("C" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible) 'r:A1~データの存在する最大行セルまでの範囲(表示されているセルのみ) 'rr:A1~データの存在する最大行セルまで、A1から1つずつ格納される For Each rr In r 'rsへ選択セルの値を格納 For Each rs In rr.Areas '選択セルの行数を取得 p = (rs.Row) 'メッセージボックスに担当者名出力 MsgBox (rr) 'メッセージボックスにセル値出力 strcolor = Range("C" & p).Interior.Color n = n + 1 Next Next Application.DisplayAlerts = False .Close Application.DisplayAlerts = True End With End Sub あと、本文の方も貼り付けておきました。 また、今こちらで動かしているExcelデータもキャプチャして貼り付けておきました。 色々と申し訳ございませんが、よろしくお願いいたします。
guest

回答2

0

ベストアンサー

質問者さんが最初に思っていた通り、C2からスタートする考え方でも問題ありません。
これで意図通りに動くはずです。

VBA

1'RangeのC1をC2に変更。 2Set r = Range("C2", Range("C" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible)

試しにオートフィルの条件をパイナップルだけにしてみてください。
7行目の弥中だけが表示されるはずです。

あと、For Eachは全件処理しますのでカウンタは不要です。
n = n + 1
という1行は削除できますし、nの宣言も不要です。
ForとFor Eachの違いを確認されると良いでしょう。

ついでに、質問者さんのコードだと他の人は実行しても動きません。
念のために、誰でも動くコードを書いておきます。

VBA

1Option Explicit 2 3Private Sub cmd_start_Click() 4 5 Dim r As Range, rr As Range, rs As Range 'Visibleセルを取得する変数 6 7 'オートフィルタをセット 8 Rows("1:1").Select 9 Selection.AutoFilter 10 ActiveSheet.Range("A1").AutoFilter Field:=1, Criteria1:=Array( _ 11 "パイナップル"), Operator:=xlFilterValues 12 13 'オートフィルタの結果から担当者の名前をメッセージボックスで表示 14 Set r = Range("C2", Range("C" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible) 15 16 'r:A1~データの存在する最大行セルまでの範囲(表示されているセルのみ) 17 'rr:A1~データの存在する最大行セルまで、A1から1つずつ格納される 18 For Each rr In r 19 'rsへ選択セルの値を格納 20 For Each rs In rr.Areas 21 MsgBox (rr) 22 Next 23 Next 24 25End Sub

投稿2019/07/09 09:13

編集2019/07/09 09:44
Secret

総合スコア220

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/11 06:48

お返事が遅くなってしまい申し訳ございませんでした。 >あと、For Eachは全件処理しますのでカウンタは不要です。 n = n + 1 という1行は削除できますし、nの宣言も不要です。 ForとFor Eachの違いを確認されると良いでしょう。 余計なコードのご指摘をありがとうございました。 そうですね、For と For Eachの違いをよく分かっていなかったことにも気づかされました。 ご丁寧にありがとうございました。
guest

0

タイトル行を除いたデータだけを表示させるようにするには

そういう場合は、いろいろやり方がありますが、
Intersect関数を使うのが便利です。

ExcelVBA

1Option Explicit 2 3Private Sub cmd_start_Click() 4 Const stroutput_FName As String = "てすと" 5 Const strSheetName As String = "Sheet1" 6 Dim wbkData As Workbook 'アウトプットファイル格納 7 Dim rngTarget As Range '抽出された担当者のセル範囲 8 Dim c As Range '各セル 9 10 'ほしいデータのあるブックを開く 11 Set wbkData = Workbooks.Open(ThisWorkbook.Path & "\" & stroutput_FName) 12 13 'シート名「Sheet1」に対しての操作 14 With wbkData.Worksheets(strSheetName) 15 '既にオートフィルターが掛かっているかチェックして 16 '掛かっていたらいったん解除 17 If .AutoFilterMode Then .AutoFilterMode = False 18 19 '指定の値でオートフィルタをセット 20 .Range("A1").AutoFilter _ 21 Field:=1, _ 22 Criteria1:=Array("パイナップル", "みかん", "リンゴ"), _ 23 Operator:=xlFilterValues 24 25 'オートフィルターが掛かっているセル範囲に対する操作 26 With .AutoFilter.Range 27 '抽出が0件なら、終了処理へ 28 If .Columns("A").SpecialCells(xlCellTypeVisible).Count = 1 Then GoTo WayOut 29 '表示されている担当者のセルを取得 30 Set rngTarget = Intersect(.Cells, .Offset(1), .Columns("C")) _ 31 .SpecialCells(xlCellTypeVisible) 32 End With 33 End With 34 35 36 'セルの値を順に表示 37 For Each c In rngTarget.Cells 38 MsgBox c.Value 39 Next 40 41WayOut: 42 wbkData.Close False 43End Sub

まだ、開発途中だとは思いますが、
無駄な変数、
無駄な空白行、
無駄なセルの選択、
文章の途中での改行、
等々非常に読みにくくないですか?

読んでみて
要点が分かり難い文章(=コード)だなぁという印象です。

投稿2019/07/09 11:02

編集2019/07/09 14:06
mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/11 06:48

お返事が遅くなってしまい申し訳ございませんでした。 そして色々とご指摘ありがとうございました。 そうですね。私ももっと他の方々のコードなどを見て勉強していきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問