[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『出現数の多い値のセルを色付け』(NOBU)
A T U V W X Y Z AA AB AM +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 1 | | 〜 | | | | | | | | | | 〜 | | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 2 | | 〜 | | | | | | | | | | 〜 | | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 3 | | 〜 |0 |0 |0 |2 |3 |5 |0 |8 |12 | 〜 |0 | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 4 | | 〜 |1 |2 |3 |0 |0 |0 |0 |9 |15 | 〜 |0 | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 5 | | 〜 |0 |0 |3 |6 |8 |9 |0 |0 |0 | 〜 |12 | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 6 | | 〜 |0 |0 |0 |2 |0 |3 |0 |7 |12 | 〜 |0 | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+ 34| | 〜 |0 |0 |0 |2 |0 |5 |0 |6 |12 | 〜 |15 | +---+ 〜 +---+---+---+---+---+---+---+---+---+ 〜 +---+
はじめまして、よろしくご教授お願いいたします。
上記のようなシートがあるのですが、検索範囲をT3:AM34とし、
値ゼロを除き出現数の1番多い値のセルを赤に、2番目に多いセルを黄に、
塗りつぶすようなマクロがあれば、いいのですがよろしくお願いいたします。
補足
検索範囲は実際の範囲と同じです。
塗りつぶすのは1番多い値のセルと2番目に多いセルのみ。(0は除く)
値は計算式で求めたものです。
環境はWindowsXP、EXEL2002です。
これでご希望のようになりますでしょうか。 Sub Test() Dim MyRange As Range, MyAreaRange1 As Range, MyAreaRange2 As Range Dim c As Range, r1 As Range, r2 As Range Dim MyR As Long, MyC As Long, MyCount As Long Dim MyA(1 To 32, 1 To 20) Set MyRange = Worksheets("Sheet1").Range("T3:AM34") MyRange.Interior.ColorIndex = 0 For Each c In MyRange MyR = c.Row - 2 MyC = c.Column - 19 If c.Value <> 0 Then MyCount = Application.CountIf(MyRange, c) Else MyCount = 0 End If MyA(MyR, MyC) = MyCount Next c 最頻数 = Application.Large(MyA, 1) 次頻数 = Application.Large(MyA, 最頻数 + 1) For Each c In MyRange MyR = c.Row - 2 MyC = c.Column - 19 If 最頻数 = MyA(MyR, MyC) Then 最頻値 = c.Value MyFlg1 = 1 ElseIf 次頻数 = MyA(MyR, MyC) Then 次頻値 = c.Value MyFlg2 = 1 End If If MyFlg1 + MyFlg2 = 2 Then Exit For Next c Set r1 = MyRange.Find(最頻値, LookIn:=xlFormulas) Set r2 = MyRange.Find(次頻値, LookIn:=xlFormulas) Set MyAreaRange1 = r1 Set MyAreaRange2 = r2 For Each c In MyRange If c = 最頻値 Then Set MyAreaRange1 = Union(c, MyAreaRange1) ElseIf c = 次頻値 Then Set MyAreaRange2 = Union(c, MyAreaRange2) End If Next c MyAreaRange1.Interior.ColorIndex = 3 MyAreaRange2.Interior.ColorIndex = 6 Set MyAreaRange1 = Nothing Set MyAreaRange2 = Nothing Set MyRange = Nothing Set r1 = Nothing Set r2 = Nothing End Sub
(川野鮎太郎)
川野様、早速お答えいただきありがとうございます。
試してみましたが ”最頻数 = " のところで、コンパイルエラー
”変数が定義されていません”のメッセージがでてしまいます。
Dimで定義しても、次頻数や最頻値やMyFlg1などが次々と同じエラーに
なっていしまいます。よろしくお願いいたします。(NOBU)
行頭にOption Explicitが記述されていると思いますので、 その行をコメントアウトして試すか、エラーが出る定数を全て定義してください。
(川野鮎太郎)
Dictiona objectを使用した方法です... 該当する値が複数存在する場合は、出現順の早いものになっています。
Sub test() Dim dic As Object, x, y, z, Colrng As Range Dim i As Long, rng As Range, r As Range Dim maxRng As Range, ff As String Set dic = CreateObject("scripting.dictionary") Set rng = Range("t3:am34") rng.Interior.ColorIndex = 0 For Each r In rng If Not IsEmpty(r) And r <> 0 Then If Not dic.exists(r.Value) Then dic.Add r.Value, 1 Else dic(r.Value) = dic(r.Value) + 1 End If End If Next x = dic.keys: y = dic.items For i = 1 To 2 z = Application.Max(y, 1) z = Application.Match(z, y, 0) Set maxRng = rng.Find(x(z - 1), , , xlWhole) If Not maxRng Is Nothing Then ff = maxRng.Address Set Colrng = maxRng Do Set maxRng = rng.FindNext(maxRng) Set Colrng = Union(Colrng, maxRng) Loop Until maxRng.Address = ff If i = 1 Then Colrng.Interior.Color = vbRed Else Colrng.Interior.Color = vbYellow End If x(z - 1) = Application.Min(x) Set maxRng = Nothing: ff = Empty Set Colrng = Nothing End If Next Set dic = Nothing: Set rng = Nothing End Sub (seiya)
川野様、seiya様、ありがとうございました。
一点だけですが最頻値、次頻値と同数字を持つ最初に出現する計算式も
引っ掛かるようです。(最頻値が5としたら例えば計算式に$P5と入っていると
赤くなってしまいます。)(NOBU)
失礼しました。そのつもりは無かったのですが、知らずに数式を探すようにしてました。 以下の部分を訂正しておいてください。 (間違い) Set r1 = MyRange.Find(最頻値, LookIn:=xlFormulas) Set r2 = MyRange.Find(次頻値, LookIn:=xlFormulas) (訂正) Set r1 = MyRange.Find(最頻値, LookIn:=xlValues) Set r2 = MyRange.Find(次頻値, LookIn:=xlValues)
(川野鮎太郎)
間違っていたらごめんなさい....
>最頻数 = Application.Large(MyA, 1) 次頻数 = Application.Large(MyA, 最頻数 + 1)
次頻数はこれでいいのですか?(seiya)
>次頻数はこれでいいのですか? はい、それで良い筈です。 配列に重複する個数を入れて、最頻数+1で次頻数としてます。 判りづらいかも知れませんので、以下の例で判りますか・・・。 ↓下のような数値があったとして、個数を配列に入れる。 5 4個 ←配列に入れた個数を大きいほうから、最頻数+1(ここでは4個+1) 3 1個 で5番目に大きい数値の『3個』が次頻数って感じです。 5 4個 5 4個 そのあとで、個数の配列から一致するセルの値を求めました。 2 1個 4 3個 何かまどろっこしい感じですが、それしか思い浮かびませんでした。_/ ̄|○ il||li 1 1個 4 3個 最頻数だけならMODE関数でいけるんですけどね。 4 3個 5 4個
(川野鮎太郎)
川野鮎太郎さん、 ご説明ありがとうございました。 なるほど、どちらかというと、Rankの機能を持たせたような感じですか? 考えが深い! (seiya)
川野様、seiya様、ありがとうございました。
何か初心者の私には、わからない話になってしまいましたが・・・(^_^;)
何度か検証しましたが、上手くいく時もあれば、検索する値によっては、
関係のない値に色(1箇所のみ)がついてしまったりする時がありますが、
あまり支障はないので、使用しています。
>最頻数だけならMODE関数でいけるんですけどね。
素人考えですがVBAで使用できる関数なら、最頻数を赤にし、つぎに同じ検索範囲
から、色の付いていないセルだけを検索範囲にして、再度、最頻数を求めれば、
次頻数になるのかな?
お手数をおかけしました。ありがとうございました。(NOBU)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.