我是新编码并尝试检查电子表格中的重复行。电子表格有50列,除了两列外,每列都要进行比较。如果行是重复的,它会将它们组合成一行,并且REQNUM和AUTHNUM列中的金额将相加。我找到的大多数样本使用" Field("列名")"。由于列数量很大,我想使用一个变量来排除比较中我不需要的两个。
例:
之前。点代表更多列
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
:-----:| :-----:| :----:| ... | :----------:| :-----------:| ....
x | y | z | ... | 1 | 1
x | y | z | ... | 2 | 3个
之后
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
------- | ------ | ------ | ... | ------------ | ------------ | ....
x | y | z | ... | 3 | 4
这是我的代码,它似乎很接近但不太正确。我期待只有重复行的结果,所以稍后我可以通过foreach运行它来汇总和删除额外的行。 dtrow获取了我想要的列。(感谢Linq Excluding a column)。当我尝试在查询中使用此变量时,我没有得到任何结果,如果我删除了" g.Count()> 1"我得到的所有行都缺少两列。我想在结果中保留所有两列,而不必在以后添加它们。
var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList();
var checkExcel = dtExcel.Rows.Cast<DataRow>()
.GroupBy(x => dtRow.Select(c => x[c]))
.Where(g => g.Count() > 1)
.Select(gr => gr);
//.CopyToDataTable();
感谢Ken的帮助。这对我需要的东西很有用。我使用了groupby子句,因此我可以将副本组合成一行并添加数字字段。也可以通过创建我在IF语句中使用的密钥进行分组。
var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList();
var excelDup = dtExcel.Rows.Cast<DataRow>()
.GroupBy(x => String.Join("", dtRow.Select(c => x[c])))
.Select(g =>
{
var row = g.First();
row.SetField("REQNUM", g.Sum(x => x.Field<double>("REQNUM")));
row.SetField("AUTHNUM", g.Sum(x => x.Field<double>("AUTHNUM")));
return row;
})
.CopyToDataTable();
我还使用了where子句为datarow compare创建变量,不需要密钥。 //创建除三个以外的所有列的变量。它用于下一个查询 var dtExcelRow = dtExcel.Columns .Cast()。其中(c =&gt; c.ColumnName!=&#34; TITLE&#34;&amp;&amp; c.ColumnName!=&#34; REQSTR&#34;&amp;&amp; c.ColumnName!= &#34; AUTHSTR&#34;。)ToList(); var dtListRow = dtList.Columns .Cast()。其中(c =&gt; c.ColumnName!=&#34; TITLE&#34;&amp;&amp; c.ColumnName!=&#34; REQSTR&#34;&amp;&amp; c.ColumnName!= &#34; AUTHSTR&#34;。)ToList();
// Querys create datarow list for compare
IEnumerable<DataRow> eRow = dtExcel.AsEnumerable()
.Where(w => dtExcelRow.Select(c => w[c]).Any())
.Select(x => x);
IEnumerable<DataRow> lRow = dtList.AsEnumerable()
.Where(w => dtListRow.Select(c => w[c]).Any())
.Select(x => x);
// 1st compare gets list of new records that have changes or are new. 2nd is list of old records being change.
var newRecords = eRow.AsEnumerable().Except(lRow.AsEnumerable(), DataRowComparer.Default);
var oldRecords = lRow.AsEnumerable().Except(eRow.AsEnumerable(), DataRowComparer.Default);
答案 0 :(得分:0)
您不能只按dtRow.Select(c => x[c])
对数据进行分组,因为它是IEnumerable
,它们可能具有相同的内容,但它们仍然不同IEnumerable
。
如果它们是string
,您可以按联接字符串对数据进行分组:
x => String.Join("", dtRow.Select(c => x[c]))