I'm doing some code revision and I'm looking at this portion of my Worksheet_Change()
event:
If Target.Address = "$A$4" Or _
Target.Address = "$A$7" Or _
Target.Address = "$A$10" Or _
Target.Address = "$B$21" Or _
Target.Address = "$B$22" Or _
Target.Address = "$B$23" Or _
Target.Address = "$B$24" Or _
Target.Address = "$B$25" Or _
Target.Address = "$B$26" Or _
Target.Address = "$B$33" Or _
Target.Address = "$B$35" Then
I'm considering using Union()
and Intersect()
to determine if my Target.Address
is within the range - would this be a better solution than what I have above? I don't like the idea of losing readability, but I also want to keep things clean and concise.
EDIT: Here's my entire Worksheet_Change()
event - have at it! Please disregard the clinical verbiage. This is all for 1 worksheet where I have several cells that can be changed. These cells reference categories, start times and end times. Based on category selection or the start date and end date, data validation is changed on another worksheet.
A good portion of this code manipulates a single chart that displays all of the employee data side by side. There's also an average line, a standard deviation line, and a special criteria line that may or may not be displayed on the chart. Additionally, certain locations can be filtered out from the chart based on the values in cells B12 through B26 (Show or Hide).
The individual bars on the graph are colored based on which location an employee belongs to. Also, n values are added as additional data points on the graph.
I'll also add that there are additional subroutines that are called in here, but they serve another purpose (they're used to create assessment reports). One also populates a listbox with employee initials that are out of range, to which a user can click them and be brought to a chart breaking down their numbers by week/month/year.
Here's what the worksheet looks like, with some private information blocked out:
Option Explicit
Option Compare Text
Dim catcol As Long, topnum As Long, botnum As Long, individual As Long, i As Long, j As Long, seriescount As Long
Dim title As String, averageformula As String, nvalueformula As String, nvaluetext As String, sdformula As String
Dim updatecharts As Boolean, yaxisnumerical As Boolean
Dim overallstats As Worksheet, datapulloverall As Worksheet, indivstats As Worksheet
Dim cht As Chart
Dim chtObj As ChartObject
Private Sub Worksheet_Change(ByVal Target As Range)
Set overallstats = ThisWorkbook.Worksheets("Overall Statistics")
Set datapulloverall = ThisWorkbook.Worksheets("Data Pull - Overall")
Set chtObj = overallstats.ChartObjects("Chart 1")
Set cht = chtObj.Chart
'Category change
If Target.Address = "$A$4" Or _
Target.Address = "$A$7" Or _
Target.Address = "$A$10" Or _
Target.Address = "$B$21" Or _
Target.Address = "$B$22" Or _
Target.Address = "$B$23" Or _
Target.Address = "$B$24" Or _
Target.Address = "$B$25" Or _
Target.Address = "$B$26" Or _
Target.Address = "$B$33" Or _
Target.Address = "$B$35" Then
'Check previous value hidden in columns near the change cell - if it's the same value, don't run the script.
If Target.Address = "$A$4" And Target.Value = overallstats.Cells(5, 1).Value Then Exit Sub
If Target.Address = "$A$7" And Target.Value = overallstats.Cells(8, 1).Value Then Exit Sub
If Target.Address = "$A$10" And Target.Value = overallstats.Cells(11, 1).Value Then Exit Sub
If Target.Address = "$B$33" And Target.Value = overallstats.Cells(34, 2).Value Then Exit Sub
If Target.Address = "$B$35" And Target.Value = overallstats.Cells(36, 2).Value Then Exit Sub
Application.EnableEvents = False
'On Error GoTo ErroredOut
Application.ScreenUpdating = False
updatecharts = True
overallstats.Unprotect "pw"
Select Case overallstats.Cells(4, 1).Value
Case "ICSI Fert Rate"
individual = 3
title = "ICSI Scientist"
nvaluetext = "Total # ICSI'd"
Case "IVF FR/Sperm Processor"
individual = 4
title = "Sperm Processor"
nvaluetext = "Total # Mature Oocytes"
Case "Necrotic Rate/ICSI Embryologist"
individual = 3
title = "ICSI Scientist"
nvaluetext = "Total # Mature Oocytes"
Case "Necrotic Rate/Fert Assessor"
individual = 5
title = "Fert Assessor"
nvaluetext = "Total # Mature Oocytes"
Case "IVF FR/Fert Assessor"
individual = 5
title = "Fert Assessor"
nvaluetext = "Total # Mature Oocytes"
Case "Ectopic Rate/Transfer Scientist"
individual = 8
title = "Transfer Scientist"
nvaluetext = "Total # Embryo Transfers"
Case "PR/UT Embryologist"
individual = 8
title = "UT Embryologist"
nvaluetext = "Total # Embryo Transfers"
Case "PR/Thaw Embryologist"
individual = 10
title = "Thaw Embryologist"
nvaluetext = "Total # Embryo Transfers"
Case "PR/Freeze Embryologist"
individual = 9
title = "Freeze Embryologist"
nvaluetext = "Total # Embryo Transfers"
Case "PR/Biopsy Embryologist"
individual = 13
title = "Biopsy Embryologist"
nvaluetext = "Total # Embryo Transfers"
Case "Average # Eggs/Scientist"
individual = 7
title = "Scientist"
yaxisnumerical = True
nvaluetext = "Total # Retrievals"
Case "Survival rate by thaw"
individual = 10
title = "Thaw Scientist"
nvaluetext = "Total # Embryos Thawed"
Case "Survival rate by freeze (cryo date)"
individual = 9
title = "Cryo Scientist"
nvaluetext = "Total # Embryos Thawed"
Case "Survival rate by freeze (thaw date)"
individual = 9
title = "Cryo Scientist"
nvaluetext = "Total # Embryos Thawed"
Case "Not recovered rate by thaw"
individual = 10
title = "Thaw Scientist"
nvaluetext = "Total # Embryos Thawed"
Case "Not recovered rate by freeze"
individual = 9
title = "Cryo Scientist"
nvaluetext = "Total # Embryos Thawed"
Case "No result biopsy rate"
individual = 11
title = "No Result BX Tech"
nvaluetext = "Total # Embryos Biopsied"
Case "Damaged during biopsy rate"
individual = 12
title = "Lysed Embryo Tech"
nvaluetext = "Total # Embryos Biopsied"
Case "Usable Blast/ICSI Embryologist"
individual = 3
title = "ICSI Embryologist"
nvaluetext = "Total # ICSI Ferts"
End Select
overallstats.Cells(16, 1).Value = nvaluetext
overallstats.Protect "pw"
End If
If updatecharts = True Then
'Repopulate the individuals lists on x-axis based on date
Call PopulateDataPullOverallValidation
overallstats.Unprotect "pw"
catcol = datapulloverall.Rows(1).Find(What:=overallstats.Cells(4, 1).Value).Column
averageformula = Replace(datapulloverall.Cells(2, catcol).Formula, "$" & ColumnLetter(individual) & "2", """*""")
sdformula = Replace(Left(Split(datapulloverall.Cells(2, catcol).Formula, "/")(1), Len(Split(datapulloverall.Cells(2, catcol).Formula, "/")(1)) - 3), "$" & ColumnLetter(individual) & "2", """*""")
'Update average column on Data Pull - Overall - NOT DYNAMIC row range
datapulloverall.Range("AG2:AG50").Formula = averageformula
'Change to whole numbers for average eggs retrieved, otherwise leave as percentage
If overallstats.Cells(4, 1).Value = "Average # Eggs/Scientist" Then
datapulloverall.Range("AG2:AG50").NumberFormat = "0.00"
datapulloverall.Range("AJ2:AJ50").NumberFormat = "0.00"
Else
datapulloverall.Range("AG2:AG50").NumberFormat = "0.00%"
datapulloverall.Range("AJ2:AJ50").NumberFormat = "0.00%"
End If
'Update the adjusted average column on Data Pull - Overall - NOT DYNAMIC row range
If overallstats.Cells(4, 1).Value = "ICSI Fert Rate" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.05)
overallstats.Range("A33").Value = "Calc 5% below mean"
ElseIf overallstats.Cells(4, 1).Value = "PR/UT Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "Necrotic Rate/ICSI Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value + (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% above mean"
ElseIf overallstats.Cells(4, 1).Value = "Survival rate by thaw" Or _
overallstats.Cells(4, 1).Value = "Survival rate by freeze (thaw date)" Or _
overallstats.Cells(4, 1).Value = "Survival rate by freeze (cryo date)" Then
datapulloverall.Range("AJ2:AJ50").Value = 0.97
overallstats.Range("A33").Value = "97% static"
ElseIf overallstats.Cells(4, 1).Value = "No result biopsy rate" Then
datapulloverall.Range("AJ2:AJ50").Value = 0.04
overallstats.Range("A33").Value = "4% static"
ElseIf overallstats.Cells(4, 1).Value = "IVF FR/Sperm Processor" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "Necrotic Rate/Fert Assessor" Then
datapulloverall.Range("AJ2:AJ50").Value = 0.04
overallstats.Range("A33").Value = "4% static"
ElseIf overallstats.Cells(4, 1).Value = "IVF FR/Fert Assessor" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "Ectopic Rate/Transfer Scientist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value + (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% above mean"
ElseIf overallstats.Cells(4, 1).Value = "PR/Thaw Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "PR/Freeze Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "PR/Biopsy Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
ElseIf overallstats.Cells(4, 1).Value = "Not recovered rate by thaw" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value * 2
overallstats.Range("A33").Value = "Above 2 x mean"
ElseIf overallstats.Cells(4, 1).Value = "Not recovered rate by freeze" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value * 2
overallstats.Range("A33").Value = "Above 2 x mean"
ElseIf overallstats.Cells(4, 1).Value = "Not recovered rate by freeze" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value * 2
overallstats.Range("A33").Value = "Above 2 x mean"
ElseIf overallstats.Cells(4, 1).Value = "Damaged during biopsy rate" Then
datapulloverall.Range("AJ2:AJ50").Value = 0.005
overallstats.Range("A33").Value = "0.5% static"
ElseIf overallstats.Cells(4, 1).Value = "Usable Blast/ICSI Embryologist" Then
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - (datapulloverall.Range("AG2").Value * 0.1)
overallstats.Range("A33").Value = "Calc 10% below mean"
Else
datapulloverall.Range("AJ2:AJ50").Value = datapulloverall.Range("AG2").Value - 0.1
overallstats.Range("A33").Value = "-0.1"
End If
'Update standard deviation column on Data Pull - Overall - NOT DYNAMIC row range
datapulloverall.Range("AI2:AI50").Formula = "=IFERROR(MAX(AG2" & overallstats.Cells(35, 1).Value & "*SQRT(AG2*(1-AG2)/" & sdformula & ")),0)"
For i = 2 To 50
nvalueformula = Left(Split(datapulloverall.Cells(i, catcol).Formula, "/")(1), Len(Split(datapulloverall.Cells(i, catcol).Formula, "/")(1)) - 3)
datapulloverall.Range("AH" & i).Formula = "=""n: "" & " & nvalueformula
Next i
topnum = 2
botnum = datapulloverall.Cells(datapulloverall.Rows.Count, individual).End(xlUp).Row
With cht
On Error Resume Next
.FullSeriesCollection(4).Delete
.FullSeriesCollection(3).Delete
.FullSeriesCollection(2).Delete
.FullSeriesCollection(1).Delete
On Error GoTo 0
'Add the main series
.SeriesCollection.NewSeries
.FullSeriesCollection(1).Name = "=""" & overallstats.Cells(4, 1).Value & """"
.FullSeriesCollection(1).Values = "='Data Pull - Overall'!$" & ColumnLetter(catcol) & "$" & topnum & ":$" & ColumnLetter(catcol) & "$" & botnum
.FullSeriesCollection(1).XValues = "='Data Pull - Overall'!$" & ColumnLetter(individual) & "$" & topnum & ":$" & ColumnLetter(individual) & "$" & botnum
.Axes(xlCategory, xlPrimary).AxisTitle.Text = title
.SeriesCollection(1).HasDataLabels = True
'This line causing errors for whatever reason, 7-25-19
On Error Resume Next
.SeriesCollection(1).DataLabels.Format.TextFrame2.TextRange.InsertChartField msoChartFieldRange, "='Data Pull - Overall'!$AH$2:$AH$" & botnum, 0
On Error GoTo 0
.SeriesCollection(1).DataLabels.ShowRange = True
.SeriesCollection(1).DataLabels.Separator = "" & Chr(13) & ""
'Add an average line
.SeriesCollection.NewSeries
.FullSeriesCollection(2).Name = "=""Average"""
.FullSeriesCollection(2).Values = "='Data Pull - Overall'!$AG$2:$AG$" & datapulloverall.Cells(datapulloverall.Rows.Count, individual).End(xlUp).Row
.FullSeriesCollection(2).ChartType = xlLine
.FullSeriesCollection(2).Format.Line.ForeColor.RGB = RGB(255, 0, 0)
On Error Resume Next
.FullSeriesCollection(2).DataLabels.ShowValue = False
On Error GoTo 0
.FullSeriesCollection(2).Format.Line.Weight = 2
seriescount = 2
If overallstats.Cells(35, 2).Value = "Show" Then
'Add a SD line
seriescount = seriescount + 1
.SeriesCollection.NewSeries
.FullSeriesCollection(seriescount).Name = "=""Standard Deviation"""
.FullSeriesCollection(seriescount).Values = "='Data Pull - Overall'!$AI$2:$AI$" & datapulloverall.Cells(datapulloverall.Rows.Count, individual).End(xlUp).Row
.FullSeriesCollection(seriescount).ChartType = xlLine
.FullSeriesCollection(seriescount).Format.Line.ForeColor.RGB = RGB(128, 0, 128)
End If
On Error Resume Next
.FullSeriesCollection(seriescount).DataLabels.ShowValue = False
On Error GoTo 0
.FullSeriesCollection(seriescount).Format.Line.Weight = 2
If overallstats.Cells(33, 2).Value = "Show" Then
'Add an average minus 10 percent line
seriescount = seriescount + 1
.SeriesCollection.NewSeries
.FullSeriesCollection(seriescount).Name = "=""Average Minus 10"""
.FullSeriesCollection(seriescount).Values = "='Data Pull - Overall'!$AJ$2:$AJ$" & datapulloverall.Cells(datapulloverall.Rows.Count, individual).End(xlUp).Row
.FullSeriesCollection(seriescount).ChartType = xlLine
.FullSeriesCollection(seriescount).Format.Line.ForeColor.RGB = RGB(175, 0, 175)
End If
On Error Resume Next
.FullSeriesCollection(seriescount).DataLabels.ShowValue = False
On Error GoTo 0
.FullSeriesCollection(seriescount).Format.Line.Weight = 2
'The following adjusts the minimum and maximum values on the y-axis so we can better view the data
If yaxisnumerical = False Then
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 1
If overallstats.Cells(4, 1).Value = "Damaged during biopsy rate" Or _
overallstats.Cells(4, 1).Value = "Necrotic Rate/Fert Assessor" Then
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 0.05
ElseIf InStr(overallstats.Cells(4, 1).Value, "Not recovered rate") Then
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 0.1
ElseIf overallstats.Cells(4, 1).Value = "No result biopsy rate" Or _
overallstats.Cells(4, 1).Value = "Necrotic Rate/ICSI Embryologist" Then
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 0.15
ElseIf InStr(overallstats.Cells(4, 1).Value, "Survival rate") Then
.Axes(xlValue).MinimumScale = 0.9
.Axes(xlValue).MaximumScale = 1
ElseIf overallstats.Cells(4, 1).Value = "Ectopic Rate/Transfer Scientist" Then
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 0.13
Else
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 1
End If
.Axes(xlValue).TickLabels.NumberFormat = "0.0%"
.Axes(xlValue, xlPrimary).AxisTitle.Text = "Rate"
Else
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 35
.Axes(xlValue).TickLabels.NumberFormat = "0"
.Axes(xlValue, xlPrimary).AxisTitle.Text = "Average # Eggs Retrieved"
End If
'Color code bars based on satellite location
Dim xvaluesarr As Variant
Dim xval As Variant
Dim j As Long
xvaluesarr = .SeriesCollection(1).XValues
j = 1
For Each xval In xvaluesarr
.FullSeriesCollection(1).Points(j).Format.Fill.Visible = msoTrue
'Location 1
If xval = "AEF" Or xval = "KMJ" Or xval = "RGR" Then
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(0, 176, 80)
'Location 2
ElseIf xval = "MLF" Or xval = "BAS" Then 'Removed CP - not on the initials list from Marianne
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(192, 0, 0)
'Location 3
ElseIf xval = "CJT" Or xval = "RXS" Then 'Removed KH - not on the initials list from Marianne
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(225, 153, 0)
'Location 4
ElseIf xval = "TLL" Or xval = "LMH" Then
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(112, 48, 160)
'Location 5
ElseIf xval = "MJA" Or xval = "ADB" Then 'Removed AW - not on initials list from Marianne
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(45, 239, 239)
'Anyone else
Else
.FullSeriesCollection(1).Points(j).Format.Fill.ForeColor.RGB = RGB(11, 0, 228)
End If
.FullSeriesCollection(1).Points(j).Format.Fill.Solid
j = j + 1
Next xval
Dim mystr As String
'Get N Value
mystr = "=" & Replace(Left(Split(datapulloverall.Cells(2, catcol).Formula, "/")(1), Len(Split(datapulloverall.Cells(2, catcol).Formula, "/")(1)) - 3), "$" & ColumnLetter(individual) & "2", """*""")
mystr = Replace(Replace(mystr, "$A$2", "'Data Pull - Overall'!A2"), "$B$2", "'Data Pull - Overall'!B2")
overallstats.Cells(17, 1).Value = mystr
updatecharts = False
yaxisnumerical = False
If overallstats.Cells(38, 22).Value <> "Presentation Mode" Then
Call PopulateBottomTable
End If
Call PopulateOutofRangeInitials
End With
If Target.Address = "$A$4" Then overallstats.Cells(5, 1).Value = Target.Value
If Target.Address = "$A$7" Then overallstats.Cells(8, 1).Value = Target.Value
If Target.Address = "$A$10" Then overallstats.Cells(11, 1).Value = Target.Value
If Target.Address = "$B$33" Then overallstats.Cells(34, 2).Value = Target.Value
If Target.Address = "$B$35" Then overallstats.Cells(36, 2).Value = Target.Value
'Update the cell that says what the chart is displaying
overallstats.Cells(8, 22).Value = Application.WorksheetFunction.VLookup(overallstats.Cells(4, 1).Value, ThisWorkbook.Worksheets("Data Validation").Range("N:Q"), 4, False)
overallstats.Protect "pw"
End If
If overallstats.Cells(38, 22).Value = "Presentation Mode" Then
Application.ScreenUpdating = True
Application.EnableEvents = True
End If
Exit Sub
ErroredOut:
overallstats.Protect "pw"
Debug.Print Err.Number
Debug.Print Err.Description
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Function ColumnLetter(colnum As Long) As String
ColumnLetter = Split(Cells(1, colnum).Address, "$")(1)
End Function