2011-10-06 24 views
18

Próbuję uzyskać ostatni wiersz arkusza programu Excel programowo za pomocą biblioteki Microsoft.interop.Excel i C#. Chcę to zrobić, ponieważ mam za zadanie zapętlić wszystkie rekordy arkusza kalkulacyjnego Excela i wykonać na nich jakąś operację. W szczególności potrzebuję rzeczywistej liczby ostatniego wiersza, ponieważ wyrzucę tę liczbę do funkcji. Ktoś ma jakiś pomysł, jak to zrobić?Programowe pobieranie ostatniego wypełnionego wiersza programu Excel przy użyciu C#

Odpowiedz

39

kilka sposobów,

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

LUB

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

Nie wiem, jak działa pierwsza opcja ... Ale druga wygląda interesująco. Jak mogę przetłumaczyć to na wartość int? – SoftwareSavant

+0

Edytowałem mój kod, nie testowałem tego kodu, ale mam nadzieję, że da ci to pomysł na to, co chcesz osiągnąć. – Priyank

+4

Ta odpowiedź podaje ostatnią komórkę w używanym arkuszu roboczym. Problem polega jednak na tym, że UsedRange nigdy się nie kurczy. Jeśli masz wartość w A1 i AA100, a następnie usuń zawartość AA100, UsedRange nadal będzie A1: AA100. AA100 będzie nadal uważany za ostatnią komórkę. – CtrlDot

14

Jest to typowy problem występujący w programie Excel.

Oto kod 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; 

znaleziono here

lub za pomocą SpecialCells

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

[Edycja] Podobne nici:

+0

To działa, zmagałem się z uzyskaniem prawidłowego rzędu. – NWessel

7

W przypadku pytań dotyczących modelu obiektowego programu Excel, często łatwiej go wypróbować w VBA, potem przekłada się C# jest dość trywialne.

W tym przypadku jeden ze sposobów, aby to zrobić w VBA jest:

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

Pryank's answer jest co pracował najbliżej mnie. Dodałem trochę pod koniec (.Row), więc nie zwrócę tylko range, ale integer.

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

Jedynym sposobem mogę zmusić go do pracy we wszystkich scenariuszach (z wyjątkiem płyt zabezpieczonych):

Obsługuje:

  • Skanowanie ukrytego wiersza/kolumny

  • ignoruje sformatowane komórki bez danych/formuły

Kod:

// 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

Doskonała odpowiedź (i jedyna, która zadziałała dla mnie). –

1

ActiveSheet.UsedRange.Value zwraca 2 wymiarową obiektu tablicę [wiersz, kolumna]. Sprawdzanie długości obu wymiarów zapewni indeks LastRow i indeks LastColumn. Poniższy przykład używa 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

Ten problem jest jeszcze gorzej, gdy są ewentualnie puste komórki. Ale musisz przeczytać wiersz, nawet jeśli wypełniona jest tylko jedna wartość. Może zająć trochę czasu, gdy jest dużo komórek niewypełnionych, ale jeśli dane wejściowe są zbliżone do poprawnych, jest to raczej szybkie.

Moje rozwiązanie ignoruje całkowicie pustych wierszy i zwraca najdłuższej kolumny liczbę rzędów:

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

Dla tych, którzy używają metody SpecialCells, (nie jestem pewien o innych) należy pamiętać, w przypadku Twoja ostatnia komórka jest scalony, nie będzie można uzyskać ostatniego wiersza i numeru kolumny za pomocą zakresu.Roz i Range.Column, aby uzyskać ostatni wiersz i kolumnę jako liczby. Najpierw musisz Odłączyć swój zasięg, a następnie ponownie uzyskać ostatnią komórkę. Bardzo mnie to kosztowało.

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 }; 
    } 
Powiązane problemy