kadgmt

Untitled

Aug 6th, 2024
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VisualBasic 35.58 KB | Source Code | 0 0
  1. Option Explicit
  2.  
  3. Public gMaxGlucoseY As Long
  4. Public gUniqueDates As Variant
  5.  
  6. Sub FindMaxGlucoseY()
  7.     Dim ws As Worksheet
  8.     Dim lastRow As Long
  9.     Dim maxGlucose As Long
  10.  
  11.     On Error GoTo ErrHandler
  12.    
  13.     ' Set the worksheet
  14.    Set ws = ThisWorkbook.Worksheets("OrigData")
  15.    
  16.     ' Find the last row with data in column B (Glucose values)
  17.    lastRow = ws.Cells(ws.Rows.count, "B").End(xlUp).Row
  18.    
  19.     ' Find the maximum glucose value
  20.    maxGlucose = Application.WorksheetFunction.Max(ws.Range("B2:B" & lastRow))
  21.    
  22.     ' Round up to the nearest multiple of 20 using CEILING function
  23.    gMaxGlucoseY = Application.WorksheetFunction.Ceiling(maxGlucose, 20)
  24.    
  25.     Exit Sub
  26.    
  27. ErrHandler:
  28.     MsgBox "Error in FindMaxGlucoseY: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  29. End Sub
  30.  
  31. Sub PlotGlucoseAndAvgGlucoseClick()
  32.     Dim ws As Worksheet
  33.     Dim startDate As Date, endDate As Date
  34.     Dim startTime As Date, endTime As Date
  35.     Dim uniqueDates As Variant
  36.  
  37.     ' Set active worksheet
  38.    Set ws = ActiveSheet
  39.    
  40.     ' Get the date and time parameters from cells
  41.    startDate = ws.Range("A2").Value
  42.     endDate = ws.Range("B2").Value
  43.     startTime = ws.Range("C2").Value
  44.     endTime = ws.Range("D2").Value
  45.    
  46.     ' Check if endTime is 12:00:00 AM and change it to 11:59:59 PM if it is
  47.    If endTime = TimeSerial(0, 0, 0) Then
  48.         endTime = TimeSerial(23, 59, 59)
  49.     End If
  50.    
  51.     ' Get unique dates
  52.    uniqueDates = gUniqueDates
  53.    
  54.     ' Call PlotMultiSeriesGlucoseVsTimeXYChart with the proper arguments
  55.    PlotMultiSeriesGlucoseVsTimeXYChart startDate, endDate, startTime, endTime, uniqueDates
  56.    
  57.     ' Call PlotMultiSeriesAverageGlucoseByHourChart with the proper arguments
  58.    
  59.     PlotMultiSeriesAverageGlucoseByHourChart startDate, endDate, startTime, endTime, uniqueDates
  60.    
  61.     DisplayStatsForSelectedTimeFrame startDate, endDate, startTime, endTime, uniqueDates
  62.    
  63. End Sub
  64. Function GetGlucoseValuesArrayForADateRange(startDate As Date, endDate As Date, startTime As Date, endTime As Date) As Variant
  65.     Dim ws As Worksheet
  66.     Dim lastRow As Long
  67.     Dim startRow As Long, endRow As Long
  68.     Dim glucoseValues() As Integer
  69.     Dim i As Long, j As Long
  70.  
  71.     On Error GoTo ErrHandler
  72.    
  73.     Set ws = ThisWorkbook.Worksheets("OrigData")
  74.    
  75.     lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).Row
  76.     If lastRow <= 1 Then
  77.         Err.Raise 999, , "No data found in worksheet 'OrigData'."
  78.     End If
  79.    
  80.     ' Find the first row matching the start date and time
  81.    startRow = 2
  82.     Do While startRow <= lastRow
  83.         If ws.Cells(startRow, "A").Value >= startDate + timeValue(startTime) Then
  84.             Exit Do
  85.         End If
  86.         startRow = startRow + 1
  87.     Loop
  88.    
  89.     ' Find the last row matching the end date and time
  90.    endRow = startRow
  91.     Do While endRow <= lastRow
  92.         If ws.Cells(endRow, "A").Value > endDate + timeValue(endTime) Then
  93.             Exit Do
  94.         End If
  95.         endRow = endRow + 1
  96.     Loop
  97.    
  98.     If startRow >= endRow Then
  99.         Err.Raise 999, , "No data found for the specified criteria. Start Date: " & Format(startDate, "mm/dd/yyyy") & ", Start Time: " & Format(startTime, "h:mm AM/PM")
  100.     End If
  101.    
  102.     ' Resize the array to hold the glucose values
  103.    ReDim glucoseValues(1 To endRow - startRow)
  104.    
  105.     ' Populate the array with glucose values
  106.    For i = startRow To endRow - 1
  107.         j = i - startRow + 1
  108.         glucoseValues(j) = CInt(ws.Cells(i, "B").Value)
  109.     Next i
  110.    
  111.     GetGlucoseValuesArrayForADateRange = glucoseValues
  112.     Exit Function
  113.    
  114. ErrHandler:
  115.     MsgBox "Error in GetGlucoseValuesArrayForADateRange: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  116.     GetGlucoseValuesArrayForADateRange = Array()  ' Return an empty array in case of error
  117. End Function
  118.  
  119. Function GetTimeValuesArrayForDateRange(startDate As Date, endDate As Date, startTime As Date, endTime As Date) As Variant
  120.     On Error GoTo ErrHandler
  121.    
  122.     Dim ws As Worksheet
  123.     Dim lastRow As Long
  124.     Dim startRow As Long, endRow As Long
  125.     Dim timeValues() As Double
  126.     Dim i As Long, j As Long
  127.    
  128.     Set ws = ThisWorkbook.Worksheets("OrigData")
  129.    
  130.     lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).Row
  131.     If lastRow <= 1 Then
  132.         Err.Raise 999, , "No data found in worksheet 'OrigData'."
  133.     End If
  134.    
  135.     ' Find the first row matching the start date and time
  136.    startRow = 2
  137.     Do While startRow <= lastRow
  138.         If ws.Cells(startRow, "A").Value >= startDate + timeValue(startTime) Then
  139.             Exit Do
  140.         End If
  141.         startRow = startRow + 1
  142.     Loop
  143.    
  144.     ' Find the last row matching the end date and time
  145.    endRow = startRow
  146.     Do While endRow <= lastRow
  147.         If ws.Cells(endRow, "A").Value > endDate + timeValue(endTime) Then
  148.             Exit Do
  149.         End If
  150.         endRow = endRow + 1
  151.     Loop
  152.    
  153.     If startRow >= endRow Then
  154.         Err.Raise 999, , "No data found for the specified criteria. Start Date: " & Format(startDate, "mm/dd/yyyy") & ", Start Time: " & Format(startTime, "h:mm AM/PM")
  155.     End If
  156.    
  157.     ' Resize the array to hold the time values
  158.    ReDim timeValues(1 To endRow - startRow)
  159.    
  160.     ' Populate the array with time values
  161.    For i = startRow To endRow - 1
  162.         j = i - startRow + 1
  163.         timeValues(j) = timeValue(ws.Cells(i, "A").Value)
  164.     Next i
  165.    
  166.     GetTimeValuesArrayForDateRange = timeValues
  167.     Exit Function
  168.    
  169. ErrHandler:
  170.     MsgBox "Error in GetTimeValuesArrayForDateRange: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  171.     GetTimeValuesArrayForDateRange = Array()      ' Return an empty array in case of error
  172. End Function
  173. Option Explicit
  174.  
  175. Public gMaxGlucoseY As Long
  176. Public gUniqueDates As Variant
  177.  
  178. Sub FindMaxGlucoseY()
  179.     Dim ws As Worksheet
  180.     Dim lastRow As Long
  181.     Dim maxGlucose As Long
  182.  
  183.     On Error GoTo ErrHandler
  184.    
  185.     ' Set the worksheet
  186.    Set ws = ThisWorkbook.Worksheets("OrigData")
  187.    
  188.     ' Find the last row with data in column B (Glucose values)
  189.    lastRow = ws.Cells(ws.Rows.count, "B").End(xlUp).Row
  190.    
  191.     ' Find the maximum glucose value
  192.    maxGlucose = Application.WorksheetFunction.Max(ws.Range("B2:B" & lastRow))
  193.    
  194.     ' Round up to the nearest multiple of 20 using CEILING function
  195.    gMaxGlucoseY = Application.WorksheetFunction.Ceiling(maxGlucose, 20)
  196.    
  197.     Exit Sub
  198.    
  199. ErrHandler:
  200.     MsgBox "Error in FindMaxGlucoseY: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  201. End Sub
  202.  
  203. Sub PlotGlucoseAndAvgGlucoseClick()
  204.     Dim ws As Worksheet
  205.     Dim startDate As Date, endDate As Date
  206.     Dim startTime As Date, endTime As Date
  207.     Dim uniqueDates As Variant
  208.  
  209.     ' Set active worksheet
  210.    Set ws = ActiveSheet
  211.    
  212.     ' Get the date and time parameters from cells
  213.    startDate = ws.Range("A2").Value
  214.     endDate = ws.Range("B2").Value
  215.     startTime = ws.Range("C2").Value
  216.     endTime = ws.Range("D2").Value
  217.    
  218.     ' Check if endTime is 12:00:00 AM and change it to 11:59:59 PM if it is
  219.    If endTime = TimeSerial(0, 0, 0) Then
  220.         endTime = TimeSerial(23, 59, 59)
  221.     End If
  222.    
  223.     ' Get unique dates
  224.    uniqueDates = gUniqueDates
  225.    
  226.     ' Call PlotMultiSeriesGlucoseVsTimeXYChart with the proper arguments
  227.    PlotMultiSeriesGlucoseVsTimeXYChart startDate, endDate, startTime, endTime, uniqueDates
  228.    
  229.     ' Call PlotMultiSeriesAverageGlucoseByHourChart with the proper arguments
  230.    
  231.     PlotMultiSeriesAverageGlucoseByHourChart startDate, endDate, startTime, endTime, uniqueDates
  232.    
  233.     DisplayStatsForSelectedTimeFrame startDate, endDate, startTime, endTime, uniqueDates
  234.    
  235. End Sub
  236. Function GetGlucoseValuesArrayForADateRange(startDate As Date, endDate As Date, startTime As Date, endTime As Date) As Variant
  237.     Dim ws As Worksheet
  238.     Dim lastRow As Long
  239.     Dim startRow As Long, endRow As Long
  240.     Dim glucoseValues() As Integer
  241.     Dim i As Long, j As Long
  242.  
  243.     On Error GoTo ErrHandler
  244.    
  245.     Set ws = ThisWorkbook.Worksheets("OrigData")
  246.    
  247.     lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).Row
  248.     If lastRow <= 1 Then
  249.         Err.Raise 999, , "No data found in worksheet 'OrigData'."
  250.     End If
  251.    
  252.     ' Find the first row matching the start date and time
  253.    startRow = 2
  254.     Do While startRow <= lastRow
  255.         If ws.Cells(startRow, "A").Value >= startDate + timeValue(startTime) Then
  256.             Exit Do
  257.         End If
  258.         startRow = startRow + 1
  259.     Loop
  260.    
  261.     ' Find the last row matching the end date and time
  262.    endRow = startRow
  263.     Do While endRow <= lastRow
  264.         If ws.Cells(endRow, "A").Value > endDate + timeValue(endTime) Then
  265.             Exit Do
  266.         End If
  267.         endRow = endRow + 1
  268.     Loop
  269.    
  270.     If startRow >= endRow Then
  271.         Err.Raise 999, , "No data found for the specified criteria. Start Date: " & Format(startDate, "mm/dd/yyyy") & ", Start Time: " & Format(startTime, "h:mm AM/PM")
  272.     End If
  273.    
  274.     ' Resize the array to hold the glucose values
  275.    ReDim glucoseValues(1 To endRow - startRow)
  276.    
  277.     ' Populate the array with glucose values
  278.    For i = startRow To endRow - 1
  279.         j = i - startRow + 1
  280.         glucoseValues(j) = CInt(ws.Cells(i, "B").Value)
  281.     Next i
  282.    
  283.     GetGlucoseValuesArrayForADateRange = glucoseValues
  284.     Exit Function
  285.    
  286. ErrHandler:
  287.     MsgBox "Error in GetGlucoseValuesArrayForADateRange: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  288.     GetGlucoseValuesArrayForADateRange = Array()  ' Return an empty array in case of error
  289. End Function
  290.  
  291. Function GetTimeValuesArrayForDateRange(startDate As Date, endDate As Date, startTime As Date, endTime As Date) As Variant
  292.     On Error GoTo ErrHandler
  293.    
  294.     Dim ws As Worksheet
  295.     Dim lastRow As Long
  296.     Dim startRow As Long, endRow As Long
  297.     Dim timeValues() As Double
  298.     Dim i As Long, j As Long
  299.    
  300.     Set ws = ThisWorkbook.Worksheets("OrigData")
  301.    
  302.     lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).Row
  303.     If lastRow <= 1 Then
  304.         Err.Raise 999, , "No data found in worksheet 'OrigData'."
  305.     End If
  306.    
  307.     ' Find the first row matching the start date and time
  308.    startRow = 2
  309.     Do While startRow <= lastRow
  310.         If ws.Cells(startRow, "A").Value >= startDate + timeValue(startTime) Then
  311.             Exit Do
  312.         End If
  313.         startRow = startRow + 1
  314.     Loop
  315.    
  316.     ' Find the last row matching the end date and time
  317.    endRow = startRow
  318.     Do While endRow <= lastRow
  319.         If ws.Cells(endRow, "A").Value > endDate + timeValue(endTime) Then
  320.             Exit Do
  321.         End If
  322.         endRow = endRow + 1
  323.     Loop
  324.    
  325.     If startRow >= endRow Then
  326.         Err.Raise 999, , "No data found for the specified criteria. Start Date: " & Format(startDate, "mm/dd/yyyy") & ", Start Time: " & Format(startTime, "h:mm AM/PM")
  327.     End If
  328.    
  329.     ' Resize the array to hold the time values
  330.    ReDim timeValues(1 To endRow - startRow)
  331.    
  332.     ' Populate the array with time values
  333.    For i = startRow To endRow - 1
  334.         j = i - startRow + 1
  335.         timeValues(j) = timeValue(ws.Cells(i, "A").Value)
  336.     Next i
  337.    
  338.     GetTimeValuesArrayForDateRange = timeValues
  339.     Exit Function
  340.    
  341. ErrHandler:
  342.     MsgBox "Error in GetTimeValuesArrayForDateRange: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  343.     GetTimeValuesArrayForDateRange = Array()      ' Return an empty array in case of error
  344. End Function
  345. Option Explicit
  346.  
  347. Sub PlotMultiSeriesGlucoseVsTimeXYChart(startDate As Date, endDate As Date, startTime As Date, endTime As Date, uniqueDates As Variant)
  348.     Dim currentDate As Date
  349.     Dim ws As Worksheet
  350.     Dim cht As ChartObject
  351.     Dim srs As series
  352.     Dim chartLeft As Double, chartTop As Double, chartWidth As Double, chartHeight As Double
  353.     Dim chartTitle As String
  354.     Dim i As Long
  355.     Dim tempGlucoseArray As Variant
  356.     Dim tempTimeArray As Variant
  357.     Dim colorIndex As Long
  358.     Dim visibleRange As Range
  359.     Dim yValues As Variant
  360.     Dim yMax As Double
  361.  
  362.     Set ws = ActiveSheet
  363.    
  364.     ' Delete existing chart if it exists
  365.    For Each cht In ws.ChartObjects
  366.         If cht.Name = "ChartGlucose" Then
  367.             cht.Delete
  368.         End If
  369.     Next cht
  370.    
  371.     ' Get visible range
  372.    Set visibleRange = ActiveWindow.ActivePane.visibleRange
  373.     chartWidth = visibleRange.Width / 2 - 6
  374.     chartHeight = visibleRange.Height - ws.Cells(3, 1).Top - 10
  375.     chartLeft = ws.Cells(3, 1).Left
  376.     chartTop = ws.Cells(3, 1).Top
  377.    
  378.     ' Create new chart
  379.    Set cht = ws.ChartObjects.Add(Left:=chartLeft, Top:=chartTop, Width:=chartWidth, Height:=chartHeight)
  380.     cht.Name = "ChartGlucose"
  381.     cht.Chart.ChartType = xlXYScatterSmoothNoMarkers
  382.    
  383.     ' Clear existing series
  384.    Do While cht.Chart.SeriesCollection.count > 0
  385.         cht.Chart.SeriesCollection(1).Delete
  386.     Loop
  387.    
  388.     ' Plot glucose data
  389.    colorIndex = 1
  390.     For i = LBound(uniqueDates) To UBound(uniqueDates)
  391.         currentDate = uniqueDates(i)
  392.         If currentDate >= startDate And currentDate <= endDate Then
  393.             tempGlucoseArray = GetGlucoseValuesArrayForADateRange(currentDate, currentDate, startTime, endTime)
  394.             tempTimeArray = GetTimeValuesArrayForDateRange(currentDate, currentDate, startTime, endTime)
  395.             If IsArray(tempGlucoseArray) And IsArray(tempTimeArray) And UBound(tempGlucoseArray) >= 0 And UBound(tempTimeArray) >= 0 Then
  396.                 Set srs = cht.Chart.SeriesCollection.NewSeries
  397.                 With srs
  398.                     .xValues = tempTimeArray
  399.                     .Values = tempGlucoseArray
  400.                     .Name = ""                    ' This removes the legend entry
  401.                    .Format.Line.Weight = 1       ' Adjust line weight for better visibility
  402.                    .Format.Line.Visible = True
  403.                     .Format.Line.ForeColor.RGB = RGB(colorIndex * 25 Mod 255, colorIndex * 50 Mod 255, colorIndex * 75 Mod 255)
  404.                 End With
  405.                 colorIndex = colorIndex + 1
  406.             End If
  407.         End If
  408.     Next i
  409.    
  410.     ' Add horizontal lines at y-values 70, 140, 180, and y-max
  411.    yMax = gMaxGlucoseY
  412.     yValues = Array(70, 140, 180, yMax)
  413.     For i = LBound(yValues) To UBound(yValues)
  414.         Set srs = cht.Chart.SeriesCollection.NewSeries
  415.         With srs
  416.             .ChartType = xlXYScatterLines
  417.             .xValues = Array(0, 1)                ' X-values spanning the entire width of the chart
  418.            .Values = Array(yValues(i), yValues(i))
  419.             .Name = ""                            ' This removes the legend entry
  420.            .Format.Line.Weight = 1.5             ' Adjust line weight for better visibility
  421.            If yValues(i) = 70 Or yValues(i) = 140 Then
  422.                 .Format.Line.ForeColor.RGB = RGB(0, 255, 0) ' Green color for lines at 70 and 140
  423.            Else
  424.                 .Format.Line.ForeColor.RGB = RGB(255, 0, 0) ' Red color for lines at 180 and y-max
  425.            End If
  426.             .MarkerStyle = xlMarkerStyleNone      ' No markers
  427.        End With
  428.     Next i
  429.    
  430.     ' Format axes
  431.    With cht.Chart.Axes(xlCategory)
  432.         .MinimumScale = 0
  433.         .MaximumScale = 1.04166667                ' Changed as requested
  434.        .MajorUnit = 0.04166667                   ' 1 hour interval
  435.        .MinorUnit = 0.04166667                   ' 1 hour interval
  436.        .HasMajorGridlines = True
  437.         .HasMinorGridlines = True
  438.         .TickLabels.Orientation = xlUpward        ' Rotate text 270 degrees
  439.        .TickLabels.NumberFormat = "h AM/PM"
  440.     End With
  441.    
  442.     With cht.Chart.Axes(xlValue)
  443.         .MajorUnit = 20
  444.         .MinorUnit = 10
  445.         .HasMajorGridlines = True
  446.         .HasMinorGridlines = True
  447.         .MinimumScale = 0
  448.         .MaximumScale = gMaxGlucoseY              ' Set max Y-axis bound to gMaxGlucoseY
  449.    End With
  450.    
  451.     ' Set chart title
  452.    If startDate = endDate Then
  453.         chartTitle = "Glucose Values on " & Format(startDate, "ddd, mmm d, yyyy")
  454.     Else
  455.         chartTitle = "Glucose Values from " & Format(startDate, "mm/dd/yyyy") & " to " & Format(endDate, "mm/dd/yyyy")
  456.     End If
  457.    
  458.     With cht.Chart
  459.         .HasTitle = True
  460.         .chartTitle.Text = chartTitle
  461.         .chartTitle.Format.TextFrame2.TextRange.Font.Size = 16 ' Set font size to 16
  462.        .Axes(xlCategory).HasTitle = True
  463.         .Axes(xlCategory).AxisTitle.Text = "Time"
  464.         .Axes(xlValue).HasTitle = True
  465.         .Axes(xlValue).AxisTitle.Text = "Glucose"
  466.         .HasLegend = False                        ' Remove the legend
  467.    End With
  468.    
  469.     cht.Chart.Refresh
  470. End Sub
  471.  
  472. Sub PlotMultiSeriesAverageGlucoseByHourChart(startDate As Date, endDate As Date, startTime As Date, endTime As Date, uniqueDates As Variant)
  473.     Dim ws As Worksheet
  474.     Dim cht As ChartObject
  475.     Dim srs As series
  476.     Dim chartLeft As Double, chartTop As Double, chartWidth As Double, chartHeight As Double
  477.     Dim chartTitle As String
  478.     Dim hourlyTotals(0 To 23) As Long
  479.     Dim hourCounts(0 To 23) As Long
  480.     Dim hourlyAverages(0 To 23) As Long
  481.     Dim i As Long, j As Long, k As Long, hourIndex As Long
  482.     Dim currentDate As Date
  483.     Dim glucoseValues As Variant
  484.     Dim timeValues As Variant
  485.     Dim xValues(0 To 23) As String
  486.     Dim totalSum As Long
  487.     Dim totalCount As Long
  488.     Dim avgGlucose As Long
  489.     Dim visibleRange As Range
  490.     Dim startHour As Integer, endHour As Integer
  491.     Dim gmi As Double
  492.     On Error GoTo ErrHandler
  493.     Set ws = ActiveSheet
  494.     For i = 0 To 23
  495.         hourlyTotals(i) = 0
  496.         hourCounts(i) = 0
  497.         xValues(i) = Format(TimeSerial(i, 0, 0), "h AM/PM")
  498.     Next i
  499.     For i = LBound(uniqueDates) To UBound(uniqueDates)
  500.         currentDate = uniqueDates(i)
  501.         If currentDate >= startDate And currentDate <= endDate Then
  502.             glucoseValues = GetGlucoseValuesArrayForADateRange(currentDate, currentDate, startTime, endTime)
  503.             timeValues = GetTimeValuesArrayForDateRange(currentDate, currentDate, startTime, endTime)
  504.             If IsArray(glucoseValues) And IsArray(timeValues) Then
  505.                 For j = LBound(glucoseValues) To UBound(glucoseValues)
  506.                     hourIndex = hour(CDate(timeValues(j)))
  507.                     hourlyTotals(hourIndex) = hourlyTotals(hourIndex) + glucoseValues(j)
  508.                     hourCounts(hourIndex) = hourCounts(hourIndex) + 1
  509.                     totalSum = totalSum + glucoseValues(j)
  510.                     totalCount = totalCount + 1
  511.                 Next j
  512.             End If
  513.         End If
  514.     Next i
  515.     For i = 0 To 23
  516.         If hourCounts(i) > 0 Then
  517.             hourlyAverages(i) = CLng(hourlyTotals(i) / hourCounts(i))
  518.         Else
  519.             hourlyAverages(i) = 0
  520.         End If
  521.     Next i
  522.     If totalCount > 0 Then
  523.         avgGlucose = CLng(totalSum / totalCount)
  524.     Else
  525.         avgGlucose = 0
  526.     End If
  527.     gmi = 3.31 + 0.02392 * avgGlucose
  528.     For Each cht In ws.ChartObjects
  529.         If cht.Name = "ChartAvgGlucose" Then cht.Delete
  530.     Next cht
  531.     Set visibleRange = ActiveWindow.ActivePane.visibleRange
  532.     chartWidth = visibleRange.Width / 2 - 6
  533.     chartHeight = visibleRange.Height - ws.Cells(3, 1).Top - 10
  534.     chartLeft = ws.Cells(3, 1).Left + chartWidth
  535.     chartTop = ws.Cells(3, 1).Top
  536.     Set cht = ws.ChartObjects.Add(Left:=chartLeft, Top:=chartTop, Width:=chartWidth, Height:=chartHeight)
  537.     cht.Chart.ChartType = xlColumnClustered
  538.     cht.Name = "ChartAvgGlucose"
  539.     Set srs = cht.Chart.SeriesCollection.NewSeries
  540.     With srs
  541.         .Values = hourlyAverages
  542.         .xValues = xValues
  543.         .Name = ""
  544.     End With
  545.     For i = 1 To srs.Points.count
  546.         With srs.Points(i).Format.Fill.ForeColor
  547.             If srs.Values(i) <= 97 Then
  548.                 .RGB = RGB(0, 255, 0)             ' Green for values 96 or less
  549.            ElseIf srs.Values(i) >= 132 Then
  550.                 .RGB = RGB(255, 0, 0)             ' Red for values 132 or more
  551.            ElseIf srs.Values(i) >= 98 Then
  552.                 .RGB = RGB(255, 165, 0)           ' Orange for values between 97 and 131
  553.            End If
  554.         End With
  555.     Next i
  556.     With cht.Chart.Axes(xlCategory)
  557.         .TickLabelSpacing = 1
  558.         .TickMarkSpacing = 1
  559.         .HasMajorGridlines = True
  560.         .TickLabels.Orientation = xlUpward
  561.         .TickLabels.NumberFormat = "h AM/PM"
  562.     End With
  563.     With cht.Chart.Axes(xlValue)
  564.         .MajorUnit = 20
  565.         .MinorUnit = 10
  566.         .HasMajorGridlines = True
  567.         .HasMinorGridlines = True
  568.         .MinimumScale = 0
  569.         .MaximumScale = gMaxGlucoseY              ' Set max Y-axis bound to gMaxGlucoseY
  570.    End With
  571.    
  572.     ' Set chart title
  573.    If startDate = endDate Then
  574.         chartTitle = "Average Hourly Glucose on " & Format(startDate, "ddd, mmm d, yyyy") & " from " & Format(startTime, "h AM/PM") & " to " & Format(endTime, "h AM/PM")
  575.     Else
  576.         chartTitle = "Average Hourly Glucose from " & Format(startDate, "mm/dd/yyyy") & " " & Format(startTime, "h:mm AM/PM") & _
  577.                      " to " & Format(endDate, "mm/dd/yyyy") & " " & Format(endTime, "h:mm AM/PM")
  578.     End If
  579.    
  580.     With cht.Chart
  581.         .HasTitle = True
  582.         .chartTitle.Text = chartTitle
  583.         .chartTitle.Format.TextFrame2.TextRange.Font.Size = 16 ' Set font size to 16
  584.        .Axes(xlCategory).HasTitle = True
  585.         .Axes(xlCategory).AxisTitle.Text = "Hour"
  586.         .Axes(xlValue).HasTitle = True
  587.         .Axes(xlValue).AxisTitle.Text = "Average Glucose"
  588.         .HasLegend = False
  589.     End With
  590.     srs.HasDataLabels = True
  591.     With srs.DataLabels
  592.         .ShowValue = True
  593.         .Position = xlLabelPositionInsideEnd
  594.         .NumberFormat = "0"
  595.     End With
  596.    
  597.     ' Add horizontal lines at y-values 97, 132, and avgGlucose
  598.    Dim lineSeriesNames As Variant
  599.     Dim lineValues As Variant
  600.     Dim lineColors As Variant
  601.     Dim lineSrs As series
  602.     Dim lineText As Variant
  603.    
  604.     lineSeriesNames = Array("97Normal", "132Diabetic", "AverageGlucose")
  605.     lineValues = Array(97, 132, avgGlucose)
  606.     lineColors = Array(RGB(0, 255, 0), RGB(255, 0, 0), RGB(0, 0, 0))
  607.    
  608.     For k = 0 To 2
  609.         Set lineSrs = cht.Chart.SeriesCollection.NewSeries
  610.         With lineSrs
  611.             .ChartType = xlXYScatterLines
  612.             .xValues = Array(0, 24)               ' X-values spanning the entire width of the chart
  613.            .Values = Array(lineValues(k), lineValues(k))
  614.             .Name = lineSeriesNames(k)
  615.             .Format.Line.ForeColor.RGB = lineColors(k)
  616.             If k = 0 Then
  617.                 .Format.Line.Weight = 3           ' Normal line width 3
  618.            Else
  619.                 .Format.Line.Weight = 1.5         ' Other lines width 2
  620.            End If
  621.             .MarkerStyle = xlMarkerStyleNone      ' No markers
  622.        End With
  623.     Next k
  624.    
  625.     ' Add text box with line descriptions
  626.    Dim textBox As Shape
  627.     Set textBox = cht.Chart.Shapes.AddTextbox(msoTextOrientationHorizontal, 50, 50, 300, 100)
  628.     With textBox.TextFrame2.TextRange
  629.         .Text = "Average Glucose: " & avgGlucose & " (" & Format(gmi, "0.0") & "%)" & vbCrLf & "<= 97 (5.6%) Normal" & vbCrLf & ">= 98 (5.7%) & <= 132 (6.5%) (132) Pre-Diabetic" & vbCrLf & ">= 132 (6.5%) Diabetic"
  630.         .Font.Size = 14
  631.         .Font.Bold = msoTrue
  632.         .ParagraphFormat.Alignment = msoAlignRight
  633.         .Paragraphs(1).Font.Fill.ForeColor.RGB = RGB(0, 0, 0) ' Black for Average
  634.        .Paragraphs(2).Font.Fill.ForeColor.RGB = RGB(0, 255, 0) ' Green for Normal
  635.        .Paragraphs(3).Font.Fill.ForeColor.RGB = RGB(255, 165, 0) ' Orange for Pre Diabetic
  636.        .Paragraphs(4).Font.Fill.ForeColor.RGB = RGB(255, 0, 0) ' Red for Diabetic
  637.    End With
  638.    
  639.     cht.Chart.Refresh
  640.     Exit Sub
  641. ErrHandler:
  642.     MsgBox "Error in PlotMultiSeriesAverageGlucoseByHourChart: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  643. End Sub
  644.  
  645. Sub CreateHeatMap()
  646.     Dim wsHeatMap As Worksheet
  647.     Dim wsOrigData As Worksheet
  648.     Dim uniqueDates As Variant
  649.     Dim uniqueMonths As Collection
  650.     Dim currentDate As Date
  651.     Dim avgGlucose As Double
  652.     Dim glucoseValues As Variant
  653.     Dim totalGlucose As Double
  654.     Dim count As Long
  655.     Dim i As Long, j As Long, k As Long
  656.     Dim dayOfMonth As Integer
  657.     Dim targetCell As Range
  658.     Dim monthCell As Range
  659.     Dim monthYear As String
  660.     Dim lastRow As Long
  661.     On Error GoTo ErrHandler
  662.    
  663.     ' Set worksheets
  664.    Set wsHeatMap = ThisWorkbook.Worksheets("heatmap")
  665.     Set wsOrigData = ThisWorkbook.Worksheets("OrigData")
  666.    
  667.     ' Clear existing content and formatting
  668.    wsHeatMap.Cells.Clear
  669.     wsHeatMap.Cells.ClearFormats
  670.    
  671.     ' Get unique dates
  672.    uniqueDates = gUniqueDates
  673.    
  674.     ' Initialize unique months collection
  675.    Set uniqueMonths = New Collection
  676.    
  677.     ' Extract unique month/year combinations
  678.    On Error Resume Next
  679.     For i = LBound(uniqueDates) To UBound(uniqueDates)
  680.         monthYear = Format(uniqueDates(i), "MMM-YY")
  681.         uniqueMonths.Add monthYear, monthYear
  682.     Next i
  683.     On Error GoTo 0
  684.    
  685.     ' Set up the top row with dates from 1 to 31
  686.    wsHeatMap.Cells(3, 2).Value = "Month"
  687.     For i = 1 To 31
  688.         wsHeatMap.Cells(3, i + 2).Value = i
  689.     Next i
  690.    
  691.     ' Bold and set font size for the top row and first column
  692.    wsHeatMap.Rows(3).Font.Bold = True
  693.     wsHeatMap.Rows(3).Font.Size = 12
  694.     wsHeatMap.Columns(2).Font.Bold = True
  695.     wsHeatMap.Columns(2).Font.Size = 12
  696.    
  697.     ' Loop through unique months
  698.    For i = 1 To uniqueMonths.count
  699.         monthYear = uniqueMonths(i)
  700.         Set monthCell = wsHeatMap.Cells(i + 3, 2) ' Month column is column B
  701.        monthCell.Value = monthYear
  702.         monthCell.NumberFormat = "MMM-YY"         ' Format the cell as "MMM-YY"
  703.        
  704.         ' Loop through unique dates to find matching month/year
  705.        For j = LBound(uniqueDates) To UBound(uniqueDates)
  706.             If Format(uniqueDates(j), "MMM-YY") = monthYear Then
  707.                 currentDate = uniqueDates(j)
  708.                 glucoseValues = GetGlucoseValuesArrayForADateRange(currentDate, currentDate, TimeSerial(0, 0, 0), TimeSerial(23, 59, 59))
  709.                
  710.                 ' Calculate average glucose for the date
  711.                If IsArray(glucoseValues) Then
  712.                     totalGlucose = 0
  713.                     count = 0
  714.                     For k = LBound(glucoseValues) To UBound(glucoseValues)
  715.                         totalGlucose = totalGlucose + glucoseValues(k)
  716.                         count = count + 1
  717.                     Next k
  718.                     If count > 0 Then
  719.                         avgGlucose = Int(totalGlucose / count) ' Convert to integer
  720.                    Else
  721.                         avgGlucose = 0
  722.                     End If
  723.                 Else
  724.                     avgGlucose = 0
  725.                 End If
  726.                
  727.                 ' Determine the day of the month and target cell
  728.                dayOfMonth = Day(currentDate)
  729.                 Set targetCell = wsHeatMap.Cells(i + 3, dayOfMonth + 2) ' Offset by 3 rows and 2 columns
  730.                
  731.                 ' Write average glucose value in the target cell
  732.                targetCell.Value = avgGlucose
  733.                
  734.                 ' Apply conditional formatting
  735.                If avgGlucose <= 97 Then
  736.                     targetCell.Interior.Color = RGB(0, 255, 0) ' Green
  737.                ElseIf avgGlucose >= 98 And avgGlucose <= 132 Then
  738.                     targetCell.Interior.Color = RGB(255, 165, 0) ' Orange
  739.                ElseIf avgGlucose >= 132 Then
  740.                     targetCell.Interior.Color = RGB(255, 0, 0) ' Red
  741.                End If
  742.             End If
  743.         Next j
  744.     Next i
  745.    
  746.     ' Find the last row with data
  747.    lastRow = wsHeatMap.Cells(wsHeatMap.Rows.count, "B").End(xlUp).Row
  748.    
  749.     ' Apply borders to the entire heatmap data
  750.    With wsHeatMap.Range("B3:AG" & lastRow)
  751.         .Borders(xlEdgeLeft).LineStyle = xlContinuous
  752.         .Borders(xlEdgeTop).LineStyle = xlContinuous
  753.         .Borders(xlEdgeBottom).LineStyle = xlContinuous
  754.         .Borders(xlEdgeRight).LineStyle = xlContinuous
  755.         .Borders(xlInsideVertical).LineStyle = xlContinuous
  756.         .Borders(xlInsideHorizontal).LineStyle = xlContinuous
  757.     End With
  758.    
  759.     ' AutoFit column width
  760.    wsHeatMap.Range("B3:AG" & lastRow).Columns.AutoFit
  761.    
  762.     Exit Sub
  763.    
  764. ErrHandler:
  765.     MsgBox "Error in CreateHeatMap: " & Err.Description & vbNewLine & "Error Number: " & Err.Number
  766. End Sub
  767.  
  768.  
  769. Option Explicit
  770. Sub PrevButtonClick()
  771.     Dim ws As Worksheet
  772.     Dim currentStartDate As Date
  773.     Dim newStartDate As Date
  774.     Dim startTime As Date, endTime As Date
  775.     Dim uniqueDates As Variant
  776.  
  777.     Set ws = ActiveSheet
  778.     currentStartDate = ws.Range("A2").Value
  779.     startTime = ws.Range("C2").Value
  780.     endTime = ws.Range("D2").Value
  781.    
  782.     ' Check if endTime is 12:00:00 AM and change it to 11:59:59 PM if it is
  783.    If endTime = TimeSerial(0, 0, 0) Then
  784.         endTime = TimeSerial(23, 59, 59)
  785.     End If
  786.    
  787.     Debug.Print "PrevButtonClick calling GetUniqueDates"
  788.     uniqueDates = gUniqueDates
  789.     newStartDate = FindPreviousDate(currentStartDate, uniqueDates)
  790.    
  791.     If newStartDate <> 0 Then
  792.         ws.Range("A2").Value = newStartDate
  793.         'ws.Range("B2").Value = newStartDate ' Set end date same as start date
  794.        
  795.         PlotMultiSeriesGlucoseVsTimeXYChart newStartDate, newStartDate, startTime, endTime, uniqueDates
  796.         PlotMultiSeriesAverageGlucoseByHourChart newStartDate, newStartDate, startTime, endTime, uniqueDates
  797.         DisplayStatsForSelectedTimeFrame newStartDate, newStartDate, startTime, endTime, uniqueDates
  798.     Else
  799.         MsgBox "No previous date available."
  800.     End If
  801. End Sub
  802.  
  803. Sub NextButtonClick()
  804.     Dim ws As Worksheet
  805.     Dim currentStartDate As Date
  806.     Dim newStartDate As Date
  807.     Dim startTime As Date, endTime As Date
  808.     Dim uniqueDates As Variant
  809.  
  810.     Set ws = ActiveSheet
  811.     currentStartDate = ws.Range("A2").Value
  812.     startTime = ws.Range("C2").Value
  813.     endTime = ws.Range("D2").Value
  814.     ' Check if endTime is 12:00:00 AM and change it to 11:59:59 PM if it is
  815.    If endTime = TimeSerial(0, 0, 0) Then
  816.         endTime = TimeSerial(23, 59, 59)
  817.     End If
  818.    
  819.     uniqueDates = gUniqueDates
  820.     newStartDate = FindNextDate(currentStartDate, uniqueDates)
  821.    
  822.     If newStartDate <> 0 Then
  823.         ws.Range("A2").Value = newStartDate
  824.         'ws.Range("B2").Value = newStartDate ' Set end date same as start date
  825.        
  826.         PlotMultiSeriesGlucoseVsTimeXYChart newStartDate, newStartDate, startTime, endTime, uniqueDates
  827.         PlotMultiSeriesAverageGlucoseByHourChart newStartDate, newStartDate, startTime, endTime, uniqueDates
  828.         DisplayStatsForSelectedTimeFrame newStartDate, newStartDate, startTime, endTime, uniqueDates
  829.     Else
  830.         MsgBox "No next date available."
  831.     End If
  832. End Sub
  833.  
  834. Function FindPreviousDate(currentDate As Date, uniqueDates As Variant) As Date
  835.     Dim i As Long
  836.     For i = UBound(uniqueDates) To LBound(uniqueDates) Step -1
  837.         If uniqueDates(i) < currentDate Then
  838.             FindPreviousDate = uniqueDates(i)
  839.             Exit Function
  840.         End If
  841.     Next i
  842.     FindPreviousDate = 0                          ' Return 0 if no previous date found
  843. End Function
  844.  
  845. Function FindNextDate(currentDate As Date, uniqueDates As Variant) As Date
  846.     Dim i As Long
  847.     For i = LBound(uniqueDates) To UBound(uniqueDates)
  848.         If uniqueDates(i) > currentDate Then
  849.             FindNextDate = uniqueDates(i)
  850.             Exit Function
  851.         End If
  852.     Next i
  853.     FindNextDate = 0                              ' Return 0 if no next date found
  854. End Function
  855. Option Explicit
  856. Sub DisplayStatsForSelectedTimeFrame(startDate As Date, endDate As Date, startTime As Date, endTime As Date, uniqueDates As Variant)
  857.     Dim ws As Worksheet
  858.     Dim glucoseValues As Variant
  859.     Dim timeValues As Variant
  860.     Dim allGlucoseValues() As Double
  861.     Dim currentDate As Date
  862.     Dim i As Long, j As Long, k As Long
  863.     Dim dataCount As Long
  864.     Dim gmi As Double
  865.  
  866.     Set ws = ActiveSheet
  867.    
  868.     ' Initialize array to store all glucose values
  869.    ReDim allGlucoseValues(1 To 1)
  870.     dataCount = 0
  871.    
  872.     ' Collect all glucose values within the specified date and time range
  873.    For i = LBound(uniqueDates) To UBound(uniqueDates)
  874.         currentDate = uniqueDates(i)
  875.         If currentDate >= startDate And currentDate <= endDate Then
  876.             glucoseValues = GetGlucoseValuesArrayForADateRange(currentDate, currentDate, startTime, endTime)
  877.             timeValues = GetTimeValuesArrayForDateRange(currentDate, currentDate, startTime, endTime)
  878.            
  879.             If IsArray(glucoseValues) And IsArray(timeValues) Then
  880.                 For j = LBound(glucoseValues) To UBound(glucoseValues)
  881.                     dataCount = dataCount + 1
  882.                     ReDim Preserve allGlucoseValues(1 To dataCount)
  883.                     allGlucoseValues(dataCount) = glucoseValues(j)
  884.                 Next j
  885.             End If
  886.         End If
  887.     Next i
  888.    
  889.     ' Calculate statistics
  890.    If dataCount > 0 Then
  891.         Dim statsRange As Range
  892.         Set statsRange = ws.Range("J1")
  893.        
  894.         ' Headers
  895.        statsRange.Offset(0, 0).Value = "Count"
  896.         statsRange.Offset(0, 1).Value = "Min"
  897.         statsRange.Offset(0, 2).Value = "Avg"
  898.         statsRange.Offset(0, 3).Value = "Median"
  899.         statsRange.Offset(0, 4).Value = "Max"
  900.         statsRange.Offset(0, 5).Value = "Std. Dev"
  901.         statsRange.Offset(0, 6).Value = "GMI%"
  902.        
  903.         Dim avgGlucose As Long
  904.         avgGlucose = Application.WorksheetFunction.Average(allGlucoseValues)
  905.         gmi = 3.31 + 0.02392 * avgGlucose
  906.        
  907.         ' Values
  908.        statsRange.Offset(1, 0).Value = dataCount
  909.         statsRange.Offset(1, 1).Value = Int(Application.WorksheetFunction.Min(allGlucoseValues))
  910.         statsRange.Offset(1, 2).Value = Int(avgGlucose)
  911.         statsRange.Offset(1, 3).Value = Int(Application.WorksheetFunction.Median(allGlucoseValues))
  912.         statsRange.Offset(1, 4).Value = Int(Application.WorksheetFunction.Max(allGlucoseValues))
  913.         statsRange.Offset(1, 5).Value = Application.WorksheetFunction.StDev_P(allGlucoseValues)
  914.         statsRange.Offset(1, 6).Value = gmi
  915.        
  916.         ' Format cells
  917.        With statsRange.Offset(1, 0).Resize(1, 5)
  918.             .NumberFormat = "0"
  919.             .Font.Bold = True
  920.         End With
  921.         statsRange.Offset(1, 5).NumberFormat = "0.00"
  922.         statsRange.Offset(1, 5).Font.Bold = True
  923.         statsRange.Offset(1, 6).NumberFormat = "0.0"
  924.         statsRange.Offset(1, 6).Font.Bold = True
  925.        
  926.         ' Add border
  927.        With statsRange.Resize(2, 7)
  928.             .Borders.Weight = xlThin
  929.             .Borders(xlEdgeBottom).Weight = xlMedium
  930.         End With
  931.     Else
  932.         MsgBox "No data found for the specified date and time range.", vbInformation
  933.     End If
  934. End Sub
  935. Private Sub Workbook_Open()
  936.     'Stop
  937.    Call InitializeWorkbook
  938.     Call InitDV_Click
  939.     ' see Private Sub Worksheet_Change(ByVal Target As Range) in FiteredData sheet event
  940. End Sub
  941. Option Explicit
  942.  
  943. Private Sub Worksheet_Change(ByVal Target As Range)
  944.     'Debug.Print "Filtered Data Worksheet_Change event triggered for " & Target.Address
  945.  
  946.     If Not Intersect(Target, Range("A2:D2")) Is Nothing Then
  947.         Application.EnableEvents = False
  948.         If Target.Address = "$A$2" Then
  949.             Call UpdateEndDateValidation
  950.         ElseIf Target.Address = "$C$2" Then
  951.             Call UpdateEndTimeValidation
  952.         ElseIf Target.Address = "$B$2" Then
  953.             'Debug.Print "EndDate Changed"
  954.            Call FindDatesBetweenStartAndEndDates
  955.         End If
  956.         Application.EnableEvents = True
  957.     End If
  958. End Sub
  959.  
Advertisement
Add Comment
Please, Sign In to add comment