Restricting User views

Variables UserSetup REC User Setup UsersTerritoryCode CODE 10


OnInit()
CLEAR(UsersTerritoryCode);
UserSetup.RESET;
UserSetup.SETFILTER("User ID",USERID);
IF UserSetup.FIND('-') THEN  BEGIN
  IF STRLEN(UserSetup."Territory Code") > 0 THEN BEGIN
    UsersTerritoryCode := UserSetup."Territory Code";
  END;
END;

OnActivateForm()
IF STRLEN(UsersTerritoryCode) > 0 THEN
  SETRANGE("Territory Code",UsersTerritoryCode);

The above code was created in answer to a request that Users that have a Territory Code in their setup only be allowed to see the appropriate records in certain forms (Posted Invoices, Sales Orders, etc.). If the User doesn’t have a Territory Code, then he should be able to see every record. Obviously, the code doesn’t work, or else I wouldn’t be writing this. I thought this would be pretty easy, but I’m obviously on the wrong tack. Any ideas?


OnActivateForm()
IF STRLEN(UsersTerritoryCode) > 0 THEN
  SETRANGE("Territory Code",UsersTerritoryCode)
ELSE
  SETRANGE("Territory Code");

Never mind. Further investigation showed that the Range wasn’t being released. This fixed it. cheers,

First some remarks about coding: 1)

UserSetup.SETFILTER("User ID",USERID);

should be replaced by

UserSetup.SETRANGE("User ID",USERID);

as the SETRANGE executes much faster as the SETFILTER command. 2) I assume that User ID is the only primary field in this table. Therefore I would use a straight forward

UserSetup.Get(USERID)

issuing an error for new users without setup. 3) Why do you use

IF STRLEN(UserSetup."Territory Code") > 0 

instead of a simple (and faster)

IF UserSetup."Territory Code" <> ''

? 4) I dont’ see a reason to read the UserSetup in OnInit and set the filters OnActivateForm. Why don’t you program the whole logic in one OnOpenForm trigger? 5) Instead of setting a simple Filter which can easily be deactivated by the user I would use the filtergroup command to make sure that the filter is set no matter what the user does. After all my code would look like this:


OnOpenForm()
UserSetup.GET (USERID);
IF (UserSetup."Territory Code") <> '' THEN BEGIN
  filtergroup(4);
  SETRANGE("Territory Code",UserSetup."Territory Code");
  filtergroup(0);
end;

The reason why your code didn’t work might be (I did not verify that) that the OnActivate() Trigger is issued before OnInit() trigger. ------- With best regards from Switzerland Marcus Fabian

Ouch! Not exactly a ringing endorsement. I appreciate the tips, and have implemented them as follows:


UserSetup.GET(USERID);
IF UserSetup."Territory Code" <> '' THEN BEGIN
  FILTERGROUP(4);
  SETRANGE("Territory Code",UserSetup."Territory Code");
  FILTERGROUP(0);
 END
ELSE
 BEGIN
  FILTERGROUP(4);
  SETRANGE("Territory Code");
  FILTERGROUP(0);
END;

in the OnOpenForm() trigger. I’d read about FilterGroups before, but didn’t really pay any attention at the time. Thanks for reminding me. cheers,

Just one comments to Marcus’ observation about SETRANGE and SETFILTER. There is NO difference on the speed of the 2 commands. Filter commands does not communicate with the DBMS, this does not happen until you retreive a record, or otherwise query the database. Therefore, the speed of SETRANGE and SETFILTER is identical. Lars Strøm Valsted Head of Project and Analysis Columbus IT Partner A/S www.columbusitpartner.com

It is correct that the speed of the SETRANGE and SETFILTER statements are the same but the first FIND(’-’) will be slower using SETFILTER. That’s at least what a programmer from NDK once told me. ------- With best regards from Switzerland Marcus Fabian

Hi Marcus, The programmer from DK was wrong then :slight_smile: The SETRANGE and SETFILTER works identically with regards to speed. Actually, internally in Navision (both 3.xx and Financials/Attain) there are only a SETFILTER command, C/AL calls to SETRANGE and SETFILTER are then interpreted internally by the same SETFILTER internal function. Lars Strøm Valsted Head of Project and Analysis Columbus IT Partner A/S www.columbusitpartner.com

While I can’t comment on the speed issue :wink: I’ll just point out that when needing to filter on a single value the Navision programing standard has always been to use setrange. So, if following conventions is important to you… Bill Benefiel Manager of Information Systems Overhead Door Company billb@ohdindy.com (317) 842-7444 ext 117