cancel
Showing results for 
Search instead for 
Did you mean: 

.net Crystal Report adding sorting dynamically

Former Member
0 Kudos

Hi,

Can anyone help me with this issue. I want to remove the old sort fields and add new sort fields. After searching alot in google I found out that there isn't a direct way to add new sort field in .net. So I have used Reflection.

Below is my code

public class ReportSortingGrouping

{

public int Index { get; set; }

public string FieldName { get; set; }

public SortDirection SortDirection { get; set; }

}

Removing Sorting and adding new sorting.

public static void ReportSorting(ReportDocument cryRpt, List<ReportSortingGrouping> sortByParams, bool resetSorting)

{

if (null != sortByParams)

{

SortFields mySortFields;

MethodInfo getRasSorts;

object rasSorts;

MethodInfo removeSort;

MethodInfo addSort;

Assembly rasAssembly;

ConstructorInfo ciRasSort;

object rasSort;

MethodInfo setSortField;

object[] aiParam = new object[1];

FieldDefinition fieldDef;

if (resetSorting)

{

int totalSortFields = cryRpt.DataDefinition.SortFields.Count;

for (int i = 0; i < totalSortFields; i++)

{

mySortFields = cryRpt.DataDefinition.SortFields;

getRasSorts = mySortFields.GetType().GetMethod("get_RasSorts", BindingFlags.NonPublic | BindingFlags.Instance);

rasSorts = getRasSorts.Invoke(mySortFields, System.Type.EmptyTypes);

removeSort = rasSorts.GetType().GetMethod("Remove");

rasAssembly = getRasSorts.ReturnType.Assembly;

ciRasSort = rasAssembly.GetType("CrystalDecisions.ReportAppServer.DataDefModel.SortClass").GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, System.Type.EmptyTypes, null);

rasSort = ciRasSort.Invoke(System.Type.EmptyTypes);

setSortField = rasSort.GetType().GetMethod("set_SortField", BindingFlags.Public | BindingFlags.Instance);

aiParam[0] = 0;

removeSort.Invoke(rasSorts, aiParam);

}

}

foreach (var param in sortByParams)

{

mySortFields = cryRpt.DataDefinition.SortFields;

fieldDef = cryRpt.DataDefinition.FormulaFields[param.FieldName]; //cryRpt.Database.Tables[0].Fields[param.FieldName];

getRasSorts = mySortFields.GetType().GetMethod("get_RasSorts", BindingFlags.NonPublic | BindingFlags.Instance);

rasSorts = getRasSorts.Invoke(mySortFields, System.Type.EmptyTypes);

addSort = rasSorts.GetType().GetMethod("Add");

rasAssembly = getRasSorts.ReturnType.Assembly;

ciRasSort = rasAssembly.GetType("CrystalDecisions.ReportAppServer.DataDefModel.SortClass").GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, System.Type.EmptyTypes, null);

rasSort = ciRasSort.Invoke(System.Type.EmptyTypes);

setSortField = rasSort.GetType().GetMethod("set_SortField", BindingFlags.Public | BindingFlags.Instance);

addSort.Invoke(rasSorts, new object[] { rasSort });

cryRpt.DataDefinition.SortFields[param.Index].Field = fieldDef;

cryRpt.DataDefinition.SortFields[param.Index].SortDirection = param.SortDirection;

}

}

}

The removing portion of sorting is working. But when I add new sortfield then those old sort fields are added back. Or is there any other alternative for this problem.

Accepted Solutions (1)

Accepted Solutions (1)

former_member183750
Active Contributor
0 Kudos

Please see if the following will help:

KBA: 1638023 - How to add sort field using RAS .NET?

KBA: 1591686 - How to add sort fields using the Inproc RAS SDK

- Ludek

Senior Support Engineer AGS Product Support, Global Support Center Canada

 

Follow us on Twitter

Former Member
0 Kudos

Hi,

    Thank you for the reply.

It tried those suggested option but I am not able to access after "ReportClientDocument"

myReport.ReportClientDocument.DataDefController.Database.Tables[0].DataFields[1];

For more details

I am using

1. Crystal Report XI

2. Visual studio 2012

<add assembly="CrystalDecisions.ReportSource, Version=13.0.2000.0, Culture=neutral, />

        <add assembly="CrystalDecisions.ReportAppServer.Controllers, Version=13.0.2000.0, Culture=neutral, />

        <add assembly="CrystalDecisions.ReportAppServer.DataDefModel, Version=13.0.2000.0, Culture=neutral,/>

        <add assembly="CrystalDecisions.CrystalReports.Engine, Version=13.0.2000.0, Culture=neutral,/>

//------------------------ My current problem is

Suppose I have 4 sort fields

Sort 1 "A"

Sort 2 "B"

Sort 3 "C"

Sort 4 "D"

now I want remove all and Add

Sort 1 "X"

Sort 2 "Y"

In my scenario

1. Remove portion is working fined. Sort count = 0

2. I am able to Add X and Y too but I get

Sort 1 "X"

Sort 2 "Y"

Sort 3 "C"

Sort 4 "D"

I have no idea why C and D is added when I only added X and Y

former_member183750
Active Contributor
0 Kudos

Not sure what SP for CRVS you are using, but make sure you are using SP 10:

On your dev computer, run the install exe, not the MSI.

- Ludek

Former Member
0 Kudos

Hi,

    I installed the one you suggested but still I have the same problem.

When I add one sort field, why is it adding all the deleted sort field. I just don't understand.

Answers (1)

Answers (1)

Former Member
0 Kudos

Thank you.

I used RAS and it helped me solve my sorting problem.

Incase if somebody needs the solution then here it is.

using CrystalDecisions.CrystalReports.Engine;

using CrystalDecisions.ReportAppServer.ClientDoc;

using CrystalDecisions.ReportAppServer.Controllers;

using CrRas= CrystalDecisions.ReportAppServer.DataDefModel;

public static void ReportSorting(ReportDocument rd, List<ReportSortingGrouping> sortByParams, bool resetSorting)

        {

            if (sortByParams != null && sortByParams.Count > 0)

            {

                ISCDReportClientDocument rcd = rd.ReportClientDocument;

                DataDefController dataDefController = rcd.DataDefController;

                CrRas.Sorts sorts = dataDefController.DataDefinition.Sorts;

                SortController sController = dataDefController.SortController;

                //First of all remove all those 'RecordSortField' sorting that are in the report otherwise there will be conflict

                                int sIndex = 0;

                foreach (SortField sField in rd.DataDefinition.SortFields)

                {

                    if (sField.SortType == SortFieldType.RecordSortField)

                    {

                        CrRas.Sort sort = (CrRas.Sort)sorts[sIndex];

                        sController.Remove(sort);

                        sIndex--;

                    }

                    sIndex++;

                }

               

                //Add new sorting

                CrRas.Fields resultFields = dataDefController.DataDefinition.FormulaFields;

                foreach (ReportSortingGrouping item in sortByParams)

                {

                    CrRas.Field sortField = (CrRas.Field)resultFields.FindField("{@" + item.FieldName + "}", CrRas.CrFieldDisplayNameTypeEnum.crFieldDisplayNameFormula, CrRas.CeLocale.ceLocaleEnglishUS);

                    SortController sortController = dataDefController.SortController;

                    if (sortController.CanSortOn(sortField))

                    {

                        CrRas.Sort newSort = new CrRas.SortClass();

                        newSort.SortField = sortField;

                        newSort.Direction = item.SortDirection == CrystalDecisions.Shared.SortDirection.AscendingOrder ? CrRas.CrSortDirectionEnum.crSortDirectionAscendingOrder : CrRas.CrSortDirectionEnum.crSortDirectionDescendingOrder;

                        int index = rd.DataDefinition.SortFields.Count;

                        sortController.Add(index, newSort);

                    }

                }

            }

        }

//This class isn't needed if you have different way of doing it.

public class ReportSortingGrouping

    {

        public int Index { get; set; }

        public string FieldName { get; set; }

        public SortDirection SortDirection { get; set; }

        public string NewFieldName { get; set; }

    }