[[20160309230445]] 『シートにデータを書き込む前に、配列の並び替えを』(マリオ) ページの最後に飛ぶ

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

 

『シートにデータを書き込む前に、配列の並び替えをしたい』(マリオ)

 シートにデータを書き込む前に、配列の並び替えをしたい

 次のコードは、シートにデータを書き込んでから、並び替えをしてます。

 ★やりたいこと
 ★シートに書き込む前にデータを並び替えて、並び替えたデータをシートに書き込みたい。
 ★どんなコードにすればいいかアドバイスお願い致します。
 ★nn配列のデータの数字が小さい順に、nn配列を並び替えたい。
 ★対応して、ad配列も並び替えたい。

 Sheet2に、次のように表示したい。
     |[A]         |[B]
  [1]|$R$3:$AD$12 |  2
  [2]|$C$15:$O$24 |  3
  [3]|$R$15:$AD$24|  4
  [4]|$C$3:$O$12  | 11

 Sub 並び替え()
     Dim ad(1 To 4) As String
     Dim nn(1 To 4) As String

     With Worksheets("Sheet2")
         .UsedRange.Clear
          ad(1) = "$C$3:$O$12"
          ad(2) = "$C$15:$O$24"
          ad(3) = "$R$15:$AD$24"
          ad(4) = "$R$3:$AD$12"
          nn(1) = "11"
          nn(2) = "3"
          nn(3) = "4"
          nn(4) = "2"
         '*************************************************
         'シートに書き込み
          For j = 1 To UBound(ad)
             .Range("A" & j).Value = ad(j)
             .Range("B" & j).Value = CLng(nn(j))
          Next j
         '*************************************************
         '並び替え
          With .Sort.SortFields
               .Clear
               .Add key:=Range("B1"), Order:=xlAscending
          End With
          With .Sort
               .SetRange Range("A:B")
               .Header = xlNo
               .Apply
          End With
         '*************************************************
     End With
 End Sub

< 使用 Excel:Excel2003、使用 OS:Windows 8.1 >


 < 使用 Excel:Excel2013、使用 OS:Windows 8.1 >でした。
(マリオ) 2016/03/09(水) 23:07

>シートにデータを書き込む前に、配列の並び替えをしたい
それはなぜですか?
Excelに備わった機能を利用するのがよいと思いますが。

どうしてもというなら、
「VBA 配列のソート」
などでネット検索してみてください。
色々なアルゴリズムがあるはずです。
回答者も務められているんですから、検索くらいしてくださいよ。
(γ) 2016/03/09(水) 23:13


ついでに言うと、座標計算のスレッドはそのままですか?
式の展開が間違っているのは見直せばすぐにわかるはずですが。

(γ) 2016/03/09(水) 23:18


 γさん、すいません。 結構めんどくさそうですね。
 ちょっと検索しただけでも。1次元配列の並べ替え(バブルソート,クイックソート)
 バブルソートを使ったとして、nn配列は並び替えられますけど、対応して、ad配列も並び替えるのは
 どうしたら、いいんだろう。検索続けます。

 座標計算のスレッドは…。見直しま〜す。

(マリオ) 2016/03/09(水) 23:34


 >結構めんどくさそうですね。
 ですから、一度作ったら 他のプログラムでも使いまわしができるようにインターフェースをじっくりと
 考えてつくるのです。そうすれば、面倒なのは一度だけ、後は、どこでも使えるようなインターフェースを
 使って、呼び出すだけで やりたいソートが出来てしまいます。

 コンピュータソフトって、上(OS)から下(ユーザーアプリ)までこの考えの積み重ねですよね
(ichinose) 2016/03/10(木) 08:15

 ichinoseさんがいわれるように、一度つくっておいて、それをどこかに保存しておいて、使う場合にインポートすれば
 そこは、ブラックボックスとして利用できますね。

 ただ、β個人は、基本的には、処理内で、配列ソートは使わないですね。(あくまで個人的な好みです)

 どんな秀逸なアルゴリズムを組み立てようと、エクセルのシート上のセル領域ソートにかなうものはないという記事を読んだことがあります。
 極端にいえば、マリオさんのコードのように配列をシートに落とし込み、そこで並び替えて必要なら、また配列に取り込むのがベストかも。
 (別トピ、45万件、70万件の処理でマリオさん自身が、シートの並び替えを加えても、処理時間がそんなに増えないということは実感されていますよね)

 テーマである ad配列のソートはソートの基準がないわけですから、このままでは並び替えができないですね。
 さがせば2次元配列の配列ソートのコードは、いろいろ紹介されていますので(やるのであれば)ad配列とnn配列を2列の二次元配列にして
 nn列側で並び替えということでできると思います。

 昔、興味がありましたので自作をしたものがあります。
 シート上の並び替えは昇順であれ降順であれ、空白が下のほうになるわけですが、一般に紹介されているものは、そうならないので
 そこのところ、ちょっと苦労したことを思い出します。
 ただ、その部品を今も重宝して使っているかというと、そうではなく、お蔵入りですね。

 シート上で処理したほうが早いですし簡単ですし、その部品を使う意味がほとんどない。

 どうしても、メモリー内で並び替えたい場合は SortedList を使ったり ArrayListを使ったりはしますけど。
 並び替えをテーマにすると SortedListが、専門機能でしょうけど、同じキーを扱えないということがあって、
 同じキーでも格納できるArrayListも使ったりします。VBAで使う場合、こちらのほうは、Dictionaryと同じく、内部データを一挙に配列として
 取り出すことができるので好きなんですが、キー、データという構造ではなく キーのみ(データのみ)という難点があって
 今回のような nnベースでadも、ということだと、格納時に少し手間をかけなきゃいけません。

 たまたま、マリオさん提示のデータ、nn配列に重複がないということで、SortedListも使えます。
 無理やり(?)SortedListとArrayListで処理すると以下のようなコードになりますね。

 ただ、今回のデータというかテーマならシートにおとして処理します。以下は、あくまで、こんな処理もできるというサンプルです。

 Sub TestA()    'ArrayList キー重複OK ただしキー部分の桁数をあわせる必要あり
    Dim al As Object
    Dim i As Long
    Dim v As Variant

    Set al = CreateObject("System.Collections.ArrayList")

    al.Add Format(11, "00") & vbTab & "$C$3:$O$12"
    al.Add Format(3, "00") & vbTab & "$C$15:$O$24"
    al.Add Format(4, "00") & vbTab & "$R$15:$AD$24"
    al.Add Format(2, "00") & vbTab & "$R$3:$AD$12"

    al.Sort

    v = al.toarray()

    For i = LBound(v) To UBound(v)
        v(i) = Array(Split(v(i), vbTab)(1), Split(v(i), vbTab)(0))
    Next

    Cells.Clear
    Range("A1").Resize(al.Count, 2).Value = WorksheetFunction.Transpose(WorksheetFunction.Transpose(v))

 End Sub

 Sub TestS()    'SortedList 'キー重複NG
    Dim sl As Object
    Dim i As Long
    Dim v As Variant

    Set sl = CreateObject("System.Collections.SortedList")

    sl(11) = "$C$3:$O$12"
    sl(3) = "$C$15:$O$24"
    sl(4) = "$R$15:$AD$24"
    sl(2) = "$R$3:$AD$12"

    ReDim v(0 To sl.Count - 1, 0 To 1)

    For i = 0 To sl.Count - 1
        v(i, 0) = sl.getbyindex(i)
        v(i, 1) = sl.getkey(i)
    Next

    Cells.Clear
    Range("A1").Resize(sl.Count, 2).Value = v

 End Sub

(β) 2016/03/10(木) 08:38


 >テーマである ad配列のソートはソートの基準がないわけですから、このままでは並び替えができないですね。
 >さがせば2次元配列の配列ソートのコードは、いろいろ紹介されていますので(やるのであれば)
 >ad配列とnn配列を2列の二次元配列にして nn列側で並び替えということでできると思います。
 >どうしても、メモリー内で並び替えたい場合は SortedList(同じキーを扱えない) を使ったり 
 >ArrayListを使ったりはしますけど。

 βさん、サンプルありがとうございます(>_<)
  TestAをじっくり見てます。使うことがあれば、見様見真似で使えそうです。

 独り言です。
 ***********************************************************************
 【ArrayList キー重複OK ただしキー部分の桁数をあわせる必要あり】
  al.Add Format(11, "00") & vbTab & "$C$3:$O$12"
  al.Sortで、タブの前の文字を並び替えしてるんですね。

  al.Add Format(11, "00") & vbTab & "$C$3:$O$12" & vbTab & "あいうえお"
  みたいにすれば、対応している情報を増やせますね。
 ***********************************************************************

 以下、初耳でした。ありがとうございます。 ペコリ m(_ _)m
 System.Collections.ArrayList、
 【オブジェクト】.Add
 【オブジェクト】.Sort
 v = 【オブジェクト】.toarray()
 SplitでArray配列をV配列に格納(区切り文字はタブ)

 System.Collections.SortedList
 getbyindex
 getkey
(マリオ) 2016/03/10(木) 18:16

コメント返信:

[ 一覧(最新更新順) ]


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