[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『セルを配列に入れて処理』(skyblue)
セルの値を一つ一つ読んで処理するのは遅いので配列に入れて処理したいと考えています。
下記のテストを試みましたがいずれも5行目でエラーが出ます。
正しい方法をご指導ください。
Sub t20190529()
Set aa = ThisWorkbook.Sheets("test2")
Dim p As Variant
p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
p1 = p(1): p29 = p(29)
Stop
End Sub
Sub t201905292()
Set aa = ThisWorkbook.Sheets("test2")
Dim p As Variant
p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
p1 = p(1, 5): p29 = p(29, 5)
Stop
End Sub
< 使用 Excel:Excel2016、使用 OS:Windows10 >
>5行目でエラー 5行目ってStopのことですか? Stop は実行を中断するステートメントですよ
中断させたくないのなら不要です。
(白茶) 2019/05/29(水) 11:26
変数宣言は全ての変数に行ってください。
話は、それが済んでからです。
(半平太) 2019/05/29(水) 11:27
ああ。 5行目って >p1 = p(1)
ここですね。 配列を初期化してないからか。失礼^^;
(白茶) 2019/05/29(水) 11:28
Step DebugしてLocal Windowで確かめれば原因はわかるはず。 (seiya) 2019/05/29(水) 11:30
Dim p(29)
For i = 1 To 29
p(i) = aa.Cells(i, 5) Next p1 = p(1): p29 = p(29)
(skyblue) 2019/05/29(水) 11:50
とりあえず 宣言出来ていない変数
aa (As Worksheet) p1 p29
(いずれもスコープが不明)
あとこれ
ローカルウィンドウの使い方|ExcelマクロVBA技術解説
https://excel-ubara.com/excelvba4/EXCEL266.html
(白茶) 2019/05/29(水) 11:59
・最初のコードは、2次元配列にセットしているのに1次元で取り出そうとしてる。
・次のコードは、2次元配列に1列分しかセットしていないのに、5列目を取り出そうとしている。
(???) 2019/05/29(水) 12:02
VBA(Excel)高速化対策 -配列化編- - Qiita
https://qiita.com/sango/items/c46a30c62e154077a0c7
(白茶) 2019/05/29(水) 12:05
Set p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
こうすると、pはRange型オブジェクトになるので、ご提示のような取り出し方もできます。 この場合は、pの変数宣言はVariantではなく、Range型にすべきでしょうね。
(???) 2019/05/29(水) 12:12
世の中にはすごい人がいる。
Sub t20190529()
Set aa = ThisWorkbook.Sheets("test2")
Set p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
p1 = p(1, 5): p29 = p(29, 5)
p1 = p(1): p29 = p(29)
Stop
End Sub
(skyblue) 2019/05/29(水) 12:47
>理由は分かりませんが、下記の方法でいずれも成功しました。
エラーがでなくなったとして、
当初の目的は達成したのでしょうか?
(マナ) 2019/05/29(水) 19:16
だと、aa には、レンジオプジェクトが格納される。
レンジオプジェクトはセルの集合体である。
よって、
p1 = p(1, 5): p29 = p(29, 5)
p1 = p(1): p29 = p(29)
はセルの値を一つ一つ読んで処理していることになる。
当初の目的は、
>セルの値を一つ一つ読んで処理するのは遅いので配列に入れて処理したい
???
(hatena) 2019/05/29(水) 21:21
Set p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
だと P にはレンジオプジェクトが格納される。
です。
(hatena) 2019/05/29(水) 21:23
Sub t20190529() Dim aa As Sheet Set aa = ThisWorkbook.Sheets("test2") Dim p As Range Set p = aa.Range(aa.Cells(1, 5), aa.Cells(29, 5))
Dim p1 As Variant, p29 As Variant
p1 = p.Cells(1, 1): p29 = p.Cells(29, 1) p1 = p.Cells(1): p29 = p.Cells(29) Stop End Sub
Cells は既定のプロパティなので省略できるので、
p.Cells(1) は p(1) と記述でき、配列のように見えるが、配列ではなくセル参照である。
また、
p1 = p(1, 5)
という書き方は間違いで、
これだと、l1 セルを参照することになる。
(hatena) 2019/05/29(水) 21:45
Sub test1() Dim aa As Worksheet Set aa = ThisWorkbook.Sheets("test2")
Dim p As Variant p = aa.Range(aa.Cells(1, 5), aa.Cells(29, 5)).Value
Dim p1 As Variant, p29 As Variant p1 = p(1, 1): p29 = p(29, 1)
Stop End Sub
Value を代入すると2次元配列になる。
Transposeで1次元配列に変換できるので、
下記のようにすることもできます。
Sub test2() Dim aa As Worksheet Set aa = ThisWorkbook.Worksheets("test2")
Dim p As Variant p = aa.Range(aa.Cells(1, 5), aa.Cells(29, 5)).Value p = WorksheetFunction.Transpose(p)
Dim p1 As Variant, p29 As Variant p1 = p(1): p29 = p(29)
Stop End Sub
(hatena) 2019/05/30(木) 09:40
> Set p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
この場合、p(1) は aa.Cells(1,5) であり、p(1,1)。 Rangeの先頭列をずらしただけなので、性能向上は無いですね。(アドレスを代入しただけであり、実体はコピーしていない) ずらしただけだから、p(30)とか、範囲外でも見れてしまうという。 これで用が足りるなら、代入なんてせずに、aa.Cells(1,5) のままで使えば良かった事でしょう。
お薦めだったのは、代入は元のまま使いVariant型の配列にして、あとは取り出し間違いだけ正すこと。
> p = Range(aa.Cells(1, 5), aa.Cells(29, 5))
これなら、1列だけとはいえ2次元配列なので p(1) とは書けませんが、p(1,1) とすれば、aa.Cells(1,5) が取り出せました。 1次元配列にする意味が無いように思えますし。
5列目から5列目まで取り出したので、出力は1列。 1列しかないのに5列目を取り出そうとしていたから、エラーになっただけ。 その間違いに気づいていれば、「理由は分かりませんが…」なんて事にはなっていなかったはず。
(???) 2019/05/30(木) 13:38
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.