This code accepts a sql string as a parameter and it downloads the necessary data, throws it into an Excel sheet, then draws three graphs based on the data it has just downloaded. The requirement is for the report to look just like its old Access counterpart, hence a lot of hard-coding has to take place.

Any way to improve this = much appreciated. I'm ready for the absolute worst of criticisms.

Thank you.

VB Code:
  1. Public Sub CreateExcelWS(strSQL As String)
  2.  
  3.     Call LoadCaption(True)
  4.  
  5.     ' Checks connection to SQL Server; there should be a connection already
  6.     ' but if there isn't it creates one; if the connection is closed (should
  7.     ' not be) then it opens it.
  8.     Call CheckConnection
  9.    
  10.     Dim objRSArray() As ADODB.Recordset
  11.     Dim objRS As ADODB.Recordset
  12.     Dim xlApp As Object
  13.     Dim xlBook As Object
  14.     Dim xlSheet As Object
  15.     Dim xlChartArray(3) As Object
  16.     Dim i As Integer
  17.     Dim strSource(3) As String
  18.     Dim strParameter As String
  19.     Dim strSproc() As String
  20.     Dim StartPosition(3) As Integer
  21.    
  22.     ' Checks to see if there is already an instance of Excel; if there is
  23.     ' then the current one is used, if not then a new one is created.
  24.     If IsExcelInstalled = True And IsExcelRunning = False Then
  25.         Set xlApp = CreateObject("Excel.Application")
  26.     Else
  27.         Set xlApp = GetObject(, "Excel.Application")
  28.     End If
  29.    
  30.     ' Instantiates Excel objects
  31.     Set xlBook = xlApp.Workbooks.Add
  32.     Set xlSheet = xlBook.ActiveSheet
  33.     xlSheet.Name = "Sheet 1"
  34.    
  35.     ' Calls UnpackString() function and assigns the output to the strSproc array
  36.     strSproc = UnpackString("SELECT SQLObject FROM tblReports WHERE ReportName = 'Weekly Summary'")
  37.        
  38.     ' Calls the DeriveWhereClause function and assigns the output to strParameter
  39.     strParameter = DeriveWhereClause
  40.    
  41.     ' Sets up the strSource array using the strSproc array
  42.     For i = 0 To UBound(strSproc)
  43.         strSource(i) = "EXEC " & strSproc(i) & " @Filter = " & "'" & strParameter & "'"
  44.     Next i
  45.    
  46.     ReDim objRSArray(UBound(strSproc))
  47.     ' Instantiates and opens the members of the recordset array and
  48.     ' sets the cursorlocation property so that we can use the
  49.     ' recordcount property later on.
  50.     For i = 0 To UBound(strSproc)
  51.         Set objRSArray(i) = New ADODB.Recordset
  52.         objRSArray(i).CursorLocation = adUseClient
  53.         objRSArray(i).Open strSource(i), cnConn, adOpenForwardOnly, adLockReadOnly, adCmdText
  54.     Next i
  55.    
  56.    
  57.     ' Initializes StartPosition(1) and moves data to Excel; starting position
  58.     ' is determined by sizes of recordsets
  59.     ' First chart
  60.     StartPosition(1) = 4
  61.     Call MoveDataExcel(objRSArray(0), xlSheet, StartPosition(1))
  62.     ' Second chart
  63.     StartPosition(2) = StartPosition(1) + 2 + objRSArray(0).RecordCount
  64.     Call MoveDataExcel(objRSArray(1), xlSheet, StartPosition(2))
  65.     ' Third chart
  66.     StartPosition(3) = StartPosition(2) + 2 + objRSArray(1).RecordCount
  67.     Call MoveDataExcel(objRSArray(2), xlSheet, StartPosition(3))
  68.    
  69.     ' Instantiates chart objects and adds them to the Excel spreadsheet
  70.     For i = 1 To 3
  71.         Set xlChartArray(i) = xlApp.Charts.Add
  72.         Call CreateXLChart(xlSheet, xlChartArray(i), StartPosition(i), xlColumnStacked, "Sheet 1")
  73.     Next i
  74.    
  75.     ' Moves the charts to an appropriate position and sizes them
  76.     Call MoveXLCharts(xlSheet, 1, 30, 1, 500, 300)
  77.     Call MoveXLCharts(xlSheet, 2, 340, 1, 500, 300)
  78.     Call MoveXLCharts(xlSheet, 3, 650, 1, 500, 300)
  79.    
  80.     ' Custom format the first chart
  81.     With xlSheet.ChartObjects(1).Chart
  82.         .Axes(xlCategory, xlPrimary).CategoryType = xlCategoryScale
  83.         .PlotArea.ClearFormats
  84.         .HasTitle = True
  85.         .HasLegend = False
  86.         .ChartTitle.Characters.Text = "Applications Received"
  87.         .ChartTitle.Font.Size = 8
  88.         .Axes(xlValue).TickLabels.Font.Size = 9
  89.         .HasDataTable = True
  90.         With .DataTable
  91.             .ShowLegendKey = True
  92.             .Font.Size = 9
  93.         End With
  94.         ' Changes 'Other Protection' series color to red
  95.         .SeriesCollection(4).Interior.ColorIndex = 6
  96.         ' Changes 'Term' series color to light green
  97.         .SeriesCollection(3).Interior.ColorIndex = 24
  98.         ' Changes 'MLI' series color to bluey-purple
  99.         .SeriesCollection(2).Interior.ColorIndex = 22
  100.         ' Changes 'PTA' series color to pale yellow
  101.         .SeriesCollection(5).Interior.ColorIndex = 3
  102.         ' Changes 'Low Touch' series color to white
  103.         .SeriesCollection(6).Interior.ColorIndex = 2
  104.         ' Removes the prop total series from the graph but not
  105.         ' from the data table
  106.         With .SeriesCollection(1)
  107.             .ChartType = xlLine
  108.             .Border.Weight = xlThin
  109.             .Border.LineStyle = xlNone
  110.         End With
  111.     End With
  112.    
  113.     ' Custom format the second chart
  114.     With xlSheet.ChartObjects(2).Chart
  115.         .Axes(xlCategory, xlPrimary).CategoryType = xlCategoryScale
  116.         .PlotArea.ClearFormats
  117.         .HasTitle = True
  118.         .HasLegend = False
  119.         .ChartTitle.Characters.Text = "Cases Accepted - UW Decision Made"
  120.         .ChartTitle.Font.Size = 8
  121.         .Axes(xlValue).TickLabels.Font.Size = 9
  122.         .HasDataTable = True
  123.         .DataTable.ShowLegendKey = True
  124.         .DataTable.Font.Size = 9
  125.     End With
  126.    
  127.     ' Custom format the third chart
  128.     With xlSheet.ChartObjects(3).Chart
  129.         .Axes(xlCategory, xlPrimary).CategoryType = xlCategoryScale
  130.         .PlotArea.ClearFormats
  131.         .HasTitle = True
  132.         .HasLegend = False
  133.         .ChartTitle.Characters.Text = "Applications Issued"
  134.         .ChartTitle.Font.Size = 8
  135.         .Axes(xlValue).TickLabels.Font.Size = 9
  136.         .HasDataTable = True
  137.         With .DataTable
  138.             .ShowLegendKey = True
  139.             .Font.Size = 9
  140.         End With
  141.         .SeriesCollection(3).Interior.ColorIndex = 6
  142.         .SeriesCollection(4).Interior.ColorIndex = 3
  143.         .SeriesCollection(5).Interior.ColorIndex = 2
  144.         .SeriesCollection(6).Interior.ColorIndex = 15
  145.     End With
  146.    
  147.     ' Grab the rundate off the server since we need it for the
  148.     ' report title 'as at' value
  149.     Dim strDate As String
  150.     Set objRS = cnConn.Execute("SELECT RunDate FROM DateRanges")
  151.     strDate = objRS.Fields(0).Value
  152.    
  153.     ' Set up report titles
  154.     Call CreateReportTitles(xlSheet, "A1:E2", xlGeneral, "NB Protection Volumes As At: " & strDate, 12)
  155.     Call CreateReportTitles(xlSheet, "F1:J1", 4, GetgVarPrimInfoValue(), 8)
  156.     Call CreateReportTitles(xlSheet, "F2:J2", 4, AdditionalInfo(GetgVarAddInfoType(), GetgVarAddInfoValue()), 8)
  157.    
  158.     ' Sets up page margins and forces the data all onto one page.
  159.     With xlSheet.PageSetup
  160.         .LeftMargin = 0.4
  161.         .RightMargin = 0.4
  162.         .Zoom = False
  163.         .FitToPagesTall = 1
  164.         .FitToPagesWide = 1
  165.     End With
  166.    
  167.     ' Cells in the given range will have a white font
  168.     xlSheet.Range("A4:I60").Font.ColorIndex = 2
  169.    
  170.     ' Makes Excel visible
  171.     xlApp.Visible = True
  172.    
  173.     Call LoadCaption(False)
  174.    
  175.     ' Destroy objects
  176.     For i = 0 To UBound(strSproc)
  177.         objRSArray(i).Close
  178.         Set objRSArray(i) = Nothing
  179.     Next i
  180.     Set objRS = Nothing
  181.     Set xlChartArray(0) = Nothing
  182.     Set xlApp = Nothing
  183.     Set xlBook = Nothing
  184.     Set xlSheet = Nothing
  185. End Sub

UnpackString takes the comma-delimited list of three stored procedures that are the sources for the three graphs and presents them in a way that VB can deal with them:

VB Code:
  1. Public Function UnpackString(strVal As String)
  2.    
  3.     Dim rst As ADODB.Recordset
  4.     Dim strArray() As String
  5.     Dim intMemCount As Integer
  6.    
  7.     Set rst = New ADODB.Recordset
  8.     rst.Open strVal, cnConn, adOpenForwardOnly, adLockReadOnly, adCmdText
  9.    
  10.     strArray = Split(rst.GetString, ",")
  11.     intMemCount = UBound(strArray)
  12.  
  13.     ' CleanString cuts off the unwanted gremlin character at the end
  14.     strArray(intMemCount) = CleanString(strArray(intMemCount))
  15.     UnpackString = strArray
  16.  
  17.     rst.Close
  18.     Set rst = Nothing
  19.    
  20. End Function

MoveDataExcel:

VB Code:
  1. Public Sub MoveDataExcel(rstExport As ADODB.Recordset, xlSheet As Object, intStartLine As Integer)
  2.  
  3.     Dim i As Integer
  4.     For i = 0 To rstExport.Fields.Count - 1
  5.         xlSheet.Cells(intStartLine, i + 1).Value = rstExport.Fields(i).Name
  6.     Next i
  7.    
  8.     xlSheet.Range("A" & intStartLine + 1).CopyFromRecordset rstExport
  9.    
  10. End Sub

MoveXLCharts:

VB Code:
  1. Public Sub MoveXLCharts(xlSheet As Object, chartNum As Integer, _
  2.     Top, Left, Width, Height As Integer)
  3.  
  4.     With xlSheet
  5.         With .ChartObjects(chartNum)
  6.             .Top = Top
  7.             .Left = Left
  8.             .Width = Width
  9.             .Height = Height
  10.         End With
  11.     End With
  12.    
  13. End Sub