Фильтрация пустых строк в LinqToExcel перед анализом (преобразование / отображение)
Я использую LinqToExcel для сопоставления строк Excel с объектами в проекте C# / .NET.
Я поместил проверочный код в мои функции преобразования, чтобы они не только преобразовывали данные, но и предупреждали пользователя, когда некоторые данные отсутствуют. Пример:
excel.AddTransformation<PaymentObject>(x => x.PaymentPeriod, cellvalue =>
{
if (cellvalue.Length == 0)
{
throw new Exception(String.Format(Errors.EmptyField, ColumnNames.PaymentPeriod, ColumnNames.EmployeeNumber, lastCheckedEmployeeNumber));
}
return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(cellvalue);
});
Однако я НЕ хочу, чтобы эта проверка запускалась пустыми строками, которые Excel иногда добавляет внизу (см. Пустые строки LinqToExcel).
Моя проблема в том, что я не могу использовать решение, упомянутое там, потому что я не могу получить доступ к необработанным данным строки при вызове чего-то вроде
excel.Worksheet<SomeType>("WorksheetName").Where(row => row.Any(cell => cell != null));
Это потому, что сначала применяются преобразования, а метод Where будет применяться к результатам преобразования.
Также - в функциях преобразования у меня нет доступа к другим значениям в строке, поэтому я не могу проверить, является ли это одна пустая ячейка (ошибка) или строка полностью пуста.
Можно ли отфильтровать пустые строки ДО применения преобразований?
2 ответа
Вы можете объединить рабочий лист со строгой типизацией с нетипизированным рабочим листом, а затем использовать нетипизированный рабочий лист, чтобы найти полностью пустые строки:
List<T> onlyNonBlankRows = _queryFactory.Worksheet<T>(firstWorksheetWithColumnHeaders)
// calling ToList here is workaround to avoid Remotion.Data.Linq.Parsing.ParserException for Select((item,index) => ...) - "This overload of the method 'System.Linq.Queryable.Select' is currently not supported, but you can register your own parser if needed."
.ToList()
.Select((typedRow, index) => new { typedRow, index })
// Join the worksheet to an untyped projection of the same worksheet so that we can find totally blank rows
.Join(
_queryFactory.Worksheet(firstWorksheetWithColumnHeaders)
// calling ToList here is workaround to avoid Remotion.Data.Linq.Parsing.ParserException for Select((item,index) => ...)
.ToList()
.Select(
(untypedRow, indexForUntypedRow) =>
new { untypedRow, indexForUntypedRow }),
// join on row index - row 1 matches row 1 etc
arg => arg.index, arg => arg.indexForUntypedRow,
(a, b) => new { a.index, a.typedRow, b.untypedRow })
// Exclude rows where all cells are empty
.Where(x => x.untypedRow.Any(cell => cell.Value != DBNull.Value))
.Select(joined => joined.typedRow).ToList();
Есть ли какая-нибудь ячейка, которая пуста только тогда, когда вся строка пуста?
Например, обычно есть столбец Id, который всегда заполняется, за исключением пустых строк. Если это так, то следующий запрос должен работать для вас.
//assuming Id cell is only blank when the whole row is blank
excel.WorkSheet<PaymentObject>().Where(x => x.Id != "");
//the Id cell might be null instead of blank, so use this Where clause instead
excel.WorkSheet<PaymentObject>().Where(x => x.Id != null);