将 Datagridview 复制到 excel - 使 excel 进程保持打开状态
Copying Datagridview to excel - leaves excel process open
谁能指出是什么导致 excel 进程在我的代码完成后保持打开状态?
我已经研究了关于这个主题的所有内容,重点似乎是避免使用 excel 互操作的 3 个点,但我相信我已经做到了,但我仍然看不到我在哪里出错了。
我的过程是将datagridview复制到剪贴板,然后粘贴到新创建的excel文件中,保存,关闭excel,然后给用户一个打开的选项文件。
两种情况。首先,当我 运行 通过代码并且不打开 excel 文件时,它使进程保持打开状态。其次,如果我打开工作簿然后关闭工作簿,它不会留下进程 运行ning。我不明白其中的区别,因为工作簿的打开是在我尝试关闭并释放对 excel.
的所有引用之后发生的
Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application
Dim xlWorkBooks As excel.Workbooks
Dim xlWorkBook As excel.Workbook
Dim xlWorkSheet As excel.Worksheet
Dim CR As excel.Range
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = True
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkBook.Application.DisplayAlerts = False
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
xlWorkBook.SaveAs(SaveFileDialog1.FileName())
xlWorkBook.Close(False)
misValue = Nothing
ReleaseExcel(CR)
ReleaseExcel(xlWorkSheet)
ReleaseExcel(xlWorkBook)
ReleaseExcel(xlWorkBooks)
xlExcel.Quit()
ReleaseExcel(xlExcel)
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
Private Sub ReleaseExcel(ByVal O As Object)
Do While System.Runtime.InteropServices.Marshal.ReleaseComObject(O) >= 0
System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
Loop
O = Nothing
End Sub
我已将问题缩小到以下代码。如果除了指定范围和添加数据之外我做了所有事情,它会关闭并结束进程但是一旦我引用 CR = xlWorkSheet.Cells(1,1) 它就会挂起一个进程
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
编辑
因此,我将我的代码与 Karen 发布的代码进行了比较,并对我的代码进行了一些细微的调整(完整代码加上下面列出的更改),但由于某种原因,它可以工作并且不会让进程处于打开状态!不确定如何,但我会接受。
Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
Dim DateCon As DateTime = DateTime.ParseExact(Today.ToShortDateString, "M/d/yyyy", Nothing)
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic Name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application = Nothing
Dim xlWorkBooks As excel.Workbooks = Nothing
Dim xlWorkBook As excel.Workbook = Nothing
Dim xlWorkSheet As excel.Worksheet = Nothing
Dim CR As excel.Range = Nothing
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = False
xlExcel.DisplayAlerts = False
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Range("A1")
CR.PasteSpecial(excel.XlPasteType.xlPasteAll)
CR.Select()
xlWorkBook.SaveAs(SaveFileDialog1.FileName)
Clipboard.Clear()
ReleaseExcel(CR)
CR = Nothing
ReleaseExcel(xlWorkSheet)
xlWorkSheet = Nothing
xlWorkBook.Close(False)
ReleaseExcel(xlWorkBook)
xlWorkBook = Nothing
ReleaseExcel(xlWorkBooks)
xlWorkBooks = Nothing
xlExcel.Quit()
ReleaseExcel(xlExcel)
xlExcel = Nothing
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
End Sub
Private Sub ReleaseExcel(ByVal O As Object)
Try
Do Until System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O) = 0
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O)
Loop
Catch ex As Exception
Finally
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
End Sub
以下仅使用两个点。工作完成后excel妥善处理。
Option Strict On
Option Infer Off
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module Demo1
Public Sub DoPaste()
Dim FileName As String = IO.Path.Combine(Application.StartupPath, "SomeFile.xlsx")
Dim SheetName As String = "Sheet1"
Dim Proceed As Boolean = False
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
Dim xlCells As Excel.Range = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
For x As Integer = 1 To xlWorkSheets.Count
xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
If xlWorkSheet.Name = SheetName Then
Dim xlRange1 As Excel.Range = Nothing
xlRange1 = xlWorkSheet.Range("A1:B6")
xlRange1.Select()
xlRange1.Copy()
Dim xlDestination As Excel.Range = Nothing
xlDestination = xlWorkSheet.Range("C1:D6")
xlDestination.PasteSpecial(Excel.XlPasteType.xlPasteAll, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone)
Marshal.FinalReleaseComObject(xlDestination)
xlDestination = Nothing
Marshal.FinalReleaseComObject(xlRange1)
xlRange1 = Nothing
xlWorkSheet.SaveAs(FileName)
Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Exit For
End If
Next
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
ReleaseComObject(xlCells)
ReleaseComObject(xlWorkSheets)
ReleaseComObject(xlWorkSheet)
ReleaseComObject(xlWorkBook)
ReleaseComObject(xlWorkBooks)
ReleaseComObject(xlApp)
End Sub
Private Sub ReleaseComObject(ByVal obj As Object)
Try
If obj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
End If
Catch ex As Exception
obj = Nothing
End Try
End Sub
End Module
谁能指出是什么导致 excel 进程在我的代码完成后保持打开状态?
我已经研究了关于这个主题的所有内容,重点似乎是避免使用 excel 互操作的 3 个点,但我相信我已经做到了,但我仍然看不到我在哪里出错了。
我的过程是将datagridview复制到剪贴板,然后粘贴到新创建的excel文件中,保存,关闭excel,然后给用户一个打开的选项文件。
两种情况。首先,当我 运行 通过代码并且不打开 excel 文件时,它使进程保持打开状态。其次,如果我打开工作簿然后关闭工作簿,它不会留下进程 运行ning。我不明白其中的区别,因为工作簿的打开是在我尝试关闭并释放对 excel.
的所有引用之后发生的 Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application
Dim xlWorkBooks As excel.Workbooks
Dim xlWorkBook As excel.Workbook
Dim xlWorkSheet As excel.Worksheet
Dim CR As excel.Range
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = True
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkBook.Application.DisplayAlerts = False
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
xlWorkBook.SaveAs(SaveFileDialog1.FileName())
xlWorkBook.Close(False)
misValue = Nothing
ReleaseExcel(CR)
ReleaseExcel(xlWorkSheet)
ReleaseExcel(xlWorkBook)
ReleaseExcel(xlWorkBooks)
xlExcel.Quit()
ReleaseExcel(xlExcel)
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
Private Sub ReleaseExcel(ByVal O As Object)
Do While System.Runtime.InteropServices.Marshal.ReleaseComObject(O) >= 0
System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
Loop
O = Nothing
End Sub
我已将问题缩小到以下代码。如果除了指定范围和添加数据之外我做了所有事情,它会关闭并结束进程但是一旦我引用 CR = xlWorkSheet.Cells(1,1) 它就会挂起一个进程
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
编辑 因此,我将我的代码与 Karen 发布的代码进行了比较,并对我的代码进行了一些细微的调整(完整代码加上下面列出的更改),但由于某种原因,它可以工作并且不会让进程处于打开状态!不确定如何,但我会接受。
Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
Dim DateCon As DateTime = DateTime.ParseExact(Today.ToShortDateString, "M/d/yyyy", Nothing)
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic Name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application = Nothing
Dim xlWorkBooks As excel.Workbooks = Nothing
Dim xlWorkBook As excel.Workbook = Nothing
Dim xlWorkSheet As excel.Worksheet = Nothing
Dim CR As excel.Range = Nothing
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = False
xlExcel.DisplayAlerts = False
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Range("A1")
CR.PasteSpecial(excel.XlPasteType.xlPasteAll)
CR.Select()
xlWorkBook.SaveAs(SaveFileDialog1.FileName)
Clipboard.Clear()
ReleaseExcel(CR)
CR = Nothing
ReleaseExcel(xlWorkSheet)
xlWorkSheet = Nothing
xlWorkBook.Close(False)
ReleaseExcel(xlWorkBook)
xlWorkBook = Nothing
ReleaseExcel(xlWorkBooks)
xlWorkBooks = Nothing
xlExcel.Quit()
ReleaseExcel(xlExcel)
xlExcel = Nothing
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
End Sub
Private Sub ReleaseExcel(ByVal O As Object)
Try
Do Until System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O) = 0
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O)
Loop
Catch ex As Exception
Finally
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
End Sub
以下仅使用两个点。工作完成后excel妥善处理。
Option Strict On
Option Infer Off
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module Demo1
Public Sub DoPaste()
Dim FileName As String = IO.Path.Combine(Application.StartupPath, "SomeFile.xlsx")
Dim SheetName As String = "Sheet1"
Dim Proceed As Boolean = False
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
Dim xlCells As Excel.Range = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
For x As Integer = 1 To xlWorkSheets.Count
xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
If xlWorkSheet.Name = SheetName Then
Dim xlRange1 As Excel.Range = Nothing
xlRange1 = xlWorkSheet.Range("A1:B6")
xlRange1.Select()
xlRange1.Copy()
Dim xlDestination As Excel.Range = Nothing
xlDestination = xlWorkSheet.Range("C1:D6")
xlDestination.PasteSpecial(Excel.XlPasteType.xlPasteAll, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone)
Marshal.FinalReleaseComObject(xlDestination)
xlDestination = Nothing
Marshal.FinalReleaseComObject(xlRange1)
xlRange1 = Nothing
xlWorkSheet.SaveAs(FileName)
Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Exit For
End If
Next
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
ReleaseComObject(xlCells)
ReleaseComObject(xlWorkSheets)
ReleaseComObject(xlWorkSheet)
ReleaseComObject(xlWorkBook)
ReleaseComObject(xlWorkBooks)
ReleaseComObject(xlApp)
End Sub
Private Sub ReleaseComObject(ByVal obj As Object)
Try
If obj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
End If
Catch ex As Exception
obj = Nothing
End Try
End Sub
End Module