【问题标题】:Count used cells in row using Excel Interop使用 Excel 互操作计算行中使用的单元格
【发布时间】:2016-08-10 19:18:02
【问题描述】:

我想在工作表的每一行中获取最后使用的单元格的索引。我可以在整个工作表中获取最后使用的列,但是我有一个表格,其中每一行都有不同的使用单元格,如下所示:

我试过了:

var excelApp = new Excel.Application();
var workBook = excelApp.Workbooks.Open(excelFilePath);
Excel._Worksheet worksheet = workBook.Worksheets[worksheetName];

int rowsCount = worksheet.UsedRange.Rows.Count;
for (int i = 1; i <= rowsCount; i++)
{               
    Excel.Range range = worksheet.Rows[i];
    int lastColumn = range.Columns.Count;
    Console.WriteLine(lastColumn);         
}

我期待输出:

3
5
2
7

但实际输出是:

16384
16384
16384
16384

我使用 Excel 互操作库。任何建议将不胜感激。谢谢!

【问题讨论】:

  • 是的,你问的是列数,如果里面有数据你没有算。
  • 我稍微改变了我的问题和示例图像。我想获取行中最后使用的单元格的索引

标签: c# excel interop excel-interop


【解决方案1】:

你可以这样使用:

var usedRange = worksheet.UsedRange;
int startRow = usedRange.Row;
int endRow = startRow + usedRange.Rows.Count - 1;
int startColumn = usedRange.Column;
int endColumn = startColumn + usedRange.Columns.Count - 1;
for (int row = startRow; row <= endRow; row++)
{
    Excel.Range lastCell = worksheet.Cells[row, endColumn];
    if (lastCell.Value2 == null)
        lastCell = lastCell.End[Excel.XlDirection.xlToLeft];
    var lastColumn = lastCell.Column;
    Console.WriteLine($"{row}: {lastColumn}");
}

基本上,诀窍是获取一行中的最后一个单元格,如果它是空的,请使用 Range.End 属性(或方法?)和 XlDirection.xlToLeft(需要空检查,因为似乎起始单元格被排除在End 电话)。

【讨论】:

  • 如果单元格是可选的怎么办
  • @johnny5 不知道你是什么意思。我们正在连续寻找 used 单元格,因此我假设 used 意味着 has value,这与 optional 相反i> 根据我的理解。可能您想到了一些不同的情况?
  • 对不起,我读错了这个问题,我正在尝试获取已使用的行数
【解决方案2】:

以下显示了获取一行最后使用的单元格的逻辑。它不会循环遍历所有行,但您应该能够将其用于 for 迭代器。

using System;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.IO;

namespace Example 
{
    public class ExcelUsed
    {
        /// <summary>
        /// Get last used column for a row
        /// </summary>
        /// <param name="fileName">Excel file to read</param>
        /// <param name="sheetName">Sheet to work on</param>
        /// <param name="row">Row in sheet to get last used column</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>
        public void CallGarbageCollector()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        /// <summary>
        /// Method to release object used in Excel operations
        /// </summary>
        /// <param name="sender"></param>
        private void Release(object sender)
        {
            try
            {
                if (sender != null)
                {
                    Marshal.ReleaseComObject(sender);
                    sender = null;
                }
            }
            catch (Exception)
            {
                sender = null;
            }
        }
    }
}

例子

int row = 1;
int results = eu.LastColumnForRow(fileName, sheetName,row);
MessageBox.Show($"Row {row}: {results}");

在这里试试 https://code.msdn.microsoft.com/Excel-get-last-row-and-fe764cfc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多