[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『二次元配列を一次元配列へ』(みなちゃん)
おはようございます。
Range("A1:C5")に文字データが入っているとします。これを一次元配列に変換する方法を考えています。
配列 = Range("A1:C5").Value
配列 = WorksheetFunction.Transpose(配列)
ではだめだというのはローカルウインドウを見ていて思うのですが、これを一次元配列に直すにはどうすればいいのでしょうか。
< 使用 Excel:Office365、使用 OS:Windows10 >
-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 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
一次元(n) = 二次元(j, k)のように、
自分で作った値をもとにして、それを配列に入れるときは、
配列であることを自分が宣言しないとできません。
ネットで"VBA 配列”と検索してください。それぐらい自分でやってください。
(γ) 2022/07/03(日) 17:58
ごめんなさい、なにからなにまで。そうですよね....
ありがとうございました。
(みなちゃん) 2022/07/03(日) 18:04
右辺と左辺で型が違うという意味ではないですよ。
左辺が、配列ではないのに、
配列のように扱おうとして
型が違うというエラーになったのだと思います。
なので、一次元という変数を
配列として宣言してあげるのです、
>一次元には( )をつけないといけない、というところに?
(マナ) 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.