質問: activeworkbook としないでもsheets(1).copyをwbにsetする書き方はないのでしょうか?
回答: こんばんは。 少し、全体的に考えさせてもらいました。ご質問の最終的な終着点がどういうところにあるのかはあまりはっきりしませんし、私が書いたところで、この手の話は、あまり分かってもらえるという自信はありません。merlionxxさん、ご自身のvbaのコーディングの問題であって、個々の問題ではないからでもあります。 今回の質問は、merlionxx さん自身が、解答した中で考えたことでしょうし、まさか、サブルーチンや特殊なコードで解決をしようと思ったわけではないと思います。 実際のコードとして、 set wb = sheets(1).copy というのは出来ないのはご存知なわけですが、なぜ「そうしたいと思った」か、ということがポイントではないでしょうか。出来ないのは、vbaの製作者の恣意的な設計だったのか、それとも、他の要因があったのかと思います。それを、私たちユーザーレベルでは分かりません。 あえて理由を言えば、もともと、copy メソッドには、戻り値にオブジェクトではない、ということです。 実際に、 ret = sheets(1).copy で返るのは、true です。失敗すれば、実行時エラーが起こります。 質問は、前回のコード( http://oshiete1.goo.ne.jp/qa4138541.html ) から、思いついた事だとは思っていますが、sheets(1).copy の時点で、application側の暗黙的な workbookのインスタンスの生成を与えてしまっているわけで、そこで、activeworkbook で、オブジェクトを取得することに、なにかしら不自然さを感じていたとしたら、その感覚は正しいのではないかと思います。私も同じように思います。 しかし、その方法で、ブックオブジェクトを取得する方法は、activeworkbook をオブジェクトとして取る方法以外には、新たに copy メソッド自体から手を加えるぐらいしか、実現する方法はないような気がします。そうすると、その親オブジェクトのsheet のclass 設定から、手を入れなくてはなりません。それは、遥か上級の話だろうし、vbaレベルで可能かどうかさえ分かりません。それに、そんなに難しいコードが、この種のもので必要だと思えません。また、一行、二行の問題で、特別なワザもなく、わざわざfunction プロシージャで取り出すというのは、理屈ではあっても、実務的にはまず考えられません。 vbaは、合理的に出来ているようでいて、はっきりとしないものがいくつもあり、「やって見なければ分からない」としかいいようがありません。本当に単純なコードでも、vbに出来て、vbaには出来ないものがあります。自分は、プロだと豪語している人に限って、こういうところでね凡ミスをするのが常です。vbaのコーディングは、よほど初歩的なこと以外は、戻り値を想定するというような「推測」で済まされるようなことはできません。 ただ、私は全体を通してみて、もし、もう一度、考える余裕があるなら、個々のメソッドやそれに関わるワザよりも、全体のプロセス自体に手を付けたほうがよいのではないか、と思います。 前のコードを、私自身で考えてみました。これは、定番のコードではあるので、私のアレンジあるものの、それ自体がオリジナルというわけではありません。シートモジュールにあるマクロコードをコピーしたいという特例の場合は、以下のコードを少し変更して可能です。これは一例ですが、こういうものは自力で編み出したわけではなく、vbaの入門時に、教わっているものです。6年経っても、そのとき覚えたものは忘れていません。 http://oshiete1.goo.ne.jp/qa4148672.html sub 保存3() dim orgshcnt as integer ' dim shname as string dim fn as variant 'ブックのシートの規定数 orgshcnt = application.sheetsinnewworkbook application.sheetsinnewworkbook = 1 with worksheets("sheet1") ' shname = .name .cells.copy end with with workbooks.add '※ .activesheet.paste range("a1").select application.cutcopymode = false '規定数を戻す application.sheetsinnewworkbook = orgshcnt 'shname → は、"" になっている fn = application.getsaveasfilename("", "excelブック(*.xls),*.xls", 1, "保存") if vartype(fn) = vbboolean then .close false msgbox "キャンセルしました。", 48 exit sub end if .saveas fn .close false end with msgbox "終了しました。", 64 end sub ※ workbooks.add というメソッドで、明示的なブックを生成していればこそ、そのオブジェクトは確実に取得できるわけです。application の newbook イベントで、ブックオブジェクトは取得は出来ますが、それは、ひとつのプロセスの中にはありません。 はたして、本当に、sheets(1).copy でオブジェクトを捕らえることが必要なのか、と思います。私は、今まで、vbaのコードを2~3千件書いていますが、ほとんど、その方法は、記録マクロを写した程度にしか、そのような方法は出てこないように思います。 失礼な言い方があったら、お許しください。