• ベストアンサー

シートのコード(マクロ)で別のシートを指定することはできますか?

環境はWINDOWS XP, EXCEL 2003 です。 VBAについて、初歩的な質問ですみません。 コードを書けるモジュールには Microsoft Excel Objects と標準モジュールとありますが、シートのコードでは、別のシート上のセルをオブジェクトとして指定することはできないのでしょうか? 今開いていて、ボタンのあるシートを、Sheet1 (基本画面)、読み込みたいデータがあるシート(同じブック内)をSheet3 (計算用)、とします。 基本画面のセルA1に日付を入力してから、「データ選択」ボタン(コントロールツールボックスで標準で出てくるボタンです)を押すと以下のマクロが動くようにしたため、このコードはSheet1のモジュールに書きました。 このマクロの前半に、日付が、計算用のC3に事前に書き込まれている日付と一致しているかどうかを判定させ、一致しない時は中断するようにさせたのです。マクロ後半は本題と関係ないと思うので省きます。 Private Sub データ選択_Click() '前半で下準備ができているか、チェック Hidzuke = Range("A1").Value Sheets("計算用").Select Atai = Range("C3").Value Sheets("基本画面").Select If Atai <> Hidzuke _ Then Range("A2").Value = "下準備ボタンを先に押してください" Exit Sub End If '以下、省略 End Sub すると、Range("C3").Value は、Sheets("計算用") の"C3"ではなく、 Sheets("基本画面") の方の"C3"を対象として読み込んでしまいました。私はシートのコードを書くことはあまり多くなく、標準モジュールと同じ感覚で、Sheets("計算用") の"C3"の値を読んだつもりだったのですが、シートのコードと標準モジュールでは、どのような違いに注意したら良いのでしょうか。 さらに不思議なことに、この"C3"を"C7"などに変えると、Ataiの中身が "準備完了" などの文字列になったのです。しかしこの"準備完了"という文字列は、現在のブックにはどこにもありません。今のファイルの前の前ぐらいまで、確かに、 Sheets("基本画面") の"C7"には、"準備完了" と書き込んでいました。なぜ、昔のセルの中身(値)がゴーストのように残ってしまうのでしょうか・・・。 ツリーで、標準モジュールは標準モジュールで、シート専用マクロはExcel Objects で、はっきりわかれていますから、私はここの違いから理解できていなくてこんな馬鹿な質問をしてしまうのだと思います。他のシートのセルをオブジェクトとして指定したければ、モジュールが増えて多少猥雑になってでも、Call などで標準モジュールを呼び出すしかありませんか? よろしくお願いします。

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

  • ベストアンサー
  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

Atai = Sheets("計算用").Range("C3").Value と言ったように、どのシートなのかを明確にしておけばいいのでは。

QoooL
質問者

お礼

なるほど! 目が覚めました! お返事遅くなってすみません。たいへんすばやいご回答、ありがとうございました。 コンテナ、という言い方は忘れていましたが、どこのレンジなのか、名前を先に付けてやれば良かっただけなのですね。 難しく考え過ぎました。 Sheets("計算用").Select Atai = Range("C3").Value Sheets("基本画面").Select というのも、コンテナで書けば済むことをわざわざ3行で書いてしまって、見る人から見ればとても不格好だったでしょう。 的確なご回答ありがとうございました「。

その他の回答 (2)

  • Avirex
  • ベストアンサー率33% (1/3)
回答No.3

こんばんは。 私も初心者ですがMicrosoft Excel Objects のSheet部に(ThisWorkbook)以外にあえて記述するメリット?というか必要性があるのかなと、疑問に思っていました。 実際には全く使用したことがないので標準モジュールもしくはUserForm上のボタンorボックス等々上に必要なプログラムを記述すれば事足りるかなと思います。 ただその際には、n-junさんのアドバイスの通りシート名とかUserFormの番号UserForm1やUserForm2を指定します。 Sheets("計算用").Select Atai = Range("C3").Value Sheets("基本画面").Select 上を↓ Atari=Sheets("計算用").Range("C3").Value Sheets("基本画面").Select 計算用のシートがMicrosoft Excel Objects上でSheet3ならば Atari=Sheet3.Range("C3").Value Sheet1.Select と標準モジュールに書き込めばよいと思います。 今まで気にしていなかった疑問ですがMicrosoft Excel Objects のSheet部を使用するメリットがあればご指南ください。

QoooL
質問者

お礼

私の説明が足りなかった、というか私もその差がわかっていなかったのですが、私が 「データ選択」ボタン(コントロールツールボックスで標準で出てくるボタン) と言っているのはたぶん(自分のことなのに「たぶん」ですみません)ActiveX コントロールで、 Avirex様がおっしゃっているのは、ユーザーフォームコントロールのことではないですか? 私は、マクロを学び始めたのは、人(上司)がやっていることを真似ることからだったので、その後本を読んだりもしましたが、なかなか、「人がやっているのを見たことがある」こと以上には知識が広がりません。 (←言い訳がましいですが) >標準モジュールもしくはUserForm上のボタンorボックス等々上に必要なプログラムを記述すれば事足りるかな とおっしゃっている部分で、標準モジュールはわかりますが、ボタンorボックス等々上にプログラムを記述する、というのは、ボタン等にマクロを「登録する」ことを意味してらっしゃるのでしょうか? 私のエクセルでは、アイコンはActiveX コントロールのボタンの方になっているので(プロパティ、がある方)いつもこちらを多用していて、「マクロを登録」するメニューは出てきません。だからいつもボタンのあるシートのモジュールの方に Sub CommandButton1_Click() を書いています。シートじゃなくて標準モジュールの方に _Click()  を書いても発動することも、今回初めて知りました。だからなぜシートの方に書いているのかわかりません。 ユーザーフォームコントロールだと、マクロの登録をメニューで聞いてきて便利ですね。オートシェイプでは見たことありましたが、「ボタン を押すと~」の設定がクリックし続けるだけでできて、とても便利だと再認識しました。 n-jun様、Wendy02様、Avirex様(投稿順)ご回答ありがとうございました。私がお礼に質問ぽいことを書いてしまったので、この質疑はまだ続きそうですが、迷った末、回答はいったん締め切らせていただきます(18日朝に)。本題については既に、ご回答がでそろっていますので。私もさらなる疑問についてはよく調べた上で「別の質問」として再投稿したいと思います。ありがとうございました。

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

こんばんは。 >さらに不思議なことに、この"C3"を"C7"などに変えると、Ataiの中身が"準備完了" 名前登録などで出てきているのかもしれません。ただ、 >昔のセルの中身(値)がゴーストのように残ってしまうのでしょうか・・・。 フォントを白で見えなくしていない限りは、その現象は、ブックが少しずつ壊れつつあります。そのブックの継続的な使用はやめたほうがよいです。シートコピーではなく、セルコピーで、新しいシートにコピーしてください。また、名前-登録は、また同じく、ワークシートの中に値がもぐりこむ現象があります。なかなか、ややこしい現象です。 >モジュールが増えて多少猥雑になってでも、Call などで標準モジュールを呼び出すしかありませんか? ということはありませんが、「VBA」の根本的なことかもしれませんが、「猥雑」というほど、問題ではありません。VBAは、プライベートのものですから、問題なければ、それを押し通しても結構だと思います。ただ、人に教える場合のみ、そういう書き方は、イレギュラーだと覚えていてもよいです。 もう一つは、私自身、シートモジュールに必要以上にコードを書くのは、このましくないと思っています。複雑なコードがあるのなら、やはり、Call を作って、標準モジュールに書く方法もあります。 Private Sub CommandButton1_Click()   Hidzuke = Range("A1").Value   Atai = Worksheets("計算用").Range("C3").Value      If Atai <> Hidzuke Then     MsgBox "下準備ボタンを先に押してください"     Exit Sub   End If   '続き End Sub Worksheets("計算用").Range("C3").Value こういう書き方を、コンテナといいます。 親オブジェクトから書きます。また、ブックが違うときには、ブックから書いてあげるのが良いわけです。 シートモジュール(ローカル)は、標準モジュール(グローバル)と違って、親オブジェクトは、シート(または、ブック)です。 Range("A1").Value     ↓ これは、Worksheets("基本画面").Range("A1").Value ですが、省略することが可能です。しかし、標準モジュールのように、ActiveSheet が親オブジェクトになるのと違って、シートオブジェクトが親オブジェクトになります。 Me というキーワードも使えます。いくら、別のシートにSelect しても、その親オブジェクトのつながりを断ち切ることは出来ません。 ここらはややこしいので、標準的にマクロを書くのは、「標準モジュール」と覚えて使っていたほうがよいです。(Excelのみ)シートモジュール(ローカル)にマクロを書く場合は、よほど気をつけないと、エラーを発生することもあります。Me キーワードを利用してみるという手もあります。

QoooL
質問者

お礼

返事が遅くなってすみませんでした! 前の方のお返事がたいへん早かったため、次点とさせていただきましたが、補足としてたいへん充実しており、大満足です。 私が構造からわかっていないのを察して、構造から説明してくださり、たいへん理解が進んで助かりました。 なるほど、Me キーワードというのは全く知りませんでした、とても活用できそうです! 本来、別の質問にわけるべきだったかも知れませんが、 昔のセルの中身(値)がゴーストのように残ってしまう 件についても答えていただいてありがとうございました。気になっていたのです。 >フォントを白で見えなくはしていない ので、 >ブックが少しずつ壊れて きているのでしょうね・・・。120MBの大きなファイルで計算式もグラフも多く、ボタンなどのオブジェクトも多い上にオブジェクトを何度も移動させていて、マクロもたくさん組んで長いので、壊れても不思議はないかも知れません。(この3つの中でも、オブジェクトが一番悪さ(というか予想外のエラー)の原因になりやすいのでしょうか) 解決方法まで提示してくださって助かります。 かゆいところに手の届くご回答で、本当にありがとうございました!

関連するQ&A

専門家に質問してみよう