Use a Macro to add a value from one cell to another cell

# Postmortem: Silent Failure in Google Sheets Macro Due to Missing Write Operation

## Summary
A Google Sheets macro was created to add a value from cell B21 to cell B4. Despite correct value calculation, the updated result wasn't saved because the script lacked a write operation to persist changes to the spreadsheet.

## Root Cause
- **Missing sheet update call**: The script calculated `HomeScore = HS + HP` but never wrote this value back to the sheet
- **Variable scope confusion**: Re-declaring `HomeScore` as a local variable instead of updating the cell
- **No range assignment**: Failure to use `setValue()` to push the calculated result to cell B4

## Why This Happens in Real Systems
- Automated tools often abstract persistence mechanics, leading developers to assume automatic write-backs
- Transitioning between different automation environments (e.g., Excel VBA vs. Google Apps Script) causes API misunderstandings
- Logic focus shifts from I/O operations to calculation steps during development
- Stack Overflow examples often omit "obvious" persistence steps

## Real-World Impact
| Impact Area        | Consequences                                |
|--------------------|---------------------------------------------|
| **Data Accuracy**  | Correct calculations not reflected in reports |
| **Decision Making** | Stakeholders receive outdated metrics     |
| **User Trust**     | Repeated failures reduce confidence in automation |

## Example or Code
**Original Code (Flawed):**
```javascript
function SimPossession() {
  var spreadsheet = SpreadsheetApp.getActive();
  var PossessionSim = spreadsheet.getSheetByName('Possession Simulation');
  var HomeScore = PossessionSim.getRange("B4").getValue();
  var HomePossession = PossessionSim.getRange("B21").getValue();
  var HomeScore = HomeScore + HomePossession; // Never saves to sheet
}

Corrected Code:

function SimPossessionFixed() {
  var sheet = SpreadsheetApp.getActive()
                .getSheetByName('Possession Simulation');
  var updatedValue = sheet.getRange("B4").getValue() + 
                     sheet.getRange("B21").getValue();
  sheet.getRange("B4").setValue(updatedValue); // Critical write step
}

How Senior Engineers Fix It

  1. Trace data flow: Verify each variable’s read/write path through execution
  2. API contract validation: Confirm setValue() is called appropriately
  3. Boundary checks: Add logs with Logger.log() before/after write operations
  4. Idempotency guard: Prevent duplicate writes with Sheet.flush()
  5. Regression test: Create unit test that:
    function testSimPossession() {
    const initialValue = 5;
    sheet.getRange("B4").setValue(initialValue);
    SimPossessionFixed();
    const newValue = sheet.getRange("B4").getValue();
    if (newValue <= initialValue) throw "Write failed!";
    }

Why Juniors Miss It

  • 🔍 API unfamiliarity: Assumption that .getValue()/.setValue() work symmetrically
  • 🧠 Mental model mismatch: Applying Excel VBA persistence patterns to Google Apps Script
  • ⏱️ Overfocus on arithmetic: Reading/calculating values feels like “real work” vs. “administrative” I/O
  • 🌫️ Abstraction blindness: Mistaking ranges as direct value containers rather than references
    
    graph LR
    A[Junior's Flow] --> B[Read Data]
    B --> C[Compute]
    C --> D[Assume Persistence]

E[Actual Flow] –> F[Read Data]
F –> G[Compute]
G –> H[Explicit Write]