FatMan
FatMan

Reputation: 61

Finding the length of object array, where value is not-empty

I have a method that outputs an Excel range as an object[,]:

    static public Excel.Workbook OpenWorksheetAsReadOnly(string filePath)
    {
        Excel.Application excelInstance = null;

        // Open workbook as readOnly, update links
        excelInstance = new Excel.Application();
        Excel.Workbook excelWorkbook = excelInstance.Workbooks.
                                       Open(filePath, true, true);

        return excelWorkbook;
    }

static public object[,] ImportExcelIntoArray(string filePath)
    {
        Excel.Workbook source = null;
        source = OpenWorksheetAsReadOnly(filePath);

        Excel.Range sourceRange = source.Sheets[1].Range("B1:D1000");
        object[,] sourceValues = (object[,])sourceRange.Value2;

        return sourceValues;
    }

I know that my output array is 1000 rows long. I also know that not all those rows will be filled, and I know that the source document gets filled from top to bottom.

In another method I would like to iterate over the rows, but to save time, I would only like to iterate over the number of actually-filled rows. Ideally, I'd use (where excelObject is the output of the above method):

int rowCount = excelObject.Count(x => x != null);

However, it doesn't work for type object[*,*] — I think it would work for a List. I have had a look here and I have seen excelObject.Length, but that just gives me the number of cells in the object in total.

Is there any way to do this? Do I need to change the type from object to something else? The values in the cells are both strings and floats, so I'd like to keep it without type-specifying as long as possible.

Upvotes: 0

Views: 124

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205559

Since the 2d array implements the non generic IEnumerable interface, you you could use the Enumerable.Cast<T> extension method to convert it to IEnumerable<T> and then apply the desired LINQ operators on it:

int rowCount = excelObject.Cast<object>().Count(x => x != null);

But please note that the above actually counts the non empty cells. If you really want to count the non empty rows, you could use Enumerable.Range for generating row/column indices into the source array:

var rowCount = Enumerable.Range(0, excelObject.GetLength(0))
    .Count(row => Enumerable.Range(0, excelObject.GetLength(1))
        .Any(col => excelObject[row, col] != null));

Upvotes: 4

Related Questions