簡體   English   中英

使用 C# 以編程方式獲取最后填充的 excel 行

[英]Programmatically getting the last filled excel row using C#

我正在嘗試使用 Microsoft.interop.Excel 庫和 C# 以編程方式獲取 excel 工作表的最后一行。我想這樣做,因為我負責循環遍歷 excel 電子表格的所有記錄並執行某種操作在他們。 具體來說,我需要最后一行的實際數字,因為我會將這個數字放入 function 中。有人知道該怎么做嗎?

幾種方式,

using Excel = Microsoft.Office.Interop.Excel;

Excel.ApplicationClass excel = new Excel.ApplicationClass();
Excel.Application app = excel.Application;
Excel.Range all = app.get_Range("A1:H10", Type.Missing);

或者

Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Excel.Range range = sheet.get_Range("A1", last);

int lastUsedRow = last.Row;
int lastUsedColumn = last.Column;

這是 Excel 中的常見問題。

下面是一些 C# 代碼:

// Find the last real row
nInLastRow = oSheet.Cells.Find("*",System.Reflection.Missing.Value, 
System.Reflection.Missing.Value, System.Reflection.Missing.Value,    Excel.XlSearchOrder.xlByRows,Excel.XlSearchDirection.xlPrevious, false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Row;

// Find the last real column
nInLastCol = oSheet.Cells.Find("*", System.Reflection.Missing.Value,     System.Reflection.Missing.Value,System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlPrevious,    false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Column;

這里找到

或使用SpecialCells

Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Excel.Range range = sheet.get_Range("A1", last);

[編輯] 類似主題:

Pyank 的答案是最適合我的答案 我在最后添加了一點( .Row ),所以我不只是返回一個range ,而是一個integer

int lastRow = wkSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing).Row;

我可以讓它在所有場景中工作的唯一方法(受保護的工作表除外):

它支持:

  • 掃描隱藏的行/列

  • 忽略沒有數據/公式的格式化單元格

代碼:

// Unhide All Cells and clear formats
sheet.Columns.ClearFormats();
sheet.Rows.ClearFormats();

// Detect Last used Row - Ignore cells that contains formulas that result in blank values
int lastRowIgnoreFormulas = sheet.Cells.Find(
                "*",
                System.Reflection.Missing.Value,
                InteropExcel.XlFindLookIn.xlValues,
                InteropExcel.XlLookAt.xlWhole,
                InteropExcel.XlSearchOrder.xlByRows,
                InteropExcel.XlSearchDirection.xlPrevious,
                false,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value).Row;
// Detect Last Used Column  - Ignore cells that contains formulas that result in blank values
int lastColIgnoreFormulas = sheet.Cells.Find(
                "*",
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                InteropExcel.XlSearchOrder.xlByColumns,
                InteropExcel.XlSearchDirection.xlPrevious,
                false,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value).Column;

// Detect Last used Row / Column - Including cells that contains formulas that result in blank values
int lastColIncludeFormulas = sheet.UsedRange.Columns.Count;
int lastColIncludeFormulas = sheet.UsedRange.Rows.Count;

對於涉及 Excel 對象模型的問題,通常先在 VBA 中嘗試更容易,然后轉換為 C# 則相當簡單。

在這種情況下,在 VBA 中執行此操作的一種方法是:

Worksheet.UsedRange.Row + Worksheet.UsedRange.Rows.Count - 1

ActiveSheet.UsedRange.Value返回[row, column]二維對象數組。 檢查兩個維度的長度將提供LastRow索引和LastColumn索引。 下面的示例使用 C#。

Excel.Worksheet activeSheet;
Excel.Range activeRange;

public virtual object[,] RangeArray 
{
    get { return ActiveRange.Value; }
}

public virtual int ColumnCount 
{
    get { return RangeArray.GetLength(1); }
}

public virtual int RowCount
{
    get { return RangeArray.GetLength(0); }
}

public virtual int LastRow 
{
    get { return RowCount; }
}

當可能有空單元格時,這個問題會更糟。 但是即使只填充了一個值,您也必須讀取一行。 當有很多未填充的單元格時可能需要一段時間,但如果輸入接近正確,則速度相當快。

我的解決方案忽略完全空行並返回最長列的行數:

private static int GetLastRow(Worksheet worksheet)
    {
        int lastUsedRow = 1;
        Range range = worksheet.UsedRange;
        for (int i = 1; i < range.Columns.Count; i++)
        {
            int lastRow = range.Rows.Count;
            for (int j = range.Rows.Count; j > 0; j--)
            {
                if (lastUsedRow < lastRow)
                {
                    lastRow = j;
                    if (!String.IsNullOrWhiteSpace(Convert.ToString((worksheet.Cells[j, i] as Range).Value)))
                    {
                        if (lastUsedRow < lastRow)
                            lastUsedRow = lastRow;
                        if (lastUsedRow == range.Rows.Count)
                            return lastUsedRow - 1;
                        break;
                    }
                }
                else
                    break;
            }
        }
        return lastUsedRow;
    }

對於那些使用 SpecialCells 方法的人,(我不確定其他人),請注意,如果您的最后一個單元格被合並,您將無法使用 Range.Row 和 Range.Column 獲取最后一行和列號來獲取最后一行和最后一列作為數字。 您需要先取消合並范圍,然后再次獲取最后一個單元格。 我花了很多錢。

private int[] GetLastRowCol(Ex.Worksheet ws)
    {
        Ex.Range last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing);
        bool isMerged = (bool)last.MergeCells;
        if (isMerged)
        {
            last.UnMerge();
            last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing);
        }
        return new int[2] { last.Row, last.Column };
    }

如前所述,上述技術(xlCellTypeLastCell 等)並不總能提供預期的結果。 盡管遍歷列檢查值並不困難,但有時您可能會發現有空單元格或包含要在后續行中考慮的數據的行。 直接使用 Excel 時,查找最后一行的一個好方法是按 CTRL + 向下箭頭幾次(對於 XLSX 工作表,您將在第 1048576 行結束),然后按 CTRL + 向上箭頭,這將選擇最后一行填充單元格。 如果您在錄制宏時在 Excel 中執行此操作,您將獲得復制此代碼的代碼,然后只需使用 Microsoft.Office.Interop.Excel 庫為 C# 調整它。 例如:

    private int GetLastRow()
    {
        Excel.Application ExcelApp;
        ExcelApp = new Excel.Application();

        ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();
        ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();
        ExcelApp.Selection.End(Excel.XlDirection.xlDown).Select();

        ExcelApp.Selection.End(Excel.XlDirection.xlUp).Select();

        return ExcelApp.ActiveCell.Row;
    }

它可能不是最優雅的解決方案(我想您可以在使用 XlUp 之前直接導航到電子表格中的最后一行),但它似乎更可靠。

正如 CtrlDot 和 Leo Guardian 所說,該方法不是很精確,有些文件的格式會影響“SpecialCells”。

所以我使用了它加上一個 While 的組合。

Range last = sheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
Range range = sheet.get_Range("A1", last);
int lastrow = last.Row;
// Complement to confirm that the last row is the last
string textCell= "Existe";
while (textCell != null)
{
 lastrow++;
 textCell = sheet.Cells[lastrow + 1, 1].Value;
}
                
                

如果現在使用 OfficeOpenXml:

using OfficeOpenXml;
using System.IO;

FileInfo excelFile = new FileInfo(filename);
ExcelPackage package = new ExcelPackage(excelFile);
ExcelWorksheet sheet = package.Workbook.Worksheets[1];
int lastRow = sheet.Dimension.End.Row;
int lastColumn = sheet.Dimension.End.Column;

我不知道使用 Microsoft.Office.Interop.Excel 是否仍然是藝術的 state 或更多的遺留庫。 在我看來,用 OfficeOpenXml 替換我做得很好。 所以這個答案可能對未來的搜索結果有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM