如何使用 Datatable C# 跳过 =<2 空白行?
How to skip =<2 blank row using Datatable C#?
允许用户完全留空一两行。如果行中的任何单元格已被填写,则请用户填写其余单元格,并告诉他们该单元格位于哪个 row/line 中。
理想的实现逻辑是:如果找到空行,则跳过它并转到下一行,并查找是否还有任何单元格需要填充,如果找到空行,则跳过转到下一个。
我有两个 class。下面的 class 确定该行是否完全为空。
public bool isRowEmpty(DataTable dt, int index)
{
// check if index exists, if not returns false
// it will means that the row is "not empty"
if (index >= dt.Rows.Count || index < 0)
return false;
// Get row
DataRow dr = dt.Rows[index];
// Amount of empty columns
int emptyQt = 0;
// Run thourgh columns to check if any of them are empty
for (int i = 0; i < dr.ItemArray.Length; i++)
{
// If empty, add +1 to the amount of empty columns
if (string.IsNullOrWhiteSpace(dr.ItemArray[i].ToString()))
emptyQt++;
}
// if the amount of empty columns is equals to the amount of
//columns, it means that the whole row is empty
return emptyQt == dr.Table.Columns.Count;
}
使用上面的class,我确定下一个class中哪一行是空的,如果发现空我将跳过并转到下一行,如果发现不为空则查找任何单元格没有填满。
但是下面的代码并没有跳过完整的空白行。有什么见解吗?
public DataValidationModel Validate(DataTable data, IList<FieldModel> fields)
{
var fieldsSorted = fields.Where(f => f.IsInTaxonomy == true).OrderBy(f => f.TaxonomyPosition).ToList();
var model = new DataValidationModel()
{
Errors = new List<RowErrorModel>()
};
int rowCounter = 7;
for (int i =0; i < data.Rows.Count - 1; i++) //Rows.Count - 1,
{
if (!isRowEmpty(data, rowCounter-1) && isRowEmpty(data, rowCounter) && !isRowEmpty(data, rowCounter + 1))
i+=1;
if (data.Rows[rowCounter][0] == DBNull.Value || String.IsNullOrWhiteSpace(data.Rows[i][0].ToString()))
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "The name cannot be blank."
});
}
if (data.Rows[rowCounter]["Site"] == DBNull.Value || String.IsNullOrWhiteSpace(data.Rows[i]["Site"].ToString()))
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Site is required."
});
}
if (data.Rows[rowCounter]["start date"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "start date is required."
});
}
if (data.Rows[rowCounter]["end date"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "end date is required."
});
}
if (data.Rows[rowCounter]["Placement Type"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Placement Type is required."
});
}
if (data.Rows[rowCounter]["Channel"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Channel is required."
});
}
if (data.Rows[rowCounter]["Environment"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Environment is required."
});
}
if (data.Rows[rowCounter]["rate type"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "rate is required when a rate type is not blank."
});
}
if (data.Rows[rowCounter]["units"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "units is required when a rate type is not blank."
});
}
if (data.Rows[rowCounter]["cost"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "cost is required when a rate type is not blank."
});
}
model.Errors = model.Errors.OrderBy(f => f.Row).ToList();
return model;
}
为什么你不能使用 continue
一旦你发现根据你的评论
该行是空的
for (int i =0; i < data.Rows.Count - 1; i++) //Rows.Count - 1,
{
if (!isRowEmpty(data, rowCounter-1) && isRowEmpty(data, rowCounter) && !isRowEmpty(data, rowCounter + 1))
continue; // this one here, which will jump to next iteration
我给你看一个与你的附加逻辑无关的例子。
public bool isRowEmpty(DataTable dt, int index)
{
DataRow row = dt.Rows[index];
return dt.Columns.Cast<DataColumn>()
.All(c => row.IsNull(c) || string.IsNullOrWhiteSpace(row[c].ToString()));
}
在 foreach
或 for
循环中你只需要使用 continue
:
for (int i = 0; i < data.Rows.Count; i++)
{
if (isRowEmpty(data, i))
continue;
// ...
}
允许用户完全留空一两行。如果行中的任何单元格已被填写,则请用户填写其余单元格,并告诉他们该单元格位于哪个 row/line 中。
理想的实现逻辑是:如果找到空行,则跳过它并转到下一行,并查找是否还有任何单元格需要填充,如果找到空行,则跳过转到下一个。
我有两个 class。下面的 class 确定该行是否完全为空。
public bool isRowEmpty(DataTable dt, int index)
{
// check if index exists, if not returns false
// it will means that the row is "not empty"
if (index >= dt.Rows.Count || index < 0)
return false;
// Get row
DataRow dr = dt.Rows[index];
// Amount of empty columns
int emptyQt = 0;
// Run thourgh columns to check if any of them are empty
for (int i = 0; i < dr.ItemArray.Length; i++)
{
// If empty, add +1 to the amount of empty columns
if (string.IsNullOrWhiteSpace(dr.ItemArray[i].ToString()))
emptyQt++;
}
// if the amount of empty columns is equals to the amount of
//columns, it means that the whole row is empty
return emptyQt == dr.Table.Columns.Count;
}
使用上面的class,我确定下一个class中哪一行是空的,如果发现空我将跳过并转到下一行,如果发现不为空则查找任何单元格没有填满。
但是下面的代码并没有跳过完整的空白行。有什么见解吗?
public DataValidationModel Validate(DataTable data, IList<FieldModel> fields)
{
var fieldsSorted = fields.Where(f => f.IsInTaxonomy == true).OrderBy(f => f.TaxonomyPosition).ToList();
var model = new DataValidationModel()
{
Errors = new List<RowErrorModel>()
};
int rowCounter = 7;
for (int i =0; i < data.Rows.Count - 1; i++) //Rows.Count - 1,
{
if (!isRowEmpty(data, rowCounter-1) && isRowEmpty(data, rowCounter) && !isRowEmpty(data, rowCounter + 1))
i+=1;
if (data.Rows[rowCounter][0] == DBNull.Value || String.IsNullOrWhiteSpace(data.Rows[i][0].ToString()))
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "The name cannot be blank."
});
}
if (data.Rows[rowCounter]["Site"] == DBNull.Value || String.IsNullOrWhiteSpace(data.Rows[i]["Site"].ToString()))
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Site is required."
});
}
if (data.Rows[rowCounter]["start date"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "start date is required."
});
}
if (data.Rows[rowCounter]["end date"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "end date is required."
});
}
if (data.Rows[rowCounter]["Placement Type"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Placement Type is required."
});
}
if (data.Rows[rowCounter]["Channel"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Channel is required."
});
}
if (data.Rows[rowCounter]["Environment"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "Environment is required."
});
}
if (data.Rows[rowCounter]["rate type"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "rate is required when a rate type is not blank."
});
}
if (data.Rows[rowCounter]["units"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "units is required when a rate type is not blank."
});
}
if (data.Rows[rowCounter]["cost"] == DBNull.Value)
{
model.Errors.Add(new RowErrorModel()
{
Row = rowCounter,
Error = "cost is required when a rate type is not blank."
});
}
model.Errors = model.Errors.OrderBy(f => f.Row).ToList();
return model;
}
为什么你不能使用 continue
一旦你发现根据你的评论
for (int i =0; i < data.Rows.Count - 1; i++) //Rows.Count - 1,
{
if (!isRowEmpty(data, rowCounter-1) && isRowEmpty(data, rowCounter) && !isRowEmpty(data, rowCounter + 1))
continue; // this one here, which will jump to next iteration
我给你看一个与你的附加逻辑无关的例子。
public bool isRowEmpty(DataTable dt, int index)
{
DataRow row = dt.Rows[index];
return dt.Columns.Cast<DataColumn>()
.All(c => row.IsNull(c) || string.IsNullOrWhiteSpace(row[c].ToString()));
}
在 foreach
或 for
循环中你只需要使用 continue
:
for (int i = 0; i < data.Rows.Count; i++)
{
if (isRowEmpty(data, i))
continue;
// ...
}