none
Concurrent report manipulation / Report contains data of two requests RRS feed

  • Question

  • Hello all of you out there!

    I am currently experiencing a really frustrating problem, since i can't even figure out what the problem really is. As an additional information: We are still using Reporting Services 2005 and can't switch to 2008 yet, due to it's requirement of .NET 3.5 and generally our customer would need a new license again, additional costs etc.

    Okay let the story begin..

    I have one report, which represents an order offer. So that whenever a customer calls and wants to order some things, an order is begin created within our software and after all information got added, the software has the ability to print an offer paper, which will then be send to the ordering customer. So far so good.

    The Report:
    Due to the fact, that data from the database can not be placed on the header of a report, i made several hidden textboxes and placed them almost at the top of the body. Due to the fact that i have a special header, which changes its layout beginning with the second page. I needed to think of a mechanism, with which it is possible to control that. However, after some further recoding due to other occured problems i finally came out in defining a couple of VB variables in the code section of the report. Those are declared as shared strings. Furthermore, i have two kinds of methods which access one variable to set its value or return its value (Getters and Setters). All i am doing in the setters is that i check if the page number is 1, if so the value gets stored in the variable and if not it will be left at it is. I  had to do this that way, since i had to remove the saving of those variables in textboxes within my order item table. I had note field before the table which could become very big and so place the table on the second of even third page, which resulted in the first and second page not having any information in the header.

    The Problem:
    Okay however, right now i have the following problem.

    Scenario:
    User1 has an instance of our software, opened and running.
    User2 has an instance of our software, opened and running.

    Both will open a random order within the software, it doesnt matter which.
    Both will press a button which shows the report for the order in a ReportViewerControl AT THE SAME TIME.
    After both ReportViewerControls opened and anyone tries to print the report, whereas it doesnt matter if there is a huge time period between both print jobs, the resulting report looks good on the screen, but cames out very different and contains data of BOTH orders. So its weather the reporting services / report viewer control or my decent knowledge about VB and how the RS2005 Server is handling it. Here is the vb code:

    'Saved variables
    Public Shared CustomerData As String = ""
    Public Shared CustomerPhone As String = ""
    Public Shared CustomerFax As String = ""
    
    Public Function SetCustomerData(ByVal Value As String)
    	If Me.Report.Globals!PageNumber = 1 Then
    		CustomerData = Value
    	End If
    End Function
    
    Public Function GetCustomerData() As String
    	Return CustomerData
    End Function
    
    
    Public Function SetCustomerPhone(ByVal Value As String)
    	If Me.Report.Globals!PageNumber = 1 Then
    		CustomerPhone = Value
    	End If
    End Function
    
    Public Function GetCustomerPhone() As String
    	Return CustomerPhone
    End Function
    
    
    Public Function SetCustomerFax(ByVal Value As String)
    	If Me.Report.Globals!PageNumber = 1 Then
    		CustomerFax = Value
    	End If
    End Function
    
    Public Function GetCustomerFax() As String
    	Return CustomerFax
    End Function
    

    Within the hidden textboxes, i am executing the Set methods like this:

    = Code.SetCustomerPhone(First(Fields!CustomerTel.Value, "Offer"))

    To prevent overriding the variables later, all variables are just set on the first page, which is enough.

    After someone pressed the print button now, an event gets rised and my printer class start to do the job. Within the event method i am getting the ServerReport of the control and so i am once again rendering the report (this is the place something must fail since its all good on the screen!) and sending it to the printer. Here is the code:

    		private void OnPrintReport(object sender, CancelEventArgs e)
    		{
    			ReportViewer rv = sender as ReportViewer;
    
    			if (rv == null)
    				return;
    
    			PrintReport(rv.ServerReport);
    
    			e.Cancel = true;
    		}
    							   ButAskForSettings, The server report 	   , null		  , Guid.Empty		   , null) 
    		private bool PrintReport(Print printType, ServerReport serverReport, Report report, Guid fkOrganisation, params string[] parameters)
    		{
    			if (serverReport == null && report == null)
    				return false;
    
    			if (parameters != null && parameters.Length % 2 > 0)
    				throw new Exception(String.Format(rmReportingLogic.ParameterangabeFehler, report.ReportServerUrl, report.ReportPath, report.ReportType));
    
    			bool serverReportAvailable = null != serverReport;
    
    			switch(printType)
    			{
    				case Print.ButAskForSettings:
    				case Print.WithDefaultSettings:
                    case Print.WithDefaultSettingsAndPrinterName:
    				{
    					if (serverReportAvailable)
    					{
    						RenderedReport = RenderReport(serverReport);
    					}
    					else
    					{
    						if (!IsUrlAvailable(report.ReportServerUrl))
    						{
    							return false;
    						}
    
    						// Setzen von Server cred/url
    						if (!report.ReportServerUrl.EndsWith("/ReportService.asmx"))
    						{
    							_ReportService.Url = report.ReportServerUrl + @"/ReportService.asmx";
    						}
    						else _ReportService.Url = report.ReportServerUrl;
    
    						ParameterValue[] parameterValues = new ParameterValue[parameters.Length / 2 + 1];
    
    						for (int i = 0; i < parameterValues.Length - 1; i++)
    						{
    							parameterValues[i] = new ParameterValue();
    							parameterValues[i].Name = parameters[2 * i];
    							parameterValues[i].Value = parameters[2 * i + 1];
    						}
    
    						ReportingServices.ReportParameter[] reportParameters;
    						string historyID = null;
    						bool forRendering = true;
    						ParameterValue[] values = null;
    						ReportingServices.DataSourceCredentials[] credentials = null;
    
    						reportParameters = _ReportService.GetReportParameters(report.ReportPath, historyID, forRendering, values, credentials);
    
    						foreach (ReportingServices.ReportParameter reportParameter in reportParameters)
    						{
    							if (reportParameter.Name == "Organisation")
    							{
    								parameterValues[parameterValues.Length - 1] = new ParameterValue();
    								parameterValues[parameterValues.Length - 1].Name = "Organisation";
    								parameterValues[parameterValues.Length - 1].Value = fkOrganisation.ToString();
    							}
    						}
    
    						RenderedReport = RenderReport(report, parameterValues);
    					}
    					
    
    					try
    					{
    						if (_NumberOfPages < 1)
    							return false;
    
    						if (printType == Print.WithDefaultSettings)
    						{
    							... // not relevant
                            }
                            else if (printType == Print.WithDefaultSettingsAndPrinterName)
                            {
                                ... // not relevant
                            }
    						else if (printType == Print.ButAskForSettings)
    						{
    							// USED WHEN SOMEONE PRESSED THE PRINT BUTTON ON THE REPORTVIEWERCONTROL IN ORDER TO PRINT THE REPORT
    						
    							PrintDialog printDialog = new PrintDialog();
    							printDialog.AllowSomePages = true;
    							printDialog.AllowCurrentPage = true;
    							printDialog.AllowPrintToFile = true;
    							printDialog.UseEXDialog = true;
    							printDialog.PrinterSettings.MaximumPage = _NumberOfPages;
    							printDialog.PrinterSettings.MinimumPage = 1;
    							printDialog.PrinterSettings.PrintRange = PrintRange.SomePages;
    							printDialog.PrinterSettings.FromPage = 1;
    							printDialog.PrinterSettings.ToPage = _NumberOfPages;
    
    							if (printDialog.ShowDialog() == DialogResult.OK)
    							{
    								PrintDocument pd = new PrintDocument();
    								pd.OriginAtMargins = true;
    
    								if (serverReportAvailable)
    								{
    									pd.DocumentName = serverReport.DisplayName;
    								}
    								else
    								{
    									pd.DocumentName = report.ReportName;
    								}
    								
    								_CurrentPrintingPage = printDialog.PrinterSettings.FromPage;
    								_LastPrintingPage = printDialog.PrinterSettings.ToPage;
    								pd.PrinterSettings = printDialog.PrinterSettings;
    								_PrinterSettings = printDialog.PrinterSettings;
    								pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
    								pd.PrintPage += PrintPage;
    								pd.Print();
    							}
    						}
    					}
    					catch (Exception ex)
    					{
    						Console.WriteLine(ex.Message);
    					}
    					break;
    				}
    				case Print.WithPreview:
    				{
    					// USED WHEN THE REPORT IS SHOWN IN AN INSTANCE OF THE REPORTVIEWERCONTROL
    				
    					Form form = new Form();
    					form.Text = report.ReportName;
    
    					ReportViewer rv = new ReportViewer();
    
    					rv.ShowBackButton = false;
    					rv.ShowContextMenu = false;
    					rv.ShowCredentialPrompts = false;
    					rv.ShowDocumentMapButton = false;
    					rv.ShowExportButton = true;
    					rv.ShowFindControls = true;
    					rv.ShowPageNavigationControls = true;
    					rv.ShowParameterPrompts = false;
    					rv.ShowPrintButton = true;
    					rv.ShowProgress = true;
    					rv.ShowPromptAreaButton = false;
    					rv.ShowRefreshButton = true;
    					rv.ShowStopButton = true;
    					rv.ShowToolBar = true;
    					rv.ShowZoomControl = true;
    
    					rv.Print += OnPrintReport;
    
    					rv.ServerReport.ReportPath = report.ReportPath;
    					rv.ServerReport.ReportServerUrl = new Uri(report.ReportServerUrl);
    					rv.ServerReport.DisplayName = report.ReportName;
    					rv.ProcessingMode = ProcessingMode.Remote;
    					rv.SetDisplayMode(report.DisplayMode);
    
                        if (report.DisplayMode == DisplayMode.PrintLayout)
                        {
                            rv.ZoomMode = ZoomMode.Percent;
                            rv.ZoomPercent = 100;
                        }
    
    					List<ReportParameter> param = new List<ReportParameter>();
    
    					for (int i = 0; i < parameters.Length / 2; i++)
    					{
    						param.Add(new ReportParameter(parameters[2 * i], parameters[2 * i + 1]));
    					}
    
                        ReportParameterInfoCollection paramCol = rv.ServerReport.GetParameters();
                        for (int i = 0; i < paramCol.Count; i++)
                        {
                            if (paramCol[i].Name == "Organisation")
                            {
                                param.Add(new ReportParameter("Organisation", Benutzer.FKOrganisation.ToString()));
                            }
                        }
    
                        rv.ServerReport.SetParameters(param);
    					rv.Dock = DockStyle.Fill;
    					rv.RefreshReport();
    
    					form.Controls.Add(rv);
    					form.Size = new Size(800, 600);
    					form.Show();
    					break;
    				}
    			}
    
    			return true;	
    		}
    		
    				private void PrintPage(object sender, PrintPageEventArgs e)
    		{
    			e.HasMorePages = false;
    			if (_CurrentPrintingPage <= _LastPrintingPage && MoveToPage(_CurrentPrintingPage))
    			{
    				// Draw the page
    				ReportDrawPage(e);
    				// If the next page is less than or equal to the last page, 
    				// print another page.
    				if (++_CurrentPrintingPage <= _LastPrintingPage)
    					e.HasMorePages = true;
    			}
    		}
    
    		private void ReportDrawPage(PrintPageEventArgs e)
    		{
    			if (null == _CurrentPageStream || 0 == _CurrentPageStream.Length || null == _Metafile)
    				return;
    			lock (this)
    			{
    				// Set the metafile delegate.
    				_Delegate = MetafileCallback;
    
    				// Zeichnen des Rechtecks
    				Rectangle adjustedRect = new Rectangle(
    					e.PageBounds.Left, 
    					e.PageBounds.Top, 
    					e.PageBounds.Width, 
    					e.PageBounds.Height);
    
    				if (e.PageBounds.Width > e.PageBounds.Height)
    				{
    					// Landscape
    				}
    				else
    				{
    					// Portrait
    				}
    
    				e.Graphics.EnumerateMetafile(_Metafile, adjustedRect, _Delegate);
    
    				// Clean up
    				_Delegate = null;
    			}
    		}
    		private bool MetafileCallback(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData) 
    		{
    			byte[] dataArray = null;
    			// Dance around unmanaged code.
    			if (data != IntPtr.Zero)
    			{
    				// Copy the unmanaged record to a managed byte buffer 
    				// that can be used by PlayRecord.
    				dataArray = new byte[dataSize];
    				Marshal.Copy(data, dataArray, 0, dataSize);
    			}
    			// play the record.      
    			_Metafile.PlayRecord(recordType, flags, dataSize, dataArray);
    
    			return true;
    		}
    
    		private bool MoveToPage(Int32 page)
    		{
    			// Check to make sure that the current page exists in
    			// the array list
    			if (null == RenderedReport[_CurrentPrintingPage - 1])
    				return false;
    			// Set current page stream equal to the rendered page
    			_CurrentPageStream = new MemoryStream(RenderedReport[_CurrentPrintingPage - 1]);
    			// Set its postion to start.
    			_CurrentPageStream.Position = 0;
    			// Initialize the metafile
    			if (null != _Metafile)
    			{
    				_Metafile.Dispose();
    				_Metafile = null;
    			}
    			// Load the metafile image for this page
    			_Metafile = new Metafile(_CurrentPageStream);
    			return true;
    		}
    
    		public byte[][] RenderedReport
    		{
    			get
    			{
    				return _RenderedReport;
    			}
    			set
    			{
    				_RenderedReport = value;
    			}
    		}
    

    So long, i hope someone can help maybe!
    Monday, October 12, 2009 10:27 AM