Parameters for User specific reports
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
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
This discussion has been closed.
Comments
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.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
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.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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