I am using an unfiltered BAQ to feed a dashboard that is equipped with a tracker view.
The tracker view works properly in “refreshing” the records on the dashboard according to the parameters defined in the tracker view.
However, any calculated fields based off or record counts in the underlying BAQ do not calculate on the “refreshed” filtering conducted by the tracker view definition. Instead, they remain calculated off of the underlying BAQ.
So - if the underlying BAQ returned 4,000 total records, but the tracker view parameters limit the results to 1,000 – the calculated field for total records still reports on the underlying BAQ of 4,000 records, even though the other fields in the returned results are pertinent to the tracker view parameters.
How does one go about creating calculated fields (for display in the dashboard grid) that will accurately reflect what is being selected in the tracker view parameters?
Actually, maybe instead of filtering the grid, you place parameters in your baq criteria. Then call the baq and pass the parameters. Results will only be what matches your criteria
So - would I be correct in saying that the concept of the “dashboard panel”, in this particular case, would need to be thrown out in favor of the EpiUltraGrid object?
The hard answer is that you may be able to do some EpiBinding magic in your BAQ criteria to look at some of the calling objects fields (like YourForm.PartFilter.Text).
I know very little about EpiBinding within a BAQ other than what I overhead while drinking beers at Insights 2017 lol.
I know that you can use script to link a parameter to a local field, for example I’ve done this before in a criteria:
PartNum = [EpiBinding:JobHead.PartNum]
I’ll move forward a bit and see how the EpiUltraGrid object might be able to work in my situation. I’m looking at Jose’s video on this topic right now while reconstructing the tracker view.
I see that the DynamicQueryAdapter already exists in the referenced System Assembly library. When I attempted to instantiate the DQA according to Jose’s example:
DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
… the compiler wasn’t happy:
Error: CS0103 - line 60 (228) - The name 'oTrans' does not exist in the current context
Dumb question, but I need to ask it. I’ve seen the object name, “oTrans” in about 75% of the customization examples I’ve read. What is it? Where does it come from? What did I forget to do in order to make this object “known” to the DQA instantiation?
Also - I don’t have access to the menu item “Tools >> Wizards >> Customization Wizards” from the “Customization Tools Dialog” in order to validate that the correct assembly references are pulled in. Any idea why?
In order to properly customize a dashboard, you must “deploy” it to make it an assembly first. Then place it in a menu, create a customization against it, then apply that as the customization at the menu level.
Does that make sense? It seems confusing now that I’ve wrote it
Yes. I’ve found that every single thing I change in that customization BEFORE deploying causes more hassle. I’ve learned to keep the DB unmodified until it’s been deployed for my own sanity.
Click on Deploy as SmartClient (or something similar). Then when you create a menu item and select type dashboard-assembly, you’ll see it there to add in the list.
I second that. If you really want to stay in the run time, move all of your filtering to parameters and the end user will have to deal with the pop-up every time they refresh. Then the tracker view can simply be a view of what is selected in the grid.
Other wise you’ll have to move to customization on a deployed dashboard. (maybe something good to learn anyways, although it is more of a hassle to maintain.)
I’m currently diving into the suggestion both of you have proffered here and will let you know how things turn out. I’m not sure if I should be recreating the dashboard as a “fresh instance”, or not - but I’ll just deploy what I have (tracker view and all), then start working the customization from that point.
Create a simple blank tracker view panel with a specific parameterized BAQ on the back-end
Insert form controls on the tracker view to act as filter values upon which the parameterized BAQ will reference (none of which are mandatory).
Insert an UltraGrid object on the tracker view panel to capture the results of the dynamic query
Follow José Gomez’s tutorial on “Calling a BAQ from Code” to instantiate a new dynamic query adapter, define the execution parameter designated in the tracker view, perform the call to execute the query by specific ID, assign the results of the dynamic query to the grid object on the tracker view.
While compiling the code, I am getting an error that is telling me that I am missing a reference to an assembly:
> You must add a reference to assembly "Ice.Contracts.BO.DynamicQuery"
Is that not what I have in my Custom Assembly pool?
Since I have officially been recognized by my wife as being “old”, it is certainly possible that my eyesight and dormant senility are failing me on this particular task.
What are you guys seeing here that I am missing?
(By the way… “Ice.Adapters.DynamicQuery” is already referenced in “System Assemblies”)
Oddly enough (and I’m sure most of us have heard this type of “story” before), but I came in this morning and literally did nothing more than press my “F5” key to recompile the untouched code from yesterday and it magically compiled without error.
“But you had to have changed something…”
My work outfit was changed from yesterday’s abysmal choice of attire, but that’s truly the extent of it.
Other weirdness I’m experiencing on this implementation:
Now that, inexplicably, there are no errors in compiling, the parameters used in the underlying BAQ are being prompted for each time I load the tracker customization. This would be the expected behavior - if - it weren’t for the fact that, in José’s example, the prompted BAQ parameters seem to “go away” with the execution parameters in the “QueryExecutionDataSet” object defined in its place.
In other words, José illustrates that the parameters are prompted for when executing the BAQ. However, when the same parameters are defined within the customization “QueryExecutionDataSet” object (in code), the underlying BAQ no longer prompts José for a parameter value (as the parameter is now handled by the textbox object on the customization).
My customization still seems to rely on using the “prompting mechanism” within the underlying BAQ when the tracker view customization is launched - then, it decides to show the textbox objects that are supposed to handle the “parameterizing” on button click.
I’m just a bit confused on how José’s parameterized query isn’t prompting for parameters (in favor of those defined in the customization) and mine seems to insist on it.
// -- Convert the two date range values on the tracker view to strings
// -- (because the "AddExecutionParameterRow" will only accept string arguments)
string varDateRangeStart = Convert.ToString(dteDateRangeStart.Value);
string varDateRangeEnd = Convert.ToString(dteDateRangeEnd.Value);
// -- Instantiate a new Dynamic Query Adapter
DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
dqa.BOConnect();
// -- Get a list of query execution parameters from the BAQ you want to execute
QueryExecutionDataSet qds = dqa.GetQueryExecutionParametersByID("Q-SCH-OnTimeDelivery");
// -- Clear the default query execution parameters in order to replace them with specifically defined parameters on the tracker view
qds.ExecutionParameter.Clear();
// -- Define the execution parameter for the "Supplier" and "Date Range" values
qds.ExecutionParameter.AddExecutionParameterRow("Supplier", txtSupplier.Text, "nvarchar", false, Guid.NewGuid(), "A");
qds.ExecutionParameter.AddExecutionParameterRow("DateRangeStart", varDateRangeStart, "date", false, Guid.NewGuid(), "A");
qds.ExecutionParameter.AddExecutionParameterRow("DateRangeEnd", varDateRangeEnd, "date", false, Guid.NewGuid(), "A");
// -- Call to execute the query by specific ID (BAQ Name) using the previously defined execution parameters
dqa.ExecuteByID("Q-SCH-OnTimeDelivery", qds);
var ttlRecords = dqa.QueryResults.Tables["Results"].Rows.Count;
MessageBox.Show("Total records in query: " + ttlRecords);
/*
if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
{
var ttlRecords = dqa.QueryResults.Tables["Results"].Rows.Count;
MessageBox.Show("Total records in query: " + ttlRecords);
}
*/
// -- Assign the results of the dynamic query to the grid
grdRecords.DataSource = dqa.QueryResults.Tables["Results"];
// -- Dispose of the adapter object
dqa.Dispose();
I also want to make a quick mention that I originally tried this with just the “Supplier” text box alone (without muddying it further with the date parameters) and it resulted in the same behavior.
In addition, the message box breaks were put in place to see if I had any returned records. The “rows.count” value in the message box was specifically “0” (yes, there should be records in the data set based on the parameter I’m entering [the original BAQ supports that]).
Also - how does “DynamicQueryAdapter.QueryResults” know that there is a table called, “Results”? Is this intrinsic to the “DynamicQueryAdapter” object?