• 締切済み

セル範囲から一次元配列の生成

VBAで動的に一次元配列を作成しようと思っています。 Dim DataList01 DataList01 = Array("項目01", "項目02", "項目03") のような配列を DataList01 = Array(Range("A1:A3").Value) などという方法で作成することはできないでしょうか? 動的に作成したArrayを、ユーザー設定リストに登録し、 ソートを行おうと考えていますが DataList01 = Array(Range("A1:A3").Value) Application.AddCustomList Listarray:=DataList01 で行うと、登録時点でエラーが発生します。 (実行時エラー '13':型が一致しません。) 行や列の情報を除外した、RangeからValueの配列の抜き出し方を 知っている方はお願い致します。

みんなの回答

  • end-u
  • ベストアンサー率79% (496/625)
回答No.5

>インデックスをインクリメントしないと >ソートのCustomOrderに使用できないエラーは >office2007だと直ってたりするんでしょうか? 直っていません。 2007では新たにSortオブジェクトが追加されていて その[SortFields.Add メソッド]の引数[CustomOrder]ではListarrayそのものを指定するように変更されているようです。 でも2003と2007互換を保とうとするなら従来のSortメソッドを使う事になるでしょう。 2007でも従来のSortメソッドが使えます。 その場合http://support.microsoft.com/kb/134913/jaこのバグは解消されていません。 これは、試してもらえばすぐわかる事ですよね? 『2003と2007が両方使う環境で使用するもの』であれば、両方の環境でテストする必要があります。 もし貴方が他の人に使ってもらうマクロを提供している立場で、稼働環境を限定できないのなら その辺りのテストの手間を省いてはいけないのではないですか? 掲示板で訊くのもいいかもしれませんけど、その場合はせめてテストコードを提示するべきだと思います。 Option Explicit Sub Custom_SortTest()   Dim iListIndex As Long   Dim vSort   vSort = Array("b", "c", "a")   Application.AddCustomList ListArray:=vSort   iListIndex = Application.GetCustomListNum(vSort)   With Sheets.Add.Range("A1:A3")     .Value = [{"c";"b";"a"}]     .Sort Key1:=.Cells, _        Header:=xlNo, _        OrderCustom:=iListIndex     Debug.Print "1", Join(Application.Transpose(.Value))     .Sort Key1:=.Cells, _        Header:=xlNo, _        OrderCustom:=iListIndex + 1     Debug.Print "2", Join(Application.Transpose(.Value))   End With   Application.DeleteCustomList (iListIndex) End Sub あと、また余談ですが >Valueをとってあげたほうがよさそうですね。 というのは配列にとったほうが良いという意味でしょうか。 それともValueプロパティを抜いてRangeで指定したほうが良いという意味? (前者だとは思いましたが念のため) セル範囲を指定した場合エラーが出るのはバグですし、 http://support.microsoft.com/kb/211811/ja 2007でも解消されていません。 バグを避けたコードのほうが良いと思いますよ。

  • end-u
  • ベストアンサー率79% (496/625)
回答No.4

本筋とちょっとハズれるけど、実験コード。 Sub test()   Dim ws As Worksheet   Dim v, DataList01      v = [{"aaa";"bbb";"ccc"}]   Set ws = Sheets.Add   ws.Range("A1:A3").Value = v   ws.Range("B1:B3").Value = v   DataList01 = Array(ws.Range("A1:A3").Value)   On Error Resume Next   With Application     .AddCustomList ListArray:=DataList01     MsgBox "ご質問状況" & vbLf & Err().Number & ":" & Err().Description     Err().Clear     .AddCustomList ListArray:=ws.Range("A1:A3")     MsgBox "追加1-1 " & .CustomListCount     .AddCustomList ListArray:=ws.Range("B1:B3") 'ws.Range("A1:A3")     MsgBox "追加1-2 " & .CustomListCount     MsgBox "重複登録の場合" & vbLf & Err().Number & ":" & Err().Description     .DeleteCustomList (.GetCustomListNum(v))     MsgBox "削除後 " & .CustomListCount     Err().Clear          .AddCustomList ListArray:=ws.Range("A1:A3").Value     MsgBox "余談ですが" & vbLf & "追加2-1 " & .CustomListCount     .AddCustomList ListArray:=ws.Range("A1:A3").Value     MsgBox "追加2-2 " & .CustomListCount     MsgBox "余談コードのエラー" & vbLf & Err().Number & ":" & Err().Description     .DeleteCustomList (.GetCustomListNum(v))     MsgBox "削除後 " & .CustomListCount   End With   Set ws = Nothing End Sub 意外と面白い結果です。 文字列の配列を指定した時だけ ヘルプ通り『追加済みのリストを指定したときは、このメソッドは無効になります。』 #失礼。ぷち情報でした。

potluckker
質問者

お礼

おー! Rangeオブジェクトの重複登録はエラーになって、 文字列配列の場合は無効でスルーされるんですね。 登録時に If Application.GetCustomListNum(DataList1) = 0 Then '登録 End If としているので、エラーは発生しないでしょうけど。 Valueをとってあげたほうがよさそうですね。 ありがとうございます!!!!!

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 すでに、#2のend-uさんがご指摘のように、CustomList は、特に、配列にする必要はないはずです。単に、Range の範囲だけではいると思います。Helpには、「文字列の配列または Range オブジェクトを指定します。」となっています。 Application.AddCustomList Range("A1:A3") もし、入らないなら、それは、すでにCustomList に存在しているかものだったりするはずです。通常、マクロの場合は、Sort と組み合わせて使うし、後で、Application.DeleteCustomList i(←CustomListCountで数を取る) で、削除します。

potluckker
質問者

お礼

わざわざRangeやRange().ValueをArrayに突っ込んでいたからいけなかったのですね。 ありがとうございます。 インデックスは Application.GetCustomListNum(Listarray:=DataList1) というふうに取り出しているのですが インデックスをインクリメントしないと ソートのCustomOrderに使用できないエラーは office2007だと直ってたりするんでしょうか? 2003と2007が両方使う環境で使用するもので・・・

  • end-u
  • ベストアンサー率79% (496/625)
回答No.2

配列経由しなくてもできますが、あえて、なのですよね? Application.AddCustomList Listarray:=Range("A1:A3").Value >行や列の情報を除外した、RangeからValueの配列の抜き出し方を DataList01がVariant型なので DataList01 = Range("A1:A3").Value Application.AddCustomList Listarray:=DataList01 とすれば良いです。 DataList01は二次元配列になります。 一次元配列にしたいならTranspose関数を使います。 DataList01 = Application.Transpose(Range("A1:A3").Value)

potluckker
質問者

お礼

あえて、ではありません 知らなかったのです・・・・。 ありがとうございます。 Transposeか!すっかり忘れていました。 でも、そのままつっこむだけで勝手にリストにしてくれるようなので そのまま使いたいと思います。 ありがとうございました!

  • kmetu
  • ベストアンサー率41% (562/1346)
回答No.1

Dim buf As Variant buf = Range("A1:A3").Value で二次元配列 buf(n,1) にデータを格納できます。 DataList01 = Array(buf(1,1),buf(2,1),buf(3,1)) Application.AddCustomList Listarray:=DataList01 とかできませでしょうか。

potluckker
質問者

お礼

回答ありがとうございます。 二次元配列のものにアクセスして、一次元データをとるのですね。 その場合配列が長いと、Loopしなければいけなくなってしまいますので。 ちょっとためらわれます。

関連するQ&A

  • 多次元配列のソートがうまくいかない

    多次元配列のソートがうまくいかない 質問失礼します. 以下のような,String型,int型,double型の混在した多次元配列([3][3]の配列)をソートするプログラムを作成しました. このプログラムでは3番目の項目でソートを行っています. 問題点なのですが, 3番目の項目がdouble型の一桁(例えばarray[1][2]が2.0)ならばうまくソートできるのですが, 一つを2桁(例えばarray[1][2]を10.0)にすると何故か先頭の数(10.0の場合1)を基準にソートされてしまっているようです・・・ 配列へのデータの入れ方が間違っているのでしょうか? 原因がはっきりわからず困っているのですが, わかる方いましたらよろしくお願いします. public class Sort_test { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String[][] array = new String[3][3]; array[ 0 ][ 0 ] = "A"; array[ 0 ][ 1 ] = 2001+""; array[ 0 ][ 2 ] = 9.0+""; array[ 1 ][ 0 ] = "B"; array[ 1 ][ 1 ] = 1001+""; array[ 1 ][ 2 ] = 2.0+""; array[ 2 ][ 0 ] = "C"; array[ 2 ][ 1 ] = 3001+""; array[ 2 ][ 2 ] = 6.0+""; TheComparator comparator = new TheComparator(); // 3番目の項目でソートするように設定 comparator.setIndex( 2 ); // ソート実施 Arrays.sort( array, comparator ); dump(array); } public static void dump( String[][] array ) { for ( int i = 0;i < array.length;i++ ) { for ( int j = 0; j < array[ i ].length;j++ ) { System.out.print( "\t" + array[ i ][ j ] ); } System.out.println(); } } } //多次元配列ソート用クラス class TheComparator implements Comparator { /** ソート対象のカラムの位置 */ private int index = 0; /** ソートするためのカラム位置をセット */ public void setIndex( int index ) { this.index = index; } public int compare( Object a, Object b ) { String[] strA = ( String[] ) a; String[] strB = ( String[] ) b; return ( strA[ index ].compareTo( strB[ index ] ) ); } }

    • ベストアンサー
    • Java
  • 3次元配列を1次元配列に

    例えば2次元配列だと, array[row*i+j] = a[n]; といったように1次元に直すことができますよね? 同様に3次元配列を1次元配列にしたい場合には arrayの中はどのような式をつかえばいいのでしょうか。 よろしくお願いします。

  • 多次元配列のソートについて

    始めまして。 多次元配列のソート方法について分からないことがある為教えていただけないでしょうか。 $a[0] = array('2007/3/1','あ100','その他'); $a[1] = array('2007/3/1','あ200','その他'); $a[2] = array('2007/3/2','あ200','その他'); $a[3] = array('2007/3/2','あ300','その他'); $a[4] = array('2007/3/3','あ50','その他'); 上記のような配列があった場合、usort関数でやると、日付かその後ろの数値の値を元にソートできますが、両者の関係を持たせたソートは可能でしょうか。 結果としては $b[0] = "2007/3/3 あ50"; $b[1] = "2007/3/2 あ200"; $b[2] = "2007/3/2 あ300"; $b[3] = "2007/3/1 あ100"; $b[4] = "2007/3/1 あ200"; というようにしたいのです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 多次元配列の並び変えについて

    <?php $food["a"]["1"]= "hoge1"; $food["b"]["2"]= "hoge2"; $food["c"]["3"]= "hoge3"; $food["d"]["4"]= "hoge4"; ?> 上記の配列について、1,2,3,4のキーの順番でソートしたいのですが、うまく出来ません。 一次元配列だと簡単なのですが、二次元配列だとどうやったらよいのでしょうか? array_multisortを使うと、多次元でも並び変えはできると他のサイトで読みましたが、 これは結局値でソートしてますよね? 私は純粋にキーのみでソートしたいのですが、色々調べているのですがどうも複雑なプログラムを 書かないとできないような気がしてきました。

    • 締切済み
    • PHP
  • 多次元配列のソートの仕方について

    Arrayクラスにsortというメソットについて質問です。 配列が多次元の場合、そのどれか1次元についてソートしたいのですが使い方がわからなく質問しました。 たとえば、a[n][m]という配列で a[0][0]=4 a[0][1]=3         a[0][0]=4 a[0][1]=3 a[1][0]=5 a[1][1]=5    →    a[1][0]=7 a[1][1]=4 a[2][0]=7 a[2][1]=4         a[2][0]=5 a[2][1]=5 だとします。 この配列をmの値が1のときについて最初の[n]をソートしたいです。 そして、mの値が0の値も[1]でソートしたものと一緒にソートしたいです。

  • 3次元配列の記述

    VB6.0を使っています。 2次元配列は以下の様になりますが、3次元配列はどう記述すればいいのでしょうか? Dim phrase(1) As Variant phrase(0) = Array("0-0", "0-1", "0-2") phrase(1) = Array("1-0", "1-1", "1-2")

  • VB.NET 2次元配列

    二次元配列に関して質問があります。 二次元配列を定義します。 Dim a(,) As Integer = _ {{0, 0, 0, 0, 0, 0, 1, 1, 1}, _ {0, 0, 0, 0, 0, 1, 0, 0, 1}, _ {0, 0, 0, 0, 0, 0, 1, 1, 1}} 一次元配列を定義します。 Dim b() As Integer 一次元配列のb()に二次元配列a(,)の {0, 0, 0, 0, 0, 0, 1, 1, 1}の部分を 入れようとした場合、 どのように記載すればよろしいでしょうか? イメージ的には b = a(0) で出きると思ったのですが、 構文エラーとなってしまいます。 よろしくお願いします。

  • 二次元配列のソート PHP

    タイトルのとおりソートを行ってくれる関数を探しております。 $buf[][]の二次元配列の変数を日付の降順に並べ替えたいのですが、そういった関数は用意されていますか? sort()、rsort()では不可能かと思います。 以下、二次元配列の値です。配列三番目の日付の降順で再格納したいです。 ( [0] => Array ( [0] => 1[1] => name1 [2] => 2006-08-18 ) [1] => Array ( [0] => 2 [1] => name2[2] => 2006-08-28 ) [2] => Array ( [0] => 3[1] => name3 [2] => 2006-08-18 ) [3] => Array ( [0] => 4 [1] => name4[2] => 2006-08-18 ) よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • 2次元配列 ソート

    はじめまして。 FLASH8を使っています。 2次元配列のソートがうまくいかず困っています。 Array[0][0] = "かかか"; Array[0][1] = "ききき"; Array[0][2] = "くくく"; Array[1][0] = "あああ"; Array[1][1] = "いいい"; Array[1][2] = "ううう"; とあって2番目の要素(「ききき」「いいい」の部分です)をキーとしてArray[n]を昇順にソートしたいのです。 この場合結果としては、 Array[0][0] = "あああ"; Array[0][1] = "いいい"; Array[0][2] = "ううう"; Array[1][0] = "かかか"; Array[1][1] = "ききき"; Array[1][2] = "くくく"; となります。 ご存知の方がいらっしゃいましたら教えてください。 よろしくお願いします。

    • ベストアンサー
    • Flash
  • 多次元配列

    初歩的な質問ですみません。 PHPプログラミングでの質問です。 仮に、多次元配列Aに、 Array( [0] => Array ( [0] => 6 ) [1] => Array ( [0] => 2 [1] => 1 ) [2] => Array ( [0] => 0 [1] => 5 [2] => 4 ) ) 多次元配列Bに、 Array( [0] => Array ( [0] => りんご ) [1] => Array ( [0] => ぶどう [1] => パイナップル ) [2] => Array ( [0] => みかん [1] => すいか [2] => メロン ) ) のように値が入っている場合、配列Aの値を参照して 値の大きいものから順に、それに対応する配列Bの値を取り出し、 あたらしい配列Cに代入する処理の書き方を教えて下さい。 上記の例ですと、配列Cが、 Array ( [0] => りんご [1] => すいか [2] => メロン [3] => ぶどう [4] => パイナップル [5] => みかん ) となるようにしたいです。 よろしくお願いします。 長文失礼しました。

    • ベストアンサー
    • PHP

専門家に質問してみよう