I would like to use parameters in Invantive control.
For example, I would like to retrieve only the hours, of Exact Online Project management which, are in the given data parameters.
There are three often used approaches:
Use parameters in the model editor.
Use Excel values.
Use data from the databases involved.
Model Parameters
To use parameters in the model editor, you define them in the model editor:
Select a unique code.
Possibly provide a default value (always string, use to_... or casting to change it in the queries).
Define list-of-values providing a quick pick.
The unique code is in general all in uppercase and in the format P_..., but as long it is a legal identifier anything should work.
To use them in one or more block queries or triggers:
Use the building blocks button.
Or type $P{CODE} in the SQL or trigger for Excel.
The values can be entered using the parameters button (the green funnel in the Control ribbon):
Please note that parameters are always bound as parameters, and not lexicographically substituted so you can NOT say: select * from $P{TABLE_NAME}.
Please note that parameters can be dependent on each other, so in the query for the parameter you can use another parameter. Such as first choosing the country of a project and then showing a list of projects in that country. But be wise, avoid recursion and other overly complex scenarios; the user will not easily understand it.
Excel values
To use Excel values, you can define them as follows:
Enter a value somewhere in Excel.
Optionally define a named range to make it easier to change the location.
You can of course assign lists as normal in Excel as a pop-up or other validations. Also cell locking works fine.
To use the actual value in a query or trigger of Invantive Control you can use the building blocks in the query editor or use something like select * from table where code = $X{projectcode} or select * from table where code = $X{B2&C2&D2}. The last one shows that you can also use other type of Excel expressions.
Note that Excel parameters are also bound as parameters to the query, but that they are also typed, so the following query can be different depending on the general format of the Excel cell:
select *
from table
where code like $X{CELL}
When cell is a text, the database or Exact Online in this case will retrieve:
select *
from table
where code like :ex0
With ex0 being a text such as '8%'. But when cell is a percentage, the contents might still display in Excel as '8%', but the actual query will be with identical to the outcome of:
select *
from table
where code like 0.08
Caused me some headaches, but typing is in general a useful feature, especially with dates.
Parameter using database data
Option 3 is practically not feasible with Exact Online, since they are little possibilities to create your own tables and/or fields.
On other platforms such as Oracle you might want to enter new rows in Invantive Control in Excel and them upload them on sync to provide parameters. Especially handy in case of complex risk models.
Related
In Spotfire I have a dashboard that uses both filtering (only one filtering scheme) and multiple markings to show the resulting data in a table.
I have created a data function which takes a column and outputs the data in the column after the active filtering scheme and markings are applied.
However, this output column is only calculated if I have something marked in every marking.
I want the output column to be calculated no matter how many of the markings are being used. Is there a way to do this?
I was thinking I could use an IronPython script to edit the data function parameters for my input column to only check the boxes for markings that are actively being used. However, I can't find how to access those parameters with IronPython.
Thanks!
I think it would be a combination of visuals being set to OR instead of AND for markings (if you have a set of markings that are being set from others).
Also are all the input parameters set to required parameter perhaps unchecking that option would still run the script. In the r script you may want to replace null values as well.
Not too sure without some example.
Given I've created an Access Form with a ListBox; property > other > Multi Select = Extended; which permits multiple selections.
User selects multiple items.
Clicks a button that creates a report in "Print Preview"; but this report is based on the query, and the query is based on the values in the form.
This is accomplished by using this in the query when viewing in Access Query Design View (not SQL):
Like ([forms]![padc]![V2])
Where the form name is padc and the value to compare is V2.
Previously, rather than the ListBox that might show 10 options, V2 was just a field with one value. A user would either type a partial value, such as jack*, and the report would pull every instance where this value began with jack; whether that was jack, or jackie, or jacko, or jackson, etc. The LIKE part of this permitted the "fuzzy" logic bringing about varied results. The query would run, and the report would show all the records with anything starting with jack.
My goal, really, is to have a user select one, two or three, or all the available options in this box, and have the report respond correctly.
I believe the ListBox will let me do this, provided I have all the right names in the table that is the source of the options available to choose from.
I set the listbox to "multi-select" to enable multiple selections on the form.
The form is happy. It can let me click/highlight one or several items from the list.
The query is not happy.
For the field V2, neither
Like ([forms]![padc]![V2])
nor
=([forms]![padc]![V2])
Will retrieve records to populate the report; regardless of whether or not just one value in ListBox is selected or multiple values. (Like = fuzzy, and = means exact match.)
Neither work.
Of course, if the query won't perform, then the report won't perform either.
How can I write the correct query in Access, using "Query View = Design View" and or SQL to get this to function properly?
If the answer is "it can't be done without using VBA" then please point me to the VBA solution that a 5-yr old can understand, because I have zero experience using VBA.
Folks have recommended I use VBA; specifically that I should incorporate the "IN() IN function" in some manner; but I don't comprehend this solution at all.
I admit to being ignorant; not stupid; but ignorant.
I have job in Talend that is designed to bring together some data from different databases: one is a MySQL database and the other a MSSQL database.
What I want to do is match a selection of loan numbers from the MySQL database (about 82,000 loan numbers) to the corresponding information we have housed in the MSSQL database.
However, the tables in MSSQL to which I am joining the data from MySQL are much larger (~ 2 million rows), are quite wide, and thus cost much more time to query. Ideally I could perform an inner join between the two tables based on the loan number, but since they are in different databases this is not possible. The inner join that is performed inside a tMap occurs after the Lookup input has already returned its data set, which is quite large (especially since this particular MSSQL query will execute a user-defined function for each loan number).
Is there any way to create a global variable out of the output from the MySQL query (namely, the loan numbers selected by the MySQL query) and use that global variable as an IN clause in the MSSQL query?
This should be possible. I'm not working in MySQL but I have something roughly equivalent here that I think you should be able to adapt to your needs.
I've never actually answered a Stackoverflow question and while I was typing this the page started telling me I need at least 10 reputation to post more than 2 pictures/links here and I think I need 4 pics, so I'm just going to write it out in words here and post the whole thing complete with illustrations on my blog in case you need more info (quite likely, I should think!)
As you can see, I've got some data coming out of the table and getting filtered by tFilterRow_1 to only show the rows I'm interested in.
The next step is to limit it to just the field I want to use in the variable. I've used tMap_3 rather than a tFilterColumns because the field I'm using is a string and I wanted to be able to concatenate single quotes around it but if you're using an integer you might not need to do that. And of course if you have a lot of repetition you might also want to get a tUniqueRows in there as well to save a lot of unnecessary repetition
The next step is the one that does the magic. I've got a list like this:
'A1'
'A2'
'B1'
'B2'
etc, and I want to turn it into 'A1','A2','B1','B2' so I can slot it into my where clause. For this, I've used tAggregateRow_1, selecting "list" as the aggregate function to use.
Next up, we want to take this list and put it into a context variable (I've already created the context variable in the metadata - you know how to do that, right?). Use another tMap component, feeding into a tContextLoad widget. tContextLoad always has two columns in its schema, so map the output of the tAggregateRows to the "value" column and enter the name of the variable in the "key". In this example, my context variable is called MyList
Now your list is loaded as a text string and stored in the context variable ready for retrieval. So open up a new input and embed the variable in the sql code like this
"SELECT distinct MY_COLUMN
from MY_SECOND_TABLE where the_selected_row in ("+
context.MyList+")"
It should be as easy as that, and when I whipped it up it worked first time, but let me know if you have any trouble and I'll see what I can do.
I'm trying to work at getting the same information from a couple different sources but have hit a wall in trying to use NotesSQL and SQL 2008. What I am trying to do is to retrieve info from a couple different views on Domino servers. One view is a default view, the other is a created one.
One method I have used is Powershell, where I get the database, then select the view, get the first document & then iterate through the rest of the view grabbing fields that I need. The view I have selected is the People view.
I was trying to replicate this same thing using SQL 2008, using the NotesSQL driver, setting up an ODBC connection, and then creating a linked server to that Notes database. I am using the following query to select from the People view:
select * from openquery(MyNotesServer,'Select * from People')
However, what is returned from this view isn't what I am able to see when I use Powershell & then iterate through the documents returned in that view. Powershell shows 100+ columns in it, while SQL only returns 5 columns. Additionally, they're named "_12", "17" etc. Some fields (which may be custom, I don't know) have a meaningful name. Of the fields shown, I can select them by name ("_12", etc) but cannot select anything else. The number of rows (SQL) is the same as the number of documents in the view (Powershell $view.Allentries.Count).
Querying the view that was created (3 fields):
select * from openquery(MyNotesServer,'Select * from MyCreatedView')
returns all the fields in that view, and they are named as they are in the view.
In T-SQL querying the People view, how do you get the names of the columns that I know are there as I discovered in my Powershell script? They don't appear to be named the same thing, so how do you retrieve more than the 5 returned when you select * from the view? I have read through the Notes documentation & examples, but haven't been able to figure out what is mapped to where.
The reasoning behind this is wanting to utilize SQL & a notes.id file instead of running a script. Also, I want to make use of an already existing global view instead of views that may be accessible only to their author.
You can use select * from Person. Person is a form name, not a view name. Notes and Domino are not relational. The NSF file is a document database. The views in it are pre-built indexes that already have an implicit select. I.e., the "People" view selects all documents created with the "Person" form.
The above query bypasses the use of a view and will give you all the fields for all documents created with the the Person form.
Actually, come to think of it, the better query would be select * from Person where type='Person'. That's because the People view in Domino uses type="Person" instead of form="Person" in its selection formula. It is theoretically possible to have a document created with the Person form but with the Type field set to a different value. This variation will insure that you always get the same list that you see in the Person view.
But: In either case, it will be inefficient. The NotesSQL driver will have to do a full database search instead of simply reading the index of an existing view. It's going to search using the Notes formula SELECT Form="Person" & Type="Person". I really cannot recommend this, unless you are querying against a small Domino Directory database.
The best practice is to create a view containing all the fields that you really need, and do your query against that view.
First, in the Lotus Notes documentation, you'll find "columns" when you read about views, not fields.
Second, the columns have configured an option called "Programmatic Name". In that option, you can put an "alias". Lotus Notes puts values by default as "$12", "$17", etc. The thing is NotesSQL changes "$" by "_". That's the reason why you see "_12", "_17, etc.
How do you get the original names? As far as I remember (I don't have Lotus Notes near to make a verification) you can't. But, you can create another view with the columns with the data you need, and put appropiate names. The easy way to do it is copy/paste the view, delete the columns you don't need, and change that you want.
What is the best way to re-use reports on different tables / datasets?
I have a number of reports built in BIRT, which get their data from a flat (un-normalized) MySQL table, the data which in turn has been imported from an excel sheet.
In BIRT, I've constructed my query like this, such that I can change the field names and re-use the report:
SELECT * FROM
(SELECT index as "Index", name as "Name", param1 as "First Parameter" FROM mytable) t
However, then when I switch to a new client's data, I need to change the query to the new data source and this doesn't seem sustainable or anywhere near a good practice.
So... what is a good practice?
Is this a reporting issue, or a database-design issue?
Do I create a standard view that the report connects to?
If I have a standard view, do I create a different view with the same structure for each data table, or keep replacing the view with a reference to the correct data table each time I run the report?
What's annoying is the excel sheets keep changing - new columns are added, and different clients name their data differently. Even if I can standardize this, I'd store different client data in different tables... so would I need to create a different report for each client, or pass in the table name to the report?
There are two ways and the path you choose is really dictated by how much flexibility you have architecturally.
First, you are on the right track by renaming your selected columns to a common name since that name is what is used to bind the data to the control on the report. Have you considered a stored procedure to access the data? This removes the query from the report and allows you to set up the stored proc on any database to return the necessary columns. If you cannot off-load to a stored proc, you can always rely on altering the query text at run-time. Because BIRT reports are not compiled (they are XML) you can change the query based on parameters and have it executed for each run of the design. Look at the onCreate event for the Data Set and you can access this.queryText and do any dynamic string substitution you need via JavaScript. Hidden parameters are a good way to help alter/tune the query. If you build the Data Set correctly, the changing of the underlying data could be as easy as changing the Data Source and then re-associating the Data Set to the new Data Source (in the edit data set window). I have done this MANY times and it works well. If you are going down this route, I would add the Data Source(s), Data Set(s) and any controls that they provide data to a report library. With the library you can use the controls in many reports and maintain them in one spot. If you update the library, all the reports using the library get updated as well.
Alternatively, if you want to really commit to a fully re-usable strategy that allows you to build a library of reusable components you could check out the free Reusable Component Library at BIRT Exchange (Reusable Component Library). In my opinion this strategy would give you the re-use you are looking for but at the expense of maintainability. It is abstraction to the point of obfuscation. It requires totally generic names for columns and controls that make debugging very difficult. While it would not be my first choice (the option above would be) others have used it successfully so I thought I would include it here since it directly speaks to your question.