比较具有不同行数的两个数据集的表达式
Expression that compares two Datasets with different amount of rows
我有两个数据集,
这两个数据集的行数不同。
我有两个 Tablix。每个 Tablix 指向这两个不同的数据集
在一列中,我想逐行比较两个数据集。
所以我想要的想法是这样的:
这是我的两个 Tablix 和我的数据集,如您所见,学生编号 10,15 和 23 在数据集 2 上不存在。
发生这种情况时,我想写一个 0。
如果我使用查找表达式,它会在比较每个数据集存在的行时出现错误:
=IIF(Fields!Student.Value <> Lookup(Fields!Student.Value,Fields!Student.Value,Fields!Student.Value,"Dataset1"),"0","1")
那个表达式会给我一个错误。
这个想法(我认为)是坚持学生 21 并比较数据集 1 上的每个学生,当他们相等时写 1 和 0,当他们不相等时写 1 和 0,但是对于每一行。
我不能触摸数据集,我的意思是查询。
如果您需要更多信息,请告诉我。
编辑:
为了向您提供更多信息,我想做的是复制我的 Web 应用程序背后的代码在数据层中执行的操作:
ReportsDataSet.MyDatasetRow drSchool = (ReportsDataSet.MyDatasetRow)repDset.MyDataset.Rows[0];
string Student = drSchool.Student;
bool firstone = true;
bool hayApproved = false;
bool hayNotApproved = false;
bool hayNeedMoreStudy = false;
bool hayFail = false;
bool hayG5 = false;
bool hayNC = false;
if (repDset.MyDataset.Rows.Count > 0)
{
int Count = repDset.MyDataset.Rows.Count;
for (int i = 0; i < Count; i++)
{
ReportsDataSet.MyDatasetRow dr = (ReportsDataSet.MyDatasetRow)repDset.MyDataset.Rows[i];
if (dr.tipo.Trim() == "TOTAL" && firstone)
{
Student = dr.Student;
firstone = false;
switch (dr.categoria.Trim())
{
case "Approved":
hayApproved = true;
break;
case "NotApproved":
hayNotApproved = true;
break;
case "NeedMoreStudy":
hayNeedMoreStudy = true;
break;
case "Fail":
hayFail = true;
break;
case "G5":
hayG5 = true;
break;
case "N/C":
hayNC = true;
break;
}
}
else
{
if (dr.tipo.Trim() == "TOTAL" && dr.Student == Student)
{
switch (dr.categoria.Trim())
{
case "Approved":
hayApproved = true;
break;
case "NotApproved":
hayNotApproved = true;
break;
case "NeedMoreStudy":
hayNeedMoreStudy = true;
break;
case "Fail":
hayFail = true;
break;
case "G5":
hayG5 = true;
break;
case "N/C":
hayNC = true;
break;
}
}
}
if (dr.Student != Student || i == (Count-1) )
{
if (!hayApproved)
{
repDset.MyDataset.AddMyDatasetRow(Student, "Approved", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNotApproved)
{
repDset.MyDataset.AddMyDatasetRow(Student, "NotApproved", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNeedMoreStudy)
{
repDset.MyDataset.AddMyDatasetRow(Student, "NeedMoreStudy", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayFail)
{
repDset.MyDataset.AddMyDatasetRow(Student, "Fail", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayG5)
{
repDset.MyDataset.AddMyDatasetRow(Student, "G5", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNC)
{
repDset.MyDataset.AddMyDatasetRow(Student, "N/C", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayApproved && !hayNotApproved && !hayNeedMoreStudy && !hayFail && !hayG5 && !hayNC)
{
repDset.MyDataset.AddMyDatasetRow(Student, "TOTAL", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
repDset.MyDataset.AcceptChanges();
hayApproved = false;
hayNotApproved = false;
hayNeedMoreStudy = false;
hayFail = false;
hayG5 = false;
hayNC = false;
firstone = true;
if (i != (Count - 1))
{
Student = dr.Student;
i--;
}
}
}
}
编辑 2:
让我给你更多信息:
如您在上一张图片中所见,学生 11、16 等在这些情况下不存在于数据集 2 中,我必须输入“0”。
但是我用 Lookup 做的是比较 21 和 11,21 和 11,22 和 11 等等。这不是重点,重点是每次存在于 Dataset1 中的 Student 不存在于 Dataset2 中时都置 0。
应该是这样的,我将Student的值保存在Dataset 2中,然后在Dataset1上对每个Student进行比较,不相等时放0,相等时放1。
可能是函数?将 Dataset1 的所有学生保存在一个列表中,将 Dataset2 的所有学生保存在另一个列表中,并在自定义代码中的 foreach 上比较它们?
Lookup()
函数returns Nothing
如果没有匹配。它不应该给你一个错误,但你可以什么也不检查,在这种情况下 return 0 。我认为您只是在与 IIF
表达式中的错误内容进行比较。
=IIF(
IsNothing(Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")),
0,
Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")
)
除非你真的想在查找工作时只显示 1。在这种情况下:
=IIF(
IsNothing(Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")),
0,
1
)
Return
Returns a Variant, or Nothing if there is no match.
Lookup Function (Report Builder and SSRS)
演练
我要执行的操作与您要完成的操作略有不同,这样您就可以看到查找功能发生了什么。
首先,我创建了两个简单的数据集,每个数据集都包含一个 ID 和标签列表。第二个数据集只是第一个数据集的一个子集(缺少一些行,但 DataSet2 中的所有行都存在于 DataSet1 中)。
DataSet1
id | label
-----+-----------
1 | Student1-a
2 | Student2-a
3 | Student3-a
4 | Student4-a
...
25 | Student25-a
DataSet2
id | label
-----+-----------
1 | Student1-b
5 | Student5-b
10 | Student10-b
12 | Student12-b
...
25 | Student25-b
然后我在报表上创建两个 tablix。这两个 tablix 都将数据源设置为 DataSet1 因为它包含我将检查 DataSet2 以使用查找的行。
我将第一个 tablix 设置为仅在两列中显示 ID 和标签。第二个 tablix 显示 ID(来自 DataSet1)并使用表达式在 DataSet2 中查找该 ID,如果不存在则显示 0,如果存在则显示来自 dataset2 的标签。
我使用的表达方式是:
=IIF(
IsNothing(Lookup(Fields!id.Value, Fields!id.Value, Fields!label.Value, "DataSet2")),
0,
Lookup(Fields!id.Value, Fields!id.Value, Fields!label.Value, "DataSet2")
)
我得到的输出是这样的,请注意所有行如何出现在第二个 tablix 中(因为它由包含所有行的数据集提供)但是 label
列显示 0 时该行在数据集 2 中不存在。
我有两个数据集,
这两个数据集的行数不同。
我有两个 Tablix。每个 Tablix 指向这两个不同的数据集
在一列中,我想逐行比较两个数据集。
所以我想要的想法是这样的:
这是我的两个 Tablix 和我的数据集,如您所见,学生编号 10,15 和 23 在数据集 2 上不存在。
发生这种情况时,我想写一个 0。
如果我使用查找表达式,它会在比较每个数据集存在的行时出现错误:
=IIF(Fields!Student.Value <> Lookup(Fields!Student.Value,Fields!Student.Value,Fields!Student.Value,"Dataset1"),"0","1")
那个表达式会给我一个错误。
这个想法(我认为)是坚持学生 21 并比较数据集 1 上的每个学生,当他们相等时写 1 和 0,当他们不相等时写 1 和 0,但是对于每一行。
我不能触摸数据集,我的意思是查询。
如果您需要更多信息,请告诉我。
编辑: 为了向您提供更多信息,我想做的是复制我的 Web 应用程序背后的代码在数据层中执行的操作:
ReportsDataSet.MyDatasetRow drSchool = (ReportsDataSet.MyDatasetRow)repDset.MyDataset.Rows[0];
string Student = drSchool.Student;
bool firstone = true;
bool hayApproved = false;
bool hayNotApproved = false;
bool hayNeedMoreStudy = false;
bool hayFail = false;
bool hayG5 = false;
bool hayNC = false;
if (repDset.MyDataset.Rows.Count > 0)
{
int Count = repDset.MyDataset.Rows.Count;
for (int i = 0; i < Count; i++)
{
ReportsDataSet.MyDatasetRow dr = (ReportsDataSet.MyDatasetRow)repDset.MyDataset.Rows[i];
if (dr.tipo.Trim() == "TOTAL" && firstone)
{
Student = dr.Student;
firstone = false;
switch (dr.categoria.Trim())
{
case "Approved":
hayApproved = true;
break;
case "NotApproved":
hayNotApproved = true;
break;
case "NeedMoreStudy":
hayNeedMoreStudy = true;
break;
case "Fail":
hayFail = true;
break;
case "G5":
hayG5 = true;
break;
case "N/C":
hayNC = true;
break;
}
}
else
{
if (dr.tipo.Trim() == "TOTAL" && dr.Student == Student)
{
switch (dr.categoria.Trim())
{
case "Approved":
hayApproved = true;
break;
case "NotApproved":
hayNotApproved = true;
break;
case "NeedMoreStudy":
hayNeedMoreStudy = true;
break;
case "Fail":
hayFail = true;
break;
case "G5":
hayG5 = true;
break;
case "N/C":
hayNC = true;
break;
}
}
}
if (dr.Student != Student || i == (Count-1) )
{
if (!hayApproved)
{
repDset.MyDataset.AddMyDatasetRow(Student, "Approved", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNotApproved)
{
repDset.MyDataset.AddMyDatasetRow(Student, "NotApproved", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNeedMoreStudy)
{
repDset.MyDataset.AddMyDatasetRow(Student, "NeedMoreStudy", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayFail)
{
repDset.MyDataset.AddMyDatasetRow(Student, "Fail", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayG5)
{
repDset.MyDataset.AddMyDatasetRow(Student, "G5", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayNC)
{
repDset.MyDataset.AddMyDatasetRow(Student, "N/C", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
if (!hayApproved && !hayNotApproved && !hayNeedMoreStudy && !hayFail && !hayG5 && !hayNC)
{
repDset.MyDataset.AddMyDatasetRow(Student, "TOTAL", "TOTAL", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0");
Alreadyfilled++;
}
repDset.MyDataset.AcceptChanges();
hayApproved = false;
hayNotApproved = false;
hayNeedMoreStudy = false;
hayFail = false;
hayG5 = false;
hayNC = false;
firstone = true;
if (i != (Count - 1))
{
Student = dr.Student;
i--;
}
}
}
}
编辑 2:
让我给你更多信息:
如您在上一张图片中所见,学生 11、16 等在这些情况下不存在于数据集 2 中,我必须输入“0”。 但是我用 Lookup 做的是比较 21 和 11,21 和 11,22 和 11 等等。这不是重点,重点是每次存在于 Dataset1 中的 Student 不存在于 Dataset2 中时都置 0。
应该是这样的,我将Student的值保存在Dataset 2中,然后在Dataset1上对每个Student进行比较,不相等时放0,相等时放1。
可能是函数?将 Dataset1 的所有学生保存在一个列表中,将 Dataset2 的所有学生保存在另一个列表中,并在自定义代码中的 foreach 上比较它们?
Lookup()
函数returns Nothing
如果没有匹配。它不应该给你一个错误,但你可以什么也不检查,在这种情况下 return 0 。我认为您只是在与 IIF
表达式中的错误内容进行比较。
=IIF(
IsNothing(Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")),
0,
Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")
)
除非你真的想在查找工作时只显示 1。在这种情况下:
=IIF(
IsNothing(Lookup(Fields!Student.Value, Fields!Student.Value, Fields!Student.Value, "Dataset1")),
0,
1
)
Return
Returns a Variant, or Nothing if there is no match.
Lookup Function (Report Builder and SSRS)
演练
我要执行的操作与您要完成的操作略有不同,这样您就可以看到查找功能发生了什么。
首先,我创建了两个简单的数据集,每个数据集都包含一个 ID 和标签列表。第二个数据集只是第一个数据集的一个子集(缺少一些行,但 DataSet2 中的所有行都存在于 DataSet1 中)。
DataSet1
id | label
-----+-----------
1 | Student1-a
2 | Student2-a
3 | Student3-a
4 | Student4-a
...
25 | Student25-a
DataSet2
id | label
-----+-----------
1 | Student1-b
5 | Student5-b
10 | Student10-b
12 | Student12-b
...
25 | Student25-b
然后我在报表上创建两个 tablix。这两个 tablix 都将数据源设置为 DataSet1 因为它包含我将检查 DataSet2 以使用查找的行。
我将第一个 tablix 设置为仅在两列中显示 ID 和标签。第二个 tablix 显示 ID(来自 DataSet1)并使用表达式在 DataSet2 中查找该 ID,如果不存在则显示 0,如果存在则显示来自 dataset2 的标签。
我使用的表达方式是:
=IIF(
IsNothing(Lookup(Fields!id.Value, Fields!id.Value, Fields!label.Value, "DataSet2")),
0,
Lookup(Fields!id.Value, Fields!id.Value, Fields!label.Value, "DataSet2")
)
我得到的输出是这样的,请注意所有行如何出现在第二个 tablix 中(因为它由包含所有行的数据集提供)但是 label
列显示 0 时该行在数据集 2 中不存在。