tagCANDY CGI VBレスキュー(花ちゃん) - VBレスキュー(花ちゃん)の投稿サンプル用掲示板 - Visual Basic 6.0 VB2005 VB2010
VB2005用トップページへVBレスキュー(花ちゃん)のトップページVB6.0用のトップページ
VBレスキュー(花ちゃん)の投稿サンプル用掲示板
     サンプル投稿用掲示板  VB2005 〜 用トップページ  VB6.0 用 トップページ
Excel の起動・終了に関する設定(VB.NET) ( No.1 )  [親スレッドへ]
日時: 2012/06/13 08:36
名前: VBレスキュー(花ちゃん)

***********************************************************************************
* カテゴリー:[エクセル][][]                                                      *
* キーワード:VBA,Excel,Comオブジェクト,解放処理,起動,エクセル,終了,既存ファイル  *
***********************************************************************************
'===================================================================================================
'投 稿 日:2012.05.05
'投 稿 者:VBレスキュー(花ちゃん)
'タイトル:VB2010 から Excel の起動・終了に関する設定色々
'========1=========2=========3=========4=========5=========6=========7=========8=========9=========0

動作確認:WindowsVista / Windows 7 /  Excel 2007/2010   VB2010 / Framework 4 / ターゲットCPU:X86
[Option Compare Text] [Option Explicit On] [Option Infer On] [Option Strict On]で設定
プロジェクト→参照の追加→COM→Microsoft Excel 12.0(14.0) ObjectLibrary を参照設定しておいてください。
'---------------------------------------------------------------------------------------------------

'下記でエラーの波線が表示されたなら、プロジェクト→参照の追加→.NETタブ→から参照追加して下さい。
'下記の部分もバージョンに注意して下さい。(Excel 2007 〜用になっています。)
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Core
Imports System.Runtime.InteropServices
'Imports Microsoft.Vbe.Interop

Public Class Form1

#Region "Form1_Load 時の設定"

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
   'Form を右下の邪魔にならない位置に表示(お好みで設定して下さい)
   Dim w As Integer = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width
   Dim h As Integer = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height
   Me.Top = h - Me.Height - 35
   Me.Left = w - Me.Width - 25
   'メッセージボックス等がExcelの裏に隠れないようにする為に
   Me.TopMost = True
End Sub

#End Region

#Region "Excel の起動・終了に関する設定"

'---------- Private な変数の宣言 -----------------------------------
Private xlApp As Excel.Application
Private xlBooks As Excel.Workbooks
Private xlBook As Excel.Workbook
Private xlSheets As Excel.Sheets
Private xlSheet As Excel.Worksheet

Private Sub ExcelOpen(ByVal FilePath As String, ByVal SheetName As String)
'Excel のオープン処理用プロシージャ
   xlClose = False   '起動中は、ユーザが Excel を閉じれないように
   xlApp = New Excel.Application
   'Excel の WorkbookBeforeClose イベントを取得
   AddHandler xlApp.WorkbookBeforeClose, AddressOf xlApp_WorkbookBeforeClose

   xlBooks = xlApp.Workbooks
   If FilePath.Length = 0 Then
      '新規のファイルを開く場合
      xlBook = xlBooks.Add
      xlSheets = xlBook.Worksheets
      xlSheet = DirectCast(xlSheets.Item(1), Excel.Worksheet)
   Else
      '既存のファイルを開く場合
      xlBook = xlBooks.Open(FilePath)
      xlSheets = xlBook.Worksheets
      xlSheet = DirectCast(xlSheets(SheetName), Excel.Worksheet)
   End If
   xlApp.Visible = True
End Sub

Private xlClose As Boolean    'ユーザが Excel を閉じようとしたかのフラグ

Private Sub xlApp_WorkbookBeforeClose(ByVal Wb As Excel.Workbook, ByRef Cancel As Boolean)
'VB2010 から Excel の WorkbookBeforeClose イベントを監視してユーザが Excel を閉じれないようにする
   If xlClose = False Then
      Cancel = True        'ユーザが Excel を閉じれないように
   Else
      Cancel = False    'プログラム上から指定の場合は、閉じる
   End If
End Sub

Private Sub ExcelClose(ByVal FilePath As String, Optional ByVal CancelSave As Boolean = True)
'Excelファイルを上書き保存して終了処理用プロシージャ
   xlClose = True                'プログラムからExcel を閉じた時のフラグ
   xlApp.DisplayAlerts = False   '保存時の問合せのダイアログを非表示に設定
   If CancelSave Then
      Dim kts As String = System.IO.Path.GetExtension(FilePath).ToLower()
      Dim fm As Excel.XlFileFormat
      '拡張子に合せて保存形式を変更(使用する Excel のバージョンに注意)
      Select Case kts
         Case ".csv"    'CSV (カンマ区切り) 形式
            fm = Excel.XlFileFormat.xlCSV
         Case ".xls"    'Excel 97〜2003 ブック形式
            fm = Excel.XlFileFormat.xlExcel8
         Case ".xlsx"   'Excel 2007〜ブック形式
            fm = Excel.XlFileFormat.xlOpenXMLWorkbook
         Case ".xlsm"   'Excel 2007〜マクロ有効ブック形式
            fm = Excel.XlFileFormat.xlOpenXMLWorkbookMacroEnabled
         Case Else      '必要なものは、追加して下さい。
            fm = Excel.XlFileFormat.xlWorkbookDefault
            MessageBox.Show("ファイルの保存形式を確認して下さい。")
      End Select
      Try
         xlBook.SaveAs(Filename:=FilePath, FileFormat:=fm)    'ファイルに保存
      Catch ex As Exception
         MessageBox.Show(ex.Message)
      End Try
   End If
   MRComObject(xlSheet)          'xlSheet の解放
   MRComObject(xlSheets)         'xlSheets の解放
   xlBook.Close()                'xlBook を閉じる
   MRComObject(xlBook)           'xlBook の解放
   MRComObject(xlBooks)          'xlBooks の解放
   xlApp.Quit()                  'Excelを閉じる
   MRComObject(xlApp)            'xlApp を解放
End Sub

Private Sub ProcessCheck()
'タスクマネージャに、Excel.exe が残っていないか確認(テスト環境でのみ使用の事)
   Dim st As Integer = System.Environment.TickCount
   '以前は、Loop しながら5秒間程繰り返し確認していたのだが、その間に解放される場合が
   'ある事が判明したので、下記のように1回きりの確認でもデクリメント処理がキチンと
   '行われていたら解放される事が解ったので下記のように厳密に判定する事にしました。
   System.Threading.Thread.Sleep(500)
   Application.DoEvents()
   If Process.GetProcessesByName("Excel").Length = 0 Then
      '先にフォームを閉じるとエラーが発生するので
      '必要により表示するなりコメントにして下さい。
      MessageBox.Show(Me, "Excel.EXE は解放されました。")
      Exit Sub
   End If
   If Process.GetProcessesByName("Excel").Length >= 1 Then
      Dim ret As DialogResult
      ret = MessageBox.Show(Me, "まだ Excel.EXE が起動しています。強制終了しますか?", _
                                                      "確認", MessageBoxButtons.YesNo)
      If ret = Windows.Forms.DialogResult.Yes Then
         Dim localByName As Process() = Process.GetProcessesByName("Excel")
         Dim p As Process
         '起動中のExcelを取得
         For Each p In localByName
            'Windou の無い(表示していない)Excel があれば強制終了させる
            '画面に表示している Excel は、終了させないので必要なら手動で終了して下さい。
            If System.String.Compare(p.MainWindowTitle, "", True) = 0 Then
               'Excel.EXE のプロセスを削除
               p.Kill()
            End If
         Next
      End If
   End If
End Sub

Public Sub MRComObject(Of T As Class)(ByRef objCom As T, Optional ByVal force As Boolean = False)
   Dim IDEEnvironment As Boolean = False  'メッセージボックスを表示させたい場合は、True に設定
   If objCom Is Nothing Then
      If IDEEnvironment = True Then
         'テスト環境の場合は下記を実施し、後は、コメントにしておいて下さい。
         MessageBox.Show(Me, "Nothing です。")
      End If
      Return
   End If
   Try
      If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
         Dim count As Integer
         If force Then
            count = System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom)
         Else
            count = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
         End If
         If IDEEnvironment = True AndAlso count <> 0 Then
            Try
               'テスト環境の場合は下記を実施し、後は、コメントにしておいて下さい。
               MessageBox.Show(Me, TypeName(objCom) & " 要調査! デクリメントされていません。")
            Catch ex As Exception
               MessageBox.Show(Me, " 要調査! デクリメントされていません。")
            End Try
         End If
      Else
         If IDEEnvironment = True Then
            'テスト環境の場合は下記を実施し、後は、コメントにしておいて下さい。
            MessageBox.Show(Me, "ComObject ではありませんので、解放処理の必要はありません。")
         End If
      End If
   Finally
      objCom = Nothing
   End Try
End Sub

#End Region

End Class



 [スレッド一覧へ] [親スレッドへ]