
つい先ほどの質問 4150169 は掲示したコードが抜けておりましたので無視して、こちらにご回答ください。
ほんと抜けた話です。すみません。
以下のマクロtest01はエラーになります。
Sub test01()
Dim wb As Workbook
Set wb = Sheets(1).Copy 'エラー「オブジェクトが必要です」
End Sub
もちろん
Dim wb As Workbook
Sheets(1).Copy
Set wb = ActiveWorkbook
と修正すればエラーにならないことは存じていますが、ふと疑問がわきました。
Sheets(1).Copyの段階であたらしいWorkbookが誕生していますよね。
ならば、そのWorkbookはオブジェクトではないのでしょうか?
Workbooks.Add で誕生したWorkbookは
Set wb = Workbooks.Add
と変数wbにSetできるのに
Set wb = Sheets(1).Copy
ができないのが不思議です。
Set wb = ActiveWorkbook
としないでもSheets(1).CopyをwbにSetする書き方はないのでしょうか?
No.6ベストアンサー
- 回答日時:
こんばんは。
少し、全体的に考えさせてもらいました。ご質問の最終的な終着点がどういうところにあるのかはあまりはっきりしませんし、私が書いたところで、この手の話は、あまり分かってもらえるという自信はありません。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千件書いていますが、ほとんど、その方法は、記録マクロを写した程度にしか、そのような方法は出てこないように思います。
失礼な言い方があったら、お許しください。
Wendy02さま、ご丁寧な解説を有難うございます。
また、わたしのこれまでの回答までご覧になっていただき、その上での適切なご回答、とても勉強になりました。
これからもご指導くださいますようお願い申し上げます。
No.5
- 回答日時:
No4です。
訂正です。
Set wb = Workbooks.Add(ActiveWorkbook.Sheets(1).Copy)
という形でTemplateに指定します。
ただし「Sheet1」というブックが何故か余分にできてしまい
理由がわからないので完全な回答になっていません。
ありがとうございます。
今、自宅の2003で試しましたら#3のコードも#4のコードもエラーになりませんね
でも両方とも余分なBookができてしまうのは困りものです。
やはり、素直にそういうものなんだと覚えることにします。
No.4
- 回答日時:
こんにちは。
こんなコードは絶対エラーになると思って
試したことがありませんでしたが投稿者さんの
疑問ももっともですね。
コピー先の指定が無いとSheets(1).Copy の前に
「Workbooks.Add」が動作してるのでしょう。
そしてブックの中身を指定したシートのみに入れ替えています。
次のように明示的に指定してみると動作しました。
Set wb = Workbooks.Add(Sheets(1).Copy)
ただしブックの名前が「Sheet1」になりますが・・・。
No.2
- 回答日時:
Sub test01()
Dim wb As Workbook
Set wb = Sheets(1).Copy 'エラー「オブジェクトが必要です
End Sub
は何をしたいのか。
ワークブックを増やして、増えたブックの第1シートをコピーしたいのか。
シートを増やせば、とかコピーすれば、ブックが増えるという発想がわからない。
それにしても
Dim Newbook As Workbook
Set Newbook = Workbooks.Add
Newbook.SaveAs FileName:="新規ブック"
または
Workbooks.Add.SaveAs Filename:="新規ブック.xls"
がないのはどうしてか。
>Sheets(1).Copyの段階であたらしいWorkbookが誕生していますよね
>Set wb = Sheets(1).Copy
>Set wb = Sheets(1).Copyができないのが不思議です
ができないのが不思議です。
コピーしてもオブジェクトが新しく作られるとか、既存オブジェクトが捉えられないのは、Copyメソッドはそういうものじゃ無いのだから当たり前。
なんか独りよがり的な点が見えて、聞いていることが理解しにくい。
いえ、別にしたいことがあるわけじゃないんです。
ただ、目の前に新しいBookが出来たのに「オブジェクトが必要です」とエクセルから叱られると釈然としなかったもので・・・・・。
Copyメソッドはそういうものじゃ無いと言われてしまえばそれまでの話なんですが。
No.1
- 回答日時:
> Workbooks.Add で誕生したWorkbookは
> Set wb = Workbooks.Add
> と変数wbにSetできるのに
------------------------------------------------------------
ヘルプより
Workbooks オブジェクトの Add メソッド
オブジェクトを返すメソッドです。新しいブックを作成します。新しいブックが作業中のブックになります。ブック (Workbook オブジェクト) を返します。
------------------------------------------------------------
> Set wb = Sheets(1).Copy
> ができないのが不思議です。
------------------------------------------------------------
Chart、Charts、Sheets、Worksheet、および Worksheets オブジェクトの Copy メソッド
シートをブック内の他の場所にコピーします。
------------------------------------------------------------
Copy メソッド はオブジェクトを返さないので
右辺には、wb に代入すべきオブジェクトがありません。
で、「オブジェクトが必要です」 と言われます。
仮に Copy メソッド がオブジェクトを返したとしても
おそらく Workbook ではなく、Worksheet でしょうね。
この回答への補足
いま試しましたが、
Sub test()
Sheets(1).Copy
MsgBox Workbooks.Count
End Sub
これを実行するたびにWorkbookの数は一つずつ増えていきます。
さっそくありがとうございます。
> Copy メソッド
> シートをブック内の他の場所にコピーします。
Sheets(1).Copy Before:=Sheets(1) のように書けばその通りですが、例えばBook1で、Sheets(1).Copy だけで実行すると、Book2が出来てしまいます。このBook2はWorkbookでオブジェクトですよね?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 別ブックからシートのコピー 3 2022/04/01 20:07
- Visual Basic(VBA) VBAでWorkbook.addの使い方 3 2023/02/01 11:58
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Visual Basic(VBA) VBAでファイルを開くプログラムがエラーです 2 2023/02/21 16:56
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Excel(エクセル) エクセル 値をコピペした時に、条件付き書式で塗られた背景色もペーストさせる 2 2023/04/05 17:21
- Visual Basic(VBA) エクセルVBA Workbook変数に変数を使ったファイル名を格納したい 5 2023/06/13 14:46
- Visual Basic(VBA) エクセルVBA(実行時エラー438)の対処法を教えてもらえないでしょうか 3 2023/04/22 13:43
- Visual Basic(VBA) VBA This Workbookモジュールを別ファイルにコピーする方法 1 2022/09/14 01:51
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
このQ&Aを見た人はこんなQ&Aも見ています
-
VBA シートをコピーする際に Copyメソッドは失敗しましたのエラーが出てしまいます
Visual Basic(VBA)
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
エクセルVBAでオートフィルター最上行を取得するには
Excel(エクセル)
-
-
4
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
5
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
6
セルのコピーで「オブジェクトが必要です。」
Visual Basic(VBA)
-
7
VBA 数式を残して値をクリアについて
Excel(エクセル)
-
8
複数の条件に合う行番号を取得するには
その他(Microsoft Office)
-
9
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
10
Excel VBAで同じフォルダ内のファイルを開くには?
Excel(エクセル)
-
11
VBA:日付を配列に入れ別セルに転記するとデータ型が変わる
Visual Basic(VBA)
-
12
WorkBooksをオープンさせずにシートにコピーしたい【EXCEL VBA】
Excel(エクセル)
-
13
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
14
エクセルVBAで5行目からオートフィルタモードに設定したいたい
Excel(エクセル)
-
15
【Excel VBA】マクロでExcel自体を終了させたい
Excel(エクセル)
-
16
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
17
非表示の列をすべて削除するマクロ
Excel(エクセル)
-
18
エクセルのシート連番の振り直し
Excel(エクセル)
-
19
「Columns(A:C")」の列文字を数字にして表記したい"
Excel(エクセル)
-
20
VBAでユーザーフォームの表示を確認
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
VBAで Set wb = Sheets(1).Cop...
-
実行時エラー 3265「要求された...
-
VBAで既に開いている別アプリケ...
-
エクセルのVBAの標準モジュール...
-
AccessVBAで「dim dbs as datab...
-
ASP レコードセットしたオブジ...
-
vb6.0でEXCELオブジェクトの使用
-
パワーポイント filedialogでフ...
-
エクセルから表をパワーポイン...
-
アクセスにてオブジェクト名変...
-
エクセルVBAで配列内に空白デー...
-
getterとsetterについて
-
CreateObjectとGetObjectの違い
-
(初心者です)VBAについて。「実...
-
AccessVBAからWordのマクロを実...
-
ListView内の検索 VB6
-
オブジェクト変数またはWITHブ...
-
sheetsメソッドの失敗
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
実行時エラー 3265「要求された...
-
エクセルのVBAの標準モジュール...
-
Excelでフィルタをかけると警告...
-
VBAで既に開いている別アプリケ...
-
テキストボックス中の文字列の...
-
EXCEL VBA オートシェイプナン...
-
VBAで Set wb = Sheets(1).Cop...
-
ExcelVBAでのNZ関数について
-
[VBA]CDOメッセージ送信エラー
-
VBAからPDFファイルにパスワー...
-
エクセルVBAでcode128のバー...
-
VBScriptからDLL参照設定したい
-
VBAについてです。 初心者です...
-
エクセルマクロエラー「'Cells'...
-
オブジェクトが見つかりません
-
エクセルVBAで配列内に空白デー...
-
Excel VBAでWordの複数ファイル...
-
VBScriptでファイルの日時順(降...
おすすめ情報