Every Monday, charts the recent history of one metric from your sheet and emails you the chart with a note on what changed.
Uses
Claude
Gmail
Google SheetsQuickChart
Weekly chart of how a metric has moved
spreadsheetUrl to blank.Set spreadsheetUrl to blank.measureName to blank.Set measureName to blank.recipientEmail to blank.Set recipientEmail to blank.historyTab to History.Set historyTab to History.maxPoints to 24.Set maxPoints to 24.measureName and save it as measureLabel.Trim measureName and save it as measureLabel.measureLabel lowercase and save it as wantedMeasure.Make measureLabel lowercase and save it as wantedMeasure.spreadsheetUrl. Save it as history.Read the rows of spreadsheetUrl. Save it as history.periodLabels to an empty list.Set periodLabels to an empty list.pointValues to an empty list.Set pointValues to an empty list.readingLines to an empty list.Set readingLines to an empty list.leftOff to an empty list.Set leftOff to an empty list.entry in history.rows:For each entry in history.rows:rowErrorIf a step below fails, save the error as rowErrorTry
entry.Measure lowercase and save it as rowMeasure.Make entry.Measure lowercase and save it as rowMeasure.rowMeasure is wantedMeasureIf rowMeasure is wantedMeasureYes
entry.Period and save it as periodRaw.Trim entry.Period and save it as periodRaw.periodRaw with "Trim periodRaw with
replaced by with , replaced by with replaced by and save it as period.entry.Value and save it as reading.Extract the first number from entry.Value and save it as reading.period is emptyIf period is emptyYes
a row with no period name to the end of leftOff and save it as leftOff.Add a row with no period name to the end of leftOff and save it as leftOff.Else if @reading is blank
period to the end of leftOff and save it as leftOff.Add period to the end of leftOff and save it as leftOff.Otherwise
period to the end of periodLabels and save it as periodLabels.Add period to the end of periodLabels and save it as periodLabels.reading as text to the end of pointValues and save it as pointValues.Add reading as text to the end of pointValues and save it as pointValues.period: reading as text to the end of readingLines and save it as readingLines.Add period: reading as text to the end of readingLines and save it as readingLines.No
No steps
On error
rowError as text.Show in the output: Skipped a row that could not be read: rowError as text.cappedNote to blank.Set cappedNote to blank.takeFromEnd to 0 minus maxPoints.Set takeFromEnd to 0 minus maxPoints.periodLabels is greater than maxPointsIf the length of periodLabels is greater than maxPointsYes
periodLabels from position takeFromEnd on and save it as periodLabels.Take periodLabels from position takeFromEnd on and save it as periodLabels.pointValues from position takeFromEnd on and save it as pointValues.Take pointValues from position takeFromEnd on and save it as pointValues.readingLines from position takeFromEnd on and save it as readingLines.Take readingLines from position takeFromEnd on and save it as readingLines.cappedNote to Only the most recent maxPoints as text readings are charted. Raise 'maxPoints' to chart more, at the cost of a more crowded axis.Change cappedNote to Only the most recent maxPoints as text readings are charted. Raise 'maxPoints' to chart more, at the cost of a more crowded axis.No
No steps
periodLabels is emptyIf periodLabels is emptyYes
recipientEmail.Send an email to recipientEmail.
Subject: No readings to chart for measureLabelNothing on the '@historyTab' tab had a readable number against the measure '@measureLabel', so there is no chart to send.
Check that the measure is spelled the same way in the Measure column, and that whatever fills that tab is still running.No
No steps
periodLabels with , and save it as labelsText.Join periodLabels with , and save it as labelsText.pointValues with , and save it as valuesText.Join pointValues with , and save it as valuesText.readingLines with a new line and save it as numbersText.Join readingLines with a new line and save it as numbersText.chartUrl to blank.Set chartUrl to blank.chartErrorIf a step below fails, save the error as chartErrorTry
measureLabel. Save it as chart.Create a line chart titled measureLabel. Save it as chart.chart.url and save it as chartUrl.Trim chart.url and save it as chartUrl.On error
chartError as text.Show in the output: The chart could not be drawn: chartError as text.note to blank.Set note to blank.noteErrorIf a step below fails, save the error as noteErrorTry
measureLabel
Readings:
numbersText'. Save it as written.
Maximum response length: 400written.response_text and save it as note.Trim written.response_text and save it as note.On error
noteError as text.Show in the output: The note on what changed could not be written: noteError as text.bodyParts to an empty list.Set bodyParts to an empty list.periodLabels as text readings. to the end of bodyParts and save it as bodyParts.Add Here is how '@measureLabel' has moved over its last the length of periodLabels as text readings. to the end of bodyParts and save it as bodyParts.note isn't emptyIf note isn't emptyYes
note to the end of bodyParts and save it as bodyParts.No
No steps
chartUrl is emptyIf chartUrl is emptyYes
The chart could not be drawn this time, so the readings are below on their own. to the end of bodyParts and save it as bodyParts.Add The chart could not be drawn this time, so the readings are below on their own. to the end of bodyParts and save it as bodyParts.No
chartUrl to the end of bodyParts and save it as bodyParts.numbersText to the end of bodyParts and save it as bodyParts.cappedNote isn't emptyIf cappedNote isn't emptyYes
cappedNote to the end of bodyParts and save it as bodyParts.Add cappedNote to the end of bodyParts and save it as bodyParts.No
No steps
leftOff isn't emptyIf leftOff isn't emptyYes
leftOff joined by , to the end of bodyParts and save it as bodyParts.Add Left off the chart, with no readable number: leftOff joined by , to the end of bodyParts and save it as bodyParts.No
No steps
bodyParts with a blank line and save it as emailBody.Join bodyParts with a blank line and save it as emailBody.recipientEmail.Send an email to recipientEmail.
Subject: measureLabel - how it has movedemailBody