web-dev-qa-db-fra.com

Obtenir par programme la dernière ligne Excel remplie en utilisant C #

J'essaie d'obtenir la dernière ligne d'une feuille Excel par programme en utilisant la bibliothèque Microsoft.interop.Excel et C #. Je souhaite le faire, car je suis chargé de parcourir en boucle tous les enregistrements d’un tableur Excel et d’y effectuer une opération quelconque. Plus précisément, j'ai besoin du nombre réel de la dernière ligne, car je jetterai ce nombre dans une fonction. Quelqu'un a une idée de comment faire ça?

20
SoftwareSavant

Deux manières, 

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

OR

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;
45
Priyank

C'est un problème courant dans Excel.

Voici du code 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;

trouvé ici

ou en utilisant SpecialCells

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

[EDIT] Sujets similaires:

14
JMax

La réponse de Pryank est ce qui a fonctionné le plus proche pour moi. J'ai ajouté un peu vers la fin (.Row) donc je ne retourne pas simplement une range, mais une integer.

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

Pour les questions impliquant le modèle objet Excel, il est souvent plus facile de l'essayer d'abord dans VBA, mais la traduction en C # est assez simple.

Dans ce cas, une façon de le faire dans VBA est la suivante:

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

La seule façon pour moi de le faire fonctionner dans TOUS les scénarios (sauf les feuilles protégées):

Elle supporte:

  • Analyse des lignes/colonnes masquées

  • Ignore les cellules formatées sans données/formule

Code:

// 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;
6
Gerhard Powell

ActiveSheet.UsedRange.Value renvoie un tableau d'objets à 2 dimensions de [ligne, colonne]. La vérification de la longueur des deux dimensions fournira l’indice LastRow et l’indice LastColumn. L'exemple ci-dessous utilise 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; }
		}

2
Mark Phillips

Ce problème est encore pire lorsqu'il existe peut-être des cellules vides. Mais vous devez lire une ligne même si une seule valeur est renseignée. Cela peut prendre un certain temps lorsqu'il y a beaucoup de cellules non remplies, mais si l'entrée est proche de la correction, elle est plutôt rapide.

Ma solution ignore les lignes complètement vides et renvoie le nombre de lignes de la plus longue colonne:

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
Norbert Tóth

Comme discuté précédemment, les techniques ci-dessus (xlCellTypeLastCell, etc.) ne donnent pas toujours les résultats attendus. Bien qu'il ne soit pas difficile de parcourir une colonne à la recherche de valeurs, vous constaterez parfois qu'il existe des cellules ou des lignes vides avec des données que vous souhaitez prendre en compte dans les lignes suivantes. Lorsque vous utilisez directement Excel, un bon moyen de trouver la dernière ligne consiste à appuyer plusieurs fois sur CTRL + flèche bas (vous vous retrouverez à la ligne 1048576 pour une feuille de calcul XLSX), puis à appuyer sur CTRL + flèche haut pour sélectionner la dernière. cellule peuplée. Si vous effectuez cette opération dans Excel lors de l’enregistrement d’une macro, vous obtiendrez le code permettant de le répliquer. Il vous suffira ensuite de le modifier pour C # à l’aide des bibliothèques Microsoft.Office.Interop.Excel. Par exemple:

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

Ce n'est peut-être pas la solution la plus élégante (j'imagine que vous pouvez plutôt accéder à la dernière ligne de la feuille de calcul directement avant d'utiliser XlUp), mais elle semble plus fiable.

0
MarkSci

Pour ceux qui utilisent la méthode SpecialCells, (je ne suis pas sûr des autres), veuillez noter que si votre dernière cellule est fusionnée , vous ne pourrez pas obtenir le dernier numéro de ligne et de colonne en utilisant Range.Row et Range. .Column pour obtenir la dernière ligne et la dernière colonne sous forme de nombres . Vous devez d’abord annuler la fusion votre plage, puis obtenir à nouveau la dernière cellule . Cela m’a coûté cher.

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