使用Interop从Excel中获取最后的非空列和行索引

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

我正在尝试使用互操作库从Excel文件中删除所有额外的空白行和列。

但是,我有excel文件,其中包含一小组数据,但是有很多空行和列。(从最后一个非空行(或列)到工作表的末尾)

我试着遍历行和列,但是循环需要几个小时。

我正在尝试获取最后一个非空行和列索引,以便在一行中删除整个空范围。

XlWks.Range("...").EntireRow.Delete(xlShiftUp)

注意:我正在尝试获取包含数据的最后一行,以删除所有额外的空白(在此行或列之后)。

有什么建议吗?

提问于
用户回答回答于

可以使用下面的代码获取索引小于最后一个空行的最后非空行

List<int> NonEmptyRows = Enumerable.Range(1, rowsToDelete.Max()).ToList().Except(rowsToDelete).ToList();

如果NonEmptyRows.Max() < rowsToDelete.Max()最后一个非空行是NonEmptyRows.Max()否则就是worksheet.Rows.Count最后一次使用后没有空行。

同样的方法可以得到最后一个非空列。

代码是在DeleteColsDeleteRows职能:

    private static void DeleteRows(List<int> rowsToDelete, Microsoft.Office.Interop.Excel.Worksheet worksheet)
    {
        // the rows are sorted high to low - so index's wont shift

        List<int> NonEmptyRows = Enumerable.Range(1, rowsToDelete.Max()).ToList().Except(rowsToDelete).ToList();

        if (NonEmptyRows.Max() < rowsToDelete.Max())
        {

            // there are empty rows after the last non empty row

            Microsoft.Office.Interop.Excel.Range cell1 = worksheet.Cells[NonEmptyRows.Max() + 1,1];
            Microsoft.Office.Interop.Excel.Range cell2 = worksheet.Cells[rowsToDelete.Max(), 1];

            //Delete all empty rows after the last used row
            worksheet.Range[cell1, cell2].EntireRow.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftUp);


        }    //else last non empty row = worksheet.Rows.Count



        foreach (int rowIndex in rowsToDelete.Where(x => x < NonEmptyRows.Max()))
        {
            worksheet.Rows[rowIndex].Delete();
        }
    }

    private static void DeleteCols(List<int> colsToDelete, Microsoft.Office.Interop.Excel.Worksheet worksheet)
    {
        // the cols are sorted high to low - so index's wont shift

        //Get non Empty Cols
        List<int> NonEmptyCols = Enumerable.Range(1, colsToDelete.Max()).ToList().Except(colsToDelete).ToList();

        if (NonEmptyCols.Max() < colsToDelete.Max())
        {

            // there are empty rows after the last non empty row

            Microsoft.Office.Interop.Excel.Range cell1 = worksheet.Cells[1,NonEmptyCols.Max() + 1];
            Microsoft.Office.Interop.Excel.Range cell2 = worksheet.Cells[1,NonEmptyCols.Max()];

            //Delete all empty rows after the last used row
            worksheet.Range[cell1, cell2].EntireColumn.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftToLeft);


        }            //else last non empty column = worksheet.Columns.Count

        foreach (int colIndex in colsToDelete.Where(x => x < NonEmptyCols.Max()))
        {
            worksheet.Columns[colIndex].Delete();
        }
    }
用户回答回答于

几年前,我创建了一个MSDN代码示例,允许开发人员从工作表中获取最后使用的行和列。我修改了它,将所有需要的代码放在一个带有windows表单前端的类库中,以演示操作。

底层代码使用Microsoft.Office.Interop.Excel。

在这里,我得到Excel文件中的第一个工作表,得到最后使用的行和行,并将其作为有效的单元格地址呈现。

Private Sub cmdAddress1_Click(sender As Object, e As EventArgs) Handles cmdAddress1.Click
    Dim ops As New GetExcelColumnLastRowInformation
    Dim info = New UsedInformation
    ExcelInformationData = info.UsedInformation(FileName, ops.GetSheets(FileName))

    Dim SheetName As String = ExcelInformationData.FirstOrDefault.SheetName

    Dim cellAddress = (
        From item In ExcelInformationData
        Where item.SheetName = ExcelInformationData.FirstOrDefault.SheetName
        Select item.LastCell).FirstOrDefault

    MessageBox.Show($"{SheetName} - {cellAddress}")

End Sub

在演示项目中,我还获得了Excel文件的所有工作表,并将它们显示在ListBox中。从列表框中选择工作表名称,并在有效的单元格地址中获取工作表的最后一行和列。

Private Sub cmdAddress_Click(sender As Object, e As EventArgs) Handles cmdAddress.Click
    Dim cellAddress =
        (
            From item In ExcelInformationData
            Where item.SheetName = ListBox1.Text
            Select item.LastCell).FirstOrDefault

    If cellAddress IsNot Nothing Then
        MessageBox.Show($"{ListBox1.Text} {cellAddress}")
    End If

End Sub

从上面的链接打开解决方案的第一眼,你就会注意到有很多代码。代码是最优的,并将立即释放所有对象。

扫码关注云+社区