• ベストアンサー

VB6からのExcel起動について

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

  • elec2
  • お礼率61% (105/171)

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答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に 含まれるコレクションで、新たにインスタンス化するようなモノでは ありません。

elec2
質問者

補足

詳細な説明、ありがとうございました。 実体があるか、いわゆる「ポインター」かの違いという感じでしょうか。 >尚、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 =========================================================

その他の回答 (3)

回答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イベント内にでも書いて確かめてみてください。

elec2
質問者

お礼

>インスタンスを作成していますが、どこにも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 はインターフェイスなので×

elec2
質問者

補足

ありがとうございます。 xlAppはインスタンスなので、 xlApp.Workbooksは、 意味的には、インスタンスとクラスが混在(混同)しているという理解でよろしいでしょうか。 実際はインスタンス(xlApp)からクラスを指定することはできない。 という感じでしょうか。

  • nak777r
  • ベストアンサー率36% (49/136)
回答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 を表示させた場合どうなるでしょう

elec2
質問者

補足

詳細な説明、ありがとうございました。 >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

  • VB6.0上でExcelオブジェクトを生成

    VB6.0上でExcelオブジェクトの生成についてです。 その1 Dim xlApp As New Excel.Application Dim xlBook As New Excel.Workbook Dim xlSheet As New Excel.Worksheet Set xlApp = New Excel.Application Set xlBook = xlApp.Workbooks.Add Set xlSheet = xlBook.Worksheets(1) と その2 Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Add Set xlSheet = xlBook.Worksheets(1) と、どちらが良いのでしょうか? 開発環境は  Windows2000  VB 6.0  Excel 2003 です。

  • VBからエクセルを起動。そのあとエクセルを終了

    教えてください。 VBからエクセルを起動します。 そのあと、エクセルのシートの上にデータを貼り付けます。そして、エクセルを終了します。 しかし、エクセルが終了しません。 タスクバー上のエクセルをクリックすると終了します。 どうして、このような現象が起こるのかわかりません。 教えてください。 下記に同様のサンプルを書きました 誤記入があるかも知れませんが このような感じのプログラムです。 以上、よろしくお願いします。 public sub test Dim XApp as Excel.Application Dim nfilename as string Dim xlBook As Object Dim xlSheet As Object ' エクセルを起動 Set xlApp = New Excel.Application nfilename ="AAAA.xls" ' 指定されたファイルを開く Call xlApp.Workbooks.Open(nfilename) Set xlBook = xlApp.ActiveWorkbook Set xlSheet = xlBook.Worksheets(1) 'フォームを貼り付ける xlSheet.Range("a1").PasteSpecial      'ファイル名の作成 Filename="BBBB.xls" '保存 ChDir "C:\" xlBook.SaveAs Filename:=Filename,FileFormat:=xlNormal, _ Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, _ CreateBackup:=False Set xlSheet = Nothing xlBook.Close True Set xlBook = Nothing xlApp.Quit Set xlApp = Nothing End sub

  • VBからExcelを操作

    VisualBasic6.0(初心者) VBを始めたばかりで、Excelの入力文字をVBで変換しようと考えています。 様々な保管場所にあるExcelを開いて選択セルの文字をコマンドボタンで変換しようと下記コードを考えました。(一部) 問題は、Load時にすでに開いているExcelを閉じてまいます。 何か良い方法は無いでしょうか?(アクティブなExcelを操作したい) また、下記コードで不適切なところがありましたら御教授願います。 Private Sub Form_Load() Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Add Set xlSheet = xlBook.Worksheets(1) Set xlApp = GetObject(, "Excel.Application") With xlApp.Selection Cells(1, 1).Value = "" End With xlApp.DisplayAlerts = False xlApp.Quit Set xlSheet = Nothing Set xlBook = Nothing Set xlApp = Nothing End Sub '----------------------(大文字変換) Private Sub CB2_Click() On Error Resume Next If ActiveCell.Row = Null Then MsgBox "Excel が見つかりません" Else Dim xlApp As Excel.Application Set xlApp = GetObject(, "Excel.Application") If Err.Number Then MsgBox "Excel が起動されていません" Else Dim X As Long Dim Y As Long Dim Hmae As String Dim Hgo As String X = 0 Y = 0 With xlApp.Selection Do Do Hmae = Cells(ActiveCell.Row + X, ActiveCell.Column + Y).Value Hgo = StrConv(Hmae, 1) Cells(ActiveCell.Row + X, ActiveCell.Column + Y).Value = Hgo X = X + 1 Loop Until X >= .Rows(.Rows.Count).Row - .Row + 1 X = 0 Y = Y + 1 Loop Until Y >= .Columns(.Columns.Count).Column - .Columns(1).Column + 1 End With End If xlApp.DisplayAlerts = False Set xlApp = Nothing End If End Sub

  • エクセルを表示できない

    プログラム初心者です。 Private Sub Command3_Click() On Error Resume Next Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet With xlApp.Application Set xlApp = GetObject("F:\vb6.0\book1.xls") Set xlBook = xlApp.Workbooks.Open("Book1") Set xlSheet = xlBook.Worksheets(1) xlApp.Application.Visible = True End Sub と入力したのですが、実行してボタンをクリックしてもエクセルの表が表示されません。なぜでしょうか?

  • Excel.Applicationへのシートコピー

    Public xlApp As Excel.Application Public xlBook As Excel.Workbook Set xlApp = CreateObject("Excel.Application") '非表示・画面更新無・アラート非表示 xlApp.Visible = False xlApp.ScreenUpdating = False xlApp.DisplayAlerts = False Set xlBook = xlApp.Workbooks.Add xlBook.SaveAs "test123.xls" '※ここでエラー Workbooks("TEST.xls").Sheets("TEST_1").Copy After:=xlApp.Workbooks(xlBook).Sheets(3) Set xlApp = Nothing Set xlBook = Nothing 環境:WindowXP SP2,Excel2003 SP3 以上のようにオブジェクト変数のEXCELに対してのシートコピーを行いたいのですが、コンパイルを行うとエラーがなく、実行すると「コンパイルエラー 修正候補:区切り記号 または(」とエラーが発生します。色々書き方を試してみたのですが、どれもうまくいきませんでした。 宜しくお願いします。

  • 【VB】【エクセル操作】 SaveAsでエラーが出てしまいます。

    VB6.0で作成したソフトの一部でエクセルを操作する箇所があります。 『新しいブックを作成して名前を付けて保存する』ところでエラーが出てしまいます。 Excel2007,2003では正常に動作するのですが、2000ではエラーが発生し強制終了されてしまいます。 '//////////////////////////////////////////////////////////// Private Sub EditExcelFile(FileName As String) Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Add xlApp.Visible = True With xlBook .Application.DisplayAlerts = False .SaveAs (FileName) .Application.DisplayAlerts = True End With Set xlBook = Nothing Set xlApp = Nothing End Function '//////////////////////////////////////////////////////////// 上記コードの .SaveAs (FileName)の箇所でエラーがでます。 .SaveAs (FileName)をコメント文にすると2000でも正常に動作します。 FileNameは新しいブック名のパスが入ります。 2000でも正常に動作させるにはどのような処理を加えれば良いでしょうか? 宜しくお願い致します。

  • ややこしいですがご協力ください

    アクセスからエクセルを起動してエクセルで実行した変数をアクセスに持って帰りたいです。 【アクセス側】_ Sub エクセルの値を持ってくる() Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim MyFileName As String Dim myStr As String Set xlApp = New Excel.Application MyFileName = "C:\Users\エクセル.xlsm" Set xlBook = xlApp.Workbooks.Open(MyFileName) xlApp.Visible = True xlApp.Run "'" & MyFileName & "'!" & "Excel_test" Set xlApp = Nothing MsgBox myStr ’★ End Sub 【エクセル側】 Sub Excel_test() Dim myStr As String myStr = "アクセスへ渡す" MsgBox myStr End Sub としたときに、アクセスの MsgBox myStr ★でも エクセルで実行させた変数を持って帰りたいのですが どこを修正すればよろしいでしょうか? ご教授よろしくお願いします。

  • エクセルvba

    エクセルvbaなのですが Sub test() Dim xlApp As Object Dim xlBook As Object Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Open(ActiveWorkbook.FullName) 'コード・・・ Set xlApp = Nothing Set xlBook = Nothing End Sub これだと Set xlBook = xlApp.Workbooks.Open(ActiveWorkbook.FullName) の部分で、エラーになります。 実行時エラー1004です。 自身ファイルをオブジェクトに格納して操作したいのですがどうすればいいでしょうか?

  • VBでエクセルのバージョンを指定して開く

    PCにEXCEL2002と2013がインストールされています。 VBでエクセルを起動し、マクロを実行したいのですが、その際に起動するエクセルのバージョンを指定したいと考えています。 以下でやると標準設定のEXCELが開いてしまい、バージョンの指定ができません。 Dim xlApp As New Excel.Application() Dim xlBooks As Excel.Workbooks xlBooks = xlApp.Workbooks xlBooks.Open("C:\test.xls") xlApp.Visible = True xlApp.Run("test.xls!macro") なにか方法はありますでしょうか?

  • 既に開いているエクセルを閉じるには?

    既に該当のファイルが開いているのなら閉じたいのですが xlBook.Quitだとエラーになります。 Sub test1() Dim xlApp As Excel.Application Dim xlBook As Workbook Dim FileName As String FileName = "C:\test.xlsm" Set xlApp = GetObject("", "Excel.Application") 'GetObjectで合ってるか不安 Set xlBook = xlApp.Workbooks.Open(FileName) If xlBook.ReadOnly = True Then 'ファイルが開いてるのなら MsgBox "既にファイルが開いているので閉じます。" xlBook.Quit 'エラー 438 End If xlApp.Quit 'これって何のために必要? Set xlBook = Nothing 'ココを通り過ぎるのにすごく時間がかかる。 Set xlApp = Nothing End Sub と言うコードを作りました。 xlBook.Quitがダメならどのコードを使えばいいでしょう? また、 GetObject("", "Excel.Application") と言う開き方でいいのでしょうか? あと、 xlApp.Quit は何のために必要なのでしょう? タスクマネージーのプロセスを見ると、 Set xlApp = GetObject("", "Excel.Application") を通る時に新しいEXCEL.EXEが作成され、 Set xlApp = Nothing を通り過ぎる時に、そのEXCEL.EXEが消えます。 だから xlApp.Quit は不要ですか?

専門家に質問してみよう