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

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

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

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

Q&A

解決済

3回答

1616閲覧

VBAでテーブルのrangeを ,(カンマ) で指定する方法の解説が知りたいです

bors

総合スコア11

VBA

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

0グッド

0クリップ

投稿2020/02/27 07:35

編集2020/03/02 07:15

前提・実現したいこと

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の関係がよくわかっていない初心者ですが、
どこか参考になるサイトがあったら教えて頂きたいです
よろしくお願い致します。

追記
ワークシートのrangeプロパティ

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

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

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

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

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

guest

回答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
mattuwan

総合スコア2136

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

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

mattuwan

2020/02/28 08:53

反応がないですねー。 意味が解らなくてあきらめたのかなぁ。。。。 勉強する時間がないのかなぁ。。。。 ギブアップならギブアップで反応が欲しいかなぁ。。。
bors

2020/03/02 00:39

ご返答遅くなり申し訳ございません。 長文でご解説頂いて、これはきっちり理解したいと思いまして、 今日の午前中時間を作れそうなので、もう少しお待ちいただけないでしょうか。 頂いた内容をもうちょっと自分で考えてご報告したいです。すいません。
bors

2020/03/02 07:12 編集

すいません遅くなりました。 とりあえずrangeについての理解が全然足りてないので、そこから理解しようと試みました rangeオブジェクトとrangeプロパティは全然違うもので、さらに rangeオブジェクトは範囲でありセルブロック1つでもあり プロパティは  値を返すもの  オブジェクトを返すもの があり、rangeプロパティはオブジェクト(rangeオブジェクト)を返す。 下記頂いた課題 Sub test2() ActiveSheet.Range(5, 3).Select End Sub がなぜダメなのかは、これまた教えて頂いたオブジェクトブラウザを使用すると、 cellsで指定するように書いてあるので、cellsで記述するようになる。 コメントらんでの画像の貼り方わからないので、質問に貼っておきます cellsで書かないといけない理由はttyp03さんのおっしゃるとおり、rangeの範囲が指定されていないためわからない。 imihitoさんのおっしゃるとおり、cellsプロパティは親(シート全体)のrangeをかえすものだから、位置が決まるのかなと考えました。 これで合っているでしょうか? またよくわからないのが、 ListObjects(1).Range.Default(5,3) の”range”はプロパティなのでしょうか? このrangeがオブジェクトなら理解ができそうな気がするのですが。。 オブジェクトブラウザをみるとrangeクラスのメンバーとしてrangeプロパティとデフォルトプロパティが 一緒に並んでいるので、オブジェクトにしかみえません。 ただのオブジェクトブラウザでlistobjectを見るとrangeはプロパティですよね。あれおかしい。 そもそもオブジェクトの下にオブジェクトは入らないのか。listobjectの中にrangeオブジェクトは内包されているイメージでいいんでしょうか? 時間かけた割にまとまっていなくてすいません。
mattuwan

2020/03/02 12:42

パソコンがないで簡単に。 ワークシートオブジェクトのrangeプロパティのヘルプをよく読んで下さい。
mattuwan

2020/03/03 06:57

>ListObjects(1).Range.Default(5,3) の”range”はプロパティなのでしょうか? RangeプロパティがRangeオブジェクトを返して来て、 そのRangeオブジェクトのDefaultプロパティで、 そのRangeオブジェクトの内の5行目3列目を引数で指定しています。
bors

2020/03/16 14:27

ご返事遅くなり大変申し訳ございません。 追記まで拝見し、なぜワークシートもセットしているんだろう?と思って、プロパティがわかっていなかったとわかりました。rangeの前を全部オブジェクトだと思っていました。お恥ずかしい。 載せて頂いたサイトとPACラボさんのhttps://tech-paclab.com/rangeproperty/をみて、構造が理解できたと思います。 ”同じ名前のプロパティでも、違う使い方になる可能性がある”そうなんですね!!同じ使い方になると考えていたので、そういうこともあるのかとすっきりしました。 Range("A1")(5, 3)については括弧が2つ続く記述になる理由がわからず、https://thom.hateblo.jp/entry/2016/05/30/213658 を参考にRange("A1").[_Default](5, 3)の略なのかと思ったりしていますが、まだわかりそうもありません。 丁寧に説明して頂いてるのにポンコツで申し訳ないです。基本を勉強していきます。 当初のlistobjectのrangeの疑問については理解できたと思います。 お付き合い頂きましてありがとうございました。
guest

0

mattuwanさんの回答とほぼ同内容ですが、私なりの説明で。

VBAでExcelのセルは Range オブジェクトで示されます。

この Range オブジェクトの取得方法としてよく知られているのが、
(Worksheet などの)Rangeプロパティを使う方法と、
(Worksheet などの)Cellsプロパティを使う方法です。

(ここで注意したいのが、 Range オブジェクトとRangeプロパティは名前が似ていますが全く別の概念です)

では、今回の

VBA

1ListObjects(1).Range(5, 3).Select

は上記のどちらなのかというと、どちらでもないです
しいて言うとCellsに近いです。


そもそもCellsというのはどんなプロパティかというと、
「親( WorksheetRange など。省略時は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

imihito

総合スコア2166

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

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

bors

2020/03/16 14:34

お礼大変遅くなり申し訳ありません。”上記のどちらなのかというと、どちらでもないです”そうなんですね。mattuwanさんに追記して頂きやっとわかったと思います。 itemプロパティとの関係を説明して頂いたおかげでなぜrange(15)とrange(5,3)ふたつの方法で指定できるかわかりました。ありがとうございました。
guest

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

ttyp03

総合スコア16996

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

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

bors

2020/03/02 00:24

回答ありがとうございます。 返答遅くなり申し訳ありません。 ご指摘の通りカンマです。 rangeが範囲(コレクション)だという概念からわかっていなかったので、 まだすべてを理解できてませんが、納得できました。 範囲指定すればcellsで指定しなくてもいいんですね!!知らなかったです!! わかりやすくお答えいただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問