質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

15984閲覧

Excel、VBAで複数の範囲を格納したrangeオブジェクトを、配列のように操作したい

funmas

総合スコア31

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/12/24 02:55

前提・実現したいこと

Excel, VBAにおいて、
離れた複数の範囲を取得し、それらのみを配列のように ※array(1,3), array(24,100)など
操作(取得・反映)したい

該当のソースコード

vba

1Dim hoge As range 2Set hoge = ThisWorkbook.Worksheets("Sheet1").range("A1:A3,C1:C3") 3hoge = 123 4hoge(1, 2) = 55 5hoge(1, 4) = 55

試したこと

rangeオブジェクトで、値の設定(一括のみ)は出来たが、
値の設定(単一セル)と、値の取得が行えない

hoge=123 でA1A3, C1C3に全て「123」が反映されるが、
hoge(1,2) でC1に反映されず、B1に「55」が反映されてしまう
また、hoge(1,4)など明らかな範囲外にも設定できる

目的

VBAのFindで一致したものから、Offsetで値反映を行いたい為
A1A1000がキー列
E1
E1000が取得したい値の場合、

A列HITで、offset(1,5)と取得しなければならないが、
A列とE列のみを引っ張り、offset(1,2)のように取得したいため

補足情報(FW/ツールのバージョンなど)

Excel2013

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Rangeは配列ではないですからね。
hoge(1, 2) = 55は、実際はhoge.Cells.Item(1, 2) = 55です。(.Cells.Itemは既定のプロパティなので省略できる)
Range.Item プロパティ (Excel) | Microsoft Docs
上記のヘルプに「返される範囲の最初の領域の左上のセルへの相対的な1ベースのオフセットです。」との記述があります。

極力シンプルに記述するなら下記のような感じでしょうか。

vba

1 Dim hoge As Range 2 Set hoge = ThisWorkbook.Worksheets("Sheet1").Range("A1:A3,C1:C3") 3 4 hoge.Value = 123 5 hoge.Areas(2)(1) = 55 '2つ目のエリア(C1:C3)の最初のセル(C1)

A列HITで、offset(1,5)と取得しなければならないが、

A列とE列のみを引っ張り、offset(1,2)のように取得したいため

2だろうが5だろうがマジックナンバーには変わりないので、
可読性を重視したいということなら、私なら下記のような実装にするかな。

vba

1 With ThisWorkbook.Worksheets("Sheet1") 2 Dim keyRng As Range: Set keyRng = .Range("A1:A1000") 3 Dim valueRng As Range: Set valueRng = .Range("E1:E1000") 4 End With 5 6 Dim FoundCell As Range 7 Set FoundCell = keyRng.Find(What:="hoge") 8 9 valueRng(FoundCell.Row) = "HIT"

投稿2019/12/24 03:27

編集2019/12/24 03:58
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

funmas

2019/12/24 03:57

いつも回答ありがとうございます! プロパティが省略されているとは知りませんでした。 左上基点のため今回のような処理が行えたわけですね。 Areasプロパティは一度発見したのですが、 そのような記述方法を見つけられず、目的の用途と違うものかと見逃していました。 まさかカッコを連続で使用するとは・・・(配列のようにカンマ区切りで書いてみていた) やりたいことは教えていただいたAreasで見事に実現できました 大変助かりました、ありがとうございます! PS.範囲を2列以上まとめて設定する運用はしないため問題なさそうです
funmas

2019/12/24 05:06

追加の回答ありがとうございます。 Withでそこまでキレイに書けるとは驚きです。ぜひ参考にさせていただきます。 Rowでの取得に関しては、一度挑戦したのですが、 参照範囲が1行目から始まっていないと取り回しが難しいようで、 A5セルがHITし、B2~B1000の範囲に、Rowで値を代入すると、 B6セルに代入されてしまうことが問題でしたが、 ここに関しては、開始行でズレた分、.Rowから差し引いて代入しようかと思います キレイなコードですので、一度こちらで作成してみたいと思います。 ありがとうございました!
hatena19

2019/12/24 05:27

valueRng(FoundCell.Row - valueRng(1).Row + 1) = "HIT" とするかな。うーん、あまりスマートでないですね。 結局下記のような感じが一番シンプルかな。 Const valueOffset = 5 ・・・ FoundCell.Offset(, valueOffset) = "HIT"
funmas

2019/12/24 05:44

いえ! valueRng(FoundCell.Row - valueRng(1).Row + 1) = "HIT" こちら個人的にかなりスマートです。 Rowを手入力で確保しなければと考えていましたが、 valueRng(1).Row このような記述でも取得できるとは・・・! もとよりクラス化にしてブラックボックスなつくりで運用する予定でしたので、 むしろこの記述方はありがたいです。 これで運用したいと思います!ありがとうございます!
imihito

2019/12/24 10:44

横から失礼します。 私の場合、見つかったセルをEntireRowで行全体にしてからIntersectで取得することが多いです(ちょっと大仰な感じはありますが) Intersect(FoundCell.EntireRow, valueRng).Value = "HIT"
guest

0

解決済みのようですが。。。

ExcelVBA

1Sub test() 2 Dim rng As Range 3 Dim vv(1 To 2) As Variant 4 Dim ix As Long 5 6 Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:A30,E1:E30") 7 Set vv(1) = rng.Areas(1) 8 Set vv(2) = rng.Areas(2) 9 10 On Error GoTo WayOut 11 ix = WorksheetFunction.Match(123, vv(1), 0) 12 On Error GoTo 0 13 14 MsgBox vv(2)(ix).Value 15 16WayOut: 17End Sub

無理やり感が半端ないですね^^;
クラスを作るなら、どうにでもなるかと思いますが、、、、
敢えてクラスを自作する必要性があるのかな。。。。

ExcelVBA

1Sub test2() 2 Dim Rng As Range 3 Dim ixRow As Variant 4 Dim sProm As String 5 6 Set Rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:E30") 7 ixRow = Application.Match(123, Rng.Columns(1), 0) 8 9 If IsError(ixRow) Then 10 sProm = "見つかりませんでした。" 11 Else 12 With Rng(ixRow, 5) 13 Application.Goto .Cells 14 sProm = .Address(False, False) 15 End With 16 End With 17 18 MsgBox sProm 19End Sub

投稿2019/12/24 08:33

mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問