我如何find连续使用的最后一列? C#

我有一本我正在阅读的Excel表。 它包含多行(无标题),每行包含不同数量的填充列。 即行1在前三列中有数据。 第2行在前140列中有数据。 第3行在前32列中有数据。 等等

如果我需要找出第2行使用了多less列(包含多less数据),我将如何启动。

我现在教自己犀利,文盲是行话,所以请尽可能做到“一对一”。

任何帮助将不胜感激。

谢谢。

编辑————————

有一个快速浏览一些书签,并有一个大概的代码,我用来获取包含我需要计数的列的行号。 (我不能testing,因为我没有安装在家里的VS.所以不要把这个作为福音,但它似乎“大约”正确,对不起)。

private static Excel.Application HCObjApp = null; private static Excel.Workbook HCBook = null; private static Excel.Worksheet HCSheet = null; XLApp = new Excel.Application(); HCBook = MyApp.Workbooks.Open(@"WBPATH\WB.exe"); HCSheet = HCBook.Sheets[1]; lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row; Excel.Range range = HCSheet.Columns["A", Type.Missing]; currentFind = range.Find("Australia",HCSheet.Cells[lastrow, 1]); 

从这里我需要find行CurrentFind中使用的列的数量。

– – – – – – – – – – 编辑 – – – – – – – – – – – – – – – —最后回到办公室,这是我必须find行号的代码;

  EHObjApp.Visible = true; string ColumnHeader = ResourceDetails.ResourceHolder("Root") + ResourceDetails.ResourceHolder("ResourceFolder") + ResourceDetails.ResourceHolder("ColumnHeaders"); HCBook = EHObjApp.Workbooks.Open(ColumnHeader); HCSheet = HCBook.Worksheets.get_Item(1); InputBook = EHObjApp.Workbooks.Open(ResourceDetails.ResourceHolder("Root") + @"\Sales\Output\Zoho_Upload\ZOHOSales.xlsx"); InputSheet = InputBook.Worksheets.get_Item(1); long ExRownumber = HCSheet.Range["A:A"].Find("SalesAustralia").Row + 1; Range NewColumns = InputSheet.Range["A1:A" + InputSheet.UsedRange.Columns.Count]; 

非常感谢@Hambone,我find了解决scheme(更准确的说,我find了0.1%的解决scheme,Hambonefind了其余的)。

  Excel.Range ur = HCSheet.UsedRange; Excel.Range r = HCSheet.Cells[ExRownumber, ur.Columns.Count +1]; r = r.Columns.End[Excel.XlDirection.xlToLeft]; // r = r.get_End(Excel.XlDirection.xlUp); long ExistingColumns = r.Column; MessageBox.Show(lastCol.ToString()); 

这将find行中最后使用的列。

你们是一个了不起的帮助!

谢谢

———-加法—————当find较小的列号,即行或30或31列等,这工作得很好。 我试图find更大的数字,即140列的行时遇到了一个问题。 将xlToLeft更改回xlUp解决了这个问题。

以为我会将这添加到任何需要此解决scheme的人。

我已经看到在VBA中使用这种技术来查找范围中的最后一行,并且它非常适合C#:

 Excel.Range ur = HCSheet.UsedRange; Excel.Range r = HCSheet.Cells[2, ur.Columns.Count]; r = r.get_End(Excel.XlDirection.xlToLeft); 

此时r的值将是第2行中最后一个已填充的单元格。要获得除2以外的行,只需更改.Cells索引器中的第一个参数.Cells

为了certificate它是有效的,你可以做这样的事情:

 r.Value = "Gotcha"; 

要find最后一个列号,我认为这是你的问题:

 int lastCol = r.Column; 

Excel自动化是从任何.NET语言开始的雄心勃勃的努力。 最初,网上的很多例子都没有考虑到正确释放内存,并在不需要的时候使用调用垃圾回收器。 在下面的示例代码中,UsedRowsColumns方法不需要对垃圾收集器进行任何调用,只是因为我遵循我所说的两点规则 (即99.99%的时间释放所有对象,但是您将会看到并不总是)。 你会注意到点击该网页上的kevininstructor两点规则将失败,我改变了它,因为我改变了kareninstructor 。

  • 下面显示的类,我会testing它们,如果它们符合您的需要,将它们放到类项目中,所以如果您想在其他项目中使用此代码,只需添加对这些项目的引用,而不是将代码从项目复制到项目。
  • Console1中的Console.WriteLine使用VS2015语法,如果使用较低版本,则需要进行调整Console.WriteLine(“{0} {1}”,….

与UsedRowsColumns方法不同,LastColumnForRow(应该回答你的问题)必须做一些额外的工作,因为垃圾回收器需要被调用,但不是在同一个方法中,所以我设置了一个方法CallGarbageCollector,在调用LastColumnForRow之后,我调用这个来释放Range xlColumns,即使在执行两个点规则时也不会释放。

表单代码来testing,button1打电话来获得第2行的最后一列。

 using System; using System.Windows.Forms; using System.IO; namespace UsedRowsCols { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private string fileName = Path.Combine( AppDomain.CurrentDomain.BaseDirectory, "Demo.xlsx"); private string sheetName = "Sheet1"; /// <summary> /// Get last row and last column for a worksheet. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { ExcelUsed eu = new ExcelUsed(); ExcelLast results = eu.UsedRowsColumns(fileName, sheetName); // send results to Visual Studio Output window Console.WriteLine($"{results.Row} {results.Column}"); } /// <summary> /// Get last used column for a specific row /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { ExcelUsed eu = new ExcelUsed(); try { int results = eu.LastColumnForRow(fileName, sheetName,2); // send results to Visual Studio Output window Console.WriteLine(results); } finally { eu.CallGarbageCollector(); } } } } 

负责获取上面button1中使用的列的类,以及上面的button2中使用的行和列。

 using System; using Excel = Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; using System.IO; namespace UsedRowsCols { public class ExcelUsed { /// <summary> /// Get last used column for a row /// </summary> /// <param name="fileName"></param> /// <param name="sheetName"></param> /// <param name="row"></param> /// <returns></returns> public int LastColumnForRow(string fileName, string sheetName, int row) { int lastColumn = -1; if (File.Exists(fileName)) { Excel.Application xlApp = null; Excel.Workbooks xlWorkBooks = null; Excel.Workbook xlWorkBook = null; Excel.Worksheet xlWorkSheet = null; Excel.Sheets xlWorkSheets = null; xlApp = new Excel.Application(); xlApp.DisplayAlerts = false; xlWorkBooks = xlApp.Workbooks; xlWorkBook = xlWorkBooks.Open(fileName); xlApp.Visible = false; xlWorkSheets = xlWorkBook.Sheets; for (int x = 1; x <= xlWorkSheets.Count; x++) { xlWorkSheet = (Excel.Worksheet)xlWorkSheets[x]; if (xlWorkSheet.Name == sheetName) { Excel.Range xlCells = null; xlCells = xlWorkSheet.Cells; Excel.Range workRange = xlCells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell); Excel.Range xlColumns = xlWorkSheet.Columns; int count = xlColumns.Count; Marshal.FinalReleaseComObject(xlColumns); xlColumns = null; Excel.Range xlLastRange = (Excel.Range)xlWorkSheet.Cells[row, count]; Excel.Range xlDirRange = xlLastRange.End[Excel.XlDirection.xlToLeft]; Marshal.FinalReleaseComObject(xlLastRange); xlLastRange = null; lastColumn = xlDirRange.Column; Marshal.FinalReleaseComObject(xlDirRange); xlDirRange = null; Marshal.FinalReleaseComObject(workRange); workRange = null; Marshal.FinalReleaseComObject(xlCells); xlCells = null; break; } Marshal.FinalReleaseComObject(xlWorkSheet); xlWorkSheet = null; } xlWorkBook.Close(); xlApp.UserControl = true; xlApp.Quit(); Release(xlWorkSheets); Release(xlWorkSheet); Release(xlWorkBook); Release(xlWorkBooks); Release(xlApp); return lastColumn; } else { throw new Exception("'" + fileName + "' not found."); } } /// <summary> /// /// </summary> /// <param name="fileName">file to get information form</param> /// <param name="sheetName">valid sheet name to get last row and column</param> /// <returns>ExcelLast</returns> public ExcelLast UsedRowsColumns(string fileName, string sheetName) { int RowsUsed = -1; int ColsUsed = -1; if (File.Exists(fileName)) { Excel.Application xlApp = null; Excel.Workbooks xlWorkBooks = null; Excel.Workbook xlWorkBook = null; Excel.Worksheet xlWorkSheet = null; Excel.Sheets xlWorkSheets = null; xlApp = new Excel.Application(); xlApp.DisplayAlerts = false; xlWorkBooks = xlApp.Workbooks; xlWorkBook = xlWorkBooks.Open(fileName); xlApp.Visible = false; xlWorkSheets = xlWorkBook.Sheets; for (int x = 1; x <= xlWorkSheets.Count; x++) { xlWorkSheet = (Excel.Worksheet)xlWorkSheets[x]; if (xlWorkSheet.Name == sheetName) { Excel.Range xlCells = null; xlCells = xlWorkSheet.Cells; Excel.Range workRange = xlCells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell); RowsUsed = workRange.Row; ColsUsed = workRange.Column; Marshal.FinalReleaseComObject(workRange); workRange = null; Marshal.FinalReleaseComObject(xlCells); xlCells = null; break; } Marshal.FinalReleaseComObject(xlWorkSheet); xlWorkSheet = null; } xlWorkBook.Close(); xlApp.UserControl = true; xlApp.Quit(); Release(xlWorkSheets); Release(xlWorkSheet); Release(xlWorkBook); Release(xlWorkBooks); Release(xlApp); return new ExcelLast() { Row = RowsUsed, Column = ColsUsed }; } else { throw new Exception("'" + fileName + "' not found."); } } public void CallGarbageCollector() { GC.Collect(); GC.WaitForPendingFinalizers(); } private void Release(object sender) { try { if (sender != null) { Marshal.ReleaseComObject(sender); sender = null; } } catch (Exception) { sender = null; } } } public class ExcelLast { /// <summary> /// Last used row in specific sheet /// </summary> public int Row { get; set; } /// <summary> /// Last used column in specific sheet /// </summary> public int Column { get; set; } } }