[[20150413144145]] 『ちょっと複雑な抽出』(yoota) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『ちょっと複雑な抽出』(yoota)

お世話になります。
以前の投稿([[20150209183032]])の応用になりますが、ご提案いただいた
関数式、マクロ共に“未消化”で全く応用できずご教授ください。

(やりたいこと)
シート1にある「番号の組み−数値」の組(後述)から下記要領でシート2に番号を出力する 
(説明)
・「番号の組み−数値」(2行1列)は左側から「数値」の昇順(順位)に並んでいます
・番号の組み「番##-$$」の番号は「##」<「$$」(小-大)です
・「##,$$」は「01〜18」の範囲ですが、組により最大数は異なります
・「##」=「$$」(同じ)はありません
・例表のデータはシート1のH列2行目が開始セルです
・「番号の組み−数値」は横に30個(列)を処理対象とします(可変希望)
 ※“空欄”列もあり得ます(稀ですが)
・「番号の組み−数値」の30個(列)を1組として下に最大100組まで
−以下1組単位で説明−
・左から5番目まで(H−L列)の「番号の組み」の中で最も出現する番号をAとします
 ※5番目の数値と以降の数値が同値の場合は、最大8番目までをカウント対象とします
 ※Aが複数ある場合は、最も順位が上(左)に出現する方を選択します
 (Aは必ず1個に特定されます)
・Aと対になる番号でより順位が上(左)に出現する番号を順にB,C,D..とします
 (Aと対にならない番号は“飛ばし”ます)
(要領)
・シート2には、各組毎にAを先頭にB,C,D..と順番に下行に出力
 ※2組目は1組目の下(以降の組も同様)
・組と組の間は1行空ける
・各組最大18個出力されますが、番号の組合せによってはそれより少なくなります

(例表−8列までを説明します)
シート1

 H列     I列     J列     K列     L列     M列     N列     O列..
 番07-11  番03-07  番03-04  番07-14  番11-14  番03-14  番04-07	番04-11
 7.0	  7.8	   13.5	    14.9     17.3     33.9     41.8	42.5
 番09-10  番01-05  番01-08  番01-09  番06-09  番01-06  番06-09	番05-10
 3.8	  4.2	   7.0	    7.7      8.9      8.9      21.2	31.6
シート2(A列2行目が開始セル)
 07
 11
 03
 14
 04
 ..
(1行空ける)
 01
 05
 08
 09
 06
 ..

よろしくお願いします。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


 >  ※5番目の数値と以降の数値が同値の場合は、最大8番目までをカウント対象とします 
 とのことですが、

 このことと、
 ・「番号の組み−数値」の30個(列)を1組として
 や、
 ・各組最大18個出力されます
 こととの関係が不明です。

 ※X番目の数値と以降の数値が同値の場合は、最大Y番目までを
 の「X」と「Y」はどう考えているのですか?
 ご説明ください。

 まったく未消化なら、それらを消化するのが先じゃないですか?
(γ) 2015/04/13(月) 21:00

ありがとうございます。

 >まったく未消化なら、それらを消化するのが先じゃないですか?

→ごもっともだと思います。_ _;
 ただ、“まったく”未消化ということではなく、自分なりにやれることは
 やったつもりだが“完全理解”には未だ遠い..という意味で“未消化”です。
 回答いただいた内容を全て理解してからでないと次の質問ができない..
 となると正直いって私には“キツイ”です。

 >X番目の数値と以降の数値が同値の場合は、最大Y番目までをの「X」と「Y」はどう考えているのですか?

→X番目は5番目、Y番目は8番目と特定しています。

提示した例表では4行目の「番06-09」と「番01-06」の数値が「8.9」と同値なので、
6番目までで最も出現が多い番号「01」が「A」となります。
で、Aと対になる番号が上位(左)から順に「05,08,09,06」となります。
「番号の組み−数値」(例では「番06-09」と「8.9」)は横に最大153個(18個の組合せ)
あり得ますが、処理対象は30個まで(可変希望)としました。
そして、この「番号の組み−数値」2行を1組としています。
出力は最大で番号「01」〜「18」で18個となりますが、各組の「番号」は「01」〜「07」や
「01」〜「11」までとマチマチで、出現の仕方でも個数は変わり得ると思います。
 
礼儀上コメントには応えたつもりですが、今回の質問アップが本欄の主旨に合わないようなら
取り下げますので、遠慮なくコメントください。

(yoota) 2015/04/14(火) 11:01


元々、条件が複雑なので、様々な工夫をしたマクロを組まないと対応できなかったのが問題と思いますね。
1行1データとかならまだしも、2行1データだし、複数列に別れているし。

これを、番号で1列、数値で1列の2列だけにして、縦に長いデータに変えるとか、シンプルな構成にできませんか?
条件が複雑だから、理解できないマクロになり、理解できないからまた他人に頼る、という循環になってます。

理解できる形にして、自力でマクロ修正してください。1日でマクロが組めないからといって諦めては駄目ですよ。
1週間、1ヶ月。どれだけかけても自力解決することが大事です。そして、判らない箇所だけ質問するようにしましょう。
(???) 2015/04/14(火) 12:00


 >番号で1列、数値で1列の2列だけにして、縦に長いデータに変えるとか..

→これは、単に2行を1行(番01-06 8.9 と)にする意味ではなさそうですね?
 番号の組みを更に「01」と「06」に分解し各々に「8.9」を割当てる..でしょうか?

 >どれだけかけても自力解決することが大事..判らない箇所だけ質問するように..

→仰られていることはわかりますが、今回はさすがにハードルが高く(苦笑)
  
シンプルな構成を考えて再アップする方向で再検討しようと思います。
ありがとうございました。

(yoota) 2015/04/14(火) 14:20


シート1の改良案ですが、例えば番01-05は4.2、番03-04は13.5、番03-07は7.8を、以下のように表現しては駄目なのでしょうか?
現状の、数値ばらばら、並びばらばら、規則性なしの状況では、何をするにも難しいかと思います。

	A	B	C	D	E	F	G	H
1		1	2	3	4	5	6	7
2	1					4.2
3	2
4	3				13.5			7.8
5	4
(???) 2015/04/14(火) 14:47

 もう見ないかもしれませんが。

 前スレでは途中撤退した身ですので、あれこれいう資格もないかもしれませんが、
 前スレでもコメントしたように、実際に、どんなことがら(テーマ)に対して、どういった結果を求めているのか
 その具体的なものの説明が全くなく、あくまで、「頭の体操」のように、これをこうする方法について述べよ なんていわれているような印象です。

 ・こういったテーマがあって、その結果を求めるために、こんな方法を考えた。
 ・ついては、その実現のためのコード実装をお願いしたい。

 こうすべきでは?

 そうすると、2つのメリットがあります。

 1.いやいや、その実現のために考えた「こんな方法」では、ここが不十分 といった、構想したロジックそのもののバグの指摘が得られる。
 2.その実現のためには、全く異なるアプローチで、「別の解決方法」があるといった提案が得られる。

 そうではなく、あくまで、(yoota)さんが、右に行ってくれ!、あぁ、行き過ぎた、こんな場合は左に一歩さがってくれ!
 そういっているように感じますねぇ・・・

(β) 2015/04/14(火) 15:13


???さん、βさん、  ありがとうございます。

テーマは「市場分析」です。 詳細はご勘弁願いたいですが、
・どのアイテムが売れているか?(前述のAになります)
・そのアイテムと「一緒に」、「より」売れているアイテムは何か?(同B,C,D,..)
・売れているかどうかの判断が数値(指標)です

そのA以下を求める方法を前述の(説明)に書いたつもりだったんですが..
・5番目までで最も出現するのをAとする
・同値の場合は8番目までとする
・そのAと対になって「より」出現するのをB,C,D,..とする

これは“独断”に過ぎませんし、将来変わる(変える)可能性はあります。
アイテムの組合せは無数にあり、何を分析するかによりどのアイテムに注目するかが
課題であり、A以下を求める方法(考え方)もいろいろあり得るわけで...

ここらあたりを説明に入れるべきかどうか実は迷っていました。
人によっては余計な事ととられかねないですし、説明ベタなので説明の説明で
終わってしまいそうで..どっちにしろ既にそうなってますが(笑)

表形式にするのはデータ収集の方法から考え直す必要があり、時間いただけますか?
(その場合は別スレ?にした方がよさそうですね)

(yoota) 2015/04/14(火) 17:11


 ぜんぜん質問と関係無いですが、
 >・そのアイテムと「一緒に」、「より」売れているアイテムは何か?(同B,C,D,..) 
 は相関分析、相関係数などで検索するともしかしたら参考になることがあるかもしれません。
http://hitorimarketing.net/tools/correlation-analysis.html EXCEL(エクセル)でおこなうビジネスデータの分析 散布図と相関係数(相関分析)

(Mook) 2015/04/14(火) 17:18


Mookさん、 ありがとうございます。

そうですね、各アイテム間の関係性の分析手法として多変量解析を含め
ごくごく薄〜くですが書物やネットを齧っているところです。
成果は出てませんが..(苦笑)

(yoota) 2015/04/14(火) 18:08


 ところで、サンプルとしてアップされている1組目の結果ですが、N列の04−07も対象になっているんですか?
 チェックするものは左から5つ(同じものがあればMAX8つ)なので、1組目はL列までが対象じゃないのですか?

 あるいは、ここにも、「摩訶不思議で哲学的な」、βなんぞには思い当らない判断基準があるんでしょうかね?

(β) 2015/04/14(火) 20:57


 ↑でコメントした通り、1組目の 04 は対象外になりますが。

 たまたまアップされたサンプルの範囲で結果が出ているだけで、別の事例では、まったく使い物にならないかも。
 自信度、0.5%ぐらいです。

 Sub Test()
    Dim i As Long
    Dim j As Long
    Dim dic1 As Object
    Dim dic2 As Object
    Dim dic3 As Object
    Dim dic4 As Object
    Dim w As Variant
    Dim c As Range
    Dim num1 As String
    Dim num2 As String
    Dim A As String
    Dim d As Variant
    Dim mx As Long
    Dim col As Long
    Dim sl As Object
    Dim sh1 As Worksheet
    Dim sh2 As Worksheet
    Dim pos As Range
    Dim x As Long
    Dim key1 As String
    Dim key2 As String

    Set dic1 = CreateObject("Scripting.Dictionary")
    Set dic2 = CreateObject("Scripting.Dictionary")
    Set dic3 = CreateObject("Scripting.Dictionary")
    Set dic4 = CreateObject("Scripting.Dictionary")
    Set sl = CreateObject("System.Collections.SortedList")
    Set sh1 = Sheets("Sheet1")
    Set sh2 = Sheets("Sheet2")
    Set pos = sh2.Range("A1")
    sh2.UsedRange.ClearContents

    For i = 1 To sh1.Range("H" & Rows.Count).End(xlUp).Row Step 2
        For j = 12 To sh1.Cells(i + 1, Columns.Count).End(xlToLeft).Column
            If j = 16 Then Exit For
            If sh1.Cells(i + 1, j).Value <> sh1.Cells(i + 1, j + 1).Value Then Exit For
        Next

        dic1.RemoveAll
        dic2.RemoveAll
        sl.Clear
        A = Empty

        For Each c In sh1.Range(sh1.Cells(i, "H"), sh1.Cells(i, j))
            w = Split(c.Value, "-")
            num1 = Replace(w(0), "番", "")
            num2 = w(1)

            dic1(num1) = dic1(num1) + 1
            dic1(num2) = dic1(num2) + 1

            If Not dic2.exists(num1) Then dic2(num1) = c.Column
            If Not dic2.exists(num2) Then dic2(num2) = c.Column

            If Not dic3.exists(num1) Then Set dic3(num1) = CreateObject("Scripting.Dictionary")
            If Not dic3.exists(num2) Then Set dic3(num2) = CreateObject("Scripting.Dictionary")

            dic3(num1)(dic3(num1).Count) = num2
            dic3(num2)(dic3(num2).Count) = num1

            key1 = num1 & num2
            key2 = num2 & num1
            If Not dic4.exists(key1) Then dic4(key1) = c.Column
            If Not dic4.exists(key2) Then dic4(key2) = c.Column

        Next

        For Each d In dic1
            If dic1(d) > mx Then
                A = d
                mx = dic1(d)
                col = dic2(d)
            ElseIf dic1(d) = mx Then
                If dic2(d) < col Then
                    A = d
                    mx = dic1(d)
                    col = dic2(d)
                End If
            End If
        Next

        For Each d In dic3(A).items
            sl.Add dic4(A & d), d
        Next

        Set pos = pos.Offset(1)

        pos.Value = "'" & A
        For x = 0 To sl.Count - 1
            Set pos = pos.Offset(1)
            pos.Value = "'" & sl.getbyindex(x)
        Next
        Set pos = pos.Offset(1)

    Next

 End Sub

(β) 2015/04/14(火) 21:25


 こんばんは。

 いやあ、私が思っていたのは、
 最大8番目までカウントすれば良いのに、
 なぜ、30個(列)が必要なんだろうかと思ったのです。

 説明がないので、想像します。

 ・上記のAの決定には最大で8番目までとする。
 ・Aとペアになっている番号の取得は、30 個(列)まで使う、
 ということですか?
 また、18 というマジックナンバーの意味も不明でした。
 これらの説明があると良かったと思います。

 -------------------------
 ところで、
 Aの決定にあたっては、
 ・まず、対象列の範囲を決定します。
   5番目から右に見ていって、異なる数字になるか、
   9番目になるまでの範囲です。

 ・同一候補が発生する際の優劣の判定には、例えば次のような手があるでしょう。
     "07" → 1 + exp(- 1) 
     "11" → 1 + exp(- 1)
     "03" → 1 + exp(- 2)
     "04" → 1 + exp(- 2)
     以下同じように、数値を対応づけます。
     こうしておいて、組が同じものどうしを合計した判定値を作成し、
     その判定値が最大となる組が、求める A です。
     # 加算調整額は 0 < x < 1を満たし、登場順を反映出来るところがミソです。

 あと、Aとペアとなる組をみつけるのは簡単でしょう。
 もういちど、左からひとつずつAが含まれるかどうかを判定していくだけです。

 こうしてみると、前回の応用というより、前回に比べ、ごく簡単な作業になるでしょう。
 # 対象範囲が可変というところの謎が残っていますけど。

 前回のスレッドを復習されれば、必要なコードはすでに提供されているはずです。
  ご自分でトライするだけでしょう。

 -----------------------
 なお、求める組の求め方がこれで最善か、疑問はあります。
 例えば、
 2番目のケースで、
 Aの対応する 05 が二番目に来ていますが、
 例えば、
 "09"は、"05"よりも前に登場しますし、しかも何度も登場します。
 "05"よりも優先するのが適切ではないかという気がします。
 ("05" はたまたま "01"にくっついているだけです。
  それで目的は果たしているというなら、それまでですけど。)

 まあ、これは質問者さんがトライされる前提ですから、
 こちらがどうこう言うのもおかしいかもしれません。
 是非頑張ってください。

 # 同時に更新したらしく、更新の衝突とメッセージが表示されました。

(γ) 2015/04/14(火) 21:27


 γさんの

 >・Aとペアになっている番号の取得は、30 個(列)まで使う、

 あぁ、そうなんですねぇ。きっと。

 >"09"は、"05"よりも前に登場しますし、しかも何度も登場します。
 >"05"よりも優先するのが適切ではないかという気がします。

 私もそう思いました。
 で、最初に書き上げたコードで、09 が最初にきて、サンプルとは違うので ??? と思い、
 あぁ、01 とペアになった 09 がどうかを見るということなのかと、それでコードを書き直して
 とってつけたような Dic4 をつけたして処理しました。

 でも、γさんと同じく、09 って、優劣からいえば優なんじゃないかと、今でも思います。

(β) 2015/04/14(火) 21:40


 18についての説明を読み飛ばしていました。これは失礼しました。
(γ) 2015/04/14(火) 21:42

 04 を対象にするコード、変更分のみ。(でも、コメントしたように 09 が軽んじられているのはかわいそうだなぁと)

        For Each c In sh1.Range(sh1.Cells(i, "H"), sh1.Cells(i, j))
            w = Split(c.Value, "-")
            num1 = Replace(w(0), "番", "")
            num2 = w(1)

            dic1(num1) = dic1(num1) + 1
            dic1(num2) = dic1(num2) + 1

 この部分を

        For Each c In sh1.Range(sh1.Cells(i, "H"), sh1.Cells(i, Columns.Count).End(xlToLeft))
            w = Split(c.Value, "-")
            num1 = Replace(w(0), "番", "")
            num2 = w(1)

            If c.Column <= j Then
                dic1(num1) = dic1(num1) + 1
                dic1(num2) = dic1(num2) + 1
            End If

(β) 2015/04/15(水) 07:40


 βさん コード拝見しました。
 SortedList勉強になります。
 一点だけですが、dic3.RemoveAll が必要かもしれません。

 また、これは質問者さんにお聞きすることですが、
 番01-02	番02-03	番02-06	番01-04	番01-05	番03-14	番04-07	番04-11
 7	7.8	13.5	14.9	17.3	33.9	41.8	42.5
 の場合、想定結果はどうなりますか?
 A は "01" ですか? "02"ですか?

(γ) 2015/04/15(水) 07:42


ありがとうございます。
急に今週は時間とれなくなった為、取急ぎ補足させていただきます。

 >・上記のAの決定には最大で8番目までとする
 >・Aとペアになっている番号の取得は、30 個(列)まで使う

→その通りです

 >対象範囲が可変というところの謎が残っていますけど

→Aのペアを抽出して判断するのに30個までが適当かどうか現時点では不明です。
 20個でいいかも知れないし、30個以上かも知れない..
 このあたりは使用しながら決めたい..との思いです。

 >"09"は、"05"よりも前に登場しますし、しかも何度も登場します。
 >"05"よりも優先するのが適切ではないかという気がします。

→「一番売れてるアイテム」と「ペアで売れてるアイテム」に着目していますので..
 としかいいようがないです(スミマセン)
 一番上位にくるのが“売れてる”んだろ?..というのも当然「あり」だと思いますし、 
 ここは“独断”ということでお許しください(苦笑)

 >..の場合、想定結果はどうなりますか?..A は "01" ですか? "02"ですか?

→悩ましいところの説明が抜けていました、すみません。
 理想はA候補のカウントが同数の場合は、カウント範囲の右へ検索して最初に
 出現する方を選択する..ですが、さすがにやっかいそうですね。
 その組は「該当なし」とわかる表示をお願いできますか?

拙い説明で恐縮です、戻りしだいご提示の確認等させていただきます。

(yoota) 2015/04/15(水) 11:06


 To γさん

 ご指摘ありがとうございます!
 継ぎ足し継ぎ足しで書きましたので、初期化漏れですね。
 Dic3 のみならず Dic4 も 初期化が必要でしたね。

 To (yoota)さん

 dic3.RemoveAll 
 dic4.RemoveAll 
 mx = 0
 col = 0

 この追加が必要です。

(β) 2015/04/15(水) 14:07


 >→「一番売れてるアイテム」と「ペアで売れてるアイテム」に着目していますので..  としかいいようがないです

 あぁ、なんとなくわかります。コンビニの抱き合わせ販売戦略のようなものですね。
 ビールと女性用●● とか(順序は逆かも)

 なので【一番じゃなくてもちょいちょい売れているもの】と、そのついでに、同じ棚におけば売れる可能性の高いもの。
 そういった分析ですね。なるほど。

(β) 2015/04/15(水) 16:22


 こまぎれにコード変更を(しかも部分的に)アップしましたので、一応、フルセットを再掲します。
 週末にでも時間がとれたらお試しいただければ幸甚。

 21:00 追記

 >その組は「該当なし」とわかる表示をお願いできますか?

 ↓のコードは、その対応はしていません。同じ列にある 01-02 がともに A の候補の場合は
 先に現れている 01 を採用しています。

 Sub Test2()
    Dim i As Long
    Dim j As Long
    Dim dic1 As Object
    Dim dic2 As Object
    Dim dic3 As Object
    Dim dic4 As Object
    Dim w As Variant
    Dim c As Range
    Dim num1 As String
    Dim num2 As String
    Dim A As String
    Dim d As Variant
    Dim mx As Long
    Dim col As Long
    Dim sl As Object
    Dim sh1 As Worksheet
    Dim sh2 As Worksheet
    Dim pos As Range
    Dim x As Long
    Dim key1 As String
    Dim key2 As String

    Set dic1 = CreateObject("Scripting.Dictionary")
    Set dic2 = CreateObject("Scripting.Dictionary")
    Set dic3 = CreateObject("Scripting.Dictionary")
    Set dic4 = CreateObject("Scripting.Dictionary")
    Set sl = CreateObject("System.Collections.SortedList")
    Set sh1 = Sheets("Sheet1")
    Set sh2 = Sheets("Sheet2")
    Set pos = sh2.Range("A1")
    sh2.UsedRange.ClearContents

    For i = 1 To sh1.Range("H" & Rows.Count).End(xlUp).Row Step 2
        For j = 12 To sh1.Cells(i + 1, Columns.Count).End(xlToLeft).Column
            If j = 16 Then Exit For
            If sh1.Cells(i + 1, j).Value <> sh1.Cells(i + 1, j + 1).Value Then Exit For
        Next

        dic1.RemoveAll
        dic2.RemoveAll
        dic3.RemoveAll
        dic4.RemoveAll
        sl.Clear
        A = Empty
        mx = 0
        col = 0

        For Each c In sh1.Range(sh1.Cells(i, "H"), sh1.Cells(i, Columns.Count).End(xlToLeft))
            w = Split(c.Value, "-")
            num1 = Replace(w(0), "番", "")
            num2 = w(1)

            If c.Column <= j Then
                dic1(num1) = dic1(num1) + 1
                dic1(num2) = dic1(num2) + 1
            End If

            If Not dic2.exists(num1) Then dic2(num1) = c.Column
            If Not dic2.exists(num2) Then dic2(num2) = c.Column

            If Not dic3.exists(num1) Then Set dic3(num1) = CreateObject("Scripting.Dictionary")
            If Not dic3.exists(num2) Then Set dic3(num2) = CreateObject("Scripting.Dictionary")

            dic3(num1)(dic3(num1).Count) = num2
            dic3(num2)(dic3(num2).Count) = num1

            key1 = num1 & num2
            key2 = num2 & num1
            If Not dic4.exists(key1) Then dic4(key1) = c.Column
            If Not dic4.exists(key2) Then dic4(key2) = c.Column

        Next

        For Each d In dic1
            If dic1(d) > mx Then
                A = d
                mx = dic1(d)
                col = dic2(d)
            ElseIf dic1(d) = mx Then
                If dic2(d) < col Then
                    A = d
                    mx = dic1(d)
                    col = dic2(d)
                End If
            End If
        Next

        For Each d In dic3(A).items
            sl.Add dic4(A & d), d
        Next

        Set pos = pos.Offset(1)

        pos.Value = "'" & A
        For x = 0 To sl.Count - 1
            Set pos = pos.Offset(1)
            pos.Value = "'" & sl.getbyindex(x)
        Next
        Set pos = pos.Offset(1)

    Next

 End Sub

(β) 2015/04/15(水) 16:25


 >  番01-02 番02-03 番02-06 番01-04 番01-05 番03-14 番04-07 番04-11
 >  7       7.8     13.5    14.9    17.3    33.9    41.8    42.5
 >  の場合、想定結果はどうなりますか?
 "01"は
 7 ,14,9  ,17.3 に貢献し、
 "02"は
 7 , 7.8  ,13.5 に貢献している。
 数値が小さいほうが優れているとすると、
 普通は、02をAとして採用すると思いますが。
 なぜ、「該当なし」とするのか、ちょっと理解しにくいですね。

 # まあ、そんなレアなことはどうでもいいよ、ということなんでしょうか。
 # それなら、前のスレッドの色々な議論は何だったのか、という気はします。

(γ) 2015/04/18(土) 07:19


 > # まあ、そんなレアなことはどうでもいいよ、ということなんでしょうか。
 ># それなら、前のスレッドの色々な議論は何だったのか、という気はします。

 前スレでも同様の感想を持ちました。
 前スレでは比較検討するものが5つ、だけど5つめ等が同値なら、こうこう、同値のそれぞれを判定して
 採用するものを決める・・なんていう、事細かな要件提示があって、β的には、左の4つは貢献度大だけど
 5つめは、かなり貢献度小だろうから、どれを選んでもいいじゃないか、ささいなことなのでは? なんて思いが
 ぬぐいきれず、かつ、前スレでも、あるところでは、ざくっと、今回の「該当なし」と同じような要件がだされたり。

 右のほうのものを事細かに処理したい割には、大事な左のほうに同値があるからといって、「該当なし」は
 ないでしょうと思いますね。
 同値の A は すべて、それぞれの A に紐付くペアを出力 というなら考え方として理解できますが。

(β) 2015/04/18(土) 07:42


βさん、γさん、ありがとうございます。

 >コンビニの抱き合わせ販売戦略のようなものですね..
 >一番じゃなくてもちょいちょい売れているもの..

→業界は違いますがほぼ核心をついておられます(驚)
 木曜にその業界の客先(我が家から500kmほど)にクレーム対応で伺い、本日夕方帰宅したところです(涙)
 そうですね、この「ちょいちょい」に人間の心理(真理)があると考えていまして...(大袈裟ですが ^ ^;) 

 >なぜ、「該当なし」とするのか、ちょっと理解しにくい..

→上述しました「ちょいちょい」に拘るとカウント同数の場合は更に「右」を調べることになるわけで..
 「該当なし」にしてもいいかなと思ったのは、先述した“やっかいそう”も理由ですが、それ以上に
そもそも同数のケースにあまり「価値」を置いていないことが理由です。
同じように「ちょいちょい」売れてるのが複数ある時に、わざわざ"紐(ペア)"に注目する必然性はないわけで..

 >同値のAはすべて、それぞれのAに紐付くペアを出力というなら考え方として理解できますが..

→しごく“真っ当”なお考えと思いますが、ここは私の“独断”ということでお許しを...

ご提案のマクロを試行(データ範囲「H2:AK73」)しましたが、「num2 = w(1)」の箇所でエラーメッセージ("9")が出ます。
ただ、3行上のFor 以下の2カ所の Cells(i,… を Cells(i+1… にすると同じくエラーメッセージは出ますが、求める実行結果が得られているようです。

未だマクロを“読めて”いませんので、もう少し確認時間をください。

(yoota) 2015/04/19(日) 22:34


 遠方への出張ご苦労様です。

 月曜朝からする話でもないが、日中はアクセスしないので、少しメモしておきます。

 >  →上述しました「ちょいちょい」に拘るとカウント同数の場合は更に「右」を調べることになるわけで.. 
 >   「該当なし」にしてもいいかなと思ったのは、先述した“やっかいそう”も理由ですが、それ以上に 
 >  そもそも同数のケースにあまり「価値」を置いていないことが理由です。 
 >  同じように「ちょいちょい」売れてるのが複数ある時に、わざわざ"紐(ペア)"に注目する必然性はないわけで.. 
 おっしゃっていることが理解しかねます。
 私が申し上げたのは、どれが一番売れているかの判定の話です。
 >  "01"は
 >  7 ,14,9  ,17.3 に貢献し、
 >  "02"は
 >  7 , 7.8  ,13.5 に貢献している。
 と言う情報だけで判定は可能なはず(*)で、さらに右を調べる必要はありません。

 >  そもそも同数のケースにあまり「価値」を置いていないことが理由です。 
 だったら、前スレッドの順位判定の細かい話はなんだったの?

 どっちも売れているときは、それは両方ともなかったことにする、
 というテキトーな方針で、販売分析、マーケット分析ができるのですか? 

 (*)
 両方を対象にしてもいいかもしれないが、一番を判定することは可能ですよ。
 例えば、評価関数として、
    1 + exp((-1) * 数値)
 のようなものを考えて、その合計どうしで比較すればよいでしょう。 
 ・ 1 はrankingに入ったことに対する一律評価
 ・ exp((-1)*数値)は、上記の要素のウエイト(=1)を上回らない範囲で、
   数値の大小を反映する意味です。  

(γ) 2015/04/20(月) 07:20


 >ご提案のマクロを試行(データ範囲「H2:AK73」)しましたが、「num2 = w(1)」の箇所でエラーメッセージ("9")が出ます。 
 >ただ、3行上のFor 以下の2カ所の Cells(i,… を Cells(i+1… にすると同じくエラーメッセージは出ますが、求める実行結果が得られているようです。 

 データは2行目からだったんですか!
 アップしたコードは1行目からという前提です。つけやきばで、部分的に手を入れると、他との整合性が狂う可能性もありますよ!!

 手を入れられたところを元に戻して、一番最初の

     For i = 1 To sh1.Range("H" & Rows.Count).End(xlUp).Row Step 2

 これを

     For i = 2 To sh1.Range("H" & Rows.Count).End(xlUp).Row Step 2

 にしてください。

(β) 2015/04/20(月) 16:10


ありがとうございます。
また時間がとれなくなっていますのでコメントのみで失礼します。
評価関数のお話はすごく参考になりますし、判定の話もわかります。

「そもそも同数のケースにあまり「価値」を置いていない」の補足です。
・Aは、「ダントツであればあるほど良い」と考えています。
 上位5番全てに出現する場合などは「ダントツ」ですが、2,3回程度では
 「キワドイ」かなぁ〜と。
・その「ダントツ」のAと一緒に売れているペアには価値があると思いますが、
 「キワドイ」Aのペアはどんなものかと..
・Aが「ダントツ」でないなら一層のこと上位○番目に出現する回数が多いのを
 順にピックアップして分析する..といったやり方もあるかなと。
(実際にその手法を使っているケースもあります)

 >どっちも売れているときは、それは両方ともなかったことにする、
 >というテキトーな方針で、販売分析、マーケット分析ができるのですか? 

→これは返答に困りますね(苦笑)
 分析の対象や目的により何が「有用」か..は常に考えているつもりですが、未来永劫に
 わたって“独断”が正しいとも思ってませんしご提示の評価関数を取り入れるかも知れません。
 先ずはやってみよう..というのが正直なところです。(やはりテキトーですね^^)

βさん、まだ確認できる環境にありませんのでもう少し時間ください。
(因みにH2がデータ開始セルということは質問の冒頭に書いていますので^^;)

(yoota) 2015/04/22(水) 17:44


 >・例表のデータはシート1のH列2行目が開始セルです 

 ここですね。失礼しました。

 いずれにしても、(β) 2015/04/20(月) 16:10 で申し上げた対応をお願いします。

(β) 2015/04/22(水) 19:11


 追記です。

 >分析の対象や目的により何が「有用」か..は常に考えているつもりですが、未来永劫に 
 >わたって“独断”が正しいとも思ってませんしご提示の評価関数を取り入れるかも知れません。 
 >先ずはやってみよう..というのが正直なところです。

 異論はありません。その通りだと思います。分析の成否は、あくまで分析者の責任ですから。

 別のポイントで、要件に回答案を提示する立場から言えば、

 ・確固たる要件を提示いただき、それにそった回答案を提案する。
 ・別途の方式が必要になった場合は、(yoota)さん自身が、コードを組み立てる。
  (今までのシリーズで処理するに必要なコード部品は、多くの皆さんからアップされています。それを組み合わせるだけですので)

 回答側の立場で困るのは、結構がんばってコードをかいたのに、あぁ、これはやめましょう。かわりに、こうしてくださいと
 そういったことが今後、【さらっと】でてきた場合ですね。

 で、最後は【グチ】です。

 >βさん、まだ確認できる環境にありませんのでもう少し時間ください。 

 お忙しいのはわかりますが、コードを変更して流してみるのに、おそらく「10秒」もかからないと思います。
 その10秒もかける時間がないということは、あぁ、そんな程度なのかと、がっくりきますねぇ。

(β) 2015/04/22(水) 19:30


βさん、回答いただいたみなさん、ありがとうございます。
また、レス遅く申訳ありませんでした。

うまくいきました!

いただいたコメントを肥やしにして、気持ちよく回答いただける投稿を
今後は心がけたいと思います。
(それ以前に、質問しなくて済むように「自力」をつける必要がありますが..^^;)

 P.S.
 先週は時間もそうですが、身の周りに使えるパソコンがなく..
 (今どき珍しいでしょうね)
 投稿するタイミングが悪かったと反省しています。

(yoota) 2015/04/26(日) 12:18


 提示されたコードは理解されましたか?
 そうでなければ、少し仕様が変わったら、また人に聞くことになりますよ。
 今回でも、相当に軋轢を感じたと思うが、また繰り返すことになる。
 そうした分析をするのが仕事なら、気合いを入れてマクロを勉強することをお勧めします。

 Dictionaryを値に持つDictionaryとか、SortedListと利用とか、
 市販のVBA書籍には余り出ていない使い方です。
(久しく手にしてないので知らないが、そのように予想されます。)
 不明の点があれば質問してはどうですか?
 質問が出てこないところからすると、よほどスキルが高いのに手を抜いているのか、
 コードくれくれに徹しようと思っているのか、いずれかと誤解されますよ。
 いやいや、しっかりマスターしましたよ、ということなら同慶の至り。
 それなら、今後、同じような話は出て来ないと考えておきます。
(γ) 2015/04/26(日) 18:01

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.