![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_02.png?e8efa67)
環境は
WindowsXpSp3
Excel2002Sp3,Excel2003
VB6Sp6
です。
上記環境下で以下のコードの違いがよくわかりません。
Main1,Main2,Main3
で設定、処理方法(コーディング)、動作、終了(Excelオブジェクトの)の方法等で気をつけなければならないものが変わるのでしょうか。
もう一つ、
Set xlWorkbooks = xlApp.Workbooks
についてですが、こちらは
Set xlWorkbooks = new xlApp.Workbooks
とするとエラーになります。
(Set xlApp = Excel.Application は New があってもなくてもエラーは出ません)
この理由もわかりません。
インターネット上で色々検索はしてみたのですが、よくわかりませんでした。
ご存知の方、よろしくお願いいたします。
-------------------------------------------
Global xlApp As Excel.Application
Global xlWorkbooks As Workbooks
sub Main1()
Set xlApp = Excel.Application
Set xlWorkbooks = xlApp.Workbooks
end sub
sub Main2()
Set xlApp = new Excel.Application
Set xlWorkbooks = xlApp.Workbooks
end sub
sub Main3()
set xlApp = CreateObject("Excel.Application")
Set xlWorkbooks = xlApp.Workbooks
end sub
-------------------------------------------
No.1ベストアンサー
- 回答日時:
Main2 と Main3 は全く同じ意味です。
新たにExcelのインスタンスを作成すると言う意味です。Main1は初めて見た形ですが、静的な生成
と思います。繰り返し実行した場合に、Main1では最初に生成された
インスタンスが継続的に使われるのに対し、Main2とmain3では新たに
インスタンスが生成されます。尚、Main1ではインスタンスを消滅
させることができませんでした。
Excelインスタンスは使用後は、次のようにして、破棄すべきです。
xlApp.Quit
Set xlApp = Nothing
以上のことから、Main1は好ましくありません。また、インスタンスを
静的変数で受けるのも、できれば避けるべきです。
静的変数とは標準モジュールのDeclaration部で定義される変数です。
>Set xlWorkbooks = new xlApp.Workbooks
明らかな間違いです。ワークブックコレクションはアプリケーション
オブジェクトに含まれるもので、インスタンスを新たに生成して使う
ようなものではありません。因みに、複数形のものはコレクション、
単数形のものはオブジェクトです。コレクションはオブジェクトの
集合です。よって、ExcelにはWorkbooksとWorkbookの二つの型がある
のが確認できますね。これは「Workbooks=Workbook×n」という意味
です。一つのExcelで、複数のワークブックを開けるでしょう。
つまり、一つのExcelは複数のワークブックオブジェクトを管理して
いるということです。Excelをインスタンス化した直後は空のコレク
ションです。既存ブックを開く(Open)か、新規作成(Add)により
コレクション内のオブジェクト数は増えていきます。また、反対に
閉じる(Close)と減っていきます。同様に一つのワークブック内には
一つのワークシートコレクション(WorkSheets)があり、これは複数の
ワークシート(WorkSheet)の集合です。このWorkSheetsもWorkbookに
含まれるコレクションで、新たにインスタンス化するようなモノでは
ありません。
この回答への補足
詳細な説明、ありがとうございました。
実体があるか、いわゆる「ポインター」かの違いという感じでしょうか。
>尚、Main1ではインスタンスを消滅させることができませんでした。
とのことですが、こちらではタスクマネージャーのプロセスで確認したところ、3つともEXCEL.EXEは破棄されていました(何が違っているのでしょうか?)。
あらたな現象が見つかりました。
こちらでは、質問に記載したコードですと、1から3のどのコードでもEXCEL.EXEは破棄されました。
しかし、
nda23さんとnak777rさんのコードを組み合わせて実行してみると一つのEXCEL.EXEは破棄されず残ってしまいました(nda23さんが書かれていた状況なのでしょうか?)。
これに関して、何か解説いただけるようでしたら、お願いいたします。
長くなりますが、実行したコードを下記に記載します。
=========================================================
標準モジュール
---------------------------------------------------------
Global xlApp As Excel.Application
Global xlWorkbooks As Workbooks
Sub Main()
Dim strPath As String
Set xlApp = New Excel.Application
Set xlWorkbooks = xlApp.Workbooks
strPath = Left(xlApp.DefaultFilePath, InStrRev(xlApp.DefaultFilePath, "\")) & "デスクトップ\"
xlWorkbooks.Open strPath & "\sample.xls"
Form1.Show
End Sub
=========================================================
フォームモジュール
---------------------------------------------------------
Private Sub Command1_Click()
Dim xlApp1 As Excel.Application
Dim xlApp2 As Excel.Application
Dim xlApp3 As Excel.Application
Dim xlWorkbooks As Workbooks
Set xlApp1 = New Excel.Application
Set xlApp2 = New Excel.Application
Set xlApp3 = New Excel.Application
' ここで中断してタスクマネージャーの
' プロセスを確認
' イメージ名に EXCEL は何個ある?
Stop
' EXCELを終了します
xlApp1.Quit
xlApp2.Quit
xlApp3.Quit
Set xlApp1 = Nothing
Set xlApp2 = Nothing
Set xlApp3 = Nothing
End Sub
=========================================================
No.4
- 回答日時:
#3 Wizard_Zeroです。
> xlAppはインスタンス
厳格に説明すれば
「xlAppはExcel.Applicationクラスのインスタンスを格納した変数」
となります。これを分解すると
・xlApp は 変数 である
・xlApp の 型 は Excel.Application である
・xlApp に格納されているのは Excel.Applicationクラスのインスタンス である
となります。暗に「xlAppはインスタンス」と捉えてしまうと実態が掴めなくなってしまいます。
# まぁ文章だと表現・ニュアンスの違いがありますから、理解の仕方はおおよそ間違っていないと思います。
> xlApp.Workbooksは、意味的には、インスタンスとクラスが混在(混同)している
xlApp.Workbooks と Excel.Workbooks は「Workbooks」という同じ名前ではありますが、全く別物です。前者はプロパティ、後者はインターフェイスです。
・xlApp.Workbooks は プロパティ である
・xlApp.Workbooks の 型 は Excel.Workbooksインターフェイス である
という状況なので切り分けがしにくいかもしれませんね。
xlApp. のあとに続くのは、プロパティ名・関数名(メソッド名)・パブリック変数名 だけです。例え、クラス名と同じ名前が出てきたとしても、それはクラスを示すものではなく、前述した3つのうちのどれか、です。
ですので、
> 実際はインスタンス(xlApp)からクラスを指定することはできない。
この解釈は正しいと思います。
#1, #2の補足について横槍失礼します
Global xlApp As Excel.Application
この変数に対して
Set xlApp = New Excel.Application
インスタンスを作成していますが、どこにもQuitされている箇所がないので、これが残っているのではないでしょうか?
xlApp.Quit
Set xlApp = Nothing
をForm1のForm_Unloadイベント内にでも書いて確かめてみてください。
>インスタンスを作成していますが、どこにもQuitされている箇所がないので、これが残っているのではないでしょうか?
そのとおりでした。
何となく見えてきました。
ありがとうございました。
No.3
- 回答日時:
#1さん、#2さんとは少し見解が異なります。
私の解釈が間違っていたらご指摘を・・・(o*。_。)oペコッSet xlWorkbooks = new xlApp.Workbooks
これがエラーになるのは、Newの後が「クラス名ではないから」です。
Set xlApp = new Excel.Application
この場合「Excel.Application」は『クラス名』なので、Newキーワードが使えます。
対して「xlApp.Workbooks」は変数xlAppに対する「Workbooks」という名前の『プロパティ』なので、Newキーワードは使えません。
仮に
Set xlBooks = new Excel.Workbooks
とした場合も「Excel.Workbooks」はクラスではなく『インターフェイス』ですのでNewキーワードは使えません。
まとめると
New Excel.Application はクラス名なのでOK(実際にインスタンスが作成できるかどうかは別問題)
New xlApp.Workbooks はプロパティなので×
New Excel.Workbooks はインターフェイスなので×
この回答への補足
ありがとうございます。
xlAppはインスタンスなので、
xlApp.Workbooksは、
意味的には、インスタンスとクラスが混在(混同)しているという理解でよろしいでしょうか。
実際はインスタンス(xlApp)からクラスを指定することはできない。
という感じでしょうか。
No.2
- 回答日時:
まず、EXCEL には Applicationクラスという基底のクラスが存在
します。 マクロの記録を行うと、ActiveSheet とか Range とか
の関数が利用できますが、これらは全て Application クラスに属
していて、Application の部分が省略された記述で表現されます。
なのでマクロの記録後のマクロを修正して、ActiveSheet を、
Application.ActiveSheet に、Rangeを、Application.Range に
変更してもなんら変わらず実行する事が出来ます。
Set xlApp = New Excel.Application
は、OLEの機能を利用して、新規に EXCEL を立ち上げ、
その Applicationクラスを、xlApp 変数にセットするという事の
意味になります
ためしに、タスクマネージャーのプロセスで動作を確認すると、
この行で、プロセスに EXCEL が登場します
で、New Excel.Application の New ありと New なしの違いですが
New は インスタンスを新規作成すると言う意味で、
要は別の EXCEL クラスの器を新たに用意すると思えばいいです
ためしにですが
Private Sub Command1_Click()
Dim xlApp1 As Excel.Application
Dim xlApp2 As Excel.Application
Dim xlApp3 As Excel.Application
Dim xlWorkbooks As Workbooks
Set xlApp1 = New Excel.Application
Set xlApp2 = New Excel.Application
Set xlApp3 = New Excel.Application
' ここで中断してタスクマネージャーの
' プロセスを確認
' イメージ名に EXCEL は何個ある?
Stop
' EXCELを終了します
xlApp1.Quit
xlApp2.Quit
xlApp3.Quit
Set xlApp1 = Nothing
Set xlApp2 = Nothing
Set xlApp3 = Nothing
End Sub
上記を実行して、タスクマネージャーのプロセスに
EXCELが何個存在するか確認してみてください。
その後、
Set xlApp1 = New Excel.Application
Set xlApp2 = New Excel.Application
Set xlApp3 = New Excel.Application
を
Set xlApp1 = Excel.Application
Set xlApp2 = Excel.Application
Set xlApp3 = Excel.Application
にして、同様に確認してみてください。
New 有りの場合、 xlApp1、xlApp2、xlApp3、が
別物として処理されていて、New 無しの場合、
xlApp1、xlApp2、xlApp3、が同じ物として処理
されるんだとわかると思います
また、New 有りの場合、関数が終了すると同時に、
タスクマネージャーのプロセスから EXCEL が消滅
しますが、New 無しの場合、プログラムが終了する
まで消えない事がわかると思います。
これは、同一のインスタンスとして処理を行う為の
処置だと思います。
これらを踏まえて、
xlWorkbooks に new を付けるとエラーになるのは
何故かを考えてみてください。
ヒントとして(てか答えとして)
Workbooks オブジェクトにある Addメソッドを行う場合、
xlWorkbooks.Add と記述しますが、これは
xlApp.Workbooks.Add と同じ意味で、
実行するたびに EXCELに、BOOK2、BOOK3 …
を追加する関数となります。
仮に Newできたとして
Set xlApp = New Excel.Application
Set xlWorkbooks1 = New xlApp.Workbooks
Set xlWorkbooks2 = New xlApp.Workbooks
Set xlWorkbooks3 = New xlApp.Workbooks
xlWorkbooks2.Add
とした場合、
xlApp.Visible = True として
EXCEL を表示させた場合どうなるでしょう
この回答への補足
詳細な説明、ありがとうございました。
>xlWorkbooks に new を付けるとエラーになるのは
何故かを考えてみてください。
一つ作った実体に対するポインターだと理解しました。
サンプルコード、確認させていただきました。
タスクマネージャーのプロセスで確認したところ、問題なく開放されていました。
あらたな現象が見つかりました。
nda23さんとnak777rさんのコードを組み合わせて実行してみると一つのEXCEL.EXEは破棄されず残ってしまいました(nda23さんが書かれていた状況なのでしょうか?)。
長くなりますが、実行したコードを下記に記載します。
=========================================================
標準モジュール
---------------------------------------------------------
Global xlApp As Excel.Application
Global xlWorkbooks As Workbooks
Sub Main()
Dim strPath As String
Set xlApp = New Excel.Application
Set xlWorkbooks = xlApp.Workbooks
strPath = Left(xlApp.DefaultFilePath, InStrRev(xlApp.DefaultFilePath, "\")) & "デスクトップ\"
xlWorkbooks.Open strPath & "\sample.xls"
Form1.Show
End Sub
=========================================================
フォームモジュール
---------------------------------------------------------
Private Sub Command1_Click()
Dim xlApp1 As Excel.Application
Dim xlApp2 As Excel.Application
Dim xlApp3 As Excel.Application
Dim xlWorkbooks As Workbooks
Set xlApp1 = New Excel.Application
Set xlApp2 = New Excel.Application
Set xlApp3 = New Excel.Application
' ここで中断してタスクマネージャーの
' プロセスを確認
' イメージ名に EXCEL は何個ある?
Stop
' EXCELを終了します
xlApp1.Quit
xlApp2.Quit
xlApp3.Quit
Set xlApp1 = Nothing
Set xlApp2 = Nothing
Set xlApp3 = Nothing
End Sub
=========================================================
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エラー処理 3 2022/04/11 14:58
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) このVBAでExcelアプリケーションを作成は必要ですか? 3 2023/07/19 21:13
- Excel(エクセル) Excel-VBAの「しばらくお待ちください」のダイアログが自動的に閉じない 2 2023/05/24 15:31
- Visual Basic(VBA) Accessフォームで全レコードを指定のExcelのセルへ転送し印刷する方法について 2 2022/09/08 18:23
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) VBAでファイルを開くプログラムがエラーです 2 2023/02/21 16:56
- Visual Basic(VBA) Excel VBA メール作成について 本文の中にExcel でコピーした図を上下に2つ 貼り付けを 2 2023/06/14 01:48
- Visual Basic(VBA) Excel VBAで並べ替えをしたい 3 2023/02/25 09:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
次の日本語の意味を教えて下さい
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
private static という変数の修飾
-
C#において、同じインスタンス...
-
複数の変数を宣言する時、同時...
-
VB6からのExcel起動について
-
VB.NET getとsetの概念がわかり...
-
フォームのCheck boxとOLEObjec...
-
C# インスタンスの破棄
-
JavaのSingletonパターンのpriv...
-
オブジェクト参照がオブジェク...
-
newしないインスタンス?実体化...
-
生成したインスタンスを削除す...
-
クラスでnew宣言
-
C#「オブジェクト参照が必要で...
-
staticメソッドにするかどうか...
-
整数の引数に列挙を使ったとき
-
JAVA タートルグラフィック ...
-
抽象クラスのインスタンス生成...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
private static という変数の修飾
-
複数の変数を宣言する時、同時...
-
VB.NET getとsetの概念がわかり...
-
生成したインスタンスを削除す...
-
C# インスタンスの破棄
-
C#において、同じインスタンス...
-
「インスタンス」の意味をわか...
-
変数の参照でエラーが出てしま...
-
SQLを連続発行する時の正しい(?...
-
オブジェクト参照がオブジェク...
-
文字列を日付に変換でParseExce...
-
VB6.0で、DLLを動的に参照したい
-
javaのクラスの作り方、エラー...
-
インスタンスを同じ名前で作成...
-
エクセル(複数インスタンス)...
-
フォームの存在をチェックする方法
-
C#「オブジェクト参照が必要で...
-
newしないインスタンス?実体化...
おすすめ情報