• ベストアンサー

VBA オブジェクト型使用の利点は?

例えばワークシートの表現を考えます。 自分は今まで以下のようにしてました。 Dim sheet1 As String sheet1=Worksheets(1).Name Worksheets(sheet1).Activate オブジェクト型宣言を用いて以下のように書き換えられます。 Dim sheet1 As object set sheet1=Worksheets(1) sheet1.Activate ソースコードとしてはスッキリしますが、見た目以外でどのようなメリットがあるのですか?

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

  • ベストアンサー
  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.3

そうですねぇ。。まぁ、そういう書き方でヤリタイ事がしっかり出来てる分には、どっちでも構わないとは思いますが。 どーしてこういうご質問が起きたのかなとちょっと考えて、シート名は一義的に定まるのだから、オブジェクトとしてのシートとシート名から呼び出すシートは1対1だというつもりのご相談でしょうか。 ごく単純な例を一つ挙げてみると sub macro1()  dim s as string  s = activesheet(1).name  worksheets(s).activate  worksheets(s).name = "xxx"  worksheets(s).range("A1") = "xxx" end sub なんて書いてたら、勿論ダメですね。 たとえば「シート名を変更した」場合、「シートの名前」という本来の目的の他に、もう一手間かけ変数のsも同期を取って変更しておかないと整合がとれなくなってしまいます。二度手間です。 sub macro2()  dim w as worksheet  set w = worksheets(1)  w.activate  w.name = "xxx"  w.range("A1") = "xxx" end sub 変数wでシートが(直接)参照されているので、「シート名を変更する」のも「シートの配下のA1セルを操作する」のも、いずれもwという現物を基点に配下の属性を操作するだけの共通した操作として整理できます。 あとはまぁ、同じシート名のシートを持った複数のブックが開かれている状況で、ブックを渡り歩いて何か仕事をしてる場合なんかも怖いですね。 ただ現実には(と言っても所詮シロートのレベルでは、という限定で) sub macro3()  dim r as long  for r = 1 to 10   cells(r, "A") = "xxx"  next r end sub のようにインデックスで操作する場合もあれば sub macro4()  dim h as range  for each h in range("A1:A10")   h = "xxx"  next end sub のようにオブジェクトで操作する場合もあります。片手間マクロでしたら、具体的な仕事の中身に応じて便利に使い分けるのでいいんじゃないですかね。

over_the_galaxy
質問者

お礼

ありがとうございます。 御推察の通り仕事の片手間に使っており、取り立ててobjectが必須というものではありません。 「これ使うと何か良い事あるのかな?」と思い質問しました。 他回答でも可読性を良くする変数等も紹介頂き、思いの外収穫がありました。

その他の回答 (2)

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

Dim sheet1 As Object →Dim mySheet1 As Worksheet としましょう。 Object型ではなく、本来の型を用いるのが基本です。 Excel以外のオブジェクトを使用する時も、最初は参照設定して本来の型を使用すべきです。 こうする事で、mySheet1までキーインしたところで、インテリセンスが効いてシートオブジェクトのメンバが表示されますので、コード作成が楽になります。Rangeオブジェクトを使用すると、ビックリするほど多岐にわたるメンバの存在を知り、視野が広がるでしょう。 また、sheet1という変数名も、VBAが使いそうな気もするので、避ける方が無難でしょう。(君子危うきに近寄らずというやつです) VBAを始めた頃、myほにゃららという変数名を使用しているのに違和感を覚えましたが、確実に予約語を避け、かつ分かり易い変数名という趣旨だと思い至り、今では真似しています。 なお、Set mySheet1=Worksheet(1)とした後で、Activateする必要はほとんど無いと思います。(ActiveCellに画像をペーストする時くらいしか必要性を感じません)せっかくのObject変数なので、そのメンバーに対する処理としてどんどん使ってみて下さい。 VBの記事ですが、インテリセンスのご参考に... http://homepage1.nifty.com/rucio/main/nyumon/nyumon5.htm

over_the_galaxy
質問者

お礼

ありがとうございます。 my~というのは見たことありませんが、予約語を避けるのですね。確かにそうかとおもいます。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.1

変数名sheet1は、Dimを見ないと目的がわからないのでソースの可読性がよろしくない。 私だったら、前半を strSheetNameに、後半をobjSheetかwssheetとする。

over_the_galaxy
質問者

お礼

ありがとうございます。 変数名の付け方ですね。

関連するQ&A

  • Excel VBA でExecuteExcel4Macro("GET.OBJECT(48,

    エクセル2000です。 以前、ワークシートに配置したフォームツールのラベルの参照元を取得するマクロをご教示いただき、以下のTest01は問題なく作動しています。 Sub test01() Dim obj As Object Dim i As Integer Dim obj_n As String 'オブジェクトの名前 With ActiveSheet For Each obj In .Labels i = i + 1 .Cells(i, 2) = obj.Name: obj_n = obj.Name .Cells(i, 3) = obj.TopLeftCell.Address 'GET.OBJECT で、リンクがないものを取ると、False になる .Cells(i, 5) = ExecuteExcel4Macro("GET.OBJECT(48,""" & obj_n & """)") .Cells(i, 6) = obj.OnAction Next End With End Sub 今回、同一シートではなく別シートに表示させようと以下のTest02を書いたのですが、やってみると .Cells(i, 5) はすべて#VALUE!エラーになってしまいました。 ExecuteExcel4Macro("GET.OBJECT(48~がどのようなものかわからずやっているので応用がききません。(そもそも48って?) どのようになおしたらよいのかご教示いただければ幸いです。 Sub test02() Dim obj As Object Dim i As Integer Dim obj_n As String Dim ws As Worksheet, ns As Worksheet Set ws = ActiveSheet Set ns = Worksheets.Add With ns For Each obj In ws.Labels i = i + 1 .Cells(i, 2) = obj.Name: obj_n = obj.Name .Cells(i, 3) = obj.TopLeftCell.Address .Cells(i, 5) = ExecuteExcel4Macro("GET.OBJECT(48,""" & obj_n & """)") .Cells(i, 6) = obj.OnAction Next End With End Sub

  • VBAでオブジェクト変数にsetしたシートがactiveかどうかを調べるには?

    標準モジュールの冒頭でワークシート用のオブジェクト変数を確保し、 あるタイミングで、あるシートをそのオブジェクト変数にSetしています。 で、そのシートに値をセットするときに、そのシートがActiveだった場合だけやりたい処理があるのですが、Setしてあるオブジェクト変数だけを見てそのシートがActiveか否かを判断する方法って、あるのでしょうか。 コード例) Private oSheetA as Worksheet Sub SetSheet(sName as String)   Set oSheetA = worksheets(sName) End Sub Sub SetValue(nValue as integer)   xxxxxx ←ここでoSheetAがActiveならやりたいことがある。   oSheetA.Cells(nRow, nCol) = cValue End Sub 具体的には、複数のBookを開いている状態で、Activeシートが何であるかはオペレータの操作次第なので固定化できない状態で、SetValueが呼び出されたとき、oSheetAがActiveだったら、値をセットするセルが見えるようにセルをActivateかスクロールさせたいんです。

  • Excel VBA オブジェクトの指定方法と速度

    Excel VBAについて質問です。 ワークシートを指定するときの書き方には色々ありますが、1~3の速度の順番はどうなりますか? オブジェクトは、変数に入れて使用したほうが速度が速くなるそうなので、 1より2のほうが速いと思いますが、3はどうでしょうか? 1.Worksheets("sheet1") 2.Dim ws As Worksheet   Set ws = Worksheets("sheet1") 3.Sheet1 (VBE画面で表示されるシートのプロパティのオブジェクト名) Excelのオブジェクトについて詳しいかたがいらっしゃいましたら教えてください。 よろしくお願いいたします。

  • VBA どうしてなのでしょうか?

    どうしてなのかまったくわかりません… Sub test() Dim TW As Worksheet Set TW = Worksheets("Sheet2") TW.Activate Range("G5").Activate End Sub は良いのに Sub test() Dim TW As Worksheet Set TW = Worksheets("Sheet2") TW.Range("G5").Activate End Sub はエラーがでます… この理由をご存知の方いらっしゃいますか?? よかったら教えていただけませんか?

  • VBA なんですが

    VBA なんですが すべてのワークシートを順番に選択して 指定した範囲をコピーし『まとめ』と言う別のシートに貼り付けたいのですが どうしたらいいのかわかりません。 それらしいのは考えたのですが Set sh = Worksheets(sh.Name)でエラーになります。 頭がいいかた教えてください。   Dim sh3 As Worksheet Dim sh As Worksheet Dim en As Long Set sh3 = Worksheets("まとめ") For Each sh In ActiveWorkbook.Worksheets If sh.Name <> "まとめ" Then en = sh.UsedRange.Rows.Count Set sh = Worksheets(sh.Name) sh.Range(Cells(2, 1), Cells(en, 10)).Copy

  • Excel VBA 定数にオブジェクトを指定したい

    Excel VBA 定数にオブジェクトを指定したい いつもお世話になりますm(__)m Excel VBAで、定数としてオブジェクトの指定はできないのでしょうか? 例えば、WorkSheets("Sheet1")を定数「Srt1」として設定したいのですが、  Public Const Srt1 As Object = Worksheets("Sheet1") としても「定数のデータ型が不正です」とエラーがでます。 例えば、セルに値をセットする時に Worksheets("Sheet1").Range("A1").Value="あああ" Worksheets("Sheet1").Range("A2").Value="いいい" Worksheets("Sheet1").Range("A3").Value="ううう" と書きますが、これを Srt1.Range("A1").Value="あああ" Srt1.Range("A2").Value="いいい" Srt1.Range("A3").Value="ううう" と書ければプログラムも見やすく、書きやすくなると思いました。 プログラムの最初に Dim Srt1 As Object Set Srt1 = Worksheets("Sheet1") とすれば使えるのですが、複数のシート名をまずは定数として登録したいと思っていますが、オブジェクト(ワークシート名)は定数として登録することは出来ないのでしょうか? お詳しいかた、是非ともご教授お願い致しますm(__)m

  • VBAのオブジェクト変数について

    人に教えなければいけないことなので、、、 困っています。 あるVBAのテキストを見て、そのテキストをそのまま入力しても実行できません。 (条件としては、Book1.xlsとBook2.xlsというファイルを開いた状態で、Book1.xlsのほうに、以下のモジュールを入力します。) Sub Set1() Dim myBook As Workbook Dim mySheet As Worksheet Dim myCell As Range Set myWBook = Workbooks("Book2.xls") Set myWSheet = Worksheets("Sheet2") Set myCell = Range("A1:D10") myWBook.Activate myWSheet.Activate myCell.Value = "ABC" End Sub これを実行すると、アクティブな状態のファイルにしか、値"ABC"が入ってこないのです。テキストでは、Book2.xlsのSheet2のA1:D10に値"ABC"が入ってくると言っていますが、Book1.xlsに値が入ってしまったりします。 長くなってしまってすみません。 もちろん、他の方法で実現することができるのはわかるのですが、なぜこのコードが実行できないのかがわかりません。 理由を教えていただけたら・・・と思います。 よろしくお願いいたします。

  • sheetの中身もコピーしたい

    表題通りの質問になります。以下のソースを実行すると、コピーはされますが、中身はコピーされません。どうすればよろしいでしょうか? アドバイスお願いいたします。 Sub sheetの連続コピー() Dim sheet_name As String '文字型変数の宣言 sheet_name = ActiveSheet.Name '現在アクティブになっているシート名の取得 'Range("A1") = sheet_name '取得したsheet名をA1のセルに表示 Dim NewWS As Worksheet For i = 1 To 10 'Worksheets.Add ~ 空のSheetが ○個 挿入される Set NewWS = Worksheets.Add(Before:=Worksheets(sheet_name)) NewWS.Name = sheet_name & i Next End Sub

  • VBAでの説明がわかりません

    以下のコードは、都道府県ごとに1枚のデータシートを作成する処理なんですが、コードが1行づつどんな作業を意味しているのかがわかりません。1行ごとにどのような処理をしているのかの説明をよろしくお願いします。長文で申し訳ありません。 Sub まとめ() Dim i As Integer 'カウンタ変数iの宣言 Dim n As Integer  Dim MyS1 As Worksheet 'ワークシート型オブジェクトMyS1を宣言 Dim MyC As Worksheet Worksheets.Add before:=Worksheets("全国") ActiveSheet.Name = "data" Set MyS1= Worksheets("data") With Worksheets("全国") MyS1. Range(MyS1.Cells(1,1),MyS1.Cells(11,12))=.Range(Cells(1,1),.Cells(11,12)).Value End With i=12 For Each MyC In Worksheets If MyC.Name<> "data" Then n = 12 MyS1.Cells(i,1)=MyC.Name i=i+1 Do While MyC.Cells(n,2).Value<>"" MyS1.Range(MyS1.Cells(i,1),MyS1.Cells(i,12))=MyC.Range(MyC.Cells(n,1),Mc.Cells(n,12)).Value i=i+1 n=n+1 Loop End If Next Myc End Sub

  • 「オブジェクトが必要です。」エラーになります。

    次のコードで2.は動くのですが、1.が動きません。「オブジェクトが必要です。」エラーになります。 何が違うんでしょうか? 教えてください。よろしくお願いします。 Function hoge(aa As Range) aa.Value = "Hello!!" End Function Sub Worksheet_Activate() Dim a As Range Set a = ThisWorkbook.Worksheets("Sheet1").Range("G10") hoge (a) ' ←1.これだとエラーになる ' hoge (ThisWorkbook.Worksheets("Sheet1").Range("G10")) ' 2.こちらはOK End Sub

専門家に質問してみよう