tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^2: VB2010でのエクセルの起動と終了
投稿日: 2012/04/10(Tue) 13:32
投稿者かっちゃん
> > Public Sub SetInXls(ByRef Flag As Byte, ByRef SubFl As Byte, ByRef FrmItem As String, ByRef strItem As String, ByRef SubstrIm As String, ByRef bytItem As Byte, ByRef intItem As Short, ByRef lngItem As Integer, ByRef TblX As String, ByRef TblY As String)
>
> 何故、各引数が ByRef 宣言されているのでしょうか?
> いずれも 出力引数であるようには思えませんし、ByVal のままで良いと思いますけれども。
>
はい、ありがとうございます。 ByRefでなくByVal です

> >  エクセルの起動を一度にしたいので CASE 0 の エクセル起動の中に
> Select Case Flag に渡す値は、それぞれどのような意味があるのでしょうか?
> マジックナンバーだと、第三者や後からコードを見た人が意味を掴みにくいので、
> 列挙型を使うか、あるいはせめてコメントを入れるなどしておきましょう。
>
 コメントを入れてわかりやすくしました
>
> >  エクセルワークエリアDIM5行を入れたいのですがエラーになります。
> これは、Sub SetInXls の先頭にある変数宣言の事でしょうか。
> 具体的には、どの行で何というエラーになるのでしょうか? (想像はつきますが…)

       Select Case Flag
            Case 0
            ' Excel起動
          Dim xlsInApp As New XL.Application
         Dim xlsInBooks As XL.Workbooks
              Dim xlsInbook As XL.Workbook
              Dim xlsInSheets As XL.Sheets
              Dim xlsInSheet As XL.Worksheet
            Case 1
              Select Case SubFl
                Case 0
                ' 既存のエクセルシート使用
                  xlsInBooks = xlsInApp.Workbooks
         CASE 1 以降で”宣言されていません” のエラーが当然でてしまいました

>
> > SetInXls を通るたびに エクセルが起動してしまいます。
>
> SetInXls を複数回通過する際に起動回数を減らしたいなら、
>  Excel 起動 → SetInXls → SetInXls → SetInXls → Excel 終了
> のような動きになると思いますが、その場合、Excel がいつ起動して
> いつ終了するのかという有効期間を定めるために、Excel.Application 等の変数を、
> 「Sub SetInXls の外側」で管理するようにしてください。
>
> 現在のように、「Sub SetInXls の内側」で変数を Dim 宣言していた場合、
> それらの変数の有効期間は、そのメソッド内だけに留まってしまいます。

    ' エクセルワークエリア
    Dim xlsInApp As New XL.Application
    Dim xlsInBooks As XL.Workbooks
    Dim xlsInbook As XL.Workbook
    Dim xlsInSheets As XL.Sheets
    Dim xlsInSheet As XL.Worksheet

    Public Sub SetInXls(ByVal Flag As Byte, ByVal SubFl As Byte, ByVal FrmItem As String, ByVal strItem As String, ByVal SubstrIm As String, ByVal bytItem As Byte, ByVal intItem As Short, ByVal lngItem As Integer, ByVal TblX As String, ByVal TblY As String)
        Select Case Flag
            Case 0
             ' Excel起動

「Sub SetInXls の外側」に出すと処理は無事終了するのですが

 メニューフォームで設定しているクラスを接続する箇所
  ' クラス接続(クラスオブジェクト)
    Public KaOBJ As New ClassLibrary1.KaClass

 「外側」に出した
' エクセルワークエリア
  Dim xlsInApp As New XL.Application

 を実行してしまい、プログラムが終了するまでエクセルが起動している状態です。
 クラスの最上部に設定してある
  Imports XL = Microsoft.Office.Interop.Excel
 が原因でしょうか?
 エクセルを起動するフォームで起動させ、フォームを抜けた時、エクセルも
 終了させたいです。
         
>
> メソッド内のローカル変数は、End Sub 等でメソッドを抜けると使えなくなくなります。
> もう一度 SetInXls が呼び直されたとしても、その時は新たな変数が使われるだけであり、
> たとえ Case 7 が呼び出されても、xlsInApp 変数の中身は空っぽ(Nothing)のままです。
>
> 外側で変数を用意してやることで、この状況(質問2の問題)を解決できます。
 外側に出しましたら解決しました
>
>
> > xlsInSheets = xlsInbook.Worksheets
> > xlsInSheet = xlsInbook.Sheets(Trim(SubstrIm))
> 上記では、xlsInbook.Worksheets を変数に取得していますが、
> xlsInbook.Sheets の方は変数に取得し忘れているように見えます。
> 強いて言うならば、
>  xlsInWorksheets = xlsInbook.Worksheets
>  xlsInSheets = xlsInbook.Sheets
>  xlsInSheet = xlsInSheets(Trim(SubstrIm))
> が正しいコードでは無いでしょうか。
> あるいはシートの種類によっては、
>  xlsInSheet = xlsInSheets(Trim(SubstrIm))
> でも良いかもしれません。
> (バージョンによっては、Worksheet への DirectCast が必要かも)

下記のように修正しましたら、処理は無事終了しました
' 既存のエクセルシート使用
    xlsInBooks = xlsInApp.Workbooks
    xlsInbook = xlsInBooks.Open(Trim(FrmItem) & Trim(strItem) & ".xls")
    xlsInSheets = xlsInbook.Worksheets
    xlsInSheet = xlsInSheets(Trim(SubstrIm))
>
>
> 変数に受ける理由については、下記の記事をご覧ください。
> これは、オブジェクトの早期解放処理のために必要な手順の一部であり、
> この点を見直せば、質問1の問題を解決できるはずです。
> http://hanatyan.sakura.ne.jp/dotnet/Excel08.htm
>
>
>
> > xlsInSheet.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell).Select()
> > wklngItem = xlsInApp.ActiveCell.Row
> これも同様の理由から、
>  a = xlsInSheet.Cells
>  b = a.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell)
>  'b.Select()
>  wklngItem = b.Row
> のように、個々の Range オブジェクトを変数に受けておくべきかと思います。
>
 エラーがでなかったのでいいのかと思っていましたが、
 ありがとうございます。修正いたしました。
>
> また、元のコードでは Select メソッドと ActiveCell プロパティを利用していますが、
> Active〜系プロパティや Selection プロパティ等は多用しないよう心掛けてください。
>
> これは、VB でコードを書くときに、
>   strItem = Me.TextBox1.Text
> と書くべきところで、わざわざ
>   Me.TextBox1.Focus()
>   TextBox2.Text = Me.ActiveControl.Text
> のように書かないのと同じ理屈です。

 色々参考になりました。
 どうにか、エクセルを止めたいと思っております。
 よろしくお願いいたします

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。