Change the sort order in a report group from Visual Basic

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • OldBirdman
    Contributor
    • Mar 2007
    • 675

    Change the sort order in a report group from Visual Basic

    On a Report, can I change any of the fields in the "Sorting and Grouping Dialog" from within Visual Basic??? Changing the OrderBy property of the Report doesn't change anything, nor does adding an "ORDER BY" clause to the RecordSource SQL Statement.

    I have a table, named tInventory. It contains a text field called Item. There may be more than one row where Item is duplicated. I use a field called Year to distinguish them on the printed report. Of course there is a Primary Key field which is AutoNum, and therefore each row is unique.

    I print a list of Item, with the Year added to the end. I want to list the Items alphabetically, grouped by the first letter of the Item. Originally, I listed the year as decending, as the newer of duplicate Items was the most important. I now want to give the user control of this, as the users are split on which order is best.

    My report, would therefore have:
    Code:
    RecordSource = "SELECT Left([Item],1) AS FirstLetter, " & _
    		"[Year], " & _
    		"[Item] & "" ("" & [Year] & "")"" AS PrintName" & _
    		"FROM tInventory;"
    The "Sorting and Grouping Dialog is:
    ___Field/Expression___So rt Order
    [{= FirstLetter____ _____Ascending
    ___Year________ _____Descending
    ___PrintName___ _____Ascending

    The report has the appropriate PageHeader, GroupHeader, & Detail Sections. This all works very well.

    Now I want to add an Option chkShowNewestFi rst, giving users a choice. How do I change the field in the "Sorting and Grouping Dialog" from 'Decending' to 'Ascending' if so checked?

    The above code is a simplification of the actual problem. There are actually several GroupHeader levels, each with user choices. For this simple case, I could add a new field in my SELECT statement as either "[Year] AS SortYear" or "9999-[Year] AS SortYear" before assigning to RecordSource, but that gets very messy very fast. It also slows down the program.
  • puppydogbuddy
    Recognized Expert Top Contributor
    • May 2007
    • 1923

    #2
    This link shows you step by step how :

    Comment

    • ADezii
      Recognized Expert Expert
      • Apr 2006
      • 8834

      #3
      Originally posted by OldBirdman
      On a Report, can I change any of the fields in the "Sorting and Grouping Dialog" from within Visual Basic??? Changing the OrderBy property of the Report doesn't change anything, nor does adding an "ORDER BY" clause to the RecordSource SQL Statement.

      I have a table, named tInventory. It contains a text field called Item. There may be more than one row where Item is duplicated. I use a field called Year to distinguish them on the printed report. Of course there is a Primary Key field which is AutoNum, and therefore each row is unique.

      I print a list of Item, with the Year added to the end. I want to list the Items alphabetically, grouped by the first letter of the Item. Originally, I listed the year as decending, as the newer of duplicate Items was the most important. I now want to give the user control of this, as the users are split on which order is best.

      My report, would therefore have:
      Code:
      RecordSource = "SELECT Left([Item],1) AS FirstLetter, " & _
      		"[Year], " & _
      		"[Item] & "" ("" & [Year] & "")"" AS PrintName" & _
      		"FROM tInventory;"
      The "Sorting and Grouping Dialog is:
      ___Field/Expression___So rt Order
      [{= FirstLetter____ _____Ascending
      ___Year________ _____Descending
      ___PrintName___ _____Ascending

      The report has the appropriate PageHeader, GroupHeader, & Detail Sections. This all works very well.

      Now I want to add an Option chkShowNewestFi rst, giving users a choice. How do I change the field in the "Sorting and Grouping Dialog" from 'Decending' to 'Ascending' if so checked?

      The above code is a simplification of the actual problem. There are actually several GroupHeader levels, each with user choices. For this simple case, I could add a new field in my SELECT statement as either "[Year] AS SortYear" or "9999-[Year] AS SortYear" before assigning to RecordSource, but that gets very messy very fast. It also slows down the program.
      You modify Sorting and Grouping characteristics of any given Report via the GroupLevel Property where each Group Level is identified by an Index as in:
      Code:
      Reports![rptMovie].GroupLevel(0).KeepTogether = True       '1st Level
      Reports![rptMovie].GroupLevel(1).KeepTogether = True       '2nd Level
      Reports![rptMovie].GroupLevel(2).KeepTogether = True       '3rd Level

      Comment

      • OldBirdman
        Contributor
        • Mar 2007
        • 675

        #4
        Many thanks to both for this simple answer. It completely solves my problem.

        The link by 'puppydogbuddy' is almost exactly like my program, except I use a series of toggle buttons and options groups instead of combo boxes (one less mouse click).

        The post by 'ADezii' is short & sweet, enough to solve my problem after the amount of research done before posting my question. I had spent many hours in Access Help, Google, and this site searching for an answer. I found no reference to 'GroupLevel' and really felt that this was a feature kept from VB by Access.

        Thank you again for your serious consideration to my questions?

        OldBirdman

        Comment

        • J360
          New Member
          • Aug 2008
          • 23

          #5
          Anybody know how to modify to include group level in a dynamic report? There is no report saved in database so you can't go in on the report open sub.

          Comment

          • ADezii
            Recognized Expert Expert
            • Apr 2006
            • 8834

            #6
            Originally posted by J360
            Anybody know how to modify to include group level in a dynamic report? There is no report saved in database so you can't go in on the report open sub.
            Just subscribing, I'll be back shortly.

            Comment

            • ADezii
              Recognized Expert Expert
              • Apr 2006
              • 8834

              #7
              Originally posted by J360
              Anybody know how to modify to include group level in a dynamic report? There is no report saved in database so you can't go in on the report open sub.
              1. How to create a Dynamic Report in VBA
                http://bytes.com/forum/thread696050.html
              2. The following code will create a Group Level on a [PayrollNumber] Field on a Report named rptEmployees. The Report on which the Group Level is to be created must initially be open in Design view.

                Code:
                Dim varGroupLevel As Variant
                Dim blnCreateHeaderAlso As Boolean
                Dim blnCreateFooterAlso As Boolean
                
                'Let's create a Group Header but no Group Footer on [PayrollNumber]
                blnCreateHeaderAlso = True
                blnCreateFooterAlso = False
                
                'Critical that the Report is Open in Design View
                DoCmd.OpenReport "rptEmployees", acViewDesign, , , acHidden
                
                'Create new group level on the [PayrollNumber] Field.
                varGroupLevel = CreateGroupLevel("rptEmployees", "PayrollNumber", _
                                           blnCreateHeaderAlso, blnCreateFooterAlso)
                
                'Set the Height of the Group Header to 400
                Reports!rptEmployees.Section(acGroupLevel0Header).Height = 400
                
                'Save our lovely work
                DoCmd.Close acReport, "rptEmployees", acSaveYes

              Comment

              • J360
                New Member
                • Aug 2008
                • 23

                #8
                Great, that works (my code looks slightly different). Now I'm trying to put labels in the newly created group headers. The labels currently go in the page header and the text boxes are in the acDetail section.

                I'm getting an error - either the grouping level doesn't exist or the report creates properly but the labels are nowhere to be found.

                Below is my code. Any thoughts? Also, can anyone recommend a good guide to formatting reports? That is basically the last part of my project, I just need the data to look good and have no idea how to resize/move/get everything looking proper.

                Code:
                  Case 16
                    group1 = CreateGroupLevel(rpt.Name, strCbo1, 0, 0)
                    group2 = CreateGroupLevel(rpt.Name, strCbo2, 0, 0)
                    group3 = CreateGroupLevel(rpt.Name, strCbo3, 1, 1)
                    group4 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                    With rpt
                        .GroupLevel(group3).KeepTogether = 1
                        .GroupLevel(group4).SortOrder = False
                    End With
                End Select
                
                     'create label on pageheader
                    For Each fld In rs.Fields
                        CreateReportControl rpt.Name, acLabel, acPageHeader, , fld.Name, 0, 0
                        CreateReportControl rpt.Name, acTextBox, acDetail, , fld.Name, 0, 0
                        
                    Next fld
                I've been trying acGroupLevel2He ader and acGroupLevelgro up3header, nothing seems to work

                Comment

                • ADezii
                  Recognized Expert Expert
                  • Apr 2006
                  • 8834

                  #9
                  Originally posted by J360
                  Great, that works (my code looks slightly different). Now I'm trying to put labels in the newly created group headers. The labels currently go in the page header and the text boxes are in the acDetail section.

                  I'm getting an error - either the grouping level doesn't exist or the report creates properly but the labels are nowhere to be found.

                  Below is my code. Any thoughts? Also, can anyone recommend a good guide to formatting reports? That is basically the last part of my project, I just need the data to look good and have no idea how to resize/move/get everything looking proper.

                  Code:
                    Case 16
                      group1 = CreateGroupLevel(rpt.Name, strCbo1, 0, 0)
                      group2 = CreateGroupLevel(rpt.Name, strCbo2, 0, 0)
                      group3 = CreateGroupLevel(rpt.Name, strCbo3, 1, 1)
                      group4 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                      With rpt
                          .GroupLevel(group3).KeepTogether = 1
                          .GroupLevel(group4).SortOrder = False
                      End With
                  End Select
                  
                       'create label on pageheader
                      For Each fld In rs.Fields
                          CreateReportControl rpt.Name, acLabel, acPageHeader, , fld.Name, 0, 0
                          CreateReportControl rpt.Name, acTextBox, acDetail, , fld.Name, 0, 0
                          
                      Next fld
                  I've been trying acGroupLevel2He ader and acGroupLevelgro up3header, nothing seems to work
                  Is the Report Open in Design Mode, this Step is critical?

                  Comment

                  • J360
                    New Member
                    • Aug 2008
                    • 23

                    #10
                    Yes, right before the Select Case statement I have:

                    Code:
                     DoCmd.reportOpen rpt.Name, acViewDesign
                    No luck.

                    If anybody is interested, here is all the nastiness:

                    Code:
                    Private Sub FormButton_Click()
                    Dim strAVP, strBranch, strTC, strDrug, strPay, strTrend, strTime, strCbo1, strCbo2, strCbo3, strSQL As String
                    Dim rpt As Report
                    Dim lblNew As Access.Label
                    Dim txtnew As Access.TextBox
                    Dim db As DAO.Database
                    Dim rs As DAO.Recordset
                    Dim fld As DAO.Field
                    Dim rptReport As Access.Report
                    Dim strCaption As String
                    Dim varGroupLevel As Variant
                    Dim WhatToShow As String
                    
                    'Loop to Grab AVPList Box entries.  The loops are identical for all List Boxes.
                    For Each varItem In Me.AvpList.ItemsSelected
                            strAVP = strAVP & ",'" & Me.AvpList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        'If user does not make a selection, select all choices in list box.
                        If Len(strAVP) = 0 Then
                            strAVP = "Like '*'"
                        Else
                            strAVP = Right(strAVP, Len(strAVP) - 1)
                            strAVP = "IN(" & strAVP & ")"
                    End If
                    
                    'Loop to grab Branch List Box entries
                    For Each varItem In Me.BranchList.ItemsSelected
                            strBranch = strBranch & ",'" & Me.BranchList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        If Len(strBranch) = 0 Then
                            strBranch = "Like '*'"
                        Else
                            strBranch = Right(strBranch, Len(strBranch) - 1)
                            strBranch = "IN(" & strBranch & ")"
                    End If
                    
                    'Loop to grab TCList Box entries
                    For Each varItem In Me.TCList.ItemsSelected
                            strTC = strTC & ",'" & Me.TCList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        If Len(strTC) = 0 Then
                            strTC = "Like '*'"
                        Else
                            strTC = Right(strTC, Len(strTC) - 1)
                            strTC = "IN(" & strTC & ")"
                    End If
                    
                    'Loop to grab DrugList Box entries
                    For Each varItem In Me.DrugList.ItemsSelected
                            strDrug = strDrug & ",'" & Me.DrugList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        If Len(strDrug) = 0 Then
                            strDrug = "Like '*'"
                        Else
                            strDrug = Right(strDrug, Len(strDrug) - 1)
                            strDrug = "IN(" & strDrug & ")"
                    End If
                    
                    
                    'loop for PayList Box entries
                    For Each varItem In Me.PayList.ItemsSelected
                            strPay = strPay & ",'" & Me.PayList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        If Len(strPay) = 0 Then
                            strPay = "Like '*'"
                        Else
                            strPay = Right(strPay, Len(strPay) - 1)
                            strPay = "IN(" & strPay & ")"
                    End If
                    
                    'loop for TrendList Box entries
                    For Each varItem In Me.TrendList.ItemsSelected
                            strTrend = strTrend & ",'" & Me.TrendList.ItemData(varItem) _
                            & "'"
                        Next varItem
                    
                        If Len(strTrend) = 0 Then
                            strTrend = "Like '*'"
                        Else
                            strTrend = Right(strTrend, Len(strTrend) - 1)
                            strTrend = "IN(" & strTrend & ")"
                    End If
                    
                    
                    For Each varItem In Me.PPList.ItemsSelected
                            strTime = strTime & ", tblAvpBrDg.[" & Me.PPList.ItemData(varItem) & "]"
                            
                            Next varItem
                            If Len(strTime) = 0 Then
                                MsgBox "You must select the dates you wish to see."
                                Exit Sub
                            Else
                                strTime = Right(strTime, Len(strTime) - 2)
                            End If
                             
                    'Define strings to be used for sorting purposes later
                         strCbo1 = Me.cboSortOrder1.Value
                         strCbo2 = Me.cboSortOrder2.Value
                         strCbo3 = Me.cboSortOrder3.Value
                         strCbo4 = Me.cboSortOrder4.Value
                         strCbo5 = Me.cboSortOrder5.Value
                         
                    If strCbo1 = "None" Then
                        S1 = 0
                        Else
                        S1 = 1
                    End If
                    
                    If strCbo2 = "None" Then
                        S2 = 0
                        Else
                        S2 = 5
                    End If
                    
                    If strCbo3 = "None" Then
                        S3 = 0
                        Else
                        S3 = 10
                    End If
                        
                    If strCbo4 = "None" Or IsNull(strCbo4) = True Then
                        S4 = 0
                        Else
                        S4 = 20
                    End If
                    
                    If strCbo5 = "None" Or IsNull(strCbo5) = True Then
                        S5 = 0
                        Else
                        S5 = 40
                    End If
                        
                    WhatToShow = S1 + S2 + S3 + S4 + S5
                    WhatToGroup = S1 + S2 + S3
                        Select Case WhatToShow
                            Case 0
                                      
                                        strSQL = "SELECT tblAvpBrDg.[AVP], tblAvpBrDg.[Branch], tblAvpBrDg.[THERAPY_CLASS], tblAvpBrDg.[DRUG_GROUP], tblAvpBrDg.[PayorCode], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                                    
                            Case 1
                                        strSQL = "SELECT tblAvpBrDg.[" & strCbo1 & "], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                                    
                            Case 6
                                 strSQL = "SELECT tblAvpBrDg.[" & strCbo1 & "], tblAvpBrDg.[" & strCbo2 & "], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                            Case 16
                                strSQL = "SELECT tblAvpBrDg.[" & strCbo1 & "], tblAvpBrDg.[" & strCbo2 & "], tblAvpBrDg.[" & strCbo3 & "], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                                                
                            Case 36
                                strSQL = "SELECT tblAvpBrDg.[" & strCbo1 & "], tblAvpBrDg.[" & strCbo2 & "], tblAvpBrDg.[" & strCbo3 & "], tblAvpBrDg.[" & strCbo4 & "], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                                                
                            Case 76
                                strSQL = "SELECT tblAvpBrDg.[" & strCbo1 & "], tblAvpBrDg.[" & strCbo2 & "], tblAvpBrDg.[" & strCbo3 & "], tblAvpBrDg.[" & strCbo4 & "], tblAvpBrDg.[" & strCbo5 & "], tblAvpBrDg.[Measure], " & strTime & " FROM tblAvpBrDg " & _
                                                "Where AVP " & strAVP & " AND " & _
                                                "Branch " & strBranch & " AND " & "THERAPY_CLASS " & strTC & _
                                                " AND " & "DRUG_GROUP " & strDrug & " AND " & "PayorCode " & strPay & _
                                                " AND " & "Measure " & strTrend & ";"
                                                
                        End Select
                                
                    MsgBox strSQL
                    
                         
                         'set the title
                         Title = "Title for the Report"
                      
                         ' initialise position variables
                         lngleft = 0
                         lngtop = 0
                       
                         'Create the report
                         Set rpt = CreateReport
                    
                        ' set properties of the Report
                         With rpt
                            .Width = 8500
                            .RecordSource = strSQL
                            .Caption = Title
                            .Section(acDetail).Height = 100
                             
                         End With
                        
                         ' Open SQL query as a recordset
                         Set db = CurrentDb
                         Set rs = db.OpenRecordset(strSQL)
                         
                         DoCmd.OpenReport rpt.Name, acViewDesign
                         
                    Select Case WhatToGroup
                    
                        Case 0
                            group1 = CreateGroupLevel(rpt.Name, "AVP", 0, 0)
                            group2 = CreateGroupLevel(rpt.Name, "Branch", 0, 0)
                            group3 = CreateGroupLevel(rpt.Name, "THERAPY_CLASS", 0, 0)
                            group4 = CreateGroupLevel(rpt.Name, "DRUG_GROUP", 0, 0)
                            group5 = CreateGroupLevel(rpt.Name, "PayorCode", 1, 1)
                            group6 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                            With rpt
                                .GroupLevel(group1).KeepTogether = 1
                                .GroupLevel(group6).SortOrder = False
                            End With
                            
                        Case 1
                            group1 = CreateGroupLevel(rpt.Name, strCbo1, 1, 1)
                            group2 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                            With rpt
                                .GroupLevel(group1).KeepTogether = 1
                                .GroupLevel(group2).SortOrder = False
                            End With
                            
                         Case 6
                            group1 = CreateGroupLevel(rpt.Name, strCbo1, 0, 0)
                            group2 = CreateGroupLevel(rpt.Name, strCbo2, 1, 1)
                            group3 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                            With rpt
                                .GroupLevel(group2).KeepTogether = 1
                                .GroupLevel(group3).SortOrder = False
                            End With
                        
                        Case 16
                        group1 = CreateGroupLevel(rpt.Name, strCbo1, 0, 0)
                        group2 = CreateGroupLevel(rpt.Name, strCbo2, 0, 0)
                        group3 = CreateGroupLevel(rpt.Name, strCbo3, 1, 1)
                        group4 = CreateGroupLevel(rpt.Name, "Measure", 0, 0)
                        With rpt
                            .GroupLevel(group3).KeepTogether = 1
                            .GroupLevel(group4).SortOrder = False
                        End With
                    End Select
                    
                         'create label on pageheader
                        For Each fld In rs.Fields
                            CreateReportControl rpt.Name, acLabel, acGroupLevelgroup3Header, , fld.Name, 0, 0
                            CreateReportControl rpt.Name, acTextBox, acDetail, , fld.Name, 0, 0
                            
                        Next fld
                        
                        
                        'arrange fields
                        For Each Ctrl In rpt.Controls
                        
                            Select Case Ctrl.ControlType
                              Case acTextBox
                                    If TextCol Then
                                        Ctrl.Name = Ctrl.ControlSource
                                        Ctrl.Move TextWidth, 0, Ctrl.Width, Ctrl.Height
                                        TextWidth = TextWidth + Ctrl.Width
                                    Else
                                        Ctrl.Name = Ctrl.ControlSource
                                        Ctrl.Move TextWidth, 0, Ctrl.Width, Ctrl.Height
                                        TextWidth = TextWidth + Ctrl.Width
                                    End If
                                    TextCol = False
                                Case acLabel
                                    If FirstCol Then
                                        Ctrl.Name = "lbl" & Ctrl.Caption
                                        Ctrl.Move ColWidth, 0, Ctrl.Width, Ctrl.Height
                                        
                                    Else
                                        Ctrl.Name = "lbl" & Ctrl.Caption
                                        Ctrl.Move TextWidth, 0, Ctrl.Width, Ctrl.Height
                                        
                                    End If
                                    Ctrl.FontSize = 8
                                    Ctrl.FontWeight = 700
                                    FirstCol = False
                                Case Else
                                
                            End Select
                            
                        Next Ctrl
                        
                         ' Create datestamp in Footer
                         Set lblNew = CreateReportControl(rpt.Name, acLabel, _
                         acPageFooter, , Now(), 0, 0)
                        
                         ' Create page numbering on footer
                         Set txtnew = CreateReportControl(rpt.Name, acTextBox, _
                         acPageFooter, , "='Page ' & [Page] & ' of ' & [Pages]", rpt.Width - 1000, 0)
                         txtnew.SizeToFit
                        
                        DoCmd.OpenReport rpt.Name, acViewPreview
                          
                          
                         'reset all objects
                         rs.Close
                         Set rs = Nothing
                         Set rpt = Nothing
                         Set db = Nothing
                    End Sub
                    I'm very new to access and vba - I've pieced all this together from sites like this and tons of trial and error. I just need to figure out all the report formatting tricks.

                    Comment

                    • ADezii
                      Recognized Expert Expert
                      • Apr 2006
                      • 8834

                      #11
                      Just be referencing Code Line #262,
                      Code:
                      CreateReportControl rpt.Name, acLabel, acGroupLevelgroup3Header, , fld.Name, 0, 0
                      it appears as if you are using the incorrect Intrinsic Constant for the Group Level, try:
                      Code:
                      CreateReportControl rpt.Name, acLabel, acGroupLevel3Header, , fld.Name, 0, 0

                      Comment

                      Working...