[[20080521002252]] 『セル内で使われた数字の整理』(さっぱりダメ) ページの最後に飛ぶ

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

 

『セル内で使われた数字の整理』(さっぱりダメ)

質問内容

たとえばランダムな数字がA列に入っていて

B列で

A列で使われた数字を、重複しないように整理し

さらに昇降順に並び替える 

というのは可能でしょうか?

  A     B

1 123456   123456

2 115235   1235   

3 567583   35678

4 28     28

5 98776354  3456789

B列で並び替えまで同時にするのが難しければ

さらに横のC列で並び替えとしても、差し支えはありません。

SUMとCOUNTくらいしか関数を使ったことがなくて

やり方があるのかわかりませんでした。

どなたか教えてくださるととても嬉しいです。


 おはようございま〜す。。。♪

 一般機能のフィルタオプションの設定を
 使ってみてはいかがでしょうか?

 重複しないリストを作る(フィルタオプションの設定)

http://www.geocities.jp/chiquilin_site/data/060314_integrated_list.html

 その上で

 >昇降順に並び替える  

 ご参考にどうぞ。。

 。。。Ms.Rin〜♪

 VBAでの処理になると思いますので、ユーザー定義関数を作成してみます。
Alt+F11でVBEを開き、挿入→標準モジュールに下のコードをコピー&貼り付けします。
B1セルには=suji(A1) と入力します。  (Hatch)
Function suji(c As Range)
Dim i As Integer
        For i = 1 To 10
            If c.Value Like "*" & Right(i, 1) & "*" Then
                suji = suji & Right(i, 1)
            End If
        Next i
        suji = suji * 1
End Function

 だるまです。
http://hp.vector.co.jp/authors/VA033788/index.html

 >さらに昇降順に並び替える
 それは難しいですね。昇順か降順なら可能ですが。^d^


 あら〜ツ!!

 Hatchさんの回答みたら。。。

 なるほど、そういう事だったんですね。。

 質問をよく読まずに、カン違い。。
 トンチンカンな、回答で失礼しました〜♪

 > VBAでの処理になると思いますので

 Hatchさんのおしゃる通り、数式ではチョット無理ですね。。。

 。。。Ms.Rin〜♪♪


 だるまです。
http://hp.vector.co.jp/authors/VA033788/index.html

 茶茶だけでは何なので、フィルタオプションを使わないバージョンのコードです。^d^

 Sub Hogehoge()
    Dim RR As Range
    Dim V As Variant

    Set RR = Range("A1")
    Set RR = Range(RR, RR.End(xlDown))
    V = GetSummary(RR)
    V = Application.WorksheetFunction.Transpose(V)
    With RR.Offset(, 1)
        .ClearContents
        .Resize(UBound(V)).Value = V
    End With
 End Sub

 'Rangeを受け、重複の無い一次元配列を返す
 Private Function GetSummary(RR As Range) As Variant
    '返す配列の添え字下限は0
    Dim R As Range
    Dim Dic As Object
    Dim K As Variant
    Dim V As Variant

    Set Dic = CreateObject("Scripting.Dictionary")
    For Each R In RR.Cells
        K = R.Value
        If K <> "" Then
            Dic(K) = Empty
        End If
    Next
    V = Dic.keys
    Set Dic = Nothing

    GetSummary = Csort(V)    '並べ替え不要ならCsort()は不要
 End Function

 Private Function Csort(ByVal Target As Variant) As Variant
    '昇順並べ替え、引数は1次元配列のみ可
    Dim L As Long
    Dim U As Long
    Dim i As Long
    Dim gap As Long
    Dim Temp As Variant
    Dim F As Boolean

    L = LBound(Target)
    U = UBound(Target)
    gap = U - L
    F = True

    Do While gap > 1 Or F = True
        gap = Int(gap / 1.3)
        If gap = 9 Or gap = 10 Then
            gap = 11
        ElseIf gap < 1 Then
            gap = 1
        End If
        F = False
        For i = L To U - gap
            If Target(i) > Target(i + gap) Then
                Temp = Target(i)
                Target(i) = Target(i + gap)
                Target(i + gap) = Temp
                F = True
            End If
        Next
    Loop

    Csort = Target
 End Function

 削除・・・m(__)m   (by Hatch)

 ◆関数による方法です
 ◆ただし、1回では出来ないので2列になりました
	A	 B	      C
1	123456	 6543210       123456
2	115235	 503210	      1235
3	567583	 876503000     35678
4	28	 800000200     28
5	98776354	 9876543000    3456789

 B1=SUM(IF(ISNA(MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)),0,MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)*10^(ROW($1:$9))))
 ★この式は「配列数式」です。式を入力後、Ctrl+Shift+Enter をおして、式を確定させてください。
 ★確定すると、式の両端に{ }がつきます。
 ★確定させてから下にコピー

 C1=SUM(LARGE(MID(B1,ROW(INDIRECT("1:"&LEN(B1))),1)*1,ROW(INDIRECT("1:"&LEN(B1))))*10^(ROW(INDIRECT("1:"&LEN(B1)))-1))
 ★この式も「配列数式」です。同じように式を入力後、Ctrl+Shift+Enter をおして、式を確定させてください。
 ★確定すると、式の両端に{ }がつきます。
 ★確定させてから下にコピー
 (Maron)


 Maronさん
 こんにちは〜♪

 おひさしぶり〜です!!。。。
 私は、ムリそうでしたので考えもしなかったですが

 さすが〜!!私の先生。。
 なるほどです。。

 最近、あまり回答をお見かけしませんので。。
 もっと、いらして下さいネ。。。

 関係ないレスでゴメンナサイ。。

 。。。Ms.Rin〜♪♪


 ◆Ms.Rinさん、ご無沙汰しています
 ◆最近は回答しようと思ったら、すでに回答済みで、皆さんの回答を参考にさせていただいています
 ◆遅くなりましたが、1回で出来ました
 ◆0を考慮し、前に0を表示させるなら、文字列になりますが
	A	B
1	115235	1235
2	567583	35678
3	208	028
4	710017	017

B1=IF(ISNUMBER(FIND(0,A1)),0,"")&SUBSTITUTE(SUM(IF(ISNA(MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)),0,MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)*10^(10-(ROW($1:$9))))),0,"")

 ★もちろんこの式も「配列数式」です

 ◆0 を後ろに表示させるなら
	A	B
1	115235	1235
2	567583	35678
3	208	280
4	710017	170

B1=SUBSTITUTE(SUM(IF(ISNA(MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)),0,MID(A1,MATCH(ROW($1:$9),--MID(A1,ROW($1:$9),1),0),1)*10^(10-(ROW($1:$9))))),0,"")*10^(ISNUMBER(FIND(0,A1)))

 ★「配列数式」です
 (Maron)

 数字だけだったら、2次元配列を使用して

 Sub test()
 Dim a(), b(), i As Long, n As Long, myOrder As Long
 a = Range("a1").CurrentRegion.Resize(,1).Value
 ReDim b(1 To UBound(a,1), 1 To 1)
 myOrder = Application.InputBox("昇順=1, 降順=0",type:=1) '<- 変更
 With CreateObject("Scripting.Dictionary")
     For i = 1 To UBound(a,1)
         If (a(i,1) <> "") * (Not .exists(a(i,1))) Then
             n = n + 1
             b(n,1) = Val(a(i,1))
             .add a(i,1), Nothing
         End If
     Next
 End With
 If n > 0 Then
     VSortM b, 1, n, 1, myOrder
     Range("b1").Resize(n).Value = b
 End If
 End Sub

 Sub VSortM(ary, LB, UB, ref, myOrd As Long)  '<- 変更
 Dim i As Long, ii As Long, iii As Long, M, temp 
 i = UB : ii = LB 
 M = ary(Int((LB+UB)/2),ref) 
 Do While ii <= i 
     If myOrd <> 0 Then  '<- 変更
         Do While ary(ii,ref) < M : ii = ii + 1 : Loop 
         Do While ary(i,ref) > M : i = i - 1 : Loop 
     Else 
         Do While ary(ii,ref) > M : ii = ii + 1 : Loop 
         Do While ary(i,ref) < M : i = i - 1 : Loop 
     End If 
     If ii <= i Then 
         For iii = LBound(ary,2) To UBound(ary,2) 
            temp = ary(ii,iii) : ary(ii,iii) = ary(i,iii) : ary(i,iii) = temp 
         Next 
         i = i - 1 : ii = ii + 1 
     End If 
 Loop 
 If LB < i Then VSortM ary, LB, i, ref, myOrd 
 If ii < UB Then VSortM ary, ii, UB, ref, myOrd 
 End Sub
 (seiya)
 修正箇所あり


 タイトルとご説明のサンプルからでは
 一つのセルの値に関して
 >重複しないように整理し 
 >さらに昇降順に並び替える  
 だけで良いように思いますので、私も
 ユーザー定義関数で
 '----
Function kzn(kz As Range)
Dim i As Integer, x(10)
    For i = 1 To Len(kz.Value)
        x(Mid(kz.Value, i, 1)) = Mid(kz.Value, i, 1)
    Next i
    kzn = (Join(x, "") & x(0)) * 1
End Function
 '----

 ちなみに、seiyaさんのは
 コンパイルエラー「ByRef 引数の型が一致しません。」
 が表示され
 >     VSortM a, 1, n, 2, myOrder
 の内 [myOrder]が反転(灰色)します。

 (HANA)

 HANAさん同もです。
 修正してみました。
 (seiya)

 ん?seiyaさん、これってどの様に成れば良いのですか?
 ↓の様になりますが・・・。
	[A]	[B]
[1]	123456	115235
[2]	115235	567583
[3]	567583	28
[4]	28	115235
[5]	98776354	123456
[6]	115235	567583
[7]	567583	98776354
[8]	208	280
[9]	710017	170

 (HANA)

 げっ...
 b(), n を宣言しておきながら、頓珍漢なことをしていました...
 修正しました。
 (seiya)

 この質問は、HANAさんの例でしたら、以下のようになればいいのかな?
 だるまさん、seiyaさんとは解釈が違っているようですが・・・
 上までの回答を以下のコードに変更しておきます。なお、上の回答&コードは削除(^^ゞさせていただきました。
   (Hatch)
	A	B
1	123456	28
2	115235	170
3	567583	280
4	28	1235
5	98776354	35678
6	115235	123456
7	567583	3456789
8	208	
9	710017	
 
 だるまさん、seiyaさんのコードを実行すれば↓のようになります。
	A	B
1	123456	28
2	115235	208
3	567583	115235
4	28	123456
5	98776354	567583
6	115235	710017
7	567583	98776354
8	208	
9	710017	
  
Sub test99()
    Dim x, y, z, myCnt
    Dim i As Long, j As Long, lastRow As Long
        lastRow = Cells(Rows.Count, 1).End(xlUp).Row
        x = Range(Cells(1, 1), Cells(lastRow, 1)).Value
    ReDim y(1 To lastRow, 1 To 1)
        For i = 1 To lastRow
            For j = 1 To 10
                If x(i, 1) Like "*" & Right(j, 1) & "*" Then
                    y(i, 1) = y(i, 1) & Right(j, 1)
                End If
            Next j
        Next i
     
    With CreateObject("Scripting.Dictionary")
        For i = 1 To UBound(y, 1)
            If Not .Exists(y(i, 1)) Then .Add y(i, 1), Empty
        Next
        Range("B1").Resize(.Count).Value = _
            Application.Transpose(.Keys)
    End With
    lastRow = Cells(Rows.Count, 2).End(xlUp).Row
 
    Range("B1:B" & lastRow).Sort _
        Key1:=Range("B1"), _
        Order1:=xlAscending, _
        Header:=xlNo, _
        Orientation:=xlTopToBottom
End Sub


 おっと、私が先に載せたseiyaさんの結果図の内
 B8:B9は前のデータが残ってたみたいですね。
 失礼しました。

 後は
 >Sub VSortM(ary, LB, UB, ref, myOrd As Long) 
 の前に「End Sub」が入れば
 Hatchさんが書かれている結果に成りますね。

 (HANA)

 あれ?修正時にEnd Sub 消してしまったようですね。
 元通りにしておきました。
 二次元配列を並び替えするときにでも使用してください。
 QuickSortを基に書いてあります。
 (seiya)

 こんにちは〜♪

 きょうは、お仕事も忙しくないので。。。
 関数案も、Maronさんだけだし。。。

 それに、最初はトンチンカンな回答してしまいましたので〜。。!!

 名誉挽か〜いいい!!。。。
 という事で。。。
 Maronさんの考え方をチョット盗んで。。。

 B1セルへ
 =REPT(0,ISNUMBER(FIND(0,A1)))&SUM(SMALL(IF(ISNUMBER(FIND(ROW($1:$10)-1,A1)),
(ROW($1:$10)-1),0),ROW($1:$10))*10^(10-ROW($1:$10)))

 配列数式です。。Ctrl+Shift+Enterキーで式を確定します。。
 式が{  } で囲まれます。。
 その式を下へコピー。。。

 ★データの中に、0(ゼロ)があるとやっぱり厄介ですね。。。
 上の式は、0 がある場合、最初に 0 を持ってきてます。
 その場合、文字列になります。。

 ★最後を 0 にする場合は
 こちらは、数値になります。。

 =(SUM(SMALL(IF(ISNUMBER(FIND(ROW($1:$10)-1,A1)),(ROW($1:$10)-1),0),
ROW($1:$10))*10^(10-ROW($1:$10)))&REPT(0,ISNUMBER(FIND(0,A1))))*1

 同じく配列数式です。。

 ご参考にどうぞ。。。

 。。。Ms.Rin〜♪♪


 ちなみに、
 vba array のソートはFunctionだと使用メモリーが倍になってしまうので渡された配列が巨大な場合は
 問題が発生すると思います。
 Transpose関数も然りです。
 (seiya)

 だるまです。
http://hp.vector.co.jp/authors/VA033788/index.html

 久しぶりにここを覗いて、私が頓珍漢な回答をしていることに気付きました。

 「昇順降順」だけに反応して、A列のデータを重複カットしてB列に並べる、ものと思い込んでいましが、
 最初の例を良く見ると、各セル内の値一つ一つに対してその中で重複カット&昇順にして隣のB列に表示
 が正しい質問内容だったようですね。(^^ゞ

 すでに幾つもの回答がでていますので、もう私の出番はなさそうです。どうもお騒がせしました。^d^


 ◆こんどは、Ms.Rinさんの考え方をチョット盗んで
	A	B
1	123456	123456
2	115235	1235
3	567583	35678
4	28	28
5	98776354	3456789
6	208	280
7	710017	170

 B1=SUMPRODUCT((SMALL(INDEX(ISNUMBER(FIND(ROW($1:$10)-1,A1))*(ROW($1:$10)-1),),
ROW($1:$10))*10^(10-(ROW($1:$10))))*10^(ISNUMBER(FIND(0,A1))))
 ★Enterで式を確定後、下にコピー
 (Maron)

 ふたたび〜です。。。♪

 Maronさん、フムフム。。ソ〜カッ。そ〜か。
 なるほど〜!!。。。

 ┌─┬──────┬─────┐
 │  │     A      │    B     │
 ├─┼──────┼─────┤
 │ 1│      123456│    123456│
 ├─┼──────┼─────┤
 │ 2│      115235│      1235│
 ├─┼──────┼─────┤
 │ 3│      567583│     35678│
 ├─┼──────┼─────┤
 │ 4│          28│        28│
 ├─┼──────┼─────┤
 │ 5│    98776354│   3456789│
 ├─┼──────┼─────┤
 │ 6│         208│       280│
 ├─┼──────┼─────┤
 │ 7│      710017│       170│
 └─┴──────┴─────┘

 更に、Maronさんのアイデアをお借りして(2回目)。。。
 チョッピリ、微調整。。。

 B1セルへ
 =SUMPRODUCT(SMALL(INDEX(ISNUMBER(FIND(ROW($1:$10)-1,A1))*(ROW($1:$10)-1),),ROW
($1:$10))*10^(10+ISNUMBER(FIND(0,A1))-(ROW($1:$10))))

 下へコピー。。。

 。。。Ms.Rin〜♪♪


 HANA さんのビンソート、スマートですね♪

 ところで
     10000
 のときは、
     01
が求める並びでしょうか? それとも 1 でいいのかな?
   (kanabun)


 kanabunさんの仰っている事も気になるところですが・・・
 お遊びで考えてみましたw
 
 =--(IF(LEN(SUBSTITUTE(A1,"1",))=LEN(A1),"","1")&
IF(LEN(SUBSTITUTE(A1,"2",))=LEN(A1),"","2")&
IF(LEN(SUBSTITUTE(A1,"3",))=LEN(A1),"","3")&
IF(LEN(SUBSTITUTE(A1,"4",))=LEN(A1),"","4")&
IF(LEN(SUBSTITUTE(A1,"5",))=LEN(A1),"","5")&
IF(LEN(SUBSTITUTE(A1,"6",))=LEN(A1),"","6")&
IF(LEN(SUBSTITUTE(A1,"7",))=LEN(A1),"","7")&
IF(LEN(SUBSTITUTE(A1,"8",))=LEN(A1),"","8")&
IF(LEN(SUBSTITUTE(A1,"9",))=LEN(A1),"","9")&
IF(LEN(SUBSTITUTE(A1,"0",))=LEN(A1),"","0"))
 
 (キリキ)(〃⌒o⌒)b

コメント返信:

[ 一覧(最新更新順) ]


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