• ベストアンサー

Excel VBA: カーソルのある行と同じデータを持つ行群にマーク?

お世話になります。 以前、現在選択されているセルを含む行の特定の列にマークを打つという問題がありまして、こちらで回答をいただきました。 http://okwave.jp/qa4787458.html さて、似た問題でまた詰まってしまいました。 「現在カーソルがある行の、ある列の値と、同じ列の値が同じ行のみ、別の列にマークを打つ」というものです。 5行5列のシートがあり、2列目が注目しているデータだとします。 マークは5列目に打ちたいです。 カーソル(アクティブセル)を▽であらわします。 (例題1) \ABCDE 1□□米□□ 2□□国□□ 3▽□国□□ 4□□国□□ 5□□米□□ いま、A3がアクティブセルです。 C2、C3、C5に「国」というデータがあります。 C列の他の行には違うデータ(「米」)があります。 カーソルのある3行目のC列の「国」に注目し、同じC列に「国」が入っている3つの行のE列にマーク(*)を打ちます。 処理後はこうしたいです。 \ABCDE 1□□米□□ 2□□国□* 3▽□国□* 4□□国□* 5□□米□□ 以下、処理前、処理後でやりたい処理を示します。 (例題2) \ABCDE 1□□国▽□ 2□□英□□ 3□□国□□ 4□□米□□ 5□□国□□ => \ABCDE 1□□国▽* 2□□英□□ 3□□国□* 4□□米□□ 5□□国□* (例題3) \ABCDE 1□□英□□ 2□□国□□ 3□□米□□ 4□□国□□ 5□□国▽□ => \ABCDE 1□□英□□ 2□□国□* 3□□米□□ 4□□国□* 5□□国▽* 実際にはシートはもっと大きく、注目する列がC以外に2列あるパターンもあるのですが、さしあたり上の例について解決したいと思います。 最初は例によって1行1行見ていました。 Sub test() Dim myRow as long Dim myCol as long For myRow = 1 to 65536 For myCol = 1 to 3 If Cells(myRow, myCol).Value = "国" Then Cells(myRow, 5).Value = "*" Exit For End If Next myCol Next myRow End Sub しかしこれだとシートが広いので遅くなります。 あるキーを押すと処理が走って、処理中はずっとオペレーターが待っているというフローなので、一瞬でも早くしたいところです。 次に、オートフィルターを使って3列目に「国」がある行を表示にし、上の回答で教えていただいた Intersect 関数を使ってうまくいったのですが、処理前にすでにオペレーターがフィルター設定している場合があり、そのフィルター設定が壊れると作業に支障があるのであきらめました。 処理前のオートフィルターを記憶して、処理後に復元するというのもやってみたのですが、プログラムが複雑になるので避けたい感じです。 なお、Excel 2007 と書きましたが、オペレーターによっては Excel 2003 を使い続けている人がいることが最近判明しました。 今は Excel 2003 形式の XLS にマクロをアタッチして XLSTART に入れさせています。 FileSearch のような 2007 で廃止された機能を使わない限り、2003 のマクロは 2007 で動くようです。 以上です。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.2

#1です。 オートフィルタが楽そうですが、提示されているコードで気になったのが、 ・最終行(65536)まで確認が必要か ・A~C列のうち1個でも”国”があればいいのでは と言う点で作成したコードです。 Sub try() Dim r As Range Dim rr As Range Set r = ActiveSheet.UsedRange For Each rr In Range("A1", Range("A" & r.Item(r.Cells.Count).Row)) If Application.CountIf(rr.Resize(, 3), "国") > 0 Then rr.Offset(, 4).Value = "*" End If Next Set r = Nothing End Sub どうでしょうか?

TYWalker
質問者

お礼

ありがとうございます! 緊急対応が入ってしまったので、すぐに試せませんが、必ずお返事します。 私の目的では、 >・最終行(65536)まで確認が必要か は、上記のコードのように使っている範囲で大丈夫です。 (実際には見出しを飛ばして2行目から) >・A~C列のうち1個でも”国”があればいいのでは は、「国」が出てくるのはC列に決まっています。 ただし、別の条件(D列が「kg」とか)が場合によって発生する可能性があります。 いただいたコードをよく研究します。 本当にありがとうございます!

TYWalker
質問者

補足

お世話になります。 いただいたコードを元に作成できました。 あまり速度が落ちず、満足しています。 今後も何かありましたらお願いします。

その他の回答 (3)

  • hige_082
  • ベストアンサー率50% (379/747)
回答No.4

質問をコードにすると、こうなると思うのですが? Sub test() Dim myRow As Long Dim key As Variant Dim cCol As Variant key = Cells(ActiveCell.Row, 3).Value cCol = Range("c1", Cells(65536, 3).End(xlUp).Offset(0, 2)) For myRow = 1 To UBound(cCol, 1) If cCol(myRow, 1) = key Then cCol(myRow, 3) = "*" End If Next myRow Range("c1", Cells(65536, 3).End(xlUp).Offset(0, 2)) = cCol End Sub 参考までに

TYWalker
質問者

お礼

繰り返しになりますが、今回ご相談の方法があまりよくなくて、いろいろひねくっているうちに、結果的にhige_082さんのようなコードになりました (^^;;; 本当にありがとうございます。 今後もよろしくお願いします。

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.3

#ちょっと変わった方法をお一つ。。。 >現在カーソルがある行の、ある列の値と、 >同じ列の値が同じ行のみ、別の列にマークを打つ とのことで、例示されているVBAでは、「国」をキーワードにしていらっしゃいますが、実際は Cells(myRow, myCOl).Value = Cells(ActiveCell.Row, myCOl) ですよね。 シートモジュールに Private Sub Worksheet_SelectionChange(ByVal Target As Range)  ActiveWorkbook.Names.Add Name:="AC", RefersToR1C1:="=ACTIVE.CELL()"  Range("E2:E" & Range("A1").End(xlDown).Row).FormulaR1C1 _  = "=IF(RC[-2]=INDIRECT(""C"" & ROW(AC)),""*"","""")" End Sub でいかがでしょうか? >シートが広いので遅くなります。  10000行ほどデータを入れて確認してみましたが、私の低スペックのパソコンでも、一瞬で処理できました。

TYWalker
質問者

お礼

ありがとうございます。 このようなページでプログラムの相談をする場合は、業務の守秘義務もありますし、大量のコードを読ませて回答を下さる方を煩わせるわけにもいきませんので、状況を単純化させるわけですが、今回は単純化の仕方があまりよくなかったようです。 具体的に言うと、最初に書いた問題とコードが合っていませんでした。 シートモジュールにイベントを書く、というのは面白い方法ですね。 書いていないことがあって、この方法は今回適用しませんが、覚えておいていつか使おうと思います。 本当にありがとうございました。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

>処理前にすでにオペレーターがフィルター設定している場合があり、 >そのフィルター設定が壊れると作業に支障があるのであきらめました。 まず今回の処理と上記の処理について、連動させないような配慮をするか、 重複してオートフィルタを使用しなくて済む処理手順にするかの、作業の見直しを 行なってから考えた方が宜しいのではないかと感じました。

TYWalker
質問者

お礼

ご回答ありがとうございます! つまり、私が質問した処理を行うためには、マクロでオートフィルターを使って Intersect という現状の仕様がよいというお考えでしょうか。 フィルター処理とマーク処理はまったく任意のタイミングで発生し、ユーザーを制約するのは非常に難しいケースです。。。

関連するQ&A

  • Excel VBA 2007: 選択されているセルを含む行を処理?

    いつもお世話になります。 以下の問題について何かわかりましたらご教示ください。 複数のセルが選択されているとします。 選択されているセルを■、されていないセルを□とします。 問題は「選択されているセルを含む行のE列にマークをしろ」です。 (例題1) \ABCDE 1□□□□□ 2□□■□□ 3□□■□□ 4□□■□□ 5□□□□□ 今、C2、C3、C4が選択されています。 影響のある行は2,3,4行目ですので、以下のようになります。 (マークを*で示します) \ABCDE 1□□□□□ 2□□■□* 3□□■□* 4□□■□* 5□□□□□ 以下、前と後で例題を示します。 (例題2) \ABCDE 1□□□□□ 2■■□□□ 3□□□□□ 4□□□□□ 5□□□□□ => \ABCDE 1□□□□□ 2■■□□* 3□□□□□ 4□□□□□ 5□□□□□ (例題3) \ABCDE 1□□□□□ 2□□□□□ 3□□□□□ 4□□□■□ 5□□■■□ => \ABCDE 1□□□□□ 2□□□□□ 3□□□□□ 4□□□■* 5□□■■* (例題4) \ABCDE 1■□□□□ 2□■□□□ 3□□□□□ 4□□□■□ 5□□□□□ => \ABCDE 1■□□□* 2□■□□* 3□□□□□ 4□□□■* 5□□□□□ 以下のようにやればわかっているんですが、この場合は縦方向だけでなく横方向にも処理するので、同じ行について何回も処理が発生してしまいます。 実際には縦にも横にもすごく広いので、避けたいところです。 Sub test() Dim cell As Range For Each cell In Selection Cells(cell.row, 5).Value = "*" Next cell End Sub 以下のようにすれば必ず縦方向優先ですが、同じ理由で避けたいです。 Sub test() Dim myRow as long Dim myCol as long For myRow = 1 to 65536 For myCol = 1 to 4 If Cells(myRow, myCol).Selected Then Cells(myRow, 5).Value = "*" Exit For End If Next myCol Next myRow End Sub もっといい方法があればご教示ください。 よろしくお願いします!

  • エクセル2007での質問です。A~I列にデータが入っています(1行には

    エクセル2007での質問です。A~I列にデータが入っています(1行には見出し、よって2行目からデータが入っています)。C列には名前(色々なデータが入っているので、C列には同じ名前人の名前が何行か入っています)。G列には、10~25の数字が入っています。 1行目にフィルタをかけます。C列で、Aさんの名前でフィルタをかけます(C列は、人によって行数が違います)。こしてフィルタをかけるた時に、G列の10~25あるうちの 13のみの合計を(これも13は、何行かあります)。 このAさんのみフィルタかけ、そのG行のうちの13の合計額を、A1000に出したいのですが、どうしたらいいですか?(A1000に出したいってことは、999までデータが入っています)。 どう関数を入れたらいいか教えてください。

  • エクセル 複数行にまたがっているデーターを一つの行にまとめたい

          A列  B列   C列 1行目  佐藤 北海道 りんご 2行目  佐藤 北海道 ばなな   3行目 伊藤  東京  いちご 4行目  伊藤  東京  ばなな  上記のようなデーターがあります。これを2行目と4行目を削除し下記のようにしたいのですが       A列  B列      C列 1行目  佐藤 北海道  りんごばなな 2行目  伊藤  東京   いちごばなな A列とB列のデーターが同じでC列のデータが異なる場合、上記のように一行にまとめたいのです。関数やVBAで上記の処理を出来る方法がありますでしょうか。 

  • Excel VBAでデータを自動処理したい

    Excelで大量のデータ処理をしなくてはならないのですが、以下の処理をExcel VBAで自動処理できないでしょうか? どなたかお知恵をお貸しください。 (1)A、B、C列からなるリストがあります。A,B列にはそれぞれオートフィルタが設定してあり、C列は空白です。A列、B列にそれぞれ条件を設定し、抽出したデータのC列(空白)に特定のデータを入力します。A列、B列2つの条件の組み合わせが100通りくらいあり、現在手動でオートフィルタを設定し、C列にデータを入力しております。例えばA,B列の条件の組み合わせと、それに対応するC列に入力するデータを表にしたテーブルを別に作り、A,B列の条件を自動に設定して、抽出し、C列にデータを自動に入力することを、テーブルの一番上の行から最後の行まで繰り返す、というようなことをVBAでExcelにしてもらいたいのです。自分でちゃんと勉強し、調べて、それでも分からなかったらお聞きするというのが筋だと思うのですが、今この仕事に追われて、時間がありません。(ほとんど毎日午前様です。)この仕事が片付いたら、じっくりVBAを勉強したいと思っております。どうぞよろしくお願いいたします。

  • エクセル 複数行にまたがっているデーターを一つの行

    以前に似たようなVBAの質問を元にさらにやりたいVBAがあるのですが、 (前の質問者のURL:http://okwave.jp/qa/q4955096.html)       A列  B列   C列   D列   E列 ~ R列 1行目  佐藤 北海道 りんご S 100 105 2行目  佐藤 北海道 ばなな M 100 105   3行目 伊藤  東京  いちご S 100 105 4行目  伊藤  東京  ばなな M 100 105 上記のようなデーターがあります。これを2行目と4行目を削除し下記のようにしたいのですが       A列  B列      C列      C列 1行目  佐藤 北海道  りんご,ばなな  S,M 2行目  伊藤  東京   いちご,ばなな  S,M A列とB列とE列~R列のデーターが同じでC列,D列,のデータが異なる場合、上記のように一行にまとめたいのです。関数やVBAで上記の処理を出来る方法がありますでしょうか。 

  • エクセルVBAでデータを並べる

    お願いいたします。 今 B列C列 E列F列 H列I列・・・以下略 B,C列の数値群の塊を一個と数えこの個数をm個とします。 行数は n個とします。 B列C列の最後尾にE列F列の数値群を移動させ(B,C列が縦に長く なります) さらに H列I列の数値群をそのあとに続けます。 これをm個分繰り返す処理コードをご教示ください。 なお、どの列においても、最初の数値は6行目から始まります。 したがって各列の最後部は6+n個です。B列とC列だけつながれる 分どんどん長くなります。 簡単なコードと思いましたが、この処理だけで一日かかって 解決できません。どなたか、コード例をご教示お願いします。

  • エクセルの横からのデータ抽出

    エクセルの データ → フィルター → オートフィルター を使用すると、行の一番先頭に▽マークが出てきて、列データの抽出をすることができますが、逆は可能なのでしょうか? すなわち、列の一番左部分に右横向き▽マークが出て、行のデータ抽出を行うということは、可能なのでしょうか?

  • VBAか関数 「 2と3の組合せ 」 の行が、いくつあるか?

    VBAか関数 「 2と3の組合せ 」 の行が、いくつあるか? Windows XP Home Edition SP3 Office XP Personal 2002 Excel 2002 画像の 「 C列 D列 E列 」 の 「 3列 」 だけを使った質問でございます。 数値は 2桁の整数 までしかありません。 6行目の「 C列 D列 E列 」以外で、オートフィルタをかけた後ですが、空白行もたまにございます。 オートフィルタをかけた後ですので、データのある最後行以下は全部空白です。   実際には、セルには色分けはされておりません。 ---質問のまとめ-------------------------------------- ● 「 2 と 3 の組合せ 」(画像の黄色セル) の行が、いくつあるか? を算出できる、関数 か マクロは、ありますでしょうか? 質問の例では、答えは 「 3行 」 となります。 存在しない場合には、「 0行 」 となります。 ----------------------------------------------------- また、 「 1 と 3 の組合せ 」 の行が、いくつあるか? 「 * と * の組合せ 」 の行が、いくつあるか? などのように、いろいろと算出できればと思っております。 非常にややこしい質問で、恐れ入ります。 今までは、手作業で、6行目にオートフィルタをかけて行っておりました。 何卒、ご教示のほどをお願い致します。 

  • エクセルVBA 不規則な条件に合致する場合

    エクセル2002 VBA での質問です。 A列に100~9999の数値データが不規則に存在しており、 105 108 113 114 121 531 553 2160 ・・・・・ のような不規則な値と合致するときに B列の処理をしたい場合のコードはどのように記述しますか? 私は for MyRow=1 to (最終行) if (cells(MyRow,1) =105 or cells(MyRow,1) =108 or cells(MyRow,1) =113 ・・・) then B列の処理 end if next MyRow のように If文 のなかで or を用いて全てを記述するかElseif でつなぐ方法しか思いつきません。 抽出対象の値は今後メンテナンスする必要はないのでコード内に記述しても構わないのですが or  や ElseIf を多用するのもどうかと思っています。 ※現実には50個ほどの条件での合致を検出したいです。 みなさんならどのように記述されるでしょうか?

  • ExcelのVBAで複数行削除を行う場合

    Excel2007のVBAで複数行を削除する方法を教えて下さい。 Excel2003で使用していたマクロが使えなくなってしまいました・・・。 下記のようなExcelシートに対して複数行ずつ行を削除し、削除対象が無くなるまで 削除処理を行うか、指定した行まで削除処理を行うという事をしたいのですが うまく動きません。 例      A列   B列   C列   D列   E列 1行目 aaa1   bbb1  ccc1 2行目             ccc2 3行目             ccc3 4行目             ccc4 5行目 aaa2   bbb2  ccc1 6行目             ccc2 7行目             ccc3 8行目             ccc4 例に対しての結果      A列   B列   C列   D列   E列 1行目 aaa1   bbb1  ccc4 2行目 aaa2   bbb2  ccc4 例に対して、複数行(指定した行数ここでは3行)の削除を行いたいのですが、 単純に複数行(3行)ずつ削除していくのではなく。 1行目や5行目にあるように文字や情報が入力されているA列とB列の情報は 残しつつ、4行目のC列以降の列の情報はすべて活かしていくという事をしたいのです。 Excel2003の時に使用していたVBAは以下のものです。 Sub 行を削除するマクロ() Workbooks("xxxx.xlsx").Activate '処理を行いたいExcel ※1 n = n + 0 LastRow = 2138           '処理を終了させたい行 ※2 Sheets("Sheet1").Select '処理を行いたいシート ※3 Do Until (n > LastRow) Rows(n + 4).Delete Shift:=xlsiftUp '削除したい行指定 ※4 n = n + 3 Loop End Sub 皆様の良いアドバイスやお知恵をお貸しください。 よろしくお願いします。