前提・実現したいこと
VBAでテーブルのrangeを ,(カンマ) で指定する方法の解説が知りたいです
上記"C5"の値「DDD」を選択したいとき、
テーブルで指定する場合、
listobjects(1).listcolumns(3).range(5).select listobjects(1).range(15).select
と、なるのは
Office TANAKAさんのページ
でわかったのですが、
listobjects(1).range(5,3).select
でも、指定できてしまいました。
このカンマで指定する方法ができる理由が
ネットで検索しても出てこなくてモヤモヤしています。
配列のような感じなのでしょうか?
rangeとcellの関係がよくわかっていない初心者ですが、
どこか参考になるサイトがあったら教えて頂きたいです
よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
このコロンで指定する方法ができる理由が
ネットで検索しても出てこなくてモヤモヤしています。
「,(カンマ)」の話ですね?
んとですね、、、、
activesheet.listobjects(1).range(5,3).select
と書いたとき、
Excel.Application.ActiveWindow.ActiveSheet.ListObjects(1).Range.Default(5, 3).Select
と書いたとエクセル君は忖度して読んでくれるようにVBAは作られています。
つまり、決まりきったことを長々と書かなくても、
省略して書いていいようになっているわけです。
で、
ListObjectのRangeプロパティは
ヘルプより抜粋~~
Excel 開発者用リファレンス
ListObject.Range プロパティ
指定されたリスト オブジェクトの適用範囲を表す Range オブジェクトを返します。
抜粋終わり~~
と、そのテーブルに設定されたセル範囲を返すわけですが、
個々のセルを示す引数はありません。(ヘルプに何も書いてないことを確認のこと)
ヘルプより抜粋~~
Excel 開発者用リファレンス
Range.Address プロパティ
コード記述時の言語で参照範囲を表す文字列型 (String) の値を返します。
構文式.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
抜粋終わり~~
引数があるプロパティは上記のように括弧の中に引数を書き示すよう書いてありますよね?
じゃぁ、Rangeの後の括弧とその中身の意味は?ということなんですが、
Range.Default(5, 3).Select
このようにデフォルトプロパティ(既定のプロパティ)を指定している意味になります。
同じように、
Worksheets(1)
は、Worksheets.Default(1)
という風に書いているのと同意になります。
(Worksheets.Item(1)でも同意ですので、Itemが既定のプロパティだとも言えます。
ただし、オブジェクトによっては違うプロパティが既定のプロパティかもしれません。
なのでDefault=Itemと暗記はしないで、いちいち調べて確認願います。)
じゃぁ、デフォルトプロパティって、どうやって使い方を調べるの?ってときは、
「オブジェクトブラウザ」を使って調べます。
手順としては、
F2キー押下でオブジェクトブラウザが開きます
右クリックで完全に一致するものを検索にチェック
検索窓に「Range」と入力して検索
検索結果のクラスの欄のRangeを選択
すると下のクラスの窓にRangeが選択されその右の窓にそのクラス(≒オブジェクト)のメンバー
が表示されます。
そこで、また右クリックで非表示のメンバーを表示にチェック
とすると(多少手順は前後してもよいかも?)、
_Default
というのがあると思うので、それをクリックすると、
下の欄に
Property _Default([RowIndex], [ColumnIndex])
と出てきます。
なので、
listobjects(1).range
が返すセル範囲の内、5行目の3列目のセルに対して何か操作したいなと思ったら、
activesheet.listobjects(1).range(5,3)
と書けばいいことがわかります。
も少し詳しく知りたいときは、同じ引数を持つ同じ機能のプロパティから
類推して(ここは経験や知識が必要にはなると思います)、
RangeオブジェクトのItemプロパティのヘルプを見ます。
ヘルプから抜粋~~
Excel 開発者用リファレンス
Range.Item プロパティ
指定したセル範囲のオフセット値で指定される範囲を表す Range オブジェクトを返します。
構文式.Item(RowIndex, ColumnIndex)
式 Range オブジェクトを表す変数。
パラメーター
名前 必須/オプション データ型 説明
RowIndex 必須 バリアント型 (Variant) 左から右に、次に上から下に数えて、アクセスするセルのインデックス番号を指定します。
Range.Item(1)は範囲の左上端のセルを返します。
Range.Item(2)は左上端のセルの右側のセルを返します。
ColumnIndex オプション バリアント型 (Variant) 範囲の最初の列を 1 または "A" として、アクセスするセルの列番号を示す数字または列文字を指定します。
抜粋終わり~~
コピペで分かり難いと思うので、ちゃんとヘルプを確認してください。
つまり、括弧の中の、引数を1つだけ指定したときは、
左から右を優先で数えた、何番目と認識してくれますし、
括弧の中を、左上のセルから数えて、1番目が行数、2番目が列数だと認識してくれることが、
わかります。
シート上のセルは2次元配列を可視化したものとも考えられますので、
2次元配列と同様な書き方が出来るようになってます。
また、セル範囲はセルの集合(=コレクション)とも考えられます。
なので、範囲の中の何番目という指定の仕方も出来るようになっています。
WorkBooks
WrokSheets
Cells
など、複数形なのはその集まりを示すからです。
このようにして、ヘルプとオブジェクトブラウザを駆使して、
プロパティやメソッドの利用の仕方を調べてプログラムを書いてきます。
入門書にはその辺のことが一切言及されていません。
そういう話をしても、難しすぎて勉強のモチベーションが続かないだろうというところだと思います。
なので、
ヘルプは、「初心者」への助けではなく、
「開発者」への助けなので、初心者にとっては意味が解らないことが、
書いてあります。
ヘルプをみてコードが書ければ、脱初心者と言えると思います。
とりあえず、ヘルプをいちいち確認する癖をつけてみましょう。
【Excel VBA】Rangeオブジェクトの既定のプロパティ…_Defaultプロパティ
ここで、課題。
ExcelVBA
1Sub test2() 2 ActiveSheet.Range(5, 3).Select 3End Sub
上記のコードは、
「VBA 実行時エラー ’1004’ アプリケーション定義またはオブジェクト定義のエラーです」
のエラーになるが、
1)原因は何?
2)どう書くのが正解?
調べたことを自分の言葉で説明出来たら、「理解できた。」と言えると思うので、
僕は「回答する」というところで勉強中です。
(掲示板には課題がたくさんあって、経験値を積むには恰好の場所です。)
~~ヘルプより抜粋~~
Excel 開発者用リファレンス
Worksheet.Range プロパティ
セルまたはセル範囲を表す Range オブジェクトを返します。
構文式.Range(Cell1, Cell2)
式 Worksheet オブジェクトを表す変数。
パラメーター
名前 必須/オプション データ型 説明
Cell1 必須 バリアント型 (Variant) セル範囲の名前を指定します。これは、コード記述時の言語の A1 形式での範囲である必要があります。範囲名には、範囲を表す演算子 (:)、共通部分を表す演算子 (スペース) または複数の範囲を表す演算子 (,) を含めることができます。また、ドル記号 ($) は含めることはできますが、無視されます。範囲の一部にローカルに定義した名前を使用できます。名前を使用する場合、その名前はコード記述時の言語と見なされます。
Cell2 オプション バリアント型 (Variant) セル範囲の左上隅と右下隅のセルを指定します。各引数には、単一のセル、列全体、または行全体を含む Range オブジェクト、あるいはコード記述時の言語で単一のセルの名前を示す文字列を指定できます。
~~抜粋終わり~~
ワークシートオブジェクトのRangeプロパティは、引数の指定が必須です。
なので先の課題の回答としては、
>1)原因は何?
ActiveSheet.Range.Default(5, 3).Select
という意味ではないのです。
なので、
>「VBA 実行時エラー ’1004’ アプリケーション定義またはオブジェクト定義のエラーです」
は、引数の指定の仕方が間違っている=オブジェクト定義のエラー
となります。
括弧の中は、セルのアドレスを示す文字か、Rangeオブジェクトを示す必要があります。
>2)どう書くのが正解?
Sub test3()
ActiveSheet.Range("A1")(5, 3).Select
End Sub
今までの話の流れで行くとこうなります。
こういう書き方は、ネット上のサンプルでは見かけませんが、
ヘルプを読んで考察し、実際に実験をしてみると、
こういう書き方が正解なんだろうなぁ。。。と今回こちらも勉強になりました。
ちょっと、一旦休憩。
追記
とりあえずrangeについての理解が全然足りてないので、そこから理解しようと試みました
Rangeとは何ぞやと、そこだけ追及すると混乱するかもです。
なぜなら、オブジェクトと呼ばれたりプロパティと呼ばれたりするからです。
なぜ、
「オブジェクトとは」
「プロパティとは」
ここを追求しないのでしょうか?
【Excel VBA入門】オブジェクトとは?初心者向けに概念をやさしく解説!
なかなか理解できなかったマクロ(Excel VBA)の「オブジェクト」について、セルの計算を例にあげて説明
僕がオブジェクトについて腑に落ちたのは変数にセル範囲を代入してみて、
ローカルウィンドウで中身を確認したときかなぁ。。。。
ExcelVBA
1Sub test() 2 Dim c As Range 3 4 Set c = Range("C5:F12") 5 Stop 6End Sub
こんなこと書いて実行してみて、Stopで止まった時に、
ローカルウィンドウの+cの、「+」をクリックしたときかなぁ、、、、
あとは、
ExcelVBA
1Sub test2() 2 Dim v 3 4 v = Range("C5:F12") 5 Set v = Range("C5:F12") 6End Sub
こんなコードをステップ実行してみて、
ローカルウィンドウのvの変化を確認してみたりするとわかるかと。。。。
ちなみにtest2のコードの省略されている部分を真面目に書くと以下のとおり。
ExcelVBA
1Sub test3() 2 Dim v as Variant 3 4 Let v = ActiveSheet.Range("C5:F12").Value 5 Set v = ActiveSheet.Range("C5:F12").Cells 6End Sub
こんな説明で、Rangeオブジェクトのイメージがつかめないでしょうか?
で、最初に戻ると、
>activesheet.listobjects(1).range(5,3).select
これは、
activesheet.listobjects.item(1).range.item(5,3).select
の略であり、
「アクティブシート上のテーブルの集まりのうちの一つ目のテーブルのセル範囲の5行目の3列目のセルを選択しなさい」
という意味の命令です。
たまたま、
リストオブジェクトのそのセル範囲を返すプロパティが「Range」と定義されていますが、
シート上のそのセル範囲を返すプロパティは、「Cells」であり、
シートのRangeプロパティは操作対象が違うので、同じ名前のプロパティでも、
違う使い方になる可能性があるということです。
この辺はVBAを開発した人が定義しているので、
使う側は受け入れるしかないです。
長くなりましたがRangeオブジェクトを理解するのに参考になれば幸いです。
追記
一行で書くから分かり難いのかも?
ExcelVBA
1Sub test4() 2 Dim ws As Worksheet 3 4 Dim rng As Range 5 Dim c As Range 6 7 Set ws = ActiveSheet 8 Set lst = ws.ListObjects.Item(1) 9 Set rng = lst.Range 10 Set c = rng.Item(5, 3) 11 12 MsgBox c.Address(False, False, xlA1, True) 13End Sub
沢山の変数を用意するまでもないので、
1行で書いているとも言えます。
> Dim lst As ListObject
> Set lst = ws.ListObjects.Item(1)
ListObjectが単数形だったり複数形だったりするのも違いを認識しておきましょう。
(も少し整理したら、入門書のコラムで使えそう。。。。。。な内容になってしまった^^;;)
投稿2020/02/27 09:47
編集2020/03/03 07:08総合スコア2136
0
mattuwanさんの回答とほぼ同内容ですが、私なりの説明で。
VBAでExcelのセルは Range オブジェクトで示されます。
この Range オブジェクトの取得方法としてよく知られているのが、
(Worksheet などの)Range
プロパティを使う方法と、
(Worksheet などの)Cells
プロパティを使う方法です。
(ここで注意したいのが、 Range オブジェクトとRange
プロパティは名前が似ていますが全く別の概念です)
では、今回の
VBA
1ListObjects(1).Range(5, 3).Select
は上記のどちらなのかというと、どちらでもないです。
しいて言うとCells
に近いです。
そもそもCells
というのはどんなプロパティかというと、
「親( Worksheet や Range など。省略時はActiveSheet
)のすべてのセルの集合」を示すプロパティです。
ヘルプなどを見ると、引数が定義されていないこともわかります。
親のすべてのセルの集合を示すため、Cells.Select
を実行してみると、最前面のシートのすべてのセルが選択されます。
Cells
自体は、親のすべてのセルを示すもので、引数が定義されていないとなると、
Cells(2, 1)
などはどういう意味になるのか?というところですが、
ここで出てくるのが、mattuwanさんの回答にもある既定のプロパティ(既定のメンバー)です。
Range オブジェクトには既定のメンバー(Range の場合_Default
)というのもが定義されており、位置の指定や値への変換を簡単にできるようになっています。
具体的には、Cells(2, 1)
という記述は
Cells.[_Default](2, 1)
と指定したものと解釈され、上記のヘルプにもあるように
Cells.Item(2, 1)
と解釈されます。
結果として「(最前面のシートの、)全てのセルの、左上から2行目の、1列目のセル」という意味になります。
この既定のメンバーの動作は、Range オブジェクトに定義されているものため、Cells
プロパティに限らず、Range オブジェクトを扱う場面ではだいたい使用できます。
では話をもどして
VBA
1ListObjects(1).Range(5, 3).Select
の件ですが、ListObject.Range
は、親のテーブル(ListObject)の、全てのセル(Range)を返すプロパティです。
プロパティの結果が __Range__オブジェクトである以上、上記の既定のメンバーが使用できるため、
ListObjects(1).Range(5, 3)
とすると
「(Worksheet 上の)テーブルの、1個目の、全てのセルの、左上から5行目の、3列目のセル」となります。
投稿2020/02/28 11:16
総合スコア2166
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
このコロンで指定する方法ができる理由が
コロンじゃなくてカンマですよね。
以下推測です。
WorksheetのRangeと、ListObjectのRangeでは持っているデータが異なるのではないでしょうか。
WorksheetのRangeの場合、範囲が不定(シート全体を表しているわけではない)ですから範囲を特定してからなら同様に(行,列)の参照が可能です。
VBA
1Set tmp = Worksheets(1).Range("A1:C7") 2tmp(5,3).Select
ListObjectの場合、範囲は既に特定されているため、(行,列)で参照が可能なのではないかと推測しました。
投稿2020/02/27 08:26
総合スコア16996
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/28 08:53
2020/03/02 00:39
2020/03/02 07:12 編集
2020/03/02 12:42
2020/03/03 06:57
2020/03/16 14:27