What I found
The month-end number depended on who ran it. The GL report was pulled from NetSuite by hand, and merged cells broke the paste every single month. Two people could run the same close and get two different starting points.
What I built
A load that arrives on a scheduled email and reads itself. The raw data lands untouched in its own tab, and columns are found by name rather than position, so an added upstream column no longer breaks the whole thing. Failed pulls retry instead of vanishing.
How it works
Before
- Pulled from NetSuite by hand
- Merged cells broke it every month
- The answer depended on who ran it
Now
- It loads itself from the email
- Raw data lands untouched in its own tab
- Same output every time; columns found by name not position
The honest detail is the 3 versions. It did not work on the first try. It took three passes to make it stable enough that I stopped thinking about it on close night.
Impact
- The close step went from about 2 hours to about 30 minutes.
- It has run live for 7 months without a manual pull.
- The output is the same every time, so the answer no longer depends on who ran it.
The transferable lesson
Automation is not the flashy part. The win is that a fragile, person-dependent step becomes something you can trust at eleven at night on close, and that trust is worth more than the saved time.