[[20150903204249]] 『VBA 組み合わせの抽出方法』(julius) ページの最後に飛ぶ

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

 

『VBA 組み合わせの抽出方法』(julius)

はじめまして。
VBAでプログラムを組もうとしているのですが、
初心者で分からないことが多く、質問させて頂きます。

i  j  k  
 
A  5  1
B  10 2
C  15 3
D  20 4
E  25 5

それぞれの列i,j,kに数値が入力されており、k列の数字から1つ、
あるいは2つの組み合わせを重複せず抽出したいです。
ただし、条件として、

 2つ目以降の数字は1つ目よりも大きい
 j列に対応する数字が2つ目以降は1つ目との差が10以上となるもの。
 (iがAとBの場合、jの差は15-5=10なので成立し13)

どのようなプログラムになるのでしょうか。
勉強も含め教えて頂けると幸いです。
不躾で申し訳ありませんが、よろしくお願いします。

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


 質問の意味がわかりません。

 >それぞれの列i,j,kに数値が入力されており、k列の数字から1つ、 
 >あるいは2つの組み合わせを重複せず抽出したいです。 
 まず、Iは数値じゃないですよね?

 それとK列の数値の組み合わせを抽出したいということですが、
 「重複」の定義は何ですか?
 組み合わせの重複?
 それとも同じ数値を使うことを重複?

 上記例の場合、1-3 1-4 1-5 も条件に一致します。

 最終的にどのような出力にしたいかわからないから
 回答が付かないのではないかと思います。
 例題の模範解答を作ってみてください。

(稲葉) 2015/09/04(金) 12:40


ご指摘ありがとうございます。
意味の分からない質問をしてしまい申し訳ありません。

まず、
Iは数字ではありません。
重複は同じ数字を使うことを重複としています。
解答例としては、

1-3, 1-4, 1-5, 2-4, 2-5, 3-5

となります。

(julius) 2015/09/04(金) 13:53


 横から失礼します。
 組み合わせといっておられますが、1桁目が2桁目より云々という説明がありますよね。
 ということは、組合せではなく順列ですか?

 算数音痴ですのでβが回答できるテーマではないのですが、ちょっと気になりましたので。

(β) 2015/09/04(金) 14:35


たびたび失礼しました。
仰る通り組み合わせでなく、順列になりますね。
(julius) 2015/09/04(金) 15:32

 引き続き分からないです。

 >1つ、 あるいは2つの組み合わせを重複せず抽出したいです。 
  と云うことは、

 >1-3, 1-4, 1-5, 2-4, 2-5, 3-5 となります。 
  1.その2つの組合せの前に、1,2,3,4,5 の単発が無いとおかしくないですか?

 >順列になりますね。
  2.と云うことは、ここの「5」が「1」だった場合、1-1とか、2-1などもありですね?
              ↓
         >E  25 5 

 3.※ それともK列には、そもそも同じ値が存在しない?
 4.※ K列は昇順にならんでいるのですか?

 5.I列のA,B,C・・は、何か意味があるんですか?
     あとの処理で使用するものですか?
   それとも単に説明の都合上書いた文字なんですか?

(半平太) 2015/09/04(金) 15:58


何度もご指摘頂きありがとうございます。

1.仰る通り抜けていました。単発で1,2,3,4,5の単発が存在します。
3.分かりにくく申し訳ないんですが、K列は同じ値が存在しません。
4.昇順にならんでいます。
5.i列は後の処理で使用するもので、この質問上では意味はありません。

(julius) 2015/09/04(金) 16:56


 算数音痴ですが、
  J・K列を新しいシートにコピーして、J列(コピー先のA列)で並べ替え
  J列(コピー先のA列)を順番に比較して、
  一番最初に10離れたところから、最後まで
  K列(コピー先のB列)を組み合わせる
 以上をJ列の数値分繰り返して総当たり

 単発がないとおかしいのかどうか、私にはわかりませんが
 一つ目と二つ目の差が10以上ないといけないなら、単発は発生しないような・・・
 という考えで何も入れてません。 有ったとしても全部が該当するでしょうし。

    Option Explicit

    Sub test()
        Dim ws1 As Worksheet
        Dim ws2 As Worksheet
        Dim rng As Range
        Dim i   As Long
        Dim j   As Long
        Dim tbl
        Dim dic As Object
        Set dic = CreateObject("Scripting.Dictionary")

        Set ws1 = Sheets("Sheet1")
        Set ws2 = Sheets.Add
        ws1.Range("K1", ws1.Range("J" & Rows.Count).End(xlUp)).Copy ws2.Range("A1")
        Set rng = ws2.Range("A1", ws2.Range("B" & Rows.Count).End(xlUp))
        With ws2.Sort
            .SortFields.Clear
            .SortFields.Add Key:=Range("A1"), _
                            SortOn:=xlSortOnValues, _
                            Order:=xlAscending, _
                            DataOption:=xlSortNormal
            .SetRange rng
            .Header = xlNo
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        tbl = rng.Value
        For i = 1 To UBound(tbl, 1)
            For j = i + 1 To UBound(tbl, 1)
                If tbl(i, 1) <= tbl(j, 1) - 10 Then
                    stest dic, tbl, i, j
                    Exit For
                End If
            Next j
        Next i
        ws1.Range("L1").Resize(dic.Count).Value = Application.Transpose(dic.keys)
        Application.DisplayAlerts = False
        ws2.Delete
        Application.DisplayAlerts = True
    End Sub
    Private Sub stest(ByRef dic As Object, ByVal tbl, iMe As Long, iNext As Long)
        Dim i As Long
        For i = iNext To UBound(tbl, 1)
            dic.Add tbl(iMe, 2) & "--" & tbl(i, 2), ""
        Next i
    End Sub

(稲葉) 2015/09/04(金) 18:12


 K列は同じ値が存在せず、すでに昇順に並んでいる
 という前提なら、こういう話でしょうか。

   I列  J   K  →結果  M列
 1 A    5   1          1-3
 2 B   10   2          1-4
 3 C   15   3          1-5
 4 D   20   4          2-4
 5 E   25   5          2-5
                       3-5
 ----------------

 Sub test1()
     Dim j As Long
     Dim k As Long
     Dim p As Long

     Columns("M").NumberFormatLocal = "@"
     For j = 1 To 5
         For k = j + 1 To 5
             If Abs(Cells(j, "J").Value - Cells(k, "J").Value) >= 10 Then
                  p = p + 1
                  Cells(p, "M").Value = j & "-" & k
             End If
         Next
     Next
 End Sub

 判りやすさを優先して、5といった数値をそのまま使っていますが、
 実際に合わせてEndプロパティを使ったものに修正してください。

(γ) 2015/09/05(土) 16:46


 j,k は行番号なので、正確には、
    Cells(p, "M").Value = Cells(j, "K").Value & "-" & Cells(k, "K").Value
 がよいのかもしれない。今は、同じ結果になるが。

 もしくは、識別のために付けた文字列がI列だとすると、   
    Cells(p, "M").Value = Cells(j, "I").Value & "-" & Cells(k, "I").Value
 とするかですね。

(γ) 2015/09/05(土) 18:17


少し確認に時間がかかっていますが、おかげ様で解決の目途が立ってきました。
皆様、丁寧に回答して頂きありがとうござます。
まだまだ勉強不足ですので、勉強しながら進めていきたいと思います。

(julius) 2015/09/07(月) 12:46


コメント返信:

[ 一覧(最新更新順) ]


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