Home End User
New Blog Posts: Merging Reports - Part 1 and Part 2

Parameters for User specific reports

edited April 2003 in End User
I have an application that includes a security subsystem, which
basically allows users to log in and see their own data.

I want to design reports that will show ONLY the data of the currently
logged in user. Moreover, I want the end users of the report designer to
be able to design such reports as well.

So, for example, the end user might want to design a Contact List
report, which would need an SQL select statement something like:

Select * From Contacts Where OwnerId = CurrentUserId

That's design time. When the reports are actually generated though, the
value for CurrentUserId will depend on the user that is currently logged
in to the system...

How could I achieve this?

Best Regards,

James Crosswell
Software Engineer
Microforge.net Limited
http://www.microforge.net

Comments

  • edited April 2003
    James,

    The best way to approach this problem would be to use the Autosearch feature
    in ReportBuilder without the dialog. Check out the End-User AutoSearch demo
    located in the \RBuilder\Demos\5. AutoSearch\7. Create EndUser AutoSearch
    Fields AutoSearch directory. This demo shows how to use the AutoSearch
    feature using static constraints.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited April 2003
    Thanks Nico,

    I had a think about this and that sounds like a fairly complicated
    solution...

    If I go the route that you suggested below, it seems I either replace
    all autosearches for certain fields with the CurrentUser.Id constant in
    code (which is not ideal - the user may well want to create
    administrative reports using these fields where they DO want to specify
    them at runtime as Autosearch values), or I specify some constant like
    -777 (since I know the UserId will only ever be positive) and replace
    defaults of this value, on certain autosearch fields, with the
    CurrentUser.Id from my program.... Neither of these solutions
    particularly appeals to me. The last one is just plain messy.

    What I was hoping for was the ability to create a CustomUser object that
    the end user could use in a Calc Expression, which they could then add
    to Search or AutoSearch fields... or something like this...

    About the only other thing that I can think of is maybe providing a
    premade data pipeline in both the desiger and runtime modules, which
    selects the current user... Then the end user can create master-detail
    reports using the premade pipCurrentUser pipeline as the master... but
    I'm not sure if this would work.

    Would you be able to comment on the possibility of the ideas in these
    last two paragraphs?

    Thanks in advance.

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net


  • edited April 2003
    > What I was hoping for was the ability to create a CustomUser object that

    In fact, what would be great is if the Search fields appeared in RAP as
    an Object... that way I could add the RTTI for a my own CurrentUser
    object and the end user could simply place something like the following
    in the OnBeforePrint event:

    SearchField[X] = CurrentUser.Id

    Is this viable do you think? Do you think I could extend RAP to include
    a SearchFields and CurrentUser object to use in this fashion?

    I'm just dreaming here a bit, since I've never built custom objects for
    RBuilder or even used RAP for that matter.

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net
  • edited April 2003
    James,

    It is possible to use RAP to access a value in your main application such as
    'CurrentUser.ID' by using a RAP Pass-thru function. Then you could filter
    the dataset by applying this value to the AutoSearch field value and only
    allow the user to access his or her information. For more information on
    RAP Pass-thru functions, check out the ReportBuilder Developer's guide
    available for download from our website at http://www.digital-metaphors.com.
    Also check out the autosearch demo which sets the end user criteria in code.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited April 2003
    Nico Cizik (Digital Metaphors) wrote:

    Hi Nico,

    Thanks for the reply. Is it possible to set the value for Search fields
    in code (as opposed to autosearch fields)? I'm thinking of extending RAP
    with a function like
    UseCurrentUser(SearchFieldName)

    But, if this is an Autosearch field, rather than a search field, then
    the user will still be prompted to enter this value... which I don't
    particularly want. So I need some way of setting this dynamically
    without prompting the user for the value (at the same time as allowing
    the user to enter other values that they do need to be prompted for).

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net
  • edited April 2003
    Hi James,

    You don't have to show the autosearch dialog to use the autosearch feature.
    Please re-examine the end user autosearch demo in the \RBuilder\Demos\5.
    AutoSearch\7. Create EndUser AutoSearch Fields AutoSearch... directory it
    gives a good example of creating an autosearch criteria without showing the
    autosearch dialog. All of the code in this demo can be writen in RAP.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited April 2003
    Nico Cizik (Digital Metaphors) wrote:

    Hi Nico,

    I think you misunderstood my question. I wanted to set the value for
    SEARCH fields (not Autosearch fields). Here's why:

    Imagine an end-user wants to create a report "Contacts" which will list
    all of the contacts for the user that is currently logged in. Each
    contact has an OwnerId, specifying the user that owns that contact... so
    to create this report, the end-user lists all the contacts where
    OwnerId=CurrentUserId... I have to implement this.

    If I use Autosearch fields, how do I tell the difference between fields
    that the end-user intended to be genuine autosearch fields and those
    that they intended to be replaced by the CurrentUserId value? I can't,
    so I'd rather use Search fields. That way, what I'm thinking is that I
    could extend RAP by adding:
    UseCurrentUser(SearchFieldName)

    *** Note SearchFieldName - NOT AutosearchFieldName ***

    So, back to my original question: Can I get at SEARCH fields in code (as
    opposed to autosearch fields)?

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net
  • edited April 2003
    James,

    Sorry about the misunderstanding, here is an example which adds new search
    criteria and also includes a method that shows how to change it.

    http://www.digital-metaphors.com/tips/addsearchcriteria.zip

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited April 2003
    Nico Cizik (Digital Metaphors) wrote:

    Cool - that I think I can use... So what I'm thinking is that I can
    extend RAP using RTTI and build a function:
    SearchByUserId(FieldName)

    which could be called in the BeforePrint RAP event handler. The
    implementation of that function would then add an autosearch field to
    the report and set the value of this field to the ID of the user that is
    currently logged in to my app. Since all of this would take place after
    the AutoSearch dialog itself gets shown, this wouldn't affect the normal
    behavior of the other autosearch fields.

    All very nice in theory - I'll see how it actually works! Thanks for
    your help and your patience.

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net
  • edited April 2003
    James,

    Instead of using the BeforePrint event in RAP, try using the GlobalOnCreate
    event. This is the first event that fires after the Autosearch events occur
    and would probably work best for you in this situation.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited May 2003
    Where exactly is that event (GlobalOnCreate) - I can't see it in the
    events for the report???

    You are talking about a RAP event right, not a Delphi one?

    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net

  • edited May 2003
    Nico Cizik (Digital Metaphors) wrote:

    OK, I'm getting VERY close to a solution here. It seems like the above
    would be wasting my time a little bit - since there is already a RAP
    method of the report object called CreateAutoSearchCriteria. So I just
    added a Rap function GetUserProperty(aPropertyName): Variant, and I'm
    using this as follows:

    procedure ReportOnAutoSearchDialogClose;
    begin
    Report.CreateAutoSearchCriteria(
    'mfContacts',
    'OwnerId',
    soEqual,
    IntToStr( GetUserProperty('Id') ),
    False
    );
    end;

    This works great, as long as there are some autosearch fields defined
    for the report - otherwise it doesn't get called...

    What RAP event should I place this RAP code in? It has to be after the
    AutoSearchDialog is shown, but before the SQL for the datapipelines gets
    created....


    Best Regards,

    James Crosswell
    Software Engineer
    Microforge.net Limited
    http://www.microforge.net
This discussion has been closed.