Business Objects Complex prompt - how best to set up, using 4.0? - business-objects

We're trying to create a template date prompt to be used across multiple universes, and also be used against multiple date fields (for instance, Transaction Date, Invoice Date, etc)
The prompt should display a list of values like the below (there's about 30 total):
Date Range START_DATE END_DATE
-------------------- ------------------------------ --------------
D: Yesterday 12/02/2015 12/03/2015
M: Month Before Last 10/01/2015 10/31/2015
M: Month to Date 12/01/2015 12/02/2015
Our initial attempt at this (creating a derived table, and then some aliases against the derived table, with one alias for each date type such as Transaction Date, Invoice Date, etc) was a failure - the sql generated is wrong, and includes the sql that's just supposed to provide the list of values. I think we need to use a different approach entirely.
Thanks for reading so far. I would greatly appreciate any ideas! Feel free to ask questions and I'll edit my notes to answer.
EDIT - we're using UNV (legacy Universe Design tool)

I'm going to assume you have an existing (dimension) table that contains a record for each date and the necessary columns to hold the different representations. You can also create a derived table for this.
Here are the steps to achieve what you described (sorry, no screenshots, this is off the top of my head):
Create the required dimension objects (based on your date table) in a separate class in the universe (you can hide this class at the end; the end user shouldn't see them).
Take one of the date dimension objects (e.g. Transaction Date, Invoice Date. …), enable the LOV option and edit it (which should bring up the query panel).
In the query panel, select all the dimension objects, created in step 1, that you want to show in your LOV. Important: the object holding the value to be returned, should be placed first in the query panel. Run the query (nothing will appear though).
Make sure that you enable the option to Export the LOV, otherwise your customisations will be lost upon exporting the universe. Optionally, enable the option to refresh the LOV each time the user calls it.
As you can't really define a single, reusable LOV in UDT that you can reference in different dimension objects, you'll have to perform this for each dimension object that you would want to have this LOV.
One way around this annoyance may to define the customised LOV once, note down the generated LOV name (about 8 alphanumeric characters long) and then replace the LOV name in the other dimensions with that LOV name. I'm can't guarantee that this will work though.
In contrast: with IDT you can define a customised LOV like this once (either in the Data Foundation Layer or the Business Layer), and then reference it as much as you want.

Related

MS Access Data Macro to SET a calculated field value on INSERT using DMAX

I have a two table scenario with a typical parent / child relational setup:
tblGroup - idGroup (autonumber, PK); GroupName (Short Text), Rank (Number)
tblRange - idRange (autonumber, PK), idGroup (FK -> tblGroup.idGroup), RangeName (Short Text), Rank (Number)
What I am doing on the parent (tblGroup) table is using a data macro to add the rank using the BeforeChange event:
IF
IsInsert
SetField - Rank
- DMAX(Rank, [tblGroup])+1
This works nicely and I can happily use a parametized INSERT query to add rows to the table and not have to worry about duplicate ranks and so forth.
What I would like to be able to do but cannot figure out how, is to have a data macro do the same thing for the child (tblRange) table, with the rank being set to the new highest for the parent group the child record belongs to.
If I use the same DMAX approach as I have above I am supposed to be able to set a criteria as a third option, acting like a where clause, to limit the lookup / calculation. How can I refer to the specific idGroup I am working with in tblRange in the macro? I cannot seem to figure out how to reference the new records value for this in the macro.
Something like DMAX(Rank, [tblRange], ???How_to_refer_to_idGroup_Properly???)+1
Any help greatly appreciated
Cheers
The Frog
I figured out a way to do this. Thankyou caffeinated beverages!
The reason for the strange error messages is due to limitations in the Data Macro processing, specifically in the BeforeChange event. The solution is as follows:
Create a query that selects MAX rank (MaxRank) and GROUP BY for the idGroup (ParentID)
The resultant query produces two columns of data: [MaxRank] and [ParentID]
There will be a row for every idGroup with the maximum Rank for each
Create a BeforeChange data macro
Set the following:
IF IsInsert
LookupRecord
Lookup Record In - qryGetMaxRank (or whatever you called your query)
WHERE - [qryGetMaxRank].[ParentID] = [tblRange].[idGroup]
Set Field
Name - [tblRange].[Rank]
Value - [MaxRank] + 1
The BeforeChange event cannot handle parameters for a query, and I am guessing that this applies in some form the to DMAX function here too. The use of a query that does not use any parameters, and then using the LookupRecord WHERE clause to do the filtering provided the single row result needed. The [MaxRank] value from the returned result is then able to be used to set a new value for the field.
Bit of a workaround but it does allow someone to work with the data either through a form or through the datasheet view and not create a problem.
**In answer to if this is a multi-user DB - it is not. It is just me working with it. If / when the solution is scaled up to something requiring multi-user I will likely recreate the BE in SQL Server or MySQL and use stored procedures for all data I/O. Happy to keep Access as the FE and compile into an application (using the runtime for clients), but I am a fair way off from having to do that yet. Very early stages of development at this time.
Cheers to everyone for the pointers. They helped me figure this out. Hopefully this will be of use to someone else in the future.
PS: If you need to use a parametrized query in a data macro it looks like the best bet is with the AfterInsert event or AfterUpdate event as they can support parameters.

Access combo box for DB mapping table 2-1 Table relation

I've run into a bit of a snag with a project I'm working on, and being new to Access I don't know if what I want to do is possible without VBA. I've looked around but all I can find are answers related to showing multiple columns, not controlling multiple fields in my DB.
To paint a picture I have a mapping system set up in my DB to help me distinguish the name and type of data is held in a table.
The setup is as follows:
-Data table is "LineItems" with an ID and the line data (think typical excel format)
-Mapping table is "LineItem_Mapper" with LineItem_ID, DataType, and Entity_ID
-A helper table "Data_Type" with ID and Name
-two "Entity" tables with differing properties both have ID and Name
The reason for the split is on data type is that the two types of data behave differently. One type has a parent child relation, and the other is a standalone row. I want to preserve this structure in my DB and feel I have done so with this mapping.
Now, on to the issue I'm running into. In my Access data entry form I want to use a combo box, as the options a user may chose for each line when entering are finite. However, this combo box is affecting the Mapping table above. I have been able to populate the box with my desired list with a custom query built from my 2 entity tables, but I don't know how to get Access to create or update the Mapping table using this box.
what I want to happen is when I chose something in the box, a line is created (or changed) in the mapping table with all 3 columns being populated. first the LineItem_ID for the line I am populating, and then the DataType and Entity ID to reflect the proper mapping.
Can Access do this on its own? Or do I need to do this with VBA?
As requested by the OP converting my commend as an answer (with a little bit more detail):
By far your best option is to use VBA. I doubt there is another way and even if there is it would be so convoluted it would be unworkable and unmanageable.
This should get you started:
In the combo box properties go tot the events tab and in After Update or On Change (look up the difference between the two events to see which behavior you prefer) click the down arrow and select [Event Procedure], then click on the … button. This will create a VBA module for you complete with the function that runs when the selected event is triggered.
You can use DoCmd.RunSQL "[Access SQL INSERT statement]" to add records to tables.
You can use Me.[MyComboBoxName] to get the current value of the combo box. Similarly the value of anything else in your active form.
You can use DLookup to get the value of any record in your tables.
Hopefully these will give you a relatively quick start.

Creating a global variable in Talend to use as a filter in another component

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.

Update single records in query with form based textbox

I am working with Access2013 and I have a query called PaidOrderQ with columns "SalesRep", "Customer" and "PaidAmount". I need to calculate the SalesRep's commission which isn't always the same percentage for each record. After reading through similar questions here I still haven't figured it out yet.
The way I thought doing it is to have a form called PaidOrderF with soucre is PaidOrderQ, a textbox called "CommRate" and a calculated field "Commission". The "Commission" gets calculated by "AmountPaid"*"CommRate".
I'm not sure how the percentage for commission is calculated, but there are a few ways this can be done depending on how the percentage is calculated. The first would be if you can calculate the percentage that will be used automatically. Then you can add everything automatically (even if the percentage changes based on the item). If this is possible you can open the query up in DESIGN view. Then click onto a blank field and you can make a calculated field for example:
Commission: [AmountPaid]*[CommRate]
Now you can add the calculation for CommRate for example:
CommRate: IIf([AmountPaid]>200,.15,.2)
Which would make any the comm rate 15% over $200 and 20% under.
If not you can make Text boxes in a form (which would be unbound and add an after update vba code to multiply them together and change the value of a third text box, label etc.)
You may also want to add a column to the original table to show commission rate so the information would be stored for future reference.
Let me know if anything is unclear or you would like to see an example of the vba code
EDIT::
Storing information to a table:
This one will be very basic and you probably know most of this, but just in case I will include it because it is the most straight forward.
Add a column to the table you are working from by opening up the table in Design view (you can also make a temporary table by using a make table query if you are using a liked table or do not want to modify the structure, but it is better to put it in the main table if possible). Here you could make a query that includes all of the fields plus the additional calculated field that shows amount paid * commission. Then when you make a form based on the query you will enter in the commission rate and the form will both save the information and automatically update the field to give commission.
Linking another table by Primary ID -
If neither of those options work you could also create another table that shares a primary ID. This option will be more complicated, but is possible. (I would recommend not making it a true primary ID for the second table so it is easier to modify (Or have a true primary ID and the ID you will use to link ie. 3 total columns)). If this is the option you need I can go into more depth, but the disadvantage of this method is if there is no CommRate listed for a given record it will automatically hide the information (it is possible to avoid this, but again will be more complicated) so it will be easy to make a mistake.
VBA coding
VBA will be the most complicated solution, and has the largest disadvantages. First - You will have to loop all of the records at one time (or at least for one employee) and when you close the form you will lose everything. If there is any way to avoid this I would suggest doing so, but you could theoretically store the information in an array.
The Standard Way -
As I understand it your table looks like this:
SalesRep Customer PaidAmount
John Eric 2040
Stacy Brian 1020
Stacy Eric 2004
etc.
You will want to open up your table in Design view and add a column "CommRate"
so it will look like:
SalesRep Customer PaidAmount CommRate
John Eric 2040
Stacy Brian 1020
Stacy Eric 2004
etc.
The data type for CommRate should be Number - type Double - Now I would use Comm rate as a percentage - ie 10.2 = 10.2%, but you could also do .102 = 10.2% either one is fine (more on that later) save and close the table.
Now with the table selected use the create query wizard add all of the fields to the query, give the query a name and click modify the query at the end (or save it then open it up in design view). Now you will see each field in a column with the table listed below. Copy and paste the entry below to your query in one of the bank "field" locations:
for percentage ie 10.2=10.2%
Commission: [CommRate]*[PaidAmount]/100
for .102 = 10.2%
Commission: [CommRate]*[PaidAmount]
Now save and close the query.
Lastly you will select the query then click on create form. This will make a form based on the query. With this form you can add the CommRate individually and it will be saved for the future. You will see that when you add the CommRate the Commission field will automatically update and the table will get updated with the new value.
This is the standard way of doing this. Does this work for what you are doing?
Alright well that is good news! The primary key will help a lot:
Ok here is how you can solve this with two tables.
First create a new table with three columns:
"ID" - Primary Key "RelatedID" - Number Long Int "CommRate" - Number Double
This table will basically just be used to "add on" the CommRate without changing the linked table.
Next you will make a query that includes "SalesRep", "Customer" and "PaidAmount" from the linked table AND the "RelatedID" and "CommRate" from the new table.
When you view the query in design view you will see both tables above the list of the different fields and you will click on the primary key from the linked table and drag it to the "ReatedID" in the new table. From here it will open up a dialog asking about the relationship join. This part is the most important - You want to make the relationship a LEFT JOIN - You do this by saying you want to show ALL records from the Linked table and only the record from the New table that match. Basically this makes it so it will always show the records from the new table even if there is no entry that matches in the new table.
After you have that created you will just make a calculated field as before by copying:
Commission: [CommRate]*[PaidAmount]/100
to a new field on the query design
From here everything is set up and you can create a form based on the query you just made - I would delete the field "RelatedID" from the FORM (or the Query the relationship is what links it so its not necessary it is just a good double check) so you don't change it.
How it works - Now when you cycle through the entries you can add the commission rate directly to the form. - This will make a new entry in your new table that shows the primary ID of the transaction and the commission rate for that sale. This will update the calculated field and show you the commission. Then when you view it it will save the values individually without changing your original table.
Keep me posted if you need more help on how to do this. It can be a little tricky the first time you do it.

Design - Microsoft Access - Unique "Serial" Number

I am looking for some design techniques to achieve the following:
A 3-part serial number that is generated upon record entry. Format Example: 25-001-14
The number is used to track yearly records from various locations.
The first part states the location the record is associated with, this would be a user input during record creation.
The second part is the record number, I would like for this to be automatically generated, but needs to be sequential and separate for each location and needs to reset each year.
The third part is the two digit number for the year the record was created in. I would like this to be automatically generated if possible. Note: I am currently not concerned with when this cycles back around and I face redundant data issues.
I'm thinking I would like records to be stored in multiple tables that are separated by location, if this would help things!
Any ideas would be greatly welcomed.
I think I would use 3 key fields - one field each for location, record and year. The location and year fields would be created when you get the input to create new records. I would set up a query to find the last record number used by location and year and use that query to assign the new record number when you create a new record. The concatenation of the 3 fields would be the key you described.
With a key field for location, separate tables are not necessary unless that's useful for other reasons. I would probably use just one table - you can always filter the records by location anytime you need to.