So I really need to prevent users from opening one of our custom NAV2016 pages more than once.
The page is in direct communications with a PLC controller and if it's opened (by accident) more than once causes issues.
If you open (for example) the General Journal multiple times it looks like this in the Task Manager:
Using the DotNet variables I am able to detect the Microsoft.Dynamics.Nav.Client, but I am unable to see each of the 7 processes to detect that the General Journal - CORR-Correction is opened 6 times.
Code:
Process := Process.GetCurrentProcess;
MySession := Process.SessionId;
MyProcessList := process.GetProcessesByName('Microsoft.Dynamics.Nav.Client');
lfile.TEXTMODE := TRUE;
lFile.WRITEMODE := TRUE;
lFile.CREATE('TestOutput.txt');
FOR I:=0 TO (MyProcessList.Length()-1) DO
BEGIN
Process := MyProcessList.GetValue(I);
IF MySession = Process.SessionId THEN
lFile.write('Process ID: ' + FORMAT(Process.Id) + ' MainWindowTitle: ' + Process.MainWindowTitle + ' Process: ' + Process.ToString);
END;
lFile.CLOSE;
Output File:
Process ID: 6764 MainWindowTitle: Edit - General Journal - CORR-Correction Process: System.Diagnostics.Process (Microsoft.Dynamics.Nav.Client)
Now it appears as though it has returned the correct result, but all it has done is returned the first page.. If I opened the Item Card and ran my routine I'd see the Item Card and not the other 7 pages running the General Journal.
Anyone have any luck returning the grouped processes?
Thanks in advance,
John
Answers
Sorry if I understand it wrong way ...
xStepa
This custom page is what we use to record Production.
The page reads the PLC controllers to determine what speed the machine is processing at. If the machine goes down for a length of time the page shows the downtime duration and the user needs to enter a reason for this downtime.
So at the end of the users shift, NAV knows what Production Order was used, how much Finished Goods were made, how much raw material was consumed, Shift Length, Setup Duration, Downtime Duration, and the reasons for the Downtime/Setup.
So you can see having two of these pages open causes me grief.
Or you can use a single instance Codeunit to set a marker for the session if the page opens and remove it if it closes. Check the value before opening the page and close it when it is already open.
While I still like the first option, you can also save the open state in a table... Your choice.
Carsten
==> How To Ask Questions The Smart Way
This post is my own opinion and does not necessarily reflect the opinion or view of my employer.
** In the short-term I can use a single instance codeunit and that will at least limit half the duplicate page opens.
But you can try to use some kind of semaphore - create a table and then try something like this:
The second session will throw an error (after some time), which you can handle by TRY function (I hope) ...
xStepa
xStepa nailed the idea pretty much, not sure if GET alone without MODIFY will lock the record.
What you need is a table where you will insert a single record in OnPageOpen and delete it in OnPageClose.
Assuming that your page is based on PageSemaphore table having just one field:
in OnOpenPage in OnClosePage That's about it. the first user will open the page, insert a blank record, any subsequent attempt of opening the page will fail on INSERTing the same record.
A bit more code would be needed to handle cases when client crashes while page is open and the record does not get deleted - that can be handled by storing in the semaphore table current session unique ID (but not in the primary key), checking it in OnOpenPage in Active Sessions table and if the session still exists throwing an error, if not deleting the record and insert new one.
in OnOpenPage Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03