Vb.net 以编程方式选择所有后返回用户datagridview选择

Vb.net 以编程方式选择所有后返回用户datagridview选择,vb.net,visual-studio,datagridview,Vb.net,Visual Studio,Datagridview,为了加速将datagridview中保存的数据导出到excel,我在本论坛中使用了一种方法,将datagridview的内容复制到剪贴板,然后粘贴到excel电子表格中,以减少应用程序与excel通信的次数 虽然这样做很好,但有一个缺点是,如果用户在datagridview中选择了特定的单元格,则代码将导致此选择丢失,因为它使用了datagridview.SelectAll()方法 我希望找到一个简单的解决方案,重新选择用户的原始选择后导出到excel。我尝试了以下方法: Dim myS

为了加速将datagridview中保存的数据导出到excel,我在本论坛中使用了一种方法,将datagridview的内容复制到剪贴板,然后粘贴到excel电子表格中,以减少应用程序与excel通信的次数

虽然这样做很好,但有一个缺点是,如果用户在datagridview中选择了特定的单元格,则代码将导致此选择丢失,因为它使用了
datagridview.SelectAll()
方法

我希望找到一个简单的解决方案,重新选择用户的原始选择后导出到excel。我尝试了以下方法:

    Dim mySelection As DataGridViewSelectedCellCollection

    mySelection = myDataGridView.SelectedCells

    ExportToExcel(myDataGridView, "Exported Data")

    myDataGridView.SelectedCells = mySelection
我怀疑这里使用的
DataGridViewSelectedCellCollection
不正确,因为它似乎是关于选择中保存的数据,而不是所选单元格的位置

还有一种方法可以将所有datagridview放入剪贴板,而不必使用
SelectAll()

如果需要,可在此处导出Excel代码:

Private Sub ExportToExcel(myDataGridView As DataGridView, myWorksheetName As String)

    ' Creating a Excel object.
    Dim excel As Microsoft.Office.Interop.Excel._Application = New Microsoft.Office.Interop.Excel.Application()
    Dim workbook As Microsoft.Office.Interop.Excel._Workbook = excel.Workbooks.Add(Type.Missing)
    Dim xlWorkSheet As Microsoft.Office.Interop.Excel._Worksheet = Nothing

    Try

        xlWorkSheet = workbook.ActiveSheet

        xlWorkSheet.Name = myWorksheetName


        'Data transfer from grid to Excel.  
        With xlWorkSheet
            .Range("1:1").EntireRow.Font.Bold = True
            'Set Clipboard Copy Mode     
            myDataGridView.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
            myDataGridView.SelectAll()

            'Get the content from Grid for Clipboard     
            Dim str As String = TryCast(myDataGridView.GetClipboardContent().GetData(DataFormats.UnicodeText), String)

            'Set the content to Clipboard     
            Clipboard.SetText(str, TextDataFormat.UnicodeText)

            'Identify and select the range of cells in Excel to paste the clipboard data.     
            .Range("A1").Select()

            'Paste the clipboard data     
            .Paste()
            Clipboard.Clear()
        End With

        'Getting the location and file name of the excel to save from user.
        Dim saveDialog As New SaveFileDialog()
        saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx"
        saveDialog.FilterIndex = 2

        If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            workbook.SaveAs(saveDialog.FileName)
            MessageBox.Show("Export Successful")
        End If
    Catch ex As System.Exception
        MessageBox.Show(ex.Message)
    Finally
        excel.Quit()
        workbook = Nothing
        excel = Nothing
    End Try

End Sub

由于DGV.SelectedCells是只读的,我认为您可能只需要单独将每个单元格的selected属性设置为true(除非您正在进行完整的行/列选择)。您只需迭代选定的单元格集合,然后重新选择每个单元格:

myDataGridView.ClearSelection()
If mySelection IsNot Nothing Then
    For Each dgvCell As DataGridViewCell In mySelection
        dgvCell.Selected = True
    Next
    mySelection = Nothing
End If

由于DGV.SelectedCells是只读的,我认为您可能只需要单独将每个单元格的selected属性设置为true(除非您正在进行完整的行/列选择)。您只需迭代选定的单元格集合,然后重新选择每个单元格:

myDataGridView.ClearSelection()
If mySelection IsNot Nothing Then
    For Each dgvCell As DataGridViewCell In mySelection
        dgvCell.Selected = True
    Next
    mySelection = Nothing
End If

您可以复制
DataGridView
的内容,而无需更改选择。通过组合一个以制表符分隔的unicode字符串并将其推入
剪贴板

  Sub CopyDataGridViewToClipboard(dgv As DataGridView, includeHeader As Boolean)
    Dim sbl As New System.Text.StringBuilder
    If includeHeader Then
      For intCol As Integer = 0 To dgv.Columns.Count - 1
        Dim dgvc As DataGridViewColumn = dgv.Columns(intCol)
        If intCol > 0 Then sbl.Append(vbTab)
        sbl.Append(dgvc.HeaderText)
      Next intCol
      sbl.AppendLine()
    End If
    For intRow As Integer = 0 To dgv.Rows.Count - 1
      Dim dgvr As DataGridViewRow = dgv.Rows(intRow)
      For intCol As Integer = 0 To dgv.Columns.Count - 1
        If intCol > 0 Then sbl.Append(vbTab)
        sbl.Append(dgvr.Cells(intCol).Value)
      Next intCol
      sbl.AppendLine()
    Next intRow
    Clipboard.SetText(sbl.ToString, TextDataFormat.UnicodeText)
  End Sub

您可以复制
DataGridView
的内容,而无需更改选择。通过组合一个以制表符分隔的unicode字符串并将其推入
剪贴板

  Sub CopyDataGridViewToClipboard(dgv As DataGridView, includeHeader As Boolean)
    Dim sbl As New System.Text.StringBuilder
    If includeHeader Then
      For intCol As Integer = 0 To dgv.Columns.Count - 1
        Dim dgvc As DataGridViewColumn = dgv.Columns(intCol)
        If intCol > 0 Then sbl.Append(vbTab)
        sbl.Append(dgvc.HeaderText)
      Next intCol
      sbl.AppendLine()
    End If
    For intRow As Integer = 0 To dgv.Rows.Count - 1
      Dim dgvr As DataGridViewRow = dgv.Rows(intRow)
      For intCol As Integer = 0 To dgv.Columns.Count - 1
        If intCol > 0 Then sbl.Append(vbTab)
        sbl.Append(dgvr.Cells(intCol).Value)
      Next intCol
      sbl.AppendLine()
    Next intRow
    Clipboard.SetText(sbl.ToString, TextDataFormat.UnicodeText)
  End Sub

根据,SelectedCells属性是只读的,因此,正如您所说,它不是正确的用途。为了建议一个合适的替代方案,我希望我们需要查看
ExportToExcel()
的代码,我已经添加了这个-正如我在原始问题中提到的,关键点是导出代码使用
myDataGridView。选择All()
将datagridview的内容添加到剪贴板,在我看来,您可以1)再次尝试重新选择单元格(如soohoonigan的回答),或2)将导出逻辑更改为不依赖于单元格选择的内容,例如迭代单元格,将值附加到StringBuilder,然后将该文本复制到剪贴板,或者3)通过使用库或导出CSV完全避免使用剪贴板。根据,SelectedCells属性是只读的,因此,正如您所说,不是正确的使用方法。为了建议一个合适的替代方案,我希望我们需要查看
ExportToExcel()
的代码,我已经添加了这个-正如我在原始问题中提到的,关键点是导出代码使用
myDataGridView。选择All()
将datagridview的内容添加到剪贴板,在我看来,您可以1)再次尝试重新选择单元格(如soohoonigan的回答),或2)将导出逻辑更改为不依赖于单元格选择的内容,例如迭代单元格,将值附加到StringBuilder,然后将该文本复制到剪贴板,或者3)通过使用库或导出CSV来完全避免剪贴板。虽然两种解决方案都有效-我选择了这一点作为答案,因为它避免了用户看到他们的选择发生变化,因此整个导出过程感觉不那么“笨拙”。虽然两种解决方案都有效-我选择了这一点作为答案,因为它避免了用户看到他们的选择发生变化,因此整个导出过程感觉不那么“笨重”。