Data Access Worldwide Knowledge Base

Article ID 2244
Article Title HOWTO: Add grouping on a field in Crystal Reports that does not have groups
Article URL http://www.dataaccess.com/kbasepublic/KBPrint.asp?ArticleID=2244
KBase Category VDF11
Date Created 09/19/2006
Last Edit Date 09/29/2006


Article Text
QUESTION:
I have a Crystal Reports report with no groups defined. I would like to create groups at runtime from VDF (not in CRW), like you can do with sort. How do you do that?

ANSWER:
Using the Crystal RDC interface you can do a lot of things like this. There is a method defined in the cCrystalReport class that can be used to add groups. The following code could be used to do this.

Procedure OnInitializeReport Handle hoReport
    Forward Send OnInitializeReport hoReport

    Send AppendGroup hoReport "Customer" "State" crAscendingOrder
End_Procedure // OnInitializeReport

Procedure AppendGroup Handle hoReport String sTable String sField Integer iSortOrder
    Handle hoDatabaseTable hoTableFields hoTableField
    Variant vFields vField
    String sDatabaseFieldName
    Integer iFieldCount iField iGroups
    Boolean bOk bAttached

    Get ComNumberOfGroup Of hoReport To iGroups

    Get GetTableObjectByName Of hoReport sTable To hoDatabaseTable
    Move (hoDatabaseTable > 0) to bOk
    If (bOk) Begin
        // create temporary object for all table fields
        Get Create U_cCrystalDatabaseFieldDefinitions to hoTableFields
        Get Create U_cCrystalDatabaseFieldDefinition  to hoTableField
        Get ComFields of hoDatabaseTable To vFields
        Set pvComObject of hoTableFields To vFields
        Get IsComObjectCreated of hoTableFields to bAttached
        If (bAttached) Begin
            Move (Lowercase (sField)) To sField
            Get ComCount Of hoTableFields To iFieldCount
            Move False To bOk
            Move 1 To iField
            While (Not (bOk) And (iField <= iFieldCount))
                Get ComItem Of hoTableFields iField To vField
                Set pvComObject Of hoTableField To vField
                Get IsComObjectCreated Of hoTableField To bAttached
                If (bAttached) Begin
                    Get ComDatabaseFieldName Of hoTableField To sDatabaseFieldName
                    If (Lowercase (sDatabaseFieldName) = sField) Begin
                        Send ComAddGroup Of hoReport iGroups vField crGCAnyValue iSortOrder
                        Move True To bOk
                    End
                End
                Increment iField
            Loop
        End
        Send Destroy Of hoTableField
        Send Destroy Of hoTableFields
    End
    // if can't find table or field or whatever
    If Not bOk Begin
        Error DFERR_CRYSTAL_REPORT (SFormat("Cannot add group field for %1.%2", sTable, sField))
    End
End_Procedure // AppendGroup

If you add/merge the above code with the sample preview CustomerListCR.Rv you will see the report sorted by state.

If you make a mistake in the groupnumber (if you code above yourself instead of merging and using the ComNumberOfGroup function) you will get a Com Method Invocation Error (see enclosed screenshot).

Undocumented but working is to pass a -1 for the groupnumber to just add the group. So above routine can also be written as:

Procedure AppendGroup Handle hoReport String sTable String sField Integer iSortOrder
    Handle hoDatabaseTable hoTableFields hoTableField
    Variant vFields vField
    String sDatabaseFieldName
    Integer iFieldCount iField
    Boolean bOk bAttached

    Get GetTableObjectByName Of hoReport sTable To hoDatabaseTable
    Move (hoDatabaseTable > 0) to bOk
    If (bOk) Begin
        // create temporary object for all table fields
        Get Create U_cCrystalDatabaseFieldDefinitions to hoTableFields
        Get Create U_cCrystalDatabaseFieldDefinition  to hoTableField
        Get ComFields of hoDatabaseTable To vFields
        Set pvComObject of hoTableFields To vFields
        Get IsComObjectCreated of hoTableFields to bAttached
        If (bAttached) Begin
            Move (Lowercase (sField)) To sField
            Get ComCount Of hoTableFields To iFieldCount
            Move False To bOk
            Move 1 To iField
            While (Not (bOk) And (iField <= iFieldCount))
                Get ComItem Of hoTableFields iField To vField
                Set pvComObject Of hoTableField To vField
                Get IsComObjectCreated Of hoTableField To bAttached
                If (bAttached) Begin
                    Get ComDatabaseFieldName Of hoTableField To sDatabaseFieldName
                    If (Lowercase (sDatabaseFieldName) = sField) Begin
                        Send ComAddGroup Of hoReport -1 vField crGCAnyValue iSortOrder
                        Move True To bOk
                    End
                End
                Increment iField
            Loop
        End
        Send Destroy Of hoTableField
        Send Destroy Of hoTableFields
    End
    // if can't find table or field or whatever
    If Not bOk Begin
        Error DFERR_CRYSTAL_REPORT (SFormat("Cannot add group field for %1.%2", sTable, sField))
    End
End_Procedure // AppendGroup


Contributed By:
Vincent Oorsprong
Company: Data Access Worldwide
email: vincent.oorsprong@dataaccess.eu
Web Site: http://www.dataaccess.eu

Web Links Related to this Article
File GroupNumberWrong.JPG
URL=http://www.dataaccess.com/KBasePublic/Files/2244.GroupNumberWrong.JPG


Email this Article
Email this Article to a Colleague
Send Feedback on this Article to Data Access Worldwide
Copyright ©2010 Data Access Corporation. All rights reserved.

The information provided in the Data Access Technical Knowledge Base is provided "as is" without warranty of any kind. Data Access Corporation disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. In no event shall Data Access Corporation or its suppliers be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if Data Access Corporation or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply.