SingleInstance and Variables

I’ve read the help text on the CodeUnit Property called “SingleInstance” which says : SingleInstance When you set this property to Yes on codeunit X, all codeunit variables that use codeunit X will use the same instance. That is, all codeunit variables of codeunit X will use the same set of internal variables when the code is running on the same client. Codeunit X remains instantiated until you close the company. _____________________ Here’s the problem: I have a report I’d like to “sometimes” print as a PDF file. I can’t use PrinterSelection table because it’s not determined by user, company, report, or location. But if the report is called by a specific report, then - and then only - I want to print it as a PDF file. In CU 1 ApplicationManagement (which is SingleInstance) I added the following function: SetPDFPrint(VAR ReportID : Integer) PDFUser := USERID; PDFReportID := ReportID; The two variables, since this is a SINGLEINSTANCE codeunit, should continue to hold the values I give them in the call until I reset them, correct[?] In my report, I do the following: ApplicationManagement.SetPDFPrint(ReportNo); REPORT.RUN(ReportNo); ApplicationManagement.ClearPDFPrint; What I was thinking is that the call to SetPDFPrint would set the variables to print to PDF, then I’d call the report and when it ran CU 1 PrinterSelection, it would process the following code print to printerselection table code: IF (PDFReportID = ReportID) AND (PDFUser = USERID) THEN BEGIN EXIT(‘PDFDriver’); // my pdf file printer END; What I’m seeing in debug is when this code is processed is that my two variables, PDFReportID and PDFUser are BLANK! Not set! SingleInstance[?] say what[?][:(][?] please help. [B)]

OK, starting with the obvious, PDFUser and PDFReportID are global right?

YES! (and thanks for helping!) Name DataType Subtype Length PDFReportID Integer PDFUser Code 20

I was actually working on something similar these days and tried the same approach as you, creating a new function in C1, assuming that C1 is SingleInstance but reviewing the properties of C1 it’s not! (at least in standard Navision 3.70B and 4.00) So I created a new codeunit, set the SingelInstance property to Yes and voila… it works. From your report you call that new codeunit, set a variable, and in the FindPrinter Function in C1 you call a function that retrieves that variable within the new codeunit… that’s all. Saludos Nils

Codeunit 1 is not a single instance codeunit, it runs once for each session when Navision starts. You should create your own single instance codeunit and start it from CU1 from the LoginStart function or something like that.

I know CU 1 doesn’t "act " like a single instance codeunit, and maybe this is just something we’ve done in “our version” but, it’s set to single instance. I am trying Nils’ approach, and will let you know how it works. Thanks.

Nils - CONGRATS! You are my hero for the day. [:)] With my own single instance codeunit it worked just fine. The parm was passed back and PDF Printing is possible! So, even though I don’t understand why the SingleInstance property of CU 1 is null and void, at least I have a solution. [:)][:P][:)] Your help is much appreciated!

Thanks a lot for the flowers (that’s a german saying…), glad I was able to help… [8D]


So, even though I don’t understand why the SingleInstance property of CU 1 is null and void

Well, let’s put it the other way around… why should it be single instance? There is actually no reason for that, as codeunit 1 doesn’t hold any variables that should maintain their value while the users has Navision open… Saludos Nils

OOOPs! Looks like I smiled too soon. When I run the code to select the printer in CU 1, I’m getting the following error: The code in CU 1 is as follows: It gives the error in debug when it hits the BEGIN. PDFYesNo is true, and is coded as a global boolean in both CU1 and the DSISI codeunit. What gives? [B)] Help, please…[:(]

I can’t see your screenshots… looks like that they don’t get uploaded correctly as the path points to your local drive…“C:\Documents and Settings\lan1161\My Doc…” Rather post the error message… Saludos Nils

oops…looks fine from here…but then it would, wouldn’t it [:0)][Duh!] The error says “The expression Text cannot be type-converted to an integer value.” My code is as follows: DSISI.GetPDFSettings(PDFYesNo); IF PDFYesNo = TRUE THEN BEGIN (((error occurs here))) PrinterSelection.GET(‘PDF’,’’,’’); EXIT(PrinterSelection.“Printer Name”); END; Again, thanks for your help Nils.

I assume you modified the primery key of T78 Printer Selection to include an option type field as the first field… obviously using ‘PDF’ as the first parameter causes an error as the first primary key field is option, and not a text… try using something like this: PrinterSelection.GET(PrinterSelection.PrinterType::PDF,’’,’’); Saludos Nils

Well, now that’s a nice clean approach. Of course, I didn’t use it. [:D] What I did was add a user login “PDF”, and inserted one record with UserID:PDF, and the printer name. The key to the table here is: User ID,Location,Report ID - so I’m simply omitting all other fields from the key. But - the error occurs prior to this statement even being processed - It seems to occur on the “IF PDFYesNo = TRUE THEN” statement, since debug always errors out on the line following your true error code.

Looks like I did not finish to read properly the whole statement …[Oops!] Actually the error does lie in the GET parameters… but it’s not the first field, but the third one… Report ID is an integer field, therefore: PrinterSelection.GET(‘PDF’,’’,0);

Awe…geez! Wouldn’t you know it would be something silly like that! [:I] Thanks Nils. I should have caught that! Heck, the code right below even had zeros for the parm! [xx(] So now it runs…but I get no PDF file. It does use the PDF printer… I guess. I mean it’s picking it from the FindPrinter function of CU 1 like a charm, and exiting with it. But, I can’t find a file created anywhere. This really should not be this complicated. The code within the report is as follows: SalesShipmentHeader.SETRECFILTER; PDFPrint := TRUE; DSISI.PDFPrint(PDFPrint); REPORT.RUNMODAL(ReportNo,FALSE,FALSE,SalesShipmentHeader); PDFPrint := FALSE; DSISI.PDFPrint(PDFPrint); When the REPORT.RUNMODAL is processed, it successfully goes into CU1 FindPrinter, processes the code we’ve worked on, and gets the Adobe PDF printer, and exits with it. How can I determine what’s going on after that? Sorry this is dragging on…I know you didn’t intend to make this your life’s work! [8D] …more flowers.

Well, found a problem in my code…I wasn’t refering the Printer Selection Name to the Printer table. Once I added that, it does try to send it through the Adobe PDF Printer - which I can see in the printer status window. However, it’s still not writing it where my email software is looking. Any idea how I could pass the path to save the file to it? Thanks. [8D]

… hm, that’s a difficult one. Actually I don’t know Adobe Pdf Printer in that detail, I guess there must be some solution to that one, either a character string that get’s picked up by the pdf printer, or some option that you might set before printing with some automation variable(?)… We have been using maxx pdfmailer for creating and sending pdf files recently, a nice feature is you don’t have so save the pdf, but instead create the mail directly with the attachment - don’t know if this might be a solution for you… otherwise you’ll have to dig through the adobe pdf printer documentation to find a way to pass that file location & name parameter…