Wednesday, March 14, 2018

RootComponent types in solution.xml file in Dynamics CRM 365/2016


In Microsoft Dynamic CRM 2016/365 are you as confused as me when looking at the solution.xml from the solution export? looking at the xml and trying to decode what RootComponent type means what is always a painful experience. This table should simplify things and tell you what Type number relates to what component.

TypeDescription
1Entity
2Attribute
3Relationship
4Attribute Picklist Value
5Attribute Lookup Value
6View Attribute
7Localized Label
8Relationship Extra Condition
9Option Set
10Entity Relationship
11Entity Relationship Role
12Entity Relationship Relationships
13Managed Property
20Role
21Role Privilege
22Display String
23Display String Map
24Form
25Organization
26Saved Query
29Workflow
31Report
32Report Entity
33Report Category
34Report Visibility
35Attachment
36Email Template
37Contract Template
38KB Article Template
39Mail Merge Template
44Duplicate Rule
45Duplicate Rule Condition
46Entity Map
47Attribute Map
48Ribbon Command
49Ribbon Context Group
50Ribbon Customization
52Ribbon Rule
53Ribbon Tab To Command Map
55Ribbon Diff
59Saved Query Visualization
60System Form
61Web Resource
62Site Map
63Connection Role
70Field Security Profile
71Field Permission
90Plugin Type
91Plugin Assembly
92SDK Message Processing Step
93SDK Message Processing Step Image
95Service Endpoint

Friday, November 9, 2012

Improved Custom ‘Export Button’ on Crystal Reports for Visual Studio


Crystal report works great when the export feature is used to export reports to PDF and word, but the one real drawback is the ‘Export to Excel’ feature. No matter how well you in designing the crystal report, the export to excel output is always skewed. It is the way Crystal Report runtime engine maps the objects and places them in excel cells based on the (x,y) position of the original Crystal Objects in the .RPT file.
I did not like how the default export feature was working on crystal reports and also wanted new features like:
  1. More uniform export to excel feature with less dummy rows and columns and more visually appealing output.   
  2. Restrict the number of export features to only Excel, PDF and Microsoft word and remove all the unnecessary list of export options that the system provides.
  3.  Control over Export file fonts, regardless of what font the Crystal report was developed on.
  4. A friendly option in the ‘Export Successful ‘message box for users to click on a link which opens the export file for them without going to the folder where the report was exported.
  5. Fixed width of rows for uniformity.

So let’s begin the process on steps:

Step 1: Assumptions
  • You are using Visual Studio 2005 or higher.
  • Crystal Report viewer is hosted in a windows form ‘ReportViewer.cs’
  • The example is for the report being exported to excel but it can be used for export to other formats

Step 2: Load data to the report via XML or Memory Stream
 private ReportDocument myReport = null;  
 private void ReportViewer_Load(object sender, EventArgs e)   
 {  
    myReport = new ReportDocument();  
    myData = new DataSet();  
    try   
    {  
      switch (_inputType)   
      {  
         case DataInputType.ByteArray:  
            myData.ReadXml(new System.IO.MemoryStream(_reportData));  
            break;  
         case DataInputType.MemoryStream:  
            stream.Seek(0, SeekOrigin.Begin);  
            myData.ReadXml(_stream);  
            break;  
      }  
      //Load RPT file  
      myReport.Load(reportPath + _RPTName);  
      myReport.SetDataSource(myData);  
      crystalReportViewer1.ShowFirstPage();  
      crystalReportViewer1.ShowGroupTreeButton = true;  
      crystalReportViewer1.ReportSource = myReport;  
    }  
   catch (Exception ex)   
    {  
        ErrorHandler.PublishError(false, "Error displaying report.", ex, true, true);  
    }  
 }  
Step 3: Hide the default export button and add our custom clone on the same place
 //Loop through all the controls in the crystal viewer, Strip the default export button and put a custom export button, Items [0] being the first button which happens to be the export button.  
       
 foreach (Control control in crystalReportViewer1.Controls)   
 {  
    if (control is System.Windows.Forms.ToolStrip)  
    {  
      //Remove Default Export Button, items[0]  
      ToolStripItem tsOriginalItem = ((ToolStrip) control).Items [0];  
      ((ToolStrip) control).Items.RemoveAt(0);  
   
       //Add a clone of Custom Button  
       ToolStripItem tsNewItem = ((ToolStrip) control).Items.Add("");  
        
      //Give this button the same tag,image and tooltip text so it looks and smells like the default export button  
      tsNewItem.ToolTipText = tsOriginalItem.ToolTipText;  
      tsNewItem.Tag = tsOriginalItem.Tag;  
      tsNewItem.Image = tsOriginalItem.Image;  
   
      ((ToolStrip) control).Items.Insert(0, tsNewItem);  
          
      //Write new click event for the new export button  
      tsNewItem.Click += new EventHandler(tsNewItem_Click);  
    }  
 }  
   
Step 4: Define your own custom save file dialogue window when the export button in step 3 is clicked.
 private void tsNewItem_Click(object sender, EventArgs e)   
 {  
       Form messageForm = new Form();  
       DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();  
       saveFileDialog = new SaveFileDialog();  
       saveFileDialog.Title = "Export Report";  
       saveFileDialog.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();  
       saveFileDialog.Filter = "Microsoft Excel (*.xls)|*.xls|Microsoft Excel (Data Only) (*.xls)|*.xls|PDF (*.pdf)|*.pdf|Microsoft Word (*.doc)|*.doc|xml (*.xml)|*.xml";  
       saveFileDialog.FilterIndex = 1;  
       if (saveFileDialog.ShowDialog() == DialogResult.OK) {  
           
       //show splash screen, for a nice look when the export is processing  
       //I have created a new class for this threaded process, which I will talk if possible in the future.  
       Thread splashthread = new Thread(SplashScreen.ShowSplashScreen);  
        splashthread.IsBackground = true;  
        splashthread.Start("Exporting Report...");  
   
        string fileName = saveFileDialog.FileName;  
        string fileFormat = fileName.Substring(fileName.Length - 4);  
   
        ExportOptions exportOpts = new ExportOptions();  
        exportOpts.ExportDestinationType = ExportDestinationType.DiskFile;  
        DiskFileDestinationOptions diskOpts = new DiskFileDestinationOptions();  
        diskOpts.DiskFileName = saveFileDialog.FileName;  
        exportOpts.ExportDestinationOptions = diskOpts;  
 }  
   
Step 5: Control formatting of the exported file based on what type of export it is
 switch (fileFormat)   
 {  
    case ".xls": //Export to Excel  
                   if(saveFileDialog.FilterIndex == 2) //Data only Export  
                    exportOpts.ExportFormatType = ExportFormatType.ExcelRecord;  
            else  
                   exportOpts.ExportFormatType = ExportFormatType.Excel;  
               
            ExcelFormatOptions exportFormatOptions = new ExcelFormatOptions();  
            exportFormatOptions.ShowGridLines = true;  
            exportFormatOptions.ConvertDateValuesToString = true;  
            exportFormatOptions.ExcelAreaType = AreaSectionKind.WholeReport;  
            exportFormatOptions.ExcelTabHasColumnHeadings = true;  
            exportFormatOptions.ExportPageBreaksForEachPage = true;  
            exportFormatOptions.ExportPageHeadersAndFooters = ExportPageAreaKind.OnEachPage;  
            exportFormatOptions.ExportPageBreaksForEachPage = false;  
            exportFormatOptions.ExportPageHeadersAndFooters = ExportPageAreaKind.OncePerReport;  
            exportOpts.ExportFormatOptions = exportFormatOptions;  
            break;  
   
    case ".pdf": //Export to PDF Document  
                   exportOpts.ExportFormatType = ExportFormatType.PortableDocFormat;  
            break;  
   
    case ".doc": //Export to Word Document  
            exportOpts.ExportFormatType = ExportFormatType.WordForWindows;  
            break;  
   
    case ".xml": //Export to XML  
           ExporttoXML(fileName);  
           exportOpts.ExportFormatType = ExportFormatType.Xml;  
           break;  
    default:  
           MessageBox.Show("Format not supported");  
           break;  
 }  
   
Step 6: Change Fonts and also make the cell on excel with fixed width 
 ReportDocument tmpReport = new ReportDocument();  
 tmpReport = myReport;  
 Font ft;  
 if (fileFormat == ".xls")   
 {  
   foreach (CrystalDecisions.CrystalReports.Engine.ReportObject myReportFieldObj in tmpReport.ReportDefinition.ReportObjects)   
   {  
     if (myReportFieldObj.Kind == ReportObjectKind.FieldObject || myReportFieldObj.Kind == ReportObjectKind.TextObject)   
     {  
      if (myReportFieldObj.Height < 200) //if the height of the control is less than 200 than fix it to 200  
         myReportFieldObj.Height = 200;  
   
         //Change the export document font to “Arial”  
      if (myReportFieldObj.Kind == ReportObjectKind.FieldObject)  
      {  
        FieldObject fobj = (FieldObject)myReportFieldObj;  
        ft = new Font("Arial", fobj.Font.Size, fobj.Font.Style, fobj.Font.Unit,  
        fobj.Font.GdiCharSet, fobj.Font.GdiVerticalFont);  
        fobj.ApplyFont(ft);  
      }  
      else if (myReportFieldObj.Kind == ReportObjectKind.TextObject)  
      {  
         TextObject fobj = (TextObject)myReportFieldObj;  
         ft = new Font("Arial", fobj.Font.Size, fobj.Font.Style, fobj.Font.Unit,  
         fobj.Font.GdiCharSet, fobj.Font.GdiVerticalFont);  
         fobj.ApplyFont(ft);  
       }  
     }  
  }  
  tmpReport.Export(exportOpts);  
   
  //load completed, close the splash screen  
  SplashScreen.CloseSplashScreen();  
  this.Activate();  
   
Step 7: Provide the hyper link to just created document using a custom form, if the system has Microsoft excel Installed
 Form messageForm = new Form(); //this needs to be declared at the top of the tsNewItem_Click method  
   
 messageForm.ClientSize = new Size(597, 92);  
 messageForm.Text = "Export to File";  
 messageForm.ShowInTaskbar = false;  
             
 Label lblMsg = new Label();  
 lblMsg.Text = "Export Complete. New file created at ";  
 lblMsg.Location = new Point(69, 29);  
 lblMsg.TabIndex = 0;  
 lblMsg.AutoSize = true;  
   
 LinkLabel lnkExcelFile = new LinkLabel();  
 lnkExcelFile.Text = fileName;  
 lnkExcelFile.Location = new Point(247, 29);  
 lnkExcelFile.Links.Add(0, fileName.Length, fileName);  
 lnkExcelFile.AutoSize = true;  
 lnkExcelFile.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(lnkExcel_LinkClicked);  
   
 Button btnOK = new Button();  
 btnOK.Location = new System.Drawing.Point(230, 57);  
 btnOK.Name = "btnOK";  
 btnOK.Size = new System.Drawing.Size(75, 23);  
 btnOK.TabIndex = 2;  
 btnOK.Text = "OK";  
 btnOK.UseVisualStyleBackColor = false;  
 btnOK.Click += new System.EventHandler(this.btnOK_Click);  
   
 messageForm.StartPosition = FormStartPosition.CenterScreen;  
 if (HasExcel())  
  {  
    messageForm.Controls.Add(lblMsg);  
    messageForm.Controls.Add(lnkExcelFile);  
  }  
 else  
  {  
    lblMsg.Text += " " + fileName;  
    messageForm.Controls.Add(lblMsg);  
  }  
  messageForm.Controls.Add(btnOK);  
  messageForm.TopMost = true;  
  messageForm.ShowDialog(this);  
   
Step 8: Method to check if excel is present in client system or clicked Ok and also Define the click event from the hyperlink 
  //Check to see if the system has Microsoft excel installed.  
 private bool HasExcel()  
 {  
    Microsoft.Win32.RegistryKey regClasses = Microsoft.Win32.Registry.ClassesRoot;  
    Microsoft.Win32.RegistryKey regExcel = regClasses.OpenSubKey("Excel.Application");  
   
    if (regExcel != null)  
    {  
       return true;  
    }  
    else return false;  
 }  
 // Export file linked clicked  
 private void lnkExcel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)  
 {  
    LinkLabel lnk = new LinkLabel();  
    lnk = (LinkLabel)sender;  
    lnk.Links[lnk.Links.IndexOf(e.Link)].Visited = true;  
    System.Diagnostics.Process.Start(e.Link.LinkData.ToString());  
    if (messageForm != null)  
       messageForm.Close();  
    }  
   
 // OK Button on the popup clicked  
 private void btnOK_Click(object sender, EventArgs e)  
 {  
    ActiveForm.Close();  
 }  
   

Wednesday, May 4, 2011

ObjectScript Cheat Sheet for Ensemble [Cache]


Action

Code
Alternative way
Call a class method
##class(package.class).method(arguments)
set variable = ##class(package.class).method(arguments)
Call an instance method
do oref.method(arguments) 
set variable = oref.method(arguments)
Create a new object
set oref = ##class(package.class).%New()

Open an existing object
set oref = ##class(package.class).%OpenId(id)

Save an object
set status = oref.%Save()

Validate an object without saving
set status = oref.%ValidateObject()

Validate a property without saving
set status = ##class(package.class).PropertyIsValid(oref.Property)

Delete an existing object
set status = ##class(package.class).%DeleteId(id)

Link two objects
set oref1.property = oref2


Clone an object
set clonedOref = oref.%ConstructClone()


Start the SQL shell
do $system.SQL.Shell()

>>go
>> SELECTMODE = DISPLAY

Test a class query
do ##class(%ResultSet).RunQuery(class, query)

Create a new standalone array
set arrayOref=##class(%ArrayOfDataTypes).%New()

Insert an element into an array
do oref.arrayProperty.SetAt(value,key)
do arrayOref.SetAt(value,key)
Display an element of an array
do oref.arrayProperty.GetAt(key)
do oref.arrayProperty.GetAt(key)
Display the size of an array
do oref.arrayProperty.Count()
write arrayOref.Count()
Date conversion (external à internal)
set variable = $zdh(“mm/dd/yyyy”)

Date conversion (internal à external)
set variable = $zd(internalDate, format)

Time conversion (external à internal)
set variable = $zth(“hh:mm:ss”)

Time conversion (internal à external)      
set variable = $zt(internalTime, format)

Display internal date/time string
write $system.SYS.Horolog()
write $horolog
Display UTC date/time string
write $system.SYS.TimeStamp()

Check if variable exists
write $data(variable)

Return value of variable, or "" if undefined
write $get(variable)

For Loop Syntax
For ControlVariable = StartValue:IncrementAmount:EndValue


RootComponent types in solution.xml file in Dynamics CRM 365/2016

In Microsoft Dynamic CRM 2016/365 are you as confused as me when looking at the solution.xml from the solution export? looking at the xml a...