- ベストアンサー
かんたんなエクセルマクロを教えてください!
エクセルマクロを勉強しはじめたばかりのものです。 列にある、様々な文字列で、同じ名前があったときに、 その個数を出すようにするにはどうしたらよいでしょうか? 【例】 C 1名前 2りんご 3メロン 4いちご 5りんご 6レモン 7メロン 8すいか 9メロン 10空白 Cの列に様々な名前の品物があります。そのときに、行の2~9(9はもっと長いときがあり、制限のないものとします) の中の文字列で、同じものがあったときに、その名前と個数を出すようにしたいのです。(C1は見出しなので省きます) 上記の例でしたら、「りんご」が2個、「メロン」が3個あります。2個、3個という数えた個数はB列の同じ場所の一番上に上書きで 出す形で結果を表示したいと思います。例でいえば、「りんご」は2個だったので、B2に「2」と出力。メロンは3個だったので、 B3に「3」と出力させたいのです(B列にはすでに他の文字列が入っています。それを数値で上書きします。) C列をたどって、同じ文字がないときには、「同じものはありません」とメッセージボックスで出力するようなマクロです。 例ではC9までですが、このケースではC10は空白になります。C100まであったときにはC101が空白です。 こんなカンタンなのもわからないので、ぜひお教えいただけますでしょうか?できるだけ短いものが嬉しいです。使っているエクセルはおはずかしながらEXCEL97です。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
おっしゃるとおりの動きをさせるなら、とりあえず、こんな感じでしょうか? Sub test() With ActiveSheet l = .Range("C2").End(xlDown).Row Set Rng = .Range("C2:C" & l) For i = 2 To l x = Application.CountIf(Rng, Range("C" & i)) If x > 1 Then flg = True If Application.CountIf(.Range(.Range("C2"), .Range("C" & i)), .Range("C" & i)) = 1 Then .Range("B" & i) = x End If End If Next End With If Not (flg) Then MsgBox "同じものはないみたい。" End If End Sub
その他の回答 (2)
- popesyu
- ベストアンサー率36% (1782/4883)
おそらく分かりやすいように単純化しているためだと思われますが、あまりにも単純化しているため、そのような作業であるなら何もマクロを使うまでもなく標準の関数だけで代用可能というのが回答になってしまいます。関数で出来ることをわざわざマクロで作る意義は全くありません。今回の例ならCOUNTIFで簡単に達成できてしまいます。マクロを使うのが勉強のためというのであれば話が別ですが。 http://www.relief.jp/itnote/archives/000448.php どうしても無駄・無意味と分かりつつマクロ(というかVBA)でやりたいというのであれば、まずループについて勉強しましょう。 ForEach~、Do~Loop、For~to など何れでも達成可能です。 For~Toのみ最初に終端行を確定しなければならない(まぁ確定しなくても回避方法は幾らでもありますが)という制約がありますが、とりあえずある一定の範囲内のものを一つ一つ比較するという手法で使えます。 で比較の方式については、最初から入っている語句が決まっているのであれば、決め打ちでそのAならAという語句をカウントするという流れになりますし、もう少し自由度を高めるなら、そのループの中で拾ってくる語句をその都度"動的配列"の中に入れ込んでいくという手法が使えるかと思います。 ※この辺の処理については結構複雑になるので、アルゴリズムの勉強にはなります。 コードの長さについてはどちらかと言うと長い方が初心者には理解しやすくなると思います。短ければ短いほど、コード的には美しいものにはなりますが、また大体において処理速度も速いものになりますが、初心者にも分かりやすいかというと決してそうではありません。数万行にもわたる処理であるなら、その辺に拘っても良いですが、数千行レベルで納まるものでれば、たかが数秒程度の差しかないので、本人にとって分かりやすい(=無駄に長い)というところからまずははじめるべきかと思います。 単純に今抱えている仕事をすぐに解決したいのか、勉強がてら色々やってみたいのかで回答の方向性も決まってきますので、よろしければその辺補足してください。 この命題で10行なら10行で収めるコードを知りたいという命題であるなら、きっとどこかの暇人が参加してくれると思いますので、それはそれでその旨書いたらきっとそういう方向性で回答がつくと思います。
お礼
すごく長くご説明してくださって、ありがとうございます。 そうですよね、countifでできるんですよね。 ものぐさで・・・。 マクロを覚えたい一心もありまして、実際にはどのようなマクロになるのか興味がありました。 もっと、もっと勉強しなければと思いました。3番目の方の解答がほしかったので、補足はとくにしませんが、ご容赦ください。ほんと、御丁寧な解答に感謝します。
- kapox
- ベストアンサー率21% (17/79)
とりあえず、同じシートのA1に、数えたいものを入れると、 メッセージボックスで出てくる方法。 Sub Aaaa() Dim myRange1 As Range Dim myRange2 As Range Set myRange1 = Worksheets("Sheet1").Range("C2:C100") Set myRange2 = Worksheets("Sheet1").Range("A1") answer = Application.WorksheetFunction.CountIf(myRange1, myRange2) MsgBox answer End Sub ツール→マクロ→マクロ→実行で、出来ます。
お礼
素早いご解答、ありがとうございます! 早速やってみたのですが、なぜかエラーとなってしまいます。 A1にC列にあるものを入力しているのですが・・。 なぜでしょうか。でも、私の質問でつくってくれて、感謝します!
お礼
ありがとうございます!動かしてみましたが、完璧に動きました。 merlionXXさんのご解答、大変感謝します! 「同じものはないみたい。」とのメッセージも、とても味があって、嬉しくなってしまいました。 End(xlDown).Row、 コードの意味はまだまだよくわからず、一行一行ヘルプみて勉強しなくてはと思います。みなさん、本当にありがとうございました!!!