2011-10-06 60 views
18

Estoy tratando de obtener la última fila de una hoja de Excel programáticamente utilizando Microsoft.interop.Excel Library y C#. Quiero hacer eso, porque estoy a cargo de recorrer todos los registros de una hoja de cálculo Excel y realizar algún tipo de operación sobre ellos. Específicamente, necesito el número real de la última fila, ya que incluiré este número en una función. ¿Alguien tiene alguna idea de cómo hacer eso?Obteniendo la última fila de Excel rellenada mediante programación utilizando C#

Respuesta

39

maneras Pareja,

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); 

O

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; 
+1

No estoy seguro de cómo funcionaría la primera opción ... Pero la segunda parece interesante. ¿Cómo puedo traducir eso en un valor int? – SoftwareSavant

+0

He editado mi código, no he probado ese código pero espero que te dé una idea de lo que quieres lograr. – Priyank

+4

Esta respuesta proporciona la última celda en UsedRange de la hoja de trabajo. El problema, sin embargo, es que UsedRange nunca se contrae. Si tiene un valor en A1 y AA100, entonces elimine el contenido de AA100, el UsedRange seguirá siendo A1: AA100. AA100 todavía se considerará la última celda. – CtrlDot

14

Este es un problema común en Excel.

Aquí hay un código 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; 

encontró here

o el uso de SpecialCells

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

[EDIT] hilos similares:

+0

Esto está funcionando, he estado luchando para obtener la fila correcta. – NWessel

7

Para preguntas que implican el modelo de objetos de Excel, a menudo es más fácil de probarlo en VBA en primer lugar, a continuación, se traduce en C# es bastante trivial.

En este caso, una forma de hacerlo es en VBA:

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

Pryank's answer es lo más cercano trabajó para mí. Añadí un poco hacia el final (.Row), así que no solo estoy devolviendo un range, sino un integer.

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

La única manera de que pudiera conseguir que funcione en todos los escenarios (excepto hojas protegidas):

Es compatible con:

  • Escaneo Ocultos de fila/columnas

  • Ignora celdas formateadas sin datos/fórmula

Código:

// 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; 
+1

Brillante respuesta (y la única que funcionó para mí). –

1

El ActiveSheet.UsedRange.Value devuelve una matriz de objetos dimensional 2 de [fila, columna]. Verificar la longitud de ambas dimensiones proporcionará el índice LastRow y el índice LastColumn. El siguiente ejemplo usa C#.

 Excel.Worksheet activeSheet; 
 
\t \t Excel.Range activeRange; 
 

 

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

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

 

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

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

0

Este problema es aún peor cuando hay posiblemente celdas vacías. Pero debe leer una fila incluso si solo se llena un valor. Puede tomar un tiempo cuando hay muchas celdas sin llenar, pero si la entrada está cerca de ser correcta, es bastante rápido.

Mi solución ignora filas completamente vacías y devuelve el recuento de la columna más larga fila:

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; 
    } 
0

Para aquellos que utilizan el método SpecialCells, (no estoy seguro acerca de otros), por favor en caso de que su última celda es fusionado, no podrá obtener la última fila y el número de columna utilizando Range.Row y Range.Column para obtener la última fila y columna como números. necesita primero Unmerge su rango y luego otra vez obtener la última celda. Me costó mucho.

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 }; 
    } 
Cuestiones relacionadas