2

I've looked and not been able to get my specific answer. What I'm trying to do is have a total owed cell, and an amount paid cell. I want the total owed to subtract the amount paid, and update itself to the new lesser amount, so that when I enter another amount in the same amount paid cell, it subtracts again from the previously updated amount. I've tried different formulas, but I keep ending up with a circular dependency error. Is there a way to have cells calculate in a certain order? Do cell a21 first, then do cell b21 using the updated value from a21, and so on.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
poboy975
  • 55
  • 5
  • You might be able to do something by turning off circular references, although I doubt it's a good idea :). Here's a [few pages of instructions by Jan Karel Pieterse](http://www.jkp-ads.com/Articles/circularreferences01.asp) – Doug Glancy Aug 17 '13 at 17:17

3 Answers3

3

You will need to use a VBA script to achieve what you need.

The code will need to be in the Worksheet_Change event handler for the sheet in question.

Essentially the code should use the following logic

  1. Check that the cell being updated is the amount paid cell
  2. Recalculate the total owed
  3. Optionaly, clear the amount paid.

    Private Sub Worksheet_Change(ByVal Target As Range)

    End Sub

Declan_K
  • 6,726
  • 2
  • 19
  • 30
1

An onEdit() trigger function in Google Apps Script can do this easily.

Screenshot

Refer to "Spreadsheet Edit Events" in Understanding Events, and Understanding Triggers.

function onEdit(e) {
  // For simplicity, we'll use A1 notation to refer to cells & ranges
  var cellA1Notation = e.range.getA1Notation();

  // Check if a new payment was made
  if (cellA1Notation == 'B2') {
    // Make sure we're dealing with a number
    var payment = eval(e.value.valueOf())

    // Archive payment
    var pastPaymentRange = e.range.getSheet().getRange('B3:C3');
    pastPaymentRange.setValues([[payment,new Date()]]);
    e.range.clear(); // Clear payment

    // Update total payment
    var totalPaymentRange= e.range.getSheet().getRange('B4');
    var totalPayment = totalPaymentRange.getValue();
    if (typeof totalPayment !== 'number') totalPayment = 0;
    totalPayment += payment;
    totalPaymentRange.setValue(totalPayment);

    // Update balance
    var balanceRange = e.range.getSheet().getRange('B5');
    var balance = balanceRange.getValue();
    if (typeof balance !== 'number') balance = 0;
    balance -= payment;
    balanceRange.setValue(balance);
  }
}
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • Hi, this seems to be what I'm looking for. I tried to implement it, and got a TypeError: Cannot read property "range" from undefined... this line: var cellA1Notation = e.range.getA1Notation(); Am I missing something? Though it does seem to be working correctly anyway. – poboy975 Sep 12 '13 at 03:22
  • If you got that error when running the code in the debugger, it's simply because there was no event `e` defined. Techniques for debugging trigger functions are described in [How can I test a trigger function in GAS?](http://stackoverflow.com/questions/16089041/how-can-i-test-a-trigger-function-in-gas) – Mogsdad Sep 12 '13 at 13:27
0

You can avoid scripts and circular refs by changing strategy. Add a new row every time you get in/out money. Your formulas will just add up the total as in sum(a3:a) Plus you get historical data as a bonus.

Zig Mandel
  • 19,571
  • 5
  • 26
  • 36