DataView - Reverse RowFilter condition - sql

I have a GridView with a customizable filter implemented with RowFilter. For each column, the user can specify a filter criterium. Once all the desired criteria have been set, he clicks on "Apply filter". The criteria for all columns are combined to create the RowFilter expression of the DataView.
Now, I want to implement a "Reverse" option (a check box) which would simply reverse the RowFilter condition of the DataView. My first thought was to simply say:
RowFilter = NOT (original condition)
And that would be it. Apparently not, because of fields with NULL values. For example, if the filter has the condition StatusID = 10, and if some records have the NULL value for StatusID, the condition NOT (StatusID = 10) will not include those records (according to my tests). For one field, I could easily make the change to account for NULL but, when several fields are combined in the condition, it becomes more complicated.
My question: is there a clever way to globally reverse the RowFilter condition when fields with NULL values are involved, or do I have to test for NULL for each individual field?

If I correctly understood your question you want to get the rest of the result set which is not filtered.
I know there is no direct NOT function as you have shown in your pseudo code.
What you can do is get the dataview based on filter first which probably you have already in place like something below:
DataView dv= //Whatever filter you use
Then convert it to a datatable by using DataView.ToTable()
Next you can easily find the difference between these two datatable(s) like
var rowsOnlyInDt1 = dt1.AsEnumerable().Where(r => !dt2.AsEnumerable()
.Any(r2 => r["col1"].Trim().ToLower() == r2["col1"].Trim().ToLower() && r["col2"].Trim().ToLower() == r2["col2"].Trim().ToLower()));
DataTable result = rowsOnlyInDt1.CopyToDataTable();
which is another table and gives you reverse results.

Related

Qlikview conditionally hide expression in pivot table

Struggling with a way to hide an expression on certain rows in my pivot table below. Basically, I want to be able to hide my expression 'Cumulative' when the FINANCIAL_PLAN_TYPE is not equal to 'OB_VARIANCE_TO_T1'. I figured out a way to change the text format on the lines with other FINANCIAL_PLAN_TYPE so that it appears hidden (what is showing in the picture below), but I'd really like the whole row to go away in these cases.
Additionally, I do not want to see a Total on the Cumulative lines if possible, but I do want to keep them on the Sum(AMOUNT) lines.
My expression for Cumulative is:
sum(aggr(Rangesum(above(sum({<YEAR={"$(vYear_Current)"},FINANCIAL_PLAN_TYPE={"OB_VARIANCE_TO_T1"}>}AMOUNT),0,MONTH_NUM)), FINANCIAL_PLAN_TYPE, MONTH_NUM))
I tried to use the function Only, as well as, I tried conditionally enabling/disabling the expression but I can't seem to get it to work. Any ideas would be great. Thanks!
FINAL SOLUTION:
1) Load Inline Table
Load * Inline
[MyDim
Cumulative
Vals
];
2) Created calculated dimension to combine the two desired dimensions into one and show blank ('') in cases that you don't want to show (this leaves one blank line on the pivot but there is probably a way to hide that too):
=If(MYDim='Cumulative' and FINANCIAL_PLAN_TYPE='OB_VARIANCE_TO_T1','Orig Budg Cumulative Variance',if(MYDim='Cumulative' and FINANCIAL_PLAN_TYPE='LE_VARIANCE_TO_T1','LE Cumulative Variance',if(MYDim <> 'Cumulative',FINANCIAL_PLAN_TYPE,'')))
3) Create a new expression that does one calculation in the case of your made up dimension = Value A and something else in case your calculated dimension = Value B
If(MYDim='Cumulative' and (FINANCIAL_PLAN_TYPE='OB_VARIANCE_TO_T1' OR FINANCIAL_PLAN_TYPE='LE_VARIANCE_TO_T1'),If(ColumnNo()=0,'',sum(aggr(Rangesum(above(sum({<YEAR={"$(vYear_Current)"}, DEPARTMENT={"20820"}, ACCT_TYPE={"Capital"}>}AMOUNT),0,MONTH_NUM)),
FINANCIAL_PLAN_TYPE, MONTH_NUM))),IF(MYDim='Vals', SUM({<ACCT_TYPE={"Capital"},DEPARTMENT={"20820"}>}AMOUNT)))
You cannot hide expression on some of the rows - not possible in Qlikview.
The workaround is to create a dummy floating table that holds the second column as a dimension and then use it in your chart instead of the two expressions. Then you will have one expression that says something like that :
If ( dummyField = 'Cummulative' and = 'OB_VARIANCE_TO_T1',
{Use your second expression here} ,
If (dummyField = 'sum(Amount)', {use your original first expression here}))
Regarding the Total, check out this link in the "Tricking the Pivot Table" section

Queries in access runtime return different result

I have a form with a few controls. The values entered into the controls are passed to the WHERE clause of a query I use to populate a list box on the same form.
Some of the columns that I am filtering on have null values. When the control is left empty, it should pull in all rows unfiltered by that column.
So part of my WHERE clause looks like this:
WHERE
(person.last_name like [Forms]![frmFilterPerson]![txtLastName] & "*"
OR [Forms]![frmFilterPerson]![txtLastName] Is Null)
When I run my application in the full version of access, and I leave the txtLastName control blank, I get back ALL results, including the ones where the last name is null
However, when I run it in Access Runtime, I do not get all results, only the ones that have a value in the table for last name.
Any suggestions on how I can retrieve the rows that have null values while I have a filter in my where clause based on a control on my form?
You can use this old trick - comparing the field with itself:
WHERE
person.last_name Like Nz([Forms]![frmFilterPerson]![txtLastName], person.last_name) & "*"
OR
person.last_name Is Null
Or:
WHERE
person.last_name Like Nz([Forms]![frmFilterPerson]![txtLastName], person.last_name) & "*"
OR
[Forms]![frmFilterPerson]![txtLastName] Is Null

Filter records for Dropdown control

How can I filter rows for my Dropdown control?
Currently I'm binding Items property to column e.g. Items=Table1.Name
but this populates dropdown with all possible rows. I want to filter all rows in which another column meets condition e.g. Table1.Date=Today()
You can use a Filter expression in the Items property of your dropdown control:
Items: Filter(Table1, Date = Today())
And you can select which field of your table to show in the dropdown by using the Advanced view (in the case below, Name, as you had in your example):
Just a note that I had to do something a little more complex for filtering out results for a SQL source where I also needed a Distinct.
The basic idea is I wanted years out of a table, but only last year and whatever years we had listed. Also worth noting the 500 row limit was a bit of an issue against my original date table, and so this only works with smaller tables.
In my case, I needed to create a view to reduce the data granularity
Distinct(Filter('[dbo].[YearList]', YearNumber >= Year(Now()) -1), YearNumber)

SSRS Border on Nested Row Group

I am creating an SSRS2012 report.
I have a matrix with static columns and nested row groups. I would like to add a top and bottom border on my rows based on the parent group. The matrix looks as follows:
[ProcessCell] | [Name] | [Field]|
My groups are: ProcessCell1 (parent) - Name (child)
I am currently using standard formatting to get [ProcessCell]'s borders and it works. I am using an expression (found in another article) for [Name]'s borders and it works, however the expression does not work for the [Field] box. The expression is as follows:
=IIf(Fields!ProcessCell.Value = Previous(Fields!ProcessCell.Value, "Name") OR Not(Fields!ProcessCell.Value = First(Fields!ProcessCell.Value, "Name")), "Light Gray", "Black")
I have tried changing the scopes of previous and first but it did not work.
The error I am getting is "BorderColor expression for the text box 'Field' has a scope parameter that is not valid for an aggregate function"
I had exactly the same problem today (well with a Tablix, not a matrix, and in SSRS 2008 R2). I couldn't get the Previous() function to work properly and not throw the same "BorderStyle expression for the textbox..." error that you're seeing.
What I did instead was add a new field to my Dataset that uses the ROW_NUMBER() analytic SQL function to categorize my results. The relevant fields in my report were UserName, ReportName, and DatetimeRun (yes, this was a report on report usage). I wanted borders to appear between each unique combination of UserName and ReportName, so I added this field to my dataset:
ROW_NUMBER() over (partition by UserName,ReportName order by UserName,ReportName)
as RowNum
which for each unique combination of UserName and ReportName (the fields in the Partition by portion), starts at 1 and sequentially numbers the rows returned.
Back in my BorderStyle/Top expression, instead of using Previous() I used this:
=iif(Fields!RowNum.Value = 1,"Solid","None")
to display a border only at the beginning of a new UserName/ReportName combination.
Hope this helps!

Datatable Compute Method filter on row number

I use a query which fetches say 50 records and passes it to a datatable. This record is then displayed in a tabular format. The display has pagination used displaying 10 records at a time. There is a facility to move to next or previous set of record or move forward or backwards by 1 record.
I have to find Min and Max of a column for the set of record currently visible. I am planning to use Compute method but I am not sure if it allows filtering on anything other than the columns in datatable.
Do I have to include row number in my query or is there a better solution (something along the line mentioned below)?
CType(dtLineup.Compute("Min(ArrivalDate)", dt.row(2) to dt.row(12)), Date)
There is nothing like your pseudo code in MSDN on DataColumn.Expression. You could include a row number in your query, as you said, but an alternative is to add a row number column to your data table and use that in the filter expression.
DataColumn col = new DataColumn("rownumber", typeof(int));
col.AutoIncrement = true;
col.AutoIncrementSeed = 1;
datatable.Columns.Add(col);
Another alternative could be to do paging by linq (Skip-Take) and compute the aggregate function over the returned rows. But that may be a major departure of your current application structure.