1

私のコードをチェックしてください私はvb.netでExcelからのアップロードを自動化していますここに私のコードがあります

輸入ステートメント

Imports Excel = Microsoft.Office.Interop.Excel

releaseObject 関数

Private Sub releaseObject(ByVal obj As Object)
    Try

        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)


        obj = Nothing
    Catch ex As Exception
        obj = Nothing
    Finally

        GC.Collect()

    End Try
End Sub

ボタンクリックイベント

Protected Sub ButtonUpload_Click(ByVal sender As Object, ByVal e As EventArgs) Handles ButtonUpload.Click
    If IsPostBack Then
       Dim xlApp As Excel.Application
        Dim xlWorkBooks As Excel.Workbooks
        Dim xlWorkBook As Excel.Workbook
        Dim xlWorkSheet As Excel.Worksheet
        Dim range As Excel.Range
        connStr = ConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString
        conn = New SqlConnection(connStr)
        dat = System.DateTime.Now

        Filepath = Path.GetFullPath(fileUploadBOM.PostedFile.FileName)
        sFileName = Path.GetFileName(fileUploadBOM.PostedFile.FileName)
        FileFormat = Path.GetExtension(Filepath)

        v_bom_type = "IMPORT"
        If FileFormat.Equals(".xls") Or FileFormat.Equals(".xlsx") Then
            System.IO.File.Delete("C:\inetpub\wwwroot\Uploads\" & sFileName)
            fileUploadBOM.PostedFile.SaveAs(sFileDir + sFileName)
            Try
                xlApp = New Excel.ApplicationClass
                xlWorkBooks = xlApp.Workbooks
                xlWorkBook = xlWorkBooks.Open(sFileDir + sFileName)
                xlWorkSheet = xlWorkBook.Worksheets("BOM for Import")
                range = xlWorkSheet.Cells
            Catch ex As Exception
                releaseObject(xlApp)
                'GetWindowThreadProcessId(xlApp.Hwnd, processID)
                'release(processID)

            End Try

いくつかの条件のような..

             Dim R As String
            R = CType(range.Cells(4, 2), Excel.Range).Value()
            If Not R Is Nothing Then
                If (R.Trim = "") Then
                    Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), "SetStatusText", "<script type='text/javascript'> alert('please enter the OEM for logistics cost'); </script>")
                    releaseObject(range)
                    releaseObject(xlWorkSheet)
                    xlWorkBook.Save()
                    xlWorkBook.Close()
                    releaseObject(xlWorkBook)
                    xlWorkBooks.Close()
                    releaseObject(xlWorkBooks)

                    xlApp.Quit()

                    releaseObject(xlApp)



                    'GetWindowThreadProcessId(xlApp.Hwnd, processID)
                    'MsgBox(processID)
                    'release(processID)

                    Exit Sub
                Else
                    v_logiccost = CType(range.Cells(4, 2), Excel.Range).Value()
                End If
            Else
                Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), "SetStatusText", "<script type='text/javascript'> alert('please enter the OEM for logistics cost'); </script>")
                releaseObject(range)
                releaseObject(xlWorkSheet)
                xlWorkBook.Save()
                xlWorkBook.Close()
                releaseObject(xlWorkBook)
                xlWorkBooks.Close()
                releaseObject(xlWorkBooks)

                xlApp.Quit()

                releaseObject(xlApp)


                'GetWindowThreadProcessId(xlApp.Hwnd, processID)
                'MsgBox(processID)
                'release(processID)

                Exit Sub
            End If


            '' No of yrs of support

            Dim P As String
            P = CType(range.Cells(6, 2), Excel.Range).Value()
            releaseObject(range)
            If Not P Is Nothing Then
                If (IsNumeric(P) = True) Then
                    v_year = P
                Else
                    Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), "SetStatusText", "<script type='text/javascript'> alert('No Of Years Support Should Be A Number.'); </script>")
                    releaseObject(range)
                    releaseObject(xlWorkSheet)
                    xlWorkBook.Save()
                    xlWorkBook.Close()
                    releaseObject(xlWorkBook)
                    xlWorkBooks.Close()
                    releaseObject(xlWorkBooks)

                    xlApp.Quit()

                    releaseObject(xlApp)



                    'GetWindowThreadProcessId(xlApp.Hwnd, processID)
                    'MsgBox(processID)
                    'release(processID)


                    Exit Sub
                End If
            End If

関数呼び出しから最後に解放

releaseObject(range)
                    releaseObject(xlWorkSheet)
                    xlWorkBook.Save()
                    xlWorkBook.Close()
                    releaseObject(xlWorkBook)
                    xlWorkBooks.Close()
                    releaseObject(xlWorkBooks)

                    xlApp.Quit()

                    releaseObject(xlApp)

これは私のコード全体です。問題はRange.cellsのRCWへの参照にあると思いますが、どこが間違っているかを示唆しています

4

2 に答える 2

2

いくつかのこと

A)コーディングに関しては、私は常に 1 つのエントリ ポイントと 1 つのエグジット ポイントを固く信じてきました。コードには、いくつかの終了ポイントがあります。コードは次のようになります

    If A = B Then
        '
        '~~> Rest of the code
        '
        'release object
        Exit Sub
    Else

    End If

    If C = D Then

    Else
        '
        '~~> Rest of the code
        '
        'release object
        Exit Sub
    End If

    releaseObject(xlrange)
    releaseObject(xlWorkSheet)
    releaseObject(xlWorkBook)
    releaseObject(xlApp)

オブジェクトを正しく閉じていると、追跡が非常に難しくなります。最善の方法は、それらを組み合わせてから、潜水艦を離れる直前にオブジェクトを解放することです。上記のコードは次のように書き直すことができます

    If A = B Then
        '
        '~~> Rest of the code
        '
    Else
        If C = D Then

        Else
            '
            '~~> Rest of the code
            '
        End If
    End If

    releaseObject(xlrange)
    releaseObject(xlWorkSheet)
    releaseObject(xlWorkBook)
    releaseObject(xlApp)

B) Alex と Chris が述べたように、オブジェクトを正しい順序で解放します (これはコードの途中ではなく、最後に行っています)。このような

    releaseObject(xlrange)
    releaseObject(xlWorkSheet)
    releaseObject(xlWorkBook)
    releaseObject(xlApp)

私の最初の提案を取り入れれば、リリース オブジェクト コードをどこでも維持する必要はなくなります。

C)あなたは自分の Excel オブジェクトを次のように宣言しているようPUBLICです。ButtonUpload_Click

  1. たとえばForm Load、「はい」の場合は、それらを正しくリリースしていることを確認してください
  2. いいえの場合は、それらをButtonUpload_Click

上記の提案を取り入れれば、TWO DOTルールを使用するときにオブジェクトを解放する際に問題が発生することはありません。

残りの部分は、既存のコードに問題はありません。それは私にとってはうまくいきます。

于 2013-04-22T11:34:27.697 に答える
0

すべて解決したサンクス

Private Sub releaseObject(ByVal obj As Object)
Try

    System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)



Catch ex As Exception

Finally
obj = Nothing


End Try
End Sub
于 2013-04-23T11:37:27.210 に答える