• ベストアンサー

データ型とオブジェクト型 プログラムとしてどちらが適切なのか??

Sub test1() Dim R As String R = Cells(1, 1) MsgBox R End Sub Sub test2() Dim R As Range Set R = Cells(1, 1) MsgBox R End Sub どちらも同じ結果が返ってきます。 プログラムとしてどちらが適切なのでしょうか? サンプルなどで多く見かけるのはtest2なのですが 気のせいでしょうか?

  • zxdaeg
  • お礼率98% (546/553)

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんにちは。 #3 さんへの回答のお礼の >具体的にどこがどう正しくないのでしょうか? Rangeオブジェクトに、.Value プロパティを入れない、いわゆる「暗黙のプロパティ」が、悪いと書いたテキストなんていうのは、ほとんどないはずです。それに、データ型の型キャストも言語の仕様で、お任せでも、現代のプログラミング言語なら、ほとんど通用するはずです。 ただ、私としては、「どこがどう正しくないか」と聞かれたら、細かいことを言えば、#4に書いた事実もあるのですが、今さら、旧VBを持ち出しても、あまり意味がありません。一般的には、概して、分からないというしかありません。あえていうなら、それは、「コーディング・ルール」と言ったほうがよいと思います。 VBAは、本格的なプログラミング作法を求められるわけではないし、結果が同じなら、作法や方法は、お構いないとも言えます。特殊な条件でないとエラーが出ないようなことを、気にするなんてナンセンスかもしれません。 ここのカテゴリの、自称「専門家」さんのほとんどの人のコードは、VBAのコーディング・ルールを無視したものです。それで「専門家」として通用するなら、世の中怖いものなどありません。 今どきは、「コードが美しくない」なんていう気の抜けたことを言う人はいませんが、かといって、それに携わる人がいる以上は、素人マクロのままで済ませられないと思うのです。 ある程度のVBAの経験の積んだ人は、お手本のサンプルコードを何度も読んで、真似てきた結果があるのではないか、と思うのです。何百、何千とコードを書いてみて、それで理屈は後で付いてくるものだと思います。そう書く理由や意味を求めても、微妙なところを大事に出来るか出来ないか、その違いだと思います。それが上達の要だといったら、大げさかもしれませんが、「神は細部に宿る」とも言います。そういう微妙なところなのだと考えたほうがよいと思います。

zxdaeg
質問者

お礼

たくさんコードを書くことで慣れていくのですね! ありがとうございます。参考になりました。

その他の回答 (4)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。 >データ型とオブジェクト型 プログラムとしてどちらが適切なのか?? これ自体は、データ型に目がいっているからで、それは、「求める戻り値が何か」によって決めなくてはいけません。MsgBox なら、本来、テキストであるはずですから、厳密には、String 型しかありません。ただ、データ型のキャスティングという機能がありますから、数値型でも、String 型として認識します。 今回は、オブジェクト型を使っているので、少し状況が変わってきます。 ある程度、Excel VBAの経験がある人が、質問のコードをみると、.Value プロパティを省略するのが良いかどうか、ということに目が行くものだと思います。 古い VBAの本を見ると、.Value プロパティを省略して書いているものもあります。一体、どちらが正しいのか、どちらでもよいのか、そういう疑問は、解説している本やWebサイトも少ないし、ぬぐいきれない疑問のひとつのはずです。なかなか即断というわけにはいきません。 現在のVBAに慣れている人は、.Value プロパティを省略するのは、なんとなく、見慣れないと感ずるはずです。 Excel VBAをある程度の使っている方は、Range オブジェクトの .Value プロパティ、.Text プロパティ、.Value2 プロパティを使いこなしていくわけですが、.Value プロパティだけを省略するわけにはいかないはずです。可読性が落ちるという言い方をする人もいますが、エラーが発生するわけではないので、一般的には、慣習的なものとして考えてもよいです。 VBからとか、他の言語から、Excelを扱ったりすると、こうした省略したコードに思わぬエラーが返ることがあります。それは、間違いなく、.Valueプロパティなどのデフォルト・プロパティを省略したときに発生します。 ただし、厳密に言えば、.Valueプロパティは、デフォルト(Default = 標準)・プロパティではありません。デフォルト・プロパティは、非表示のプロパティの中の、[_Default]ですので、プロパティを省略すると、.Valueプロパティになるという仕様です。VBAには、明示的(Explicit)・暗黙的(Inexplicit)という言葉がありますので、.Value プロパティがない場合に、.Valueプロパティを付けた状態と同じになるので、Rangeオブジェクトの「暗黙のプロパティ」としています。 http://officetanaka.net/excel/vba/speed/s8.htm 「標準のプロパティであるValueプロパティを省略しない方がやや遅いようです。しかし、個々の所要時間では速い回もあり、結果として差はないと判断してもいいと思います。」 有名なVBAインストラクターのサイトのひとつですが、この著者は、「実行速度」に対して着目していますが、少なくとも、この問題は、「高速化」とは無縁のものです。 '------------------------------------------ ''オートメーションを使った一例(通常は、Error は発生しません) ''ところが、場合によって、プロパティを見失うことがあります。 Sub Test1() Dim xlApp As Object Dim oBook As Object Dim mPath As String Const sFNAME = "TEST1.xls" Set xlApp = CreateObject("Excel.Application") mPath = xlApp.DefaultFilePath & "\" & sFNAME Set oBook = xlApp.Workbooks.Open(mPath) With oBook   MsgBox .Worksheets(1).Cells(1, 1) '暗黙的( = .Value)   .Close False End With Set oBook = Nothing Set xlApp = Nothing 'これは、絶対に忘れてはいけません End Sub

zxdaeg
質問者

お礼

うーん 汗 おばかな私にはよくわからないので もっと勉強してみたいと思います。 ありがとうございます。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

どちらも正しくないと思います。 正しくは下記の通りかと... Sub test1() Dim R As String R = Cells(1, 1).value MsgBox R End Sub Sub test2() Dim R As Range Set R = Cells(1, 1) MsgBox R.value End Sub VBAが融通を利かしてくれるのに、頼りきらない方が良いと思います。 といいながら、Range("A" & i)が平気になっている自分がいます。

zxdaeg
質問者

お礼

具体的にどこがどう正しくないのでしょうか? 無知すぎてよくわかりません。 すいません。

  • hallo-2007
  • ベストアンサー率41% (888/2115)
回答No.2

No1です。貼り付ける部分を間違いました。 Sub test1() Dim R As String R = Cells(1, 1).Value MsgBox R R = Cells(1, 1).Row MsgBox R R = Cells(1, 1).Font.ColorIndex MsgBox R End Sub Sub test2() Dim R As Range Set R = Cells(1, 1) MsgBox R.Value MsgBox R.Row MsgBox R.Font.ColorIndex End Sub

zxdaeg
質問者

お礼

やっぱりどちらも同じ答えが返ってきます。

  • hallo-2007
  • ベストアンサー率41% (888/2115)
回答No.1

こうしてみるとわかると思います。 MsgBox R R = Cells(1, 1).Row MsgBox R R = Cells(1, 1).Font.ColorIndex MsgBox R End Sub Sub test2() Dim R As Range Set R = Cells(1, 1) MsgBox R.Value MsgBox R.Row MsgBox R.Font.ColorIndex End Sub どちらが適切というより、目的によって使い分けるということかと。

zxdaeg
質問者

お礼

うーん 違いがよくわかりません

関連するQ&A

  • Objectで宣言するのとObject型で宣言する

    Objectで宣言するのとObject型で宣言するのではどちらがいいでしょうか? エクセルです。 VBAでコードを作るにおいて、どちらのほうがいいのでしょうか? どちらも同じ動きをします。 Sub Sample1() Dim buf As Range Set buf = Range("A1") MsgBox buf.Value End Sub Sub Sample2() Dim buf As Object Set buf = Range("A1") MsgBox buf.Value End Sub ご回答よろしくお願いします。

  • 変数の使い方の注意点なんですが・・・?

    Windows XP Home Edition Excel 2002 当方は、まだ基本がしっかり頭に入っていないので、 勝手な疑問が出てきているようでございます。 まだまだ勉強中ですが、 下記コードの場合、動作はしますが、 変数 c の使い方は間違っているのではないですか? 4は、 同プロシージャ内なので、 変数 c と r というように、区別して記述しないといけないのではないかと思って いるのですが。 3は、 プロシージャが違うので問題はないと思っております。 Dim r As Range, s As Range と記載してもいいのでしょうか?   つまり、曖昧に、ごっちゃ混ぜにしてしまうと、エラー等、PCに支障をきたすことになって しまうのではないかと心配でございます。 また、こんな記述だと、エラー等、PCに支障をきたすことになって しまうという例を 1つか2つ(又はHP等) 教えて頂けると有り難いです。 初歩的な例で結構です。 全くの初歩的な(ざっくりな)お答えで結構ですのでよろしくお願い致します。 Sub てす1() Dim r As Range, s As Range   Set s = Cells(1, 1)   s.Select  MsgBox " A1 です " End Sub '------------------------ Sub てす2() Dim r As Range, s As Range   Set s = Cells(1, 2)   s.Select  MsgBox " A2 です " End Sub '------------------------ Sub てす3() Dim r As Range, s As Range   Call てす1   Call てす2  MsgBox "  A1とA2 です " End Sub '------------------------ Sub てす4() Dim r As Range, s As Range   Set s = Cells(1, 1)   s.Select  MsgBox " A1 です "   Set s = Cells(1, 2)   s.Select  MsgBox " A2 です "  MsgBox " A1とA2 です " End Sub

  • Range.Name プロパティの使い方

    VBAの勉強中のものです。(エクセル) 一つ一つヘルプを見て、検証して勉強していこうと思ってるのですが 使い方がわからないので教えてください。 Range.Value プロパティならうまくいくのですが、 Range.Name プロパティの使い方がわかりません。 ----------------------- Sub test1() MsgBox Range("a1").Name End Sub Sub test2() Dim R As Range Set R = Range("a1") MsgBox R.Name End Sub ----------------------- どちらも、アプリケーション定義またはオブジェクト定義のエラーです。になります。 ----------------------- Sub test1() MsgBox Range("a1").Value End Sub Sub test2() Dim R As Range Set R = Range("a1") MsgBox R.Value End Sub ----------------------- rangeにすればうまくいきます。 Range.Name プロパティの使い方を教えてください。アドバイスよろしくお願いします。

  • オブジェクト??

    またまた困っております inputboxで入力した日付を検索して複数選択しようとしたのですが unionの使い方がよくわかりません(・・;) どこが間違っているのかもしくは何が足りないのか教えてください<m(__)m> どうかよろしくお願いします! Option Explicit Sub グラフ() Const SH_NAME As String = "VBA" Dim art As String Dim i Dim ws As Worksheet Dim endrow As Long Dim msg As String Dim writerow As Integer Dim grahu As Chart Dim target As Range Set ws = ThisWorkbook.Worksheets(SH_NAME) writerow = 2 art = InputBox("日付を入力してください") With ws endrow = .Cells(Rows.Count, 2).End(xlUp).Row For i = 2 To endrow If art = .Range("A" & i) Then Set target = Union(target, "D" & i) Else If InStr(msg, .Range("A" & i)) = 0 Then msg = msg & .Range("A" & i) & vbCrLf End If End If Next i target.Select End With If msg <> "" Then MsgBox msg End If MsgBox "グラフベースを作成しました" End Sub Set target = Union(target, "D" & i) ↑ここでエラーが起きて 「オブジェクトが必要です」と言われました どうすればよいのでしょうか?

  • 【vba】複数のセルをfor文で選択したい

    vbaを独学で学んでおります。 質問内容は、 for文で条件に合ったセルを複数選択するにはどうすればいいのかというものです。 下のプログラムを作ってみたんですが、ループする回数がある一定の数を超えるとエラーが起こります。rangeオブジェクトにつかえる文字列の長さは、255文字までだとかなんとかだそうです。 Public Sub test() Dim str As String Dim i As Integer str = Cells(1, 1).Address For i = 2 To 50 str = str & "," & Cells(i, i).Address Next Range(str).Select End Sub さらに、次のプログラム使っても、256個ぐらいしかセルが選択できません。(これも何かの上限?) Public Sub test2() On Error GoTo エラー Dim r As Range Dim i As Integer Set r = Cells(1, 1) For i = 2 To 300 Set r = Union(r, Cells(i, i)) Next r.Select エラー: r.Select MsgBox ("256個しか選べませんでした") End Sub もっと、無制限に、たくさんのセルを選択できるようにしたいのですが、何か手はないでしょうか? ご教授お願いします。

  • rangeオブジェクトについて

    こんばんわ。 rangeオブジェクトの行数と列数を出したいのですが、やりかた教えていただけませんでしょうか。 以下のように、方法1と方法2を試しましたが、「オブジェクトが必要です」というエラーになります(;;)ついでに、以下2つがなぜだめかも後学のために教えてください(;;) よろしくお願いします。 方法1-- dim rng as range set rng = range(cells(1,1),cells(2,2)) with rng msgbox .columns(.columns.count).column end with 方法2-- dim rng as range set rng = range(cells(1,2),cells(2,2)) msgbox ubound(range,1) -- エクセル2003

  • マクロに関するエラー(オブジェクトが必要です。)

    マクロは始めてで、いろいろ調べながら作ってみたのですが、 Set検索値の行でオブジェクトが必要ですというエラーが出て、 先に進めなくなりました。 申し訳ないのですが、何方かエラーの対処法を教えていただけないでしょうか。 よろしくお願いします。 ========================== Sub test() Worksheets("2月分").Activate Dim 検索値 As Integer Set 検索値 = Worksheets("2月分").Cells(4, 18) Worksheets("テスト").Activate Dim B As Range Dim C As Range For Each B In Range("B13,B413") ' 第一条件 If B.Value >= 検索値 Then GoTo Continue End If ' 第二条件 If B.Offset(0, 1).Value < 検索値 Then ' Offset(0, 1) は B列の隣のC列の値を取得 GoTo Continue End If Dim aValue As String aValue = B.Offset(0, 2).Value Worksheets("2月分").Cells("D19").Value = aValue Continue: Next End Sub

  • Const に dim は使えない?

    標準モジュールに ''''''''''''''''''''''''''''''''''''''''''' Dim Const moji As String = "a" Sub test1() MsgBox moji End Sub Sub test2() Dim Const moji As String = "a" MsgBox moji End Sub ''''''''''''''''''''''''''''''''''''''''''' とするとエラーになりますが ''''''''''''''''''''''''''''''''''''''''''' Public Const moji As String = "a" Sub test3() MsgBox moji End Sub ''''''''''''''''''''''''''''''''''''''''''' なら大丈夫です。 Const に対してdimは使えないのでしょうか?

  • VBA シートプログラムでRangeエラー

    いつもお世話になっております。 Excel2003を使用しております。 シートに直接プログラムを書いています。 (例として、Sheet1とします) シートの内容が変わったときに、色々プログラムを実行していこうと思っているのですが、 Private Sub Worksheet_Change(ByVal Target As Range) のTargetが上手く取得できていない気がします。 今までは上手く動いていたのですが、 急にTargetの値に数値(セルに入力した値)が入ってしまうようになり 上手く組めなくて困っています。 Private Sub Worksheet_Change(ByVal Target As Range) Dim 開始1 As Range Dim 終了1 As Range Dim 開始2 As Range Dim 終了2 As Range Set 開始1 = Range("D5:D63") Set 終了1 = Range("E5:E63") Set 開始2 = Range("F5:F63") Set 終了2 = Range("G5:G63") If ThisWorkbook.ActiveSheet.ProtectContents Then '保護かかってたら End '強制終了 End If If Not Application.Intersect(Target, 開始1) Or Application.Intersect(Target, 実績日開始2) Is Nothing Then Call 開始(Target, 開始1, 開始2) ElseIf Not Application.Intersect(Target, 終了1) Or Application.Intersect(Target, 終了2) Is Nothing Then Msgbox "テスト!" End If End Sub '----------------------------------------------- Sub 開始(ByVal Target As Range, 開始1 As Range, 開始2 As Range) If Not Application.Intersect(Target, 開始1) Is Nothing Then MsgBox Target.Row End If If Not Application.Intersect(Target, 開始2) Is Nothing Then MsgBox Target.Row + 1 End If End Sub 全部シートに書いています。 まだ、テスト段階のため適当なプログラムしか書いておりません。 (指定範囲が変更された場合に、Msgboxを出したりなど 単純なことしかしていません) どこが悪いのか、教えて頂けないでしょうか? よろしくお願い致します。

  • EXCEL2010エラーVBA

    下記を実行するとエラーになりEXCEL2010が終了してしまいます。 fDebug:0 offset00009391 がエラーメッセージです。 何が原因でしょうか。 Private Sub Worksheet_Change(ByVal Target As Range) Dim ws As Worksheet Dim rg As Range Dim r As Variant Dim c As Long Dim hanni1 As Range Dim atai As Range Set ws = Worksheets("あああ") Set rg = Worksheets("コード").Range("A1:B10") r = ws.Cells(Rows.Count, 1).End(xlUp).Row Set hanni1 = ws.Range(Cells(2, 2), Cells(r, 3)) Set atai = ws.Range(Cells(2, 3), Cells(r, 3)) atai = Application.VLookup(hanni1, rg, 2, False) End Sub

専門家に質問してみよう