[[20220703085203]] 『二次元配列を一次元配列へ』(みなちゃん) ページの最後に飛ぶ

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

 

『二次元配列を一次元配列へ』(みなちゃん)

おはようございます。

Range("A1:C5")に文字データが入っているとします。これを一次元配列に変換する方法を考えています。

配列 = Range("A1:C5").Value
配列 = WorksheetFunction.Transpose(配列)

ではだめだというのはローカルウインドウを見ていて思うのですが、これを一次元配列に直すにはどうすればいいのでしょうか。

< 使用 Excel:Office365、使用 OS:Windows10 >


例えば、A1:C3がこんなデータの場合
欲しい一次元配列を教えていただけますか

    -A-  -B-
 1   1    4
 2   2    5
 3   3    6

(マナ) 2022/07/03(日) 09:19


そのあと、一次元配列をどのように利用でするのでしょうか。
二次元配列のままでは使いにくいのでしょうか。

(マナ) 2022/07/03(日) 09:22


 訂正
 >A1:C3がこんなデータの場合
      ↓
   A1:B3がこんなデータの場合
(マナ) 2022/07/03(日) 09:43

マナさん

早速お返事いただきましてありがとうございました。

説明が足りず申し訳ございませんでした。特になにか作らなければならないコードがあるのではなく、自分の学習のためにちょっとしたコードを組んで、動作確認をしていたのです。このような目的で掲示板を使って申し訳ございません。

最初のデータは、Range("A1:C5")の5行3列の二次元配列で、ローカルでもそのようになっています。これを一次元配列としてローカルで確認できるようにするためには...というものでした。余計わかりにくいですね。縦一列と書いておけば余計なお時間を取らせませんでしたね。申し訳ございませんが、ご指導いただけますか。

プラスアルファで申し訳ございませんが、Range("A1:E1")のような場合、配列としては、一次元と言えばいいのでしょうか、それとも二次元なのでしょうか。
(みなちゃん) 2022/07/03(日) 09:54


 ぶつかった
 (10分ぐらい更新してなかっただけか)

 >Range("A1:C5")に文字データが入っているとします。これを一次元配列に変換する方法を考えています

 どんな感じの一次元配列なのかイメージ表現できますか?

 1列ないし1行づつケツにつなげた感じなんですかね?
 イメージとしては、二次元側がけし飛びそうだって感じなんですけど。
(What) 2022/07/03(日) 10:06

 >プラスアルファで申し訳ございませんが、Range("A1:E1")のような場合、配列としては、一次元と言えばいいのでしょうか、

 Range("A1:E1")に書き込む場合は、1次元がてっとり速いですが、
 基本的にセル範囲の場合は、2次元です。
(What) 2022/07/03(日) 10:25

こんな感じでしょうか

    For k = 1 To UBound(二次元, 2)
       For j = 1 To UBound(二次元, 1)
           n = n + 1
           一次元(n) = 二次元(j, k)
       Next

    Next

(マナ) 2022/07/03(日) 10:33


マナさん

ご指導ありがとうございます。ループで処理するのですね。わたしはなにか関数みたいなものがあるのかなと思っておりました。大変勉強になりました。

Whatさん

縦方向にデータが並んでいる場合は一次元、横方向に並んでいる場合は、例えば1行しかなくとも二次元と解釈しました。

お二人とも、お休みのところ、本当にありがとうございました。

(みなちゃん) 2022/07/03(日) 10:52


 >Range("A1:E1")のような場合、配列としては、一次元と言えばいいのでしょうか、

 あまり突き詰めて考えたことはないなぁ・・
 以下、にわかに考えてみたら・・ですが、

 そもそも Range("A1:E1")は、配列ではないと言う認識が正しい。
 データ配列じゃないですからねぇ。
 じゃ、何と言うのか → セル範囲です。なので、1行と称するのが正しい。

 次に、このValueプロパティですが、これは値になっているので、配列と呼ぶ。
         ↓ 
 v = Range("A1:E1").Value

 1次元の要素が1つ(しかないので、ちょっと特殊)の2次元配列である。

 最後に、vが1次元でも、2次元でも、
 何故このコードが旨く動作するのか?
    ↓
 Sub Samle()
     Dim v
     v = Array(1, 2, 3, 4, 5) 'vは1次元
     Range("A3:E3") = v

     v = Range("A3:E3")  'vは2次元
     Range("A5:E5") = v
 End Sub

 答えは、マイクロソフト社のプログラマーがそうなるように
 Valueプロパティ(のプログラム)を作ったからです。ここが分かってない人が多い。
 まぁ、Valueプロパティ(のプログラム)を見せて貰った人はいないでしょうけどね。

(半平太) 2022/07/03(日) 11:48


横からごめんなさい。私も今回の書き込みを見ながら勉強させてもらっています。

半平太さんが書かれたものを実行すると

一次元(n) = 二次元(j, k)

で実行時エラー13、型が一致しません

と出ます。ともにバリアント型で宣言しています。

教えていただけますか。
(しの) 2022/07/03(日) 15:11


しのさんへ
Sub から End Sub まで省略せずに書いたらどうですか?
そうしないと実情がわかりません。
(γ) 2022/07/03(日) 15:16

γさん、マナさん

移動中でしたので、お返事ができませんでした。またしのさんから書き込みがあって、いま自宅へ帰り、以下のようなものを作り動かしてみましたが、同じようなエラーでした。原因が同じかはわかりませんが、ここに貼り付けたいと思います。

Sub test15()
Dim 二次元
Dim 一次元
Dim k As Long
Dim j As Long
Dim n As Long

二次元 = Range("A1:C5").Value
For k = 1 To UBound(二次元, 2)

    For j = 1 To UBound(二次元, 1)
        n = n + 1
        一次元(n) = 二次元(j, k) '←ここで方が一致しないとなります。
    Next
Next

End Sub

(みなちゃん) 2022/07/03(日) 17:03


 私も横からですみません。

 >ともにバリアント型で宣言しています。
 とありますが、
 Dim 一次元 As Variant
 の様に宣言されているのではありませんか?
 Variant型が万能型だといっても、
 配列だと明示せず(配列の要素数も不明)、
 一次元(n) = 二次元(j, k) とすると、実行時エラー13になります。

    Sub Macro1()
        Dim 一次元(), 二次元
        Dim k As Long, j As Long, n As Long
        二次元 = Range("A1:C5").Value
        ReDim 一次元(1 To UBound(二次元) * UBound(二次元, 2))
        For k = 1 To UBound(二次元, 2)
            For j = 1 To UBound(二次元, 1)
                n = n + 1
                一次元(n) = 二次元(j, k)
            Next
        Next
    End Sub
(もみじ) 2022/07/03(日) 17:18

 それは  一次元 という変数が配列であることが指示されていないから、
 突然 一次元(n) = 二次元(j, k) と言われても、Excel君は困ってしまうわけです。

 例えばこんな風に。

 Sub test()
     Dim 二次元 As Variant
     Dim 一次元() As Variant
     Dim k As Long, j As Long, n As Long

     二次元 = Range("A1:C5").Value

     ReDim 一次元(1 To UBound(二次元, 1) * UBound(二次元, 2))
     For k = 1 To UBound(二次元, 2)
         For j = 1 To UBound(二次元, 1)
             n = n + 1
             一次元(n) = 二次元(j, k)
         Next
     Next
     'シートへの書き込み
     Range("E1").Resize(UBound(一次元, 1), 1) = Application.Transpose(一次元)
 End Sub

(γ) 2022/07/03(日) 17:21


もみじさん、γさん

ありがとうございます。本当に配列は学習しはじめでわからないことだらけなのです。ご指導、本当にありがとうございます。

もしよろしければ、Dimのところで、どんなときに()をつけるのか、どんなときは不要なのかを教えていただけるとうれしいのですが...。程度の低すぎる質問というのはわかっていますので、記載されているサイト情報だけでもかまいませんので、どうかお願いできますか。
(みなちゃん) 2022/07/03(日) 17:40


補足いたしますと、上の例ですと、「二次元」には( )はありません。なのに一次元には( )をつけないといけない、というところに??となった次第です。繰り返しますが、低レベルな質問ですので、ヒントだけでもかまいません。お相手くださる方、ご指導お願いいたします。
(みなちゃん) 2022/07/03(日) 17:47

セルの値を
二次元 = Range("A1:C5").Value
のようにセルの値を変数に受けるときは、
配列を値に持つVariant変数"二次元"が自動的に作成されます。

一次元(n) = 二次元(j, k)のように、
自分で作った値をもとにして、それを配列に入れるときは、
配列であることを自分が宣言しないとできません。

ネットで"VBA 配列”と検索してください。それぐらい自分でやってください。

(γ) 2022/07/03(日) 17:58


γさま

ごめんなさい、なにからなにまで。そうですよね....

ありがとうございました。
(みなちゃん) 2022/07/03(日) 18:04


>一次元(n) = 二次元(j, k)
>で実行時エラー13、型が一致しません
>と出ます。ともにバリアント型で宣言しています

右辺と左辺で型が違うという意味ではないですよ。

左辺が、配列ではないのに、
配列のように扱おうとして
型が違うというエラーになったのだと思います。

なので、一次元という変数を
配列として宣言してあげるのです、

>一次元には( )をつけないといけない、というところに?

(マナ) 2022/07/03(日) 18:24


 技術的な詳しいことはわかりませんので間違っているかもしれませんが、
 ()を付けるというか、()内に次元数・要素数を記述することによって、
 その変数が配列を扱う変数だと宣言しているのだと思います。
 ただし、()内の次元数・要素数を省略して宣言することも出来るというだけで。
 そのあたりは静的配列/動的配列について理解をされると良い気がします。

 参考ページへのリンクです。
https://excel-ubara.com/excelvba4/EXCEL209.html
https://excel-ubara.com/excelvba4/EXCEL284.html
https://excel-ubara.com/excelvba1/EXCELVBA414.html
(もみじ) 2022/07/03(日) 18:40

マナさん、もみじさん

ご説明いただきましてありがとうございます(涙)。またもみじさんにおかれましては、URLも提供くださいましてありがとうございます。アドバイスのとおり、サイトを見ながら、基本的なところを今日の夜に早速学習をしたいと思います。
(みなちゃん) 2022/07/03(日) 19:01


# しのさんという方は、音沙汰なしになってしまいましたが、
# こういう追加質問を横からするのはめったにありません。
# みなちゃんさんの分身だったのですか?

ところで、お手元にはどんな書籍をお持ちですか?
ネットの紹介という質問に、つっけんどんな回答をしてしまいましたが、
VBAのことを学習しようとするなら、書籍を購入されることを推奨します。

ネットでは色々なTipsを検索するのには向いているかも知れませんが、
今回のような配列の基本的な考え方、とかいったテーマなどは、
ネットでつまみ食いするようなことではなく、
きちんとしたテキストを読まれたほうがよいと思います。
また、このテーマに限らず、一貫したものを通読することによって、知識の偏りも防げます。
ネットでは自分の興味のままに検索しますから、どうしても偏りが出てきてしまいます。
ちょこちょことネット検索する程度でマスターできるようなものでもありません。
一応プログラム言語なので、それなりの学習は必要になります。

学習方法など各人の自由と言えばそれまでですが、
自分なりの理解を進めながら、書き込みなどをして書籍を活用するのが効果があるとは思います。

(γ) 2022/07/03(日) 21:49


 > そもそも Range("A1:E1")は、配列ではないと言う認識が正しい。
 > データ配列じゃないですからねぇ。
    ↑
 考えてみたら、配列はデータ配列に限った訳じゃなかった m(__)m

 Sub Sample()
     Dim r(1 To 5) '一次元配列

     Set r(1) = Range("A1")
     Set r(2) = Range("C1")
     Set r(3) = Range("B1:E3")
     Set r(4) = Sheets(1)
     Set r(5) = Sheets

     Debug.Print r(1).Address    '$A$1
     Debug.Print r(2).Address    '$C$1
     Debug.Print r(3).Address    '$B$1:$E$3
     Debug.Print r(4).Name       'Sheet1
     Debug.Print r(5).Count      ' 1    
 End Sub

(半平太) 2022/07/04(月) 09:31


コメント返信:

[ 一覧(最新更新順) ]


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