Solved

Operational Report Parameter - Select Value From Dropdown

  • 18 January 2022
  • 8 replies
  • 785 views

Userlevel 6
Badge +12

Hey all,

We are creating an operational report where one of the parameters is “Org Code” (field ORG_CODE from CompanyOrg LU). We would like the parameter to display existing Org Code values in the dropdown.

We have examples of showing a list of values in the dropdown when an Enumerate method can be called from a Package API. For example, we get values in the list if we link the parameter to something like Pur_Order_Print_Option_API.Enumerate(). The dropdown then looks like this:

 

 

So, we know it can be done. But we cannot find a enumeration method for Org Codes. As far as we can tell, the enumerated list is simply values with the “unit separator” character (CHR(31)) after each value. I can generate such a string with the query:

 

SELECT OrgCodeEnum FROM
(SELECT Company_Id,
LISTAGG(Org_Code, CHR(31))
WITHIN GROUP (ORDER BY Org_Code) AS OrgCodeEnum FROM Company_Org GROUP BY Company_Id)
WHERE Company_Id = '01'

 

Love me some LISTAGG(). But how do we do a manual query such as this and tell the report template to use that enumeration string for the parameter dropdown?

There are also some operational reports native to IFS that appear to list hard-coded values, like this:

 

 

In a pinch, we’d be fine hard-coding a list of Org Codes because our structure on that is probably not going to change once we establish our Organization hierarchy in PROD. Is there a way to use a hard-coded list of values in the dropdown?

In other words, how do we create an Enumerate() routine “on the fly” via our own SQL statement or PL/SQL block, or as a hard-coded list? We have our own custom API package where I could create a method that mimics something like Pur_Order_Print_Option_API.Enumerate(), but I would rather not have to go all that trouble. Documentation is sparse on this topic, so we are sort of fumbling our way in the dark when it comes to the finer points of creating operational reports.

Any help would be greatly appreciated!

 

Thanks,

Joe Kaufman

icon

Best answer by Tracy Norwillo 20 January 2022, 21:10

View original

8 replies

Userlevel 2
Badge +7

@sutekh137 

I’m not sure if I am going down the right path on this one because it seems you may already know about this but I’m not sure.

Are you referring to including an ENUMERATE= comment on your _REP view in your RDF?

For instance that Pur_Order_Print_Option_API.Enumerate() you speak of is in the view PURCHASE_ORDER_PRINT_REP on the field PUR_ORDER_PRINT_OPTION.  You can see that if you view the comments of that field in the view.

I believe this is how when the dictionary refreshes it knows how to assign an enumeration like that in the Operational Reports.

Userlevel 6
Badge +12

@hansend

Thanks for the response! Yes, we are struggling with the ENUMERATE, and even though we have streamlined things now (and got REF working), we still cannot get a custom API package method to work. I created it with a single OUT parameter, which is expected, and hard-coded a list of values with a field separator character after each one. Nothing errors out, but dropping down the list reveals nothing, no values at all.

Yet we can use any IFS-native Enumerate() method from any other package and it works.

Any idea on why our custom method is not being accessed for the enumeration? I compiled all invalid objects and refreshed all caches -- still no luck.

 

Thanks,

Joe Kaufman

Userlevel 6
Badge +12

Hey all,

Follow-up on this… We figured out the REF and QFLAGS attributes, so they will probably get us where we need to be, but ENUMERATE continues to not work (and I’d like to figure it our for future reference).

I have been playing with a very simple enumeration, the one generated by SUMMARY_DETAIL_API.Enumerate(). So, the COMMENT on the operational report parameter looks like this (straight from IFS Developer Studio, defining the report):

 

COMMENT ON COLUMN "BELL1APP"."BELL_PROJECT_HOUR_DETAIL_REP"."ORG_CODE"
IS 'FLAGS=A----^DATATYPE=STRING(10)^TITLE=Org Code^QUERY=Org Code:^ITEM_NAME=iDisplayOut^QFLAGS=A---L^ENUMERATE=SUMMARY_DETAIL_API.Enumerate^';

 

This makes the report parameter dropdown look like this:

 

 

So far so good. I copied the specification line and body procedure from SUMMARY_DETAIL_API.Enumerate() into our custom API package (which is called BELL_CUSTOM_API), so it is exactly the same, except I hard-coded a couple values in the list. The package method looks like this:

 

--@IgnoreMissingSysinit
PROCEDURE Enumerate (
client_values_ OUT VARCHAR2)
IS
PROCEDURE Base (
client_values_ OUT VARCHAR2)
IS
BEGIN
client_values_ := 'HELLO' || Client_Sys.field_separator_ || 'WORLD!' || Client_Sys.field_separator_;
END Base;
BEGIN
Base(client_values_);
END Enumerate;

 

As I said, it is exactly the same as the Summary/Detail Enumerate method with regard to structure and the single OUT parameter. I then changed the COMMENT for that report parameter to use BELL_CUSTOM_API.Enumerate, refreshed Dictionary cache, refreshed Reference cache, and ran my report. No enumerated values display in the dropdown.

Then I came at it from the other direction. Since we are on our DEV server, I changed the Summary_Detail_API.Enumerate() method itself to also use the hard-coded “HELLO WORLD!” values. I tested the method and it returns what I expect it to in the debugger. Then change the report parameter COMMENT back to that method, again refresh Dictionary and Ref cache, and run the report. The dropdown shows values again, but they are still DETAIL and SUMMARY.

I am certain I am working on the same server for all of this, so this is not an environment issue. The COMMENT changes are visible in the _REP view, and cache has been refreshed. Yet I cannot influence the values in the dropdown, and using a custom Package method yields no results.

At this point I don’t know what else to try since I can’t seem to change much of anything (though I can change the prompt, can use REF, and can make the dropdown change via QFLAGS).

Any ideas on what I am missing here?

 

Thanks,

Joe Kaufman

Userlevel 6
Badge +12

If anyone has thoughts on this I am still open to suggestions, but will be closing this issue for now. I think it is just one of those things in IFS where if you want to use ENUMERATE you need to call a native enumeration API call, and if you want an LOV lookup to be some other data set, use the REF attribute to make the “...” button appear. It makes sense, I suppose, but I liked the validation capabilities of the ENUMERATE route...

However, I might try to figure out the VALIDATE attribute, if it turns out to be an issue. Then REF ends up being the superior option because the LOV contains more context/information than a single list of values.

 

Thanks,

Joe Kaufman

Userlevel 4
Badge +11

Joe - I’ve only created a couple of operational reports from scratch, so my knowledge is limited.  That being said, I did need to create a custom enumeration for a report parameter.  The way I did it was to add an Enumeration Model in IFS Developer Studio. 

The syntax in the .enumeration file is pretty simple:  

enumerationname CMyCustomList;
component       <IFS component>;

values {
   value MyValue1;
   value MyValue2;
   value MyValue3;
}

 

Then in the .report file, the enumeration is referenced as such:

  parameter ReportSection   Enumeration<CMyCustomList> M---L {
      default   "%";
   }

 

I deployed the enumeration then generated the .rdf and deployed the .rdf.

Best way to do this?  I don’t know, but it worked for me.

 

Userlevel 6
Badge +12

Wow, @Tracy Norwillo -- I think you know plenty! We have been messing with the RDF directly because we didn’t know all you could do by changing the text of the .report file…  We have even been writing functions to populate default parameter values instead of using that nifty default keyword.

I did end up figuring out how to generate a dynamic enumeration from Org Code data -- I needed to add the method to the RPI implementation. It was just that simple. The RPI gets properly registered in the Framework and it ends up working.

Question about the hard-coded enumeration you list above: Can the enumeration be dynamic, as in a query from other parts of the Oracle database? As I mentioned, I am generating the Org Code list from the CompanyOrg LU so that I don’t need to hard-code it. Maybe that is an advantage of RDF manipulation?

But this answers my question about worrying that the RDF will get wiped out when changes are made to the report. If we can do everything in the .report file then we don’t need to worry about the RDF file. This seems like the “right” way to do things.

 

Thanks so much!

Joe Kaufman

Userlevel 4
Badge +11

For what you’re calling dynamic enumeration, I did that a different way.    This activates the ellipsis (like you get for date parameters) instead of the down arrow list of values.

 

 parameter CompanyNo       Text(100)                         O---L {
      default   ":User_Finance_API.Get_Default_Company";
      lov       "PERSON_COMPANY";
   }
   parameter Site            Text(50)                          O---- {
      lov       "USER_SITE_COMPANY";
   }

About the .rdf vs .report development, I’m not a strong pl/sql developer, so working in the .report file and then generating the .rdf was the only way to go for me.  It is challenging to do this way because you’re kind of on your own.  I looked at the seeded report files that IFS provides for their operational reports and they are done a very different way, with the .report file being a shell for the structure and the logic being in the .rdf file.  This makes it difficult if you want to emulate the functionality of a particular operational report - you can see the logic in the .rdf, but you have no idea what to put into the .report file to replicate that result.

Userlevel 6
Badge +12

@Tracy Norwillo 

What you are calling a dynamic enum, I call a REF, because it creates the “...” button. That’s a REF attribute in the RDF’s COMMENT lines, not an ENUMERATE.

So, it sounds like you can only do static enumerations (real enumerations, not LOV references), and if you want to access data dynamically, you use a REF. But by manually manipulating the RDF (and therefore the report’s RPI package, I can actually make a dynamic enumeration for those rare occasions where the data set is small enough to be reasonable in a dropdown but where I want to generate it from custom-queried data instead of hard-coding values.

Like I said in a post higher up, the only advantage of an enumerated parameter (dropdown values) is that the data entry is automatically validated against the enumerated values -- you cannot get that with a REF (the “...” button) unless you also set up a VALIDATE attribute and validation code is available in the native API. Otherwise you’d be back to generating your own validation routine in the RPI package generated by the RDF.

Your solutions have an elegance that one cannot achieve via manual RDF manipulation, though: you don’t need to worry about your .report and .RDF ever getting out of sync, because the .report runs the show.

Thanks so much for your answers! I am learning a ton!

 

Thanks,

Joe Kaufman

 

Reply