none
VB.netにて開発しているプログラムが、起動するPCによってはエラーを吐き出すことがある RRS feed

  • 質問

  • いつもお世話になっております。

    VB.netを用いてプログラムの開発をしております

    今回のプログラムではCOMObjectを用いてExcelファイルを操作するプログラムの作成をしております
    しかしながら、大抵のPCにおいては正しく動くにも関わらず
    ごく一部のPCにおいてのみ、時たま、エラーが発生してしまいます。

    このエラーは何が原因で発生しているのでしょうか。

    COMObjectの解放等はすべて正しく行われています。(こちらが原因ならばすべてのPCにおいて発生するはずです)
    実際にプログラムを動かしている際に、プロセスにExcelアプリケーションが意図せず残っていることもありません。

    プログラムの抜粋は以下になります

            Dim objBooks As Excel.Workbooks = Nothing
            Dim objBook As Excel.Workbook = Nothing
            Dim objSheets As Excel.Sheets = Nothing
            Dim objSheet As Excel.Worksheet = Nothing
            Dim objBooksD As Excel.Workbooks = Nothing
            Dim objBookD As Excel.Workbook = Nothing
            Dim objSheetsD As Excel.Sheets = Nothing
            Dim objSheetD As Excel.Worksheet = Nothing
            Dim objRange As Excel.Range = Nothing
            Dim objFont As Excel.Font = Nothing
            Dim objPageSetup As Excel.PageSetup = Nothing
            Dim objShape As Excel.Shape = Nothing
            Dim FileName As String
            Dim SeisekiNo As Integer
            Dim Var As Object
            Dim i As Integer
    
            FileName = "読み込むファイル.xlsx"
            Try
                objBooksD = objAppT.Workbooks
                objBookD = objBooksD.Open("データシートファイル.xlsx")
            Catch ex As Exception
                MessageBox.Show("エクセルフォーマットが異常です。:"&FileName, "Error",MessageBoxButtons.OK,MessageBoxIcon.Error)
                ReleaseObject(objBookD)
                ReleaseObject(objBooksD)
                Exit Function
            End Try
            Try
                '---------------------
                'いろいろな処理
                '---------------------
                objSheetsD = objBookD.Sheets
                objSheetD = objSheetsD("成績書" & Trim(Str(SeisekiNo)) & "頁")
                objSheetD.Activate()
                objSheetD.Cells.Copy()
    
                objSheet = objSheets(SheetNO)
                objSheet.Activate()
                objRange = objSheet.Range("A1")
                objRange.Select()                 'ここでエラーが起こることがある
                objSheet.Paste()
                ReleaseObject(objRange)
    
                '---------------------
                'いろいろな処理
                '---------------------
    
            Catch ex As Exception
                MessageBox.Show("エラーが発生しました。:" + ex.Message + vbCrLf + ex.ToString(), "Error",MessageBoxButtons.OK,essageBoxIcon.Error)
                MakeSEISEKI_Sheet = RET_ERROR
            Finally
                Clipboard.Clear()
    
                objBook.Close(SaveChanges:=True)
                objBookD.Close(SaveChanges:=False)
    
                ReleaseObject(objFont)
                ReleaseObject(objShape)
                ReleaseObject(objPageSetup)
                ReleaseObject(objRange)
                ReleaseObject(objSheetD)
                ReleaseObject(objSheetsD)
                ReleaseObject(objSheet)
                ReleaseObject(objSheets)
                ReleaseObject(objSheetT)
                ReleaseObject(objSheetsT)
                ReleaseObject(objBookD)
                ReleaseObject(objBooksD)
            End Try

    エラーが発生するPCの環境は
    ・Windows10 Pro 32bit
    ・Microsoft Office 2013
    となります。

    何故か32bitマシンなのに6GBのRAMが実装されていたりといろいろ謎なマシンなので
    マシン環境による不具合も視野に入れております。

    色々と曖昧な情報で申し訳ありませんが、知恵を拝借させていただきく存じます。

    よろしくお願いいたします。

    追記

    発生しているエラー文は
    「RangeクラスのSelectメゾッドが失敗しました。System.Runtime.InteropServices.COMException(0x800A03EC):RangeクラスのSelectメゾッドが失敗しました。」
    となっておりました。



    • 編集済み mifmif325 2018年2月6日 3:10
    2018年2月5日 8:09

すべての返信

  • こんにちは。

    COMってエクセプションに細かいエラー内容でないのでしたっけ。
    エラー内容わかりますか?

    2018年2月5日 11:25
    モデレータ
  • Tak1waさんも指摘されていますが、エラー内容を把握すべきです。質問文に挙げられたコードと全く無関係なエラーの可能性もあります。重要なファイルが見つからないとかディスクが満杯だとか。

    なお、.NET FrameworkではReleaseObjectは不要なように設計されています。明示的にReleaseObjectを行うのであれば一切漏れなく行う必要があります。例えば

    >  objSheetD.Cells.Copy()

    この行ですが「objSheetD.Cells」の時点で生成されたExcel.Rangeオブジェクトに対してReleaseObjectが実行されていません。ですので「ReleaseObject(objSheetD)」を実行しても解放できないわけです。

    # このような事情があるので個人的にReleaseObject呼び出しは開発者の自己満足でしかなく、.NETランタイムはこれらの呼び出しの有無に関わらず解放するよう設計されていると考えています。

    2018年2月5日 13:54
  • Officeが32bit、64bitの違いはないでしょうか? 基本は開発に使用したOfficeとそのアプリを使用するOfficeのビット数を合わせます。 OSのビット数よりOfficeのビット数の違いに着目してみて下さい。
    他の多くのマシンでエラーが発生しないこと、エラーの発生が特定の箇所であること、またその箇所がExcelの操作そのものに関わるところなどから想像するに、VBAのコード自体は問題なく、VBAとその実行環境であるExcelとの関係のような気がします。

    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    2018年2月6日 1:12
    モデレータ
  • コメントありがとうございます。

    エラー内容については追記したとおりRangeエラーでございました。

    以下画像は実際に出たエラーのex.Messageとex.Tostringの内容になります

    ----

    Range クラスの Select メソッドが失敗しました。
    場所 System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)     場所 Microsoft.Office.Interop.Excel.Range.Select()     場所 THEME.ScrCom.MakeTAIKEI_Sheet(Application objAppT, Workbook objBookT, Workbook objBook, Int32 SheetNO, Int32 gengo)

    2018年2月6日 5:32
  • このプログラムはコンソールアプリケーションでしょうか?

    あるいはWindowsFormなどのUIのあるアプリケーションでしょうか?

    コンソールアプリケーションの場合、mainメソッドにSTAThread属性はついているでしょうか?

    ※念のため

    --追記

    あ、VBはコンソールアプリでもデフォルトでSTAThreadになりましたっけか?

    だったら無関係なので無視してください。

    • 編集済み なちゃ 2018年2月6日 7:33
    2018年2月6日 7:27
  • コメントありがとうございます。

    こちらのアプリはWindows Formを用いたUIのあるアプリケーションとなっております。

    2018年2月6日 7:31