Section Reports - Scripting in Report Designer - Preview errors

Posted by: mlk20 on 18 March 2018, 8:41 pm EST

  • Posted 18 March 2018, 8:41 pm EST

    Hi,

    I would like to use scripting in my Section Report.

    I know how to write “simple scripts” and it works correctly in both Report Designer and in Report Preview when the report is generated.

    I also know how to write “complex scripts” which use external libraries that are added to the script compilation engine via sectionReport.AddScriptReference() method and it works correctly in Report Preview when the report is generated.

    However I also need the “complex scripts” work in Report Designer… but I cannot figure it out how to add script references. No matter what I do (I also tried to use .NET Reflection to add script reference to some private SectionReport instances inside GrapeCity assemblies)… I always get the following error when I switch to “Preview” Tab in Report Designer:

    Exception details:

    GrapeCity.ActiveReports.ReportScriptException: Report Script Compile Error on line 3:

    The name ‘SomeClassName’ does not exist in the current context

    at GrapeCity.ActiveReports.DDScripting.#NOn(String source, CompilerResults results, Nullable
    1 globalcodeline, Nullable
    1 namedItemLine, IList`1 expressionLineList)

    at GrapeCity.ActiveReports.DDScripting.#Vzb()

    at GrapeCity.ActiveReports.DDScripting.#Szb(String methodName, Object parameters, Boolean& success)

    at GrapeCity.ActiveReports.SectionReport.#izb()

    at GrapeCity.ActiveReports.SectionReport.#1yb(Boolean bDelayedInit)

    at GrapeCity.ActiveReports.SectionReport.Run(Boolean syncDocument)

    at GrapeCity.ActiveReports.SectionReport.Run()

    at GrapeCity.ActiveReports.Viewer.Win.Rpx.RpxReport.LoadDocument(SectionDocument document)

    at GrapeCity.ActiveReports.Viewer.Win.Rdf.RdfDocumentReportBase.<>c__DisplayClass1a.#jNI()

    at GrapeCity.ActiveReports.Viewer.Win.AsyncLoader.<>c__DisplayClass7.#cAz(Object , DoWorkEventArgs )

    at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)

    at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

    You can assume that I am using the script:

    public void Detail_Format()

    {

    this.TextBox1.Text = SomeClassName.SomeClassMethod(“some_parameter”);

    }

    I am using AR 9.2.3032.0.

    Can you please provide instruction how to achieve what I need.

    Thank you.

  • Posted 19 March 2018, 8:07 pm EST

    Hello,

    Could you please try after adding the following line in “ReportStart” event in the script section of Report;

    
    public void ActiveReport_ReportStart()
    {
    	rpt.AddScriptReference("Your DLL Name");
    
    }
    
    

    Hope it helps.

    Thanks,

    Mohit

  • Posted 19 March 2018, 11:19 pm EST

    Hi,

    How can I use “Scripts” to add missing dlls (to fix unsuccessful compilation) if the script cannot be RUN because it DOES NOT compile successfully - what you wrote is illogical.

    Have you tested this solution before suggesting it?

    Thank you.

  • Posted 20 March 2018, 12:47 am EST

    Hello,

    It is the blunder mistake which has done at my end. I had seen the output the of the other report. I am extremely sorry for the confusion. I am working on it and will update you once I get any solution for the same.

    Thanks for patience.

    Regards,

    Mohit

  • Posted 20 March 2018, 9:11 pm EST

    Hello,

    This is the limitation of the EUD. The preview tab of the Designer will not make a complete run of a report. It is mainly meant to make quick layout checks for a report’s design. Since the report is not processed in the same way as performing a full run, some features will not work properly, like the AddScriptReference method.

    What I would recommend doing is placing the End User Designer inside of a standard .NET frame control. The first frame tab will show the designer, the second can display your script code, and the third will contain a full Viewer control. When the user switches tabs, save the report’s layout, load it into a new report object, call the AddScriptReference method. Then run the report and show it to the viewer. This ensures that the report is run completely with all features. Also, with a few minor changes, you can make the tabs look exactly like that of the standard End User Designer control.

    Hope it helps.

    Thanks,

    Mohit

  • Posted 20 March 2018, 10:47 pm EST

    Hi,

    What does it mean that preview tab of the Designer will not make a complete run of a report? Will it make a half run? a quarter run? or maybe a 1% run?

    It is not professional to answer “this is a limitation of our product…” for most of the questions that do not have a good explanation why something does not work.

    I inspected the code and it seems that in the method:

    ActiveReports.ReportDesignerMain.DesignerTabControllerSelectionChanged()

    ActveReports are performing instructions like:

    				Type type = null;
    				ITypeResolutionService typeResolutionService = this._designerHost.GetService(typeof(ITypeResolutionService)) as ITypeResolutionService;
    				if (typeResolutionService != null)
    				{
    					type = typeResolutionService.GetType(this._designerHost.RootComponentClassName);
    				}
    				if (type == null)
    				{
    					type = Type.GetType(this._designerHost.RootComponentClassName);
    				}
    				if (type != null)
    				{
    					this._appDomainSetup = new AppDomainSetup();
    					string directoryName = Path.GetDirectoryName(type.Assembly.Location);
    					if (!string.IsNullOrEmpty(directoryName))
    					{
    						if (flag)
    						{
    							int num = directoryName.LastIndexOf("_shadow");
    							string text = directoryName;
    							if (num > -1)
    							{
    								text = directoryName.Substring(0, num + 7);
    							}
    							this._appDomainSetup.ApplicationBase = (this._appDomainSetup.PrivateBinPath = text);
    							this._appDomainSetup.PrivateBinPathProbe = text;
    						}
    						else
    						{
    							this._appDomainSetup.ApplicationBase = (this._appDomainSetup.PrivateBinPathProbe = (this._appDomainSetup.PrivateBinPath = directoryName));
    							this._appDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
    						}
    						if (this._tempAppDomain != null)
    						{
    							AppDomain.Unload(this._tempAppDomain);
    							this._tempAppDomain = null;
    						}
    						this._tempAppDomain = AppDomain.CreateDomain("TempAppDomain", null, this._appDomainSetup);
    						if (this._tempAppDomain != null)
    						{
    							object obj = this._tempAppDomain.CreateInstanceFromAndUnwrap(type.Assembly.Location, type.FullName);
    							if (obj is SectionReport)
    							{
    								this._previewReport = (obj as SectionReport);
    								this._previewReport.MaxPages = (long)Globals.PreviewPages;
    								this._previewReport.Run(true);
    								this.LoadReportIntoViewer(this._previewReport.Document);
    							}
    						}
    					}
    				}
    				else if (flag2)
    				{
    					string message = string.Format(CommonResources.FailedToLoadType, this._designerHost.RootComponentClassName);
    					this._viewer.HandleError(new Exception(message));
    				}
    				else
    				{
    					SectionReport sectionReport2 = (SectionReport)this._designerHost.RootComponent;
    					this._previewReport = (SectionReport)((ICloneable)sectionReport2).Clone();
    					this._previewReport.MaxPages = (long)Globals.PreviewPages;
    					this.LoadReportIntoViewer(this._previewReport);
    				}
    

    so no matter which path the program control follows you are creating some local instance of a SectionReport without properly handling of added script references…

    I can understand that you need to create a separate instance of a SectionReport - not to affect the SectionReport instance that is referenced by the End User Designer.

    I can understand that you may want to create a separate AppDomain to separate the report viewing from the report design.

    But…

    I cannot accept that you say that you do not do a complete report run - You invoke the Run() method for sure, and the invocation of Run() method contains the routines that compile and runs scripts!

    I cannot accept that you don’t maintain script references (added via AddScriptReference() method) that are part of SectionReport instance (I can find them without any problems in sectionReport.#n private field).

    This is also strange why the Clone method of a SectionReport type does not copy added script references. It looks like another negligence of support for the AddScriptReference() feature.

    	object ICloneable.#od()
    	{
    		SectionReport sectionReport = new SectionReport();
    		object result;
    		using (MemoryStream memoryStream = new MemoryStream())
    		{
    			bool isDirty = this.IsDirty;
    			try
    			{
    				this.SaveLayout(memoryStream);
    			}
    			finally
    			{
    				this.IsDirty = isDirty;
    			}
    			sectionReport.#qb.AddRange(this.#qb);
    			if (this.#m != null)
    			{
    				foreach (KeyValuePair<string, object> current in this.#m)
    				{
    					sectionReport.AddNamedItem(current.Key, current.Value);
    				}
    			}
    			memoryStream.Position = 0L;
    			sectionReport.LoadLayout(memoryStream);
    			sectionReport.DataSource = this.DataSource;
    			sectionReport.DataMember = this.DataMember;
    			sectionReport.EnableScriptDebugging = this.EnableScriptDebugging;
    			result = sectionReport;
    		}
    		return result;
    	}
    

    You have all the data that is needed in place (in sectionReport.#n private field) - you just need to use it (copy to the local instance of a report)!

    Please forward this information to the proper developers so they can review it and answer.

    Thank you.

  • Posted 20 March 2018, 10:54 pm EST

    Hello,

    I have escalated your concern to our developer team and will reply once I get any information from them.

    Thanks,

    Mohit

  • Posted 21 March 2018, 12:02 am EST

    Hello ,

    i suppose that notice about half-running report relates to the old version of product where Designer control has used the single instance of the report object for preview and design.

    for example if you call MyReport.Run() twice, the DataInitialize event will fire only once.

    moreover if controls sizes are changed, the changes are not reverted back after ReportEnd event.

    it is a reason for using of the cloned report for preview now.

    the Report property of Designer control is not supposed for manipulations in the report already loaded to the designer. we keep it for the backward compatibility of API.

    and i would like to say the serialization of the report layout does not include the custom references added by AddScriptReference method, so the cloning of the references is out of the common use case because they anyway can not be saved with the report.

    i think the custom preview UI looks like an acceptable workaround here.

    Thanks,

    Sergey Romanov.

  • Posted 21 March 2018, 5:58 pm EST

    Sergey,

    I don’t question the need of creation of cloned report in order to not affect the report that is loaded into Designer. This is a good approach, but why don’t you copy script referencess too? I believe you can copy it and the report preview in EUD will start to work in a way I expect it. Can’t you try it?

    As for the serialization issue, I can live with that. There are “places” in the SectionReport document (like e.g. Tag property) where I can store my script references with little effort. However, saying that “cloning of the references is out of the common use case” is odd. If it is not a common use case then it is enough to add a null-check to see that the collection is null and you don’t have to do any copying (so such a code should not affect the performance of the product etc…), but if somebody wants to use the api that Active Reports provide (AddScriptReference() method) then you should support it…

    Even if we may argue if such copying is needed in all the places within the libraries, it should not be a problem to add it for a single method that handles report preview in EUD, should it?

    Creating custom preview becuase of such a small reason, taking into consideration that it can be fixed with a few lines of code inside Active Reports library is NOT an acceptable workaround. I am not working with a brand new EUD but the EUD in our application is exteded with dozen of features so making the changes you propose is not an option for us.

    Please try the solution that I provided. If you are affraid to introduce such changes in your library, then you can of course add some option/switch/property that can be turned off by default to have a full bakward compatibility.

    Thank you.

  • Posted 21 March 2018, 10:15 pm EST

    Hello ,

    the main goal of the designer control is to allow the end users to make the changes in a layout via UI. the file with layout can’t store the custom references, so in the common use case, additional references are not loaded to the designer, therefore the cloning of these references, for preview, does not make sense.

    please note the request opened by Mohit for the changes you requested is still under review, however, the target product is ActiveReports 12.

    Thanks,

    Sergey Romanov.

  • Posted 22 March 2018, 8:46 pm EST

    Hello ,

    i have got the good news. the developer team already added this feature to ActiveReports 12 for internal purposes, so your scenario should work without errors after upgrade.

    Thanks,

    Sergey Romanov.

  • Posted 23 March 2018, 12:20 am EST

    Hi,

    Which exact version was this fixed in?

    And what fixed mean? Can I add script reference to the report instance that is loaded into EUD and these script references will be correctly handled on report preview tab in EUD?

    Can you add this fix to AR 11 too? I am not sure which version we will use for the very next AR upgrade…

    Thank you.

  • Posted 23 March 2018, 7:23 pm EST

    Hello ,

    there is a hotfix for ActiveReports 12 and in the next 2 weeks we will release SP1 for v12 with the same fix. in the meantime, development of ActiveReports 11 is almost finished, the final service pack is already prepared for the pre-release tests.

    i have added “(reportDesigner.Report as SectionReport).AddScriptReference(Application.StartupPath + “\clsTest.dll”);” for LoadReport action in LayoutChanged event handler of Designer and used the value of static field from clsTest in the script to change the data in TextBox. the preview shows the changed text without errors.

    Thanks,

    Sergey Romanov.

  • Posted 6 June 2019, 7:22 pm EST

    Can you please confirm the final version this bug was fixed in?

  • Posted 9 June 2019, 9:04 pm EST

    Hello,

    This bug fixed in the latest version of both AR13 and AR12. You can do the following steps;

    1: Create the custom assembly with strong name and register it to GAC

    2: Create a new sample with section report(XML based)

    3: Add report designer to form

    4:Add your code in Script section of the report like as follow:

    public void detail_Format() 
    { 
    ClassLibrary1.Class1 test = new ClassLibrary1.Class1(); 
    this.textBox1.Text = test.s; 
    } 
    
    

    5:Add the following code in “Form_Load” event

    
        SectionReport rpt = new SectionReport(); 
                System.Xml.XmlTextReader xtr = new System.Xml.XmlTextReader(@"..\..\SectionReport2.rpx"); 
                rpt.LoadLayout(xtr); 
                xtr.Close(); 
                rpt.AddScriptReference(@"C:\Users\mohitg\Documents\Visual Studio 2017\Projects\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll"); 
               designer1.Report = rpt; 
    
    

    6: Run the sample

    Hope it helps.

    Thanks.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels