调用退出后应用程序不退出

Çöđ*_*xěŕ 15 vb.net excel xls exit

嘿家伙我有一个小问题,我似乎无法弄明白.我将DataGridView(它的内容)保存到xls文件.我没有遇到任何问题,除了我的任务管理器,它仍然显示它正在运行.我打过电话:

  xlApp.Application.Quit() 
Run Code Online (Sandbox Code Playgroud)

这被声明为:

  Dim xlApp As New excel.Application
Run Code Online (Sandbox Code Playgroud)

这似乎不起作用,但这与我让用户选择将其导出到Word文档时退出的方式相同.我不知道我哪里错了...

这是我的完整代码

Imports Word = Microsoft.Office.Interop.Word
 Imports Excel = Microsoft.Office.Interop.Excel

 Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For x As Integer = 1 To 3500
        DataGridView1.Rows.Add(New Object() {"r" & x.ToString & "c1", "r" & x.ToString & "c2", "r" & x.ToString & "c3", "r" & x.ToString & "c4", "r" & x.ToString & "c5"})
    Next
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    exportToWord (DataGridView1)
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim xlApp As New Excel.Application
    Dim xlWorkBook As Excel.Workbook
    Dim xlWorkSheet As Excel.Worksheet
    'Dim misValue As Object = System.Reflection.Missing.Value


    xlWorkBook = xlApp.Workbooks.Add
    xlWorkSheet = DirectCast(xlWorkBook.Sheets("sheet1"), Excel.Worksheet)

    xlApp.Visible = True

    Dim headers = (From ch In DataGridView1.Columns _
                  Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
                  Select header.Value).ToArray()
    Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)

    Dim items() = (From r In DataGridView1.Rows _
          Let row = DirectCast(r, DataGridViewRow) _
          Where Not row.IsNewRow _
          Select (From cell In row.Cells _
              Let c = DirectCast(cell, DataGridViewCell) _
              Select c.Value).ToArray()).ToArray()

    Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
    For Each a In items
        Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
        table &= String.Join(vbTab, t) & Environment.NewLine
    Next
    table = table.TrimEnd(CChar(Environment.NewLine))
    Clipboard.SetText (table)

    Dim alphabet() As Char = "abcdefghijklmnopqrstuvwxyz".ToUpper.ToCharArray

    Dim range As excel.Range = xlWorkSheet.Range("B2:" & alphabet(headerText.Length) & (items.Length + 2).ToString)

    range.Select()
    xlWorkSheet.Paste()

    range.Borders(Excel.XlBordersIndex.xlDiagonalDown).LineStyle = Excel.XlLineStyle.xlLineStyleNone
    range.Borders(Excel.XlBordersIndex.xlDiagonalUp).LineStyle = Excel.XlLineStyle.xlLineStyleNone
    With range.Borders(Excel.XlBordersIndex.xlEdgeLeft)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlMedium
    End With
    With range.Borders(Excel.XlBordersIndex.xlEdgeTop)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlMedium
    End With
    With range.Borders(Excel.XlBordersIndex.xlEdgeBottom)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlMedium
    End With
    With range.Borders(Excel.XlBordersIndex.xlEdgeRight)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlMedium
    End With
    With range.Borders(Excel.XlBordersIndex.xlInsideVertical)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlThin
    End With
    With range.Borders(Excel.XlBordersIndex.xlInsideHorizontal)
        .LineStyle = Excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = Excel.XlBorderWeight.xlThin
    End With

    'xlApp.Visible = True

    xlWorkBook.SaveAs("C:\Users\CoDeXeR\Desktop\Word1.xls", True)
    xlWorkBook.Close()
    xlApp.Application.Quit()

    ReleaseObject(xlWorkSheet) '<~~~ Added as per comment from deleted post
    ReleaseObject (xlWorkBook)
    ReleaseObject (xlApp)


End Sub

Public Sub exportToWord(ByVal dgv As DataGridView)
    ' Create Word Application
    Dim oWord As Word.Application = DirectCast(CreateObject("Word.Application"), Word.Application)

    ' Create new word document
    Dim oDoc As Word.Document = oWord.Documents.Add()


    Dim headers = (From ch In dgv.Columns _
                  Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
                  Select header.Value).ToArray()
    Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)

    Dim items() = (From r In dgv.Rows _
          Let row = DirectCast(r, DataGridViewRow) _
          Where Not row.IsNewRow _
          Select (From cell In row.Cells _
              Let c = DirectCast(cell, DataGridViewCell) _
              Select c.Value).ToArray()).ToArray()

    Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
    For Each a In items
        Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
        table &= String.Join(vbTab, t) & Environment.NewLine
    Next
    table = table.TrimEnd(CChar(Environment.NewLine))
    Clipboard.SetText (table)

    Dim oTable As Word.Table = oDoc.Tables.Add(oDoc.Bookmarks.Item("\endofdoc").Range, items.Count + 1, headers.Count)

    oTable.Range.Paste()

    'make the first row bold, fs 14 + change textcolor
    oTable.Rows.Item(1).range.Font.Bold = &H98967E
    oTable.Rows.Item(1).range.Font.Size = 14
    oTable.Rows.Item(1).range.Font.Color = Word.WdColor.wdColorWhite

    'change backcolor of first row
    oTable.Rows.Item(1).range.Shading.Texture = Word.WdTextureIndex.wdTextureNone
    oTable.Rows.Item(1).range.Shading.ForegroundPatternColor = Word.WdColor.wdColorAutomatic
    oTable.Rows.Item(1).range.Shading.BackgroundPatternColor = Word.WdColor.wdColorLightBlue

    ''set table borders
    'With oTable.Range.Tables(1)
    '    With .Borders(Word.WdBorderType.wdBorderLeft)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth100pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    With .Borders(Word.WdBorderType.wdBorderRight)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth100pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    With .Borders(Word.WdBorderType.wdBorderTop)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth100pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    With .Borders(Word.WdBorderType.wdBorderBottom)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth100pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    With .Borders(Word.WdBorderType.wdBorderHorizontal)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth050pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    With .Borders(Word.WdBorderType.wdBorderVertical)
    '        .LineStyle = Word.WdLineStyle.wdLineStyleSingle
    '        .LineWidth = Word.WdLineWidth.wdLineWidth050pt
    '        .Color = Word.WdColor.wdColorAutomatic
    '    End With
    '    .Borders(Word.WdBorderType.wdBorderDiagonalDown).LineStyle = Word.WdLineStyle.wdLineStyleNone
    '    .Borders(Word.WdBorderType.wdBorderDiagonalUp).LineStyle = Word.WdLineStyle.wdLineStyleNone
    '    .Borders.Shadow = False
    'End With
    ' Save this word document
    oDoc.SaveAs("C:\Users\CoDeXeR\Desktop\Word1.doc", True)
    oDoc.Close()
    oWord.Application.Quit()
    'oWord.Visible = True

End Sub

Public Sub exportToExcel(ByVal dgv As DataGridView)

End Sub

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

 End Class
Run Code Online (Sandbox Code Playgroud)

Sid*_*out 31

Just Calling .Quit()不会从内存中删除应用程序.完成编码后关闭对象非常重要.这可确保正确释放所有对象,并且内存中不会留下任何内容.

看这个例子

Imports Excel = Microsoft.Office.Interop.Excel

Public Class Form1
    '~~> Define your Excel Objects
    Dim xlApp As New Excel.Application
    Dim xlWorkBook As Excel.Workbook

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '~~> Add a New Workbook
        xlWorkBook = xlApp.Workbooks.Add

        '~~> Display Excel
        xlApp.Visible = True

        '~~> Do some stuff Here

        '~~> Save the file
        xlWorkBook.SaveAs(Filename:="C:\Tutorial\SampleNew.xlsx", FileFormat:=51)

        '~~> Close the File
        xlWorkBook.Close()

        '~~> Quit the Excel Application
        xlApp.Quit()

        '~~> Clean Up
        releaseObject (xlApp)
        releaseObject (xlWorkBook)
    End Sub

    '~~> Release the objects
    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

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Me.Close()
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

另外值得一提的是2 DOT规则.

如果您喜欢从VB.Net自动化Excel,那么您可能还想查看此链接.

跟进

问题是我上面提到的2 DOT规则.当您使用2 DOT规则(例如:)时,Excel.XlBordersIndex.xlDiagonalDown您必须使用以进行垃圾收集GC.Collect().所以你需要做的就是添加这个部分

    Finally
        GC.Collect()
Run Code Online (Sandbox Code Playgroud)

在里面 Private Sub ReleaseObject(ByVal obj As Object)

Private Sub ReleaseObject(ByVal obj As Object)
    Try
        Dim intRel As Integer = 0
        Do
            intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        Loop While intRel > 0
        MsgBox("Final Released obj # " & intRel)
    Catch ex As Exception
        MsgBox("Error releasing object" & ex.ToString)
        obj = Nothing
    Finally
        GC.Collect()
    End Try
End Sub
Run Code Online (Sandbox Code Playgroud)

最终代码(经过试验和测试)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim xlApp As New excel.Application
    Dim xlWorkBook As excel.Workbook
    Dim xlWorkSheet As excel.Worksheet
    Dim xlRange As excel.Range
    'Dim misValue As Object = System.Reflection.Missing.Value

    xlWorkBook = xlApp.Workbooks.Add
    xlWorkSheet = DirectCast(xlWorkBook.Sheets("sheet1"), excel.Worksheet)

    xlApp.Visible = True

    Dim headers = (From ch In DataGridView1.Columns _
                  Let header = DirectCast(DirectCast(ch, DataGridViewColumn).HeaderCell, DataGridViewColumnHeaderCell) _
                  Select header.Value).ToArray()
    Dim headerText() As String = Array.ConvertAll(headers, Function(v) v.ToString)

    Dim items() = (From r In DataGridView1.Rows _
          Let row = DirectCast(r, DataGridViewRow) _
          Where Not row.IsNewRow _
          Select (From cell In row.Cells _
              Let c = DirectCast(cell, DataGridViewCell) _
              Select c.Value).ToArray()).ToArray()

    Dim table As String = String.Join(vbTab, headerText) & Environment.NewLine
    For Each a In items
        Dim t() As String = Array.ConvertAll(a, Function(v) v.ToString)
        table &= String.Join(vbTab, t) & Environment.NewLine
    Next
    table = table.TrimEnd(CChar(Environment.NewLine))
    Clipboard.SetText(table)

    Dim alphabet() As Char = "abcdefghijklmnopqrstuvwxyz".ToUpper.ToCharArray

    xlRange = xlWorkSheet.Range("B2:" & alphabet(headerText.Length) & (items.Length + 2).ToString)

    xlRange.Select()
    xlWorkSheet.Paste()

    xlRange.Borders(excel.XlBordersIndex.xlDiagonalDown).LineStyle = excel.XlLineStyle.xlLineStyleNone
    xlRange.Borders(excel.XlBordersIndex.xlDiagonalUp).LineStyle = excel.XlLineStyle.xlLineStyleNone

    With xlRange.Borders(excel.XlBordersIndex.xlEdgeLeft)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlMedium
    End With
    With xlRange.Borders(excel.XlBordersIndex.xlEdgeTop)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlMedium
    End With
    With xlRange.Borders(excel.XlBordersIndex.xlEdgeBottom)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlMedium
    End With
    With xlRange.Borders(excel.XlBordersIndex.xlEdgeRight)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlMedium
    End With
    With xlRange.Borders(excel.XlBordersIndex.xlInsideVertical)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlThin
    End With
    With xlRange.Borders(excel.XlBordersIndex.xlInsideHorizontal)
        .LineStyle = excel.XlLineStyle.xlContinuous
        .ColorIndex = 1 'black
        .TintAndShade = 0
        .Weight = excel.XlBorderWeight.xlThin
    End With

    xlWorkBook.SaveAs(Filename:="C:\Users\Siddharth Rout\Desktop\Word1.xls", FileFormat:=56)
    xlWorkBook.Close()
    xlApp.Quit()

    ReleaseObject(xlRange)
    ReleaseObject(xlWorkSheet)
    ReleaseObject(xlWorkBook)
    ReleaseObject(xlApp)
End Sub


Private Sub ReleaseObject(ByVal obj As Object)
    Try
        Dim intRel As Integer = 0
        Do
            intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        Loop While intRel > 0
        MsgBox("Final Released obj # " & intRel)
    Catch ex As Exception
        MsgBox("Error releasing object" & ex.ToString)
        obj = Nothing
    Finally
        GC.Collect()
    End Try
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 请问为什么使用byVal而不是byRef,是不是只发布了参数对象而不是我们使用的那个? (2认同)