- ベストアンサー
VBAワークシートオブジェクトの使用に関する問題
- VBAワークシートオブジェクトを使用したサブプロシージャが正常に動作しない問題が発生しています。
- 問題のコードでは、Thissheet変数を使用してアクティブなシートを参照していますが、これがエラーを引き起こしています。
- Thissheetの代わりにWorksheets(1)を使用すると正常に動作するため、Thissheetの使用方法に問題がある可能性があります。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>Thissheetを用いた場合、何がマズイのでしょうか? マクロで定義したThissheetは、thisworkbookの配下(メンバ)では無いからです。 方法1: Sub main() Dim Thissheet As Worksheet Set Thissheet = ActiveSheet Workbooks.Open Filename:="Book2.xlsx" Range("A1").Copy Destination:=Thissheet.Cells(1, 1) Range("B1").Copy Destination:=Thissheet.Cells(1, 2) ActiveWindow.Close End Sub 方法2: >以下の認識で書いてますが、誤りあるでしょうか? その通りに作成します。 Sub main() Dim Thissheet As Worksheet Set Thissheet = ActiveSheet Workbooks.Open Filename:="Book2.xlsx" Range("A1").Copy Destination:=ThisWorkbook.activesheet.Cells(1, 1) Range("B1").Copy Destination:=ThisWorkbook.activesheet.Cells(1, 2) ActiveWindow.Close End Sub
その他の回答 (4)
- WindFaller
- ベストアンサー率57% (465/803)
#4の回答者です。 >Thissheetがダメでmysheetなら良いのは何故でしょうか?どちらも名が体を表していると思いますが。 私は、あなたのために書いたつもりが、余計なことを書いたようですね。それで、不愉快になりましたら、すみません。 「Thissheetがダメでmysheetなら良いのは何故でしょうか?」それは、本質的には慣習だというしかありません。ただ、ThisWorkbookという語が、システム上である限りは、混じらわしいと思わないでしょうか。"This" といういわゆる限定詞は、何を意味するかということになるはずです。ThisWorkbookというのは、マクロの書いてあるブックだと書きましたが、ユーザーが勝手につけるThisSheet という変数の意味は、それを限定することができません。my というのは、あくまでも、1つのプロシージャの中で使うためのものですよ、という意味が込められています。もちろん、他の呼び方で入れる方もいますが、システム上で使われるような単語は極力避けます。 moug(http://www.moug.net/)は、日本マイクロソフト社ともつながりがありますから、こういう所でも参考になさったらいかがでしょう。私のような、どこの馬の骨かも分からないような人間よりは、アテになるかもしれません。 http://moug.net/tech/exvba/0040049.html こういうことは、前回書いたように、VB.Net やVB6などのルールや、また、Excel97 からのMicrosoft の書き方になるべく近づけようとしているにしか過ぎません。本来は、もっと厳しく細かい規則が存在しています。 私は、約10年の間に、数千個のマクロを書いています。今は、1万行を越えるVBA・マクロ・コードを書くことはありませんが、基本的なことは分かっているつもりです。Microsoft が示すいくつかのプログラマーの書法や記法のルールはあるものの、コードが通ればそれでいいというなら、それは、自己流でもご自由です。 コードを見る限りは、初歩的なレベルのつまずきですから、入門から初級レベルで、ある程度のことは覚えておいた方がよいということを書いたのです。覚えるのは今しかないと思います。 VBAのユーザーは、ほとんどは個人的に書いているものですから、他人を考慮にいれないで書いても構わないといえば構いません。最終的には、「可読性」といって、他人から見ても分かるように書くということが大事です。それは、巡り巡って、自分のためでもあるからです。 ここの掲示板の回答者にも、自己流の書き方をしている方がいますが、何年経っても、あるレベルを越えません。ある程度、上級になって複雑になると、それではエラーを起こすコードというのも中にはあります。 また、私は、現実には、ワークシートやワークブックの状況を見ていませんから、あなたが、どんな風にワークシートを使っていらしゃるか実体が分からないし、実際はそうではないという以上、こちらも、「サンプル」と明記して、書いたまでと返事をするしかありません。 >Set mySheet=ActiveSheet '大文字・小文字を混ぜる >以外の方法があるのでしょうか? 通常、Excel VBAは、標準モジュールを多用します。その場合、ActiveSheet の場合は、シートオブジェクトは書かずに、そのまま、Rangeオブジェクトを書けば、良いということが多いです。 気に入らない内容でしたら、どうぞ無視なさって良いです。時々、そういう方はいらっしゃいますから、こちらは、別に気にかけてはいません。失礼しました。
お礼
再度ありがとうございます。 何となく状況が分かって来ました。私の使い方は、あくまで「自分の」仕事上のデータ処理を効率的にするためにVBAを使います。周囲の人に配布もしません。個人で使うだけ、しかも小規模です。数人がかりで大規模なプログラムを作ることもありません。変数名のルールは、おそらく他人が見た時の分かり易さを目的としている筈です。変数名の話、大変申し上げにくいのですが、今の私には必須ではありません。 年間数百個ものマクロを書くことは今後もないでしょうし、業務内容的にもそれほどの時間は取れません。あなたの想像されているようなレベルに到達することも無いと思います。「何年経ってもあるレベルを超えない」理由は、数が少ない、個人で作る、小規模だからでしょう。その程度しか必要としないのです。 どちらかというと、必要な時に小規模マクロを短時間でスパッと書くことが必要です。作ろうか手作業か迷う場面が多いですから。現状では「ひな型」を数種類作って対応してます。
- WindFaller
- ベストアンサー率57% (465/803)
こんにちは。 なにか、全体的に書き方が変ではないでしょうか? 癖をつける前に、自己流の書き方は直したほうがよいです。 それと私は、回答者として、質問者のままを活かしてコードを書く必要はないと思います。 別に私の話なんか、どうでもよいなら無視しても構いませんが、良いとか悪いとか関係なく、このままじゃいけないと思って書いています。 >Workbooks.Open Filename:="Book2.xlsx" > Range("A1").Copy Destination:=ThisWorkbook.Thissheet.Cells(1, 1) > Range("B1").Copy Destination:=ThisWorkbook.Thissheet.Cells(1, 2) >ActiveWindow.Close それぞれの親オブジェクトや変数に入れたオブジェクトを分かって書いているならともかく、ActiveSheet は、ActiveSheetであって、何ものでもありません。ActiveSheet というのは、物理的にひとつしかありません。ActiveSheet とは、表に出ているシートのことです。ただし、ActiveSheet には例外があります。しかし、それについては無視します。 ActiveSheet を、変数に入れたら、それが、そのまま残るということです。ActiveSheetは、親オブジェクトの指定のWorkbookも含まれています。読みにくくなるので、できるだけ、名指ししたシートにすることです。 >Worksheets(1)を用いるとうまくいきます。 ということではなくて、きちんと、Worksheets("Sheet1")などと名称を入れるべきです。 こういうと、Worksheets("Sheet1")は、特定化されているのか、名称を換えられたらどうするか、というツッコミもありますが、その対処法は、今、ここには書きません。 Worksheets(1)の意味は、左側から1番目のワークシート(Sheetではなく、Worksheetです)ということです。 ThisWorkbookというのは、マクロの置いてあるブックという意味です。 >Set Thissheet = ActiveSheet それに、こういう紛らわしい名称の付け方に問題があります。ひとつオブジェクトに封入したら、ブックを含めた唯一の存在です。せめて、Sh1 などすべきです。以下では、mySheet にしています。myというプレフィックスは、ローカル(プロシージャ内だけに使われる)という意味です。 Set mySheet = ActiveSheet という書き方は、現行ではお勧めしません。 Workbooks.Open Filename:="Book2.xlsx" で、開いたブックのシートが一番上にきて、それが、ActiveSheet になります。 このレベルで問題が出るとしたら、基本通り書くべきなのですね。 なお、Sub Main() という書き方は、VB系の構造化した時に使う書き方です。これは、サブルーチン(下処理)を使う時に、差別化させるための名称です。基本的には、その用途の名称を使うか、Test1 や Macro1 や Sample1 など、枝番をつけやすい名称にしてあげます。異論のある人もいるかとは思いますが、一応、Microsoft のmsdnのVS.Net のVB系の記法など(一部はプロの記法)になるべく近づけるように心がけています。最初は面倒かとは思うでしょうけれども、その方がミスが少ないからです。 '// サンプルです。 Sub DataCopying() Dim mySheet As Worksheet Set mySheet = ThisWorkbook.Worksheets("Sheet1") With Workbooks.Open("Book2.xlsx") '* .Worksheets("Sheet1").Range("A1").Copy mySheet.Range("A1") .Worksheets("Sheet1").Range("B1").Copy mySheet.Range("B1") .Close SaveChanges:=False '** End With End Sub '*Withステートメントは、基本の記法で使うようになっています。 '**"SaveChanges:=" の名前付き引数にしなくてもよいです。
お礼
いつもありがとうございます。 全体的に変数の名前に問題があるようですね。 Thissheetがダメでmysheetなら良いのは何故でしょうか?どちらも名が体を表していると思いますが。 Worksheets(1)は、こうすれば動いたという説明のためです。むしろThissheetで動作しない理由が知りたかったのです。実使用においてはWorksheets(1)もWorksheets("sheet1")もダメです。マクロ起動時にアクティブなシートである必要があります。 Set mysheet=ActiveSheet 以外の方法があるのでしょうか?
- bin-chan
- ベストアンサー率33% (1403/4213)
> Range("A1").Copy Destination:=ThisWorkbook.Thissheet.Cells(1, 1) たぶん Range("A1").Copy Destination:=Thissheet.Cells(1, 1) だと動くのでは?
- bin-chan
- ベストアンサー率33% (1403/4213)
うーん、ThisWorkbookというオブジェクトがあるのに WorkSheetをオブジェクトにする意味って何でしょう? Dimはstringで宣言して Thissheet = ActiveSheet.name として Range("A1").Copy Destination:=ThisWorkbook.Worksheet(Thissheet).Cells(1, 1) じゃダメですか?
お礼
ありがとうございます。 Thisbook無しでThissheetだけでシートが一意指定出来るということですか? 私はBook2がアクティブの時はThissheetだけではダメだろうと思い、ThisBookを付けました。 s
お礼
ありがとうございます。 ThisWorkbookを使わない方法でうまく行きました。