This is a hot subject for a lot of companies using Navision. When was a report last executed, by whom and how many times.
The classic solution for this is to add code to every report to store this information in a table.
But it can be solved more generic...
The solution is in Codeunit 1. Here is a trigger FindPrinter that is executed prior to each report being printed. So what about implementing the solution here.
In order for this to work, we have to implement a trick, because when this code is executed, Navision is not yet in transaction state.
The trick is to save the report usage in a Temporary table first inside a SingleInstance codeunit.
Ok, let me explain this.
SingleInstance codeunits were introduced years ago. The benefit of this type of codeunits is that all variables are stored in client memory during the lifetime of the session. This includes temporary tables.
To activate this propery, just go in the codeunit's property window.
So what else do we need...
First of all the table to store data in. Off course you can make this as high tech as you want, but for this example we will store the Repord ID, the User ID, the number of runs and the last execution date.
The second thing we need is a management codeunit, the SingleInstance one.
This codeunit has two functions. One to populate/maintain the temporary table, and one to store the data in an actual table.
Remember to make the variable Temporary
Last change is to manage these functions from codeunit 1.
This is done in the FindPrinter and LogInEnd functions.
Remember that in both functions the RepUsageMgt codeunit is a LOCAL variable.
Oh, and yes, this works in the Role Tailored Client as well.
Huh... I implemented the same thing over a year ago, but I didn't use the single instace... I stored it in an array with Report ID, datetime...
Then on CompanyClose(), LoginEnd() [making sure] OnGlobalModify() I dumped the contents of the Array into a table and reset it all for next time.
In that case the solution will not work.
On the other hand, the solution is created for determining the value of ad-hoc reports. As you might know, a lot of customers have reports that are one created and never used. People leave the company and new people start, you know how it goes.
When you want to determine if a report can be overwritten the default procedure is to look in the usage table first and if not used, then renumber to a number that is outside the customers license. If it breaks or is nessesairy to use anyway you can easily put it back.
I know it is not a 100% covering solution but it helps.
Thank you for you feedback.
Hi Marq, great tip. I am using 4.0, and trying to implement it here. Great instructions. I did notice though that if you write:
it will not call findPrinter. ie if you say systemPrinter = TRUE it will not try to find a printer... any suggestions?
Yes, it works for preview.
No it does not work for processing only reports.
Does this work for processing only reports as well and for reports that only generate preview?
No problem. I might give you a call next couple of weeks. I am working on a new project where I can use your input.
Then we are even again. ;)
Thanks for the tip
Sure, we haven't moved :)
I think it's good that people make time to publish useful tips ... I mean, I feel a bit guilty that I haven't spend much time doing just that.
Good to hear Fred.
Can I send the invoice to the normal address?
Thanks! Very useful, we'll implement this immediately.
Very cool trick, up until this point I had always gone with adding code to each report which is tedious to say the least. I just wish the Navision folks would add a couple of methods to codeunit 1, like PreReportExecute and PostReportExecute, that if they existed would be called before and after running. For that matter, it would be nice to have for other objects as well. I suppose I might as well wish for a million dollars while I'm at it though.
Yes, I do. I don't like the RTM version very much...
Great :-) I assume you are using SP1?
You're welcome. ;)