- June 2026 (2)
- May 2026 (2)
- April 2026 (11)
- March 2026 (3)
- February 2026 (4)
- January 2026 (4)
- December 2025 (1)
- November 2025 (3)
- October 2025 (9)
- September 2025 (3)
- August 2025 (5)
- July 2025 (1)
- June 2025 (2)
- May 2025 (3)
- April 2025 (2)
- March 2025 (7)
- February 2025 (10)
- January 2025 (6)
- December 2024 (7)
- September 2024 (1)
- August 2024 (2)
- July 2024 (2)
- May 2024 (2)
- April 2024 (2)
- February 2024 (2)
- April 2023 (1)
- March 2023 (2)
- September 2022 (1)
- February 2022 (1)
- November 2021 (1)
- March 2021 (1)
- February 2021 (2)
- August 2019 (1)
- November 2018 (1)
- May 2017 (1)
- December 2016 (1)
- April 2016 (1)
- August 2015 (1)
- December 2014 (1)
- August 2014 (1)
- March 2014 (1)
- December 2013 (1)
- October 2013 (3)
- September 2013 (4)
- August 2013 (2)
- July 2013 (1)
- June 2013 (1)
- February 2013 (1)
- October 2012 (1)
- June 2012 (1)
- May 2012 (1)
- April 2012 (1)
- February 2012 (1)
- October 2011 (1)
- June 2011 (1)
- May 2011 (1)
- April 2011 (1)
- March 2011 (1)
- February 2011 (1)
- January 2011 (1)
- December 2010 (3)
- November 2010 (1)
- October 2010 (1)
- September 2010 (1)
- August 2010 (1)
- July 2010 (1)
- May 2010 (3)
- April 2010 (1)
- March 2010 (2)
- February 2010 (3)
- January 2010 (4)
- December 2009 (2)
- November 2009 (5)
- October 2009 (2)
- September 2009 (2)
- August 2009 (3)
- July 2009 (1)
- May 2009 (1)
- April 2009 (1)
- March 2009 (5)
- February 2009 (5)
- January 2009 (5)
- December 2008 (3)
- November 2008 (7)
- October 2008 (4)
- September 2008 (2)
- August 2008 (1)
- July 2008 (1)
- June 2008 (1)
- May 2008 (1)
- April 2008 (1)
- January 2008 (4)
- December 2007 (3)
- March 2007 (3)
- February 2007 (1)
- January 2007 (2)
- December 2006 (4)
- November 2006 (18)
- AI (83)
- TIL deep dives (75)
- Python (71)
- LLM from scratch (46)
- Resolver One (34)
- PyTorch (21)
- Blogkeeping (18)
- TIL (18)
- PythonAnywhere (17)
- Linux (16)
- Startups (15)
- Hugging Face (13)
- NSLU2 offsite backup project (13)
- Funny (11)
- Gadgets (11)
- Musings (11)
- Finance (10)
- Fine-tuning LLMs (10)
- C (9)
- Personal (8)
- Robotics (8)
- Website design (8)
- 3D (5)
- Rants (5)
- Cryptography (4)
- JavaScript (4)
- Music (4)
- Oddities (4)
- Quick links (4)
- Talks (4)
- Dirigible (3)
- Eee (3)
- JAX (3)
- Memes (3)
- Politics (3)
- Django (2)
- GPU Computing (2)
- LaTeX (2)
- MathML (2)
- OLPC XO (2)
- Retro Language Models (2)
- Space (2)
- VoIP (2)
- Copyright (1)
- Golang (1)
- Microprojects (1)
- Raspberry Pi (1)
- Software development tools (1)
- Agile Abstractions
- Astral Codex Ten
- :: (Bloggable a) => a -> IO ()
- David Friedman's Substack
- Econ & Energy
- Entrepreneurial Geekiness
- For some value of "Magic"
- Hackaday
- kaleidic.ai newsletter
- Knowing.NET
- Language Log
- Millennium Hand
- ntoll.org
- Obey the Testing Goat!
- PK
- PythonAnywhere News
- Simon Willison's Weblog
- Societive
- Software Deviser
- Some opinions, held with varying degrees of certainty
- tartley.com
VAT calculations
There's been an interesting discussion over at Smurf on Spreadsheets about the consequences of the UK government's temporary VAT rate reduction. For the benefit of non-UK readers, VAT is basically the british sales tax (it differs a little in implementation from a simple sales tax). It is currently 17.5%, but as a reaction to the financial crisis, it will be reduced to 15% from 1 December 2008 until 31 January 2010 inclusive. Whether this makes sense as a matter of economic policy is, of course, highly contentious. But this is a technical blog so I'll stick to its effect on spreadsheets :-)
The problem is, of course, that there are thousands of spreadsheets throughout
the UK using formulae like =A1 * 1.175 to calculate gross prices from net.
Finding and fixing all of these is like a miniature version of fixing y2k bugs,
worsened by the fact that this rate change was announced with just one week's
notice (which makes sense, as otherwise spending could have frozen up until the
new rate came in, but is still a pain for people who have to implement the change).
Now, I don't think there's any way that this could have been avoided entirely.
Spreadsheets frequently start out has a scratchpad, where someone is just running
some numbers and intends to throw the sheet away. Sometimes these scratchpads
are valuable enough to be kept, and sometimes when that happens, magic numbers
like 1.175 aren't extracted into a named cell called vatRate. They should be,
of course, but they won't always be. So there are a lot of crappy spreadsheets
out there.
If some spreadsheets are always going to be broken, the interesting question is:
what happens with the well-designed spreadsheets? The ones where there's a named
vatRate cell which just needs to be updated? Well, unfortunately, they're
going to be broken too. There are two problems:
- Sheets where there are different items happening at different times. Imagine
you have two transactions, one taking place on 28 November, and one on 1 December.
The VAT rate for the first is 17.5%, and for the second it is 15%. So if you
change the value in the
vatRatecell, you'll get the wrong answer for one or the other. So now you needoldVatRateandnewVatRatenamed cells -- but then, what happens when the new rate comes in? Or if the government decide to keep tweaking it up and down, as the economic situation changes? - What if you don't update all of your spreadsheets? For the first few days of
December, you can check each one as you open it for any named
vatRatecells, and if you're careful you'll probably get them all. But what about other files that the files you open depend on? Have they been updated?
How to fix the mess? Or, at least, how could you write spreadsheets to guard against this kind of problem? Obviously, as someone who runs a company producing a souped-up Python-based spreadsheet, I was hoping that there was some kind of useful trick to handle this in our product -- and after a bit of thought, I realised there is.
In Resolver One you can create a single spreadsheet to represent your VAT calculations, and then use it like a function from other sheets. So you can create a spreadsheet that, given a date and a VAT type (some products get a reduced VAT rate, or are entirely exempt -- for example, there's no VAT on groceries), will work out the VAT rate. You can then use this in your other spreadsheets, and so changes like this can be updated in one place, and will be picked up by every other sheet you have.
This is probably the kind of thing where it's better to see an example rather that read about it, so if you want to check out how it works, the Resolver Exchange has a file containing a VAT calculator spreadsheet and a spreadsheet that uses it to work out some prices. If you download and unpack it, you can open them up and see how it works. (I've saved them both under a Creative Commons license, so if you don't have Resolver One, you can take a look at them using the free non-commercial version.)
(Oh, and if you're coming from Excel and are wondering where the formulae are in the second sheet, they're column-level -- click on the column headers to see them.)
Here's what I'd really like to know -- is there a way to do this in Excel without having to encode all of the information about VAT rates into some kind of add-in?