電子書籍の厳選無料作品が豊富!

環境は
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
-------------------------------------------

A 回答 (4件)

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
=========================================================

補足日時:2009/10/22 17:33
    • good
    • 0

#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イベント内にでも書いて確かめてみてください。
    • good
    • 0
この回答へのお礼

>インスタンスを作成していますが、どこにもQuitされている箇所がないので、これが残っているのではないでしょうか?

そのとおりでした。

何となく見えてきました。

ありがとうございました。

お礼日時:2009/10/23 03:56

#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)からクラスを指定することはできない。
という感じでしょうか。

補足日時:2009/10/22 18:22
    • good
    • 0

まず、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
=========================================================

補足日時:2009/10/22 18:07
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!