Monday, December 17, 2018

How to modify sub-report location using Crystal Reports libraries in C#

I have some reports with subreports that point to invalid paths (due to some subfolders renaming). I needed to modify these subreports paths in c#.  I browsed the internet; But all what I found is unresolved questions. like:
https://archive.sap.com/discussions/thread/3903898
and
https://social.msdn.microsoft.com/Forums/en-US/e116daac-7c2e-4fbc-a833-8414098a3cf3/cr-changing-subreport-path-at-runtime-or-to-relative-path-at-design-time?forum=vscrystalreports

Finally I came up with a solution. Unfortunately above threads were locked so I had to post it here .  Hopefully someone can benefit from it.

    var aReportDocument = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
 
    // Fill the repot path
    aReportDocument.Load(rootPath);
 
    try
    {
        var aRCD = aReportDocument.ReportClientDocument;
 
        StringBuilder sb = new StringBuilder();
        var reportDefController = aRCD.ReportDefController;
        var rptObjs = reportDefController.ReportObjectController.GetAllReportObjects();
        foreach (CrystalDecisions.ReportAppServer.ReportDefModel.ReportObject rptObj in rptObjs)
        {
            // look for sub report object and display info
            if (rptObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindSubreport)
            {
                var subRptObjI = rptObj as CrystalDecisions.ReportAppServer.ReportDefModel.ISCRSubreportObject;
                var location = subRptObjI.SubreportLocation;
                if (location.Contains(@"d:\old invalid path\"))
                {
                    string newPortion = @"C:\new valid path\";
                    string newLocation = location.Replace(@"d:\old invalid path\"newPortion);
                                
                    sb.AppendLine("\tName : '" + subRptObjI.Name + "' location '" + subRptObjI.SubreportLocation + "'");
 
                    var newClone = (CrystalDecisions.ReportAppServer.ReportDefModel.ISCRSubreportObject)subRptObjI.Clone(true);
                    newClone.SubreportLocation = newLocation;
                    reportDefController.ReportObjectController.Modify(rptObjnewClone);
                }
            }
 
        }
        if (sb.Length > 0)
        {
            aReportDocument.SaveAs(newPath);
            sb.AppendLine("Saved successfully : " + newPath);
            Console.Write(sb.ToString());
        }
 
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.Message);
    }
 
    aReportDocument.Close();

No comments: