3

Suppose I'm creating a Christmas list and tracking the gifts I am getting for people using org-tables. I have a named table for each group of people I am getting gifts for. These tables contains product & price info. I also have a summary table that gathers the totals for each table and puts them in their own table with a final total.

Is there a way that I can recalculate the summary table and it will go through each named table and perform a recalculation of each sub-group?

Below is a reproducible example of what I am talking about:

 #+TBLNAME: Summary
| ! | Group    | Total |
|---+----------+-------|
| # | Kids     |   208 |
| # | Spouse   |   350 |
| # | Parents  |   155 |
| # | Siblings |   205 |
|---+----------+-------|
| # | Total:   |   918 |
| ^ |          |   tot |
#+TBLFM: $3=remote($Group,$tot)::$tot=vsum(@-I..@-II)

#+TBLNAME: Kids
|   | Product    | Price |
|---+------------+-------|
|   | Video Game |    60 |
|   | Doll House |    38 |
|   | Skateboard |    60 |
|   | Books      |    50 |
|---+------------+-------|
|   | Total:     |   208 |
| ^ |            |   tot |
#+TBLFM: $tot=vsum(@-I..@-II)

#+TBLNAME: Spouse
|   | Product | Price |
|---+---------+-------|
|   | Jewlery |   120 |
|   | Clothes |    60 |
|   | Pottery |    80 |
|   | Books   |    90 |
|---+---------+-------|
|   | Total:  |   350 |
| ^ |         |   tot |
#+TBLFM: $tot=vsum(@-I..@-II)


#+TBLNAME: Parents
|   | Product       | Price |
|---+---------------+-------|
|   | Picture Frame |    45 |
|   | Books         |    50 |
|   | Records       |    60 |
|---+---------------+-------|
|   | Total:        |   155 |
| ^ |               |   tot |
#+TBLFM: $tot=vsum(@-I..@-II)

#+TBLNAME: Siblings
|   | Product        | Price |
|---+----------------+-------|
|   | Sewing Machine |   145 |
|   | Flannel        |    60 |
|---+----------------+-------|
|   | Total:         |   205 |
| ^ |                |   tot |
#+TBLFM: $tot=vsum(@-I..@-II)

I don't mind have to perform the recalculation for each row in the summary table, but suppose I edit the Kids table. If I don't manually recalculate the Kids table, the Summary table will not update either.

5
  • 2
    Try org-table-recalculate-buffer-tables perhaps? Not sure in what order it does them though, so you might want to change the order of the tables so that the summary table is done last.
    – NickD
    Commented Oct 12, 2021 at 19:37
  • @NickD It looks like moving the summary table to end makes it calculate exactly how I want it to. Although I would've liked to keep the summary table at the top. Thanks!
    – dylanjm
    Commented Oct 12, 2021 at 19:44
  • 1
    You can keep it at the top: just do a global recalculate to make all the changes and then do C-c C-c on the TBLFM line of the summary table to update it.
    – NickD
    Commented Oct 12, 2021 at 19:45
  • 1
    Typos - I fixed the comment. BTW, I think TBLNAME is obsolete: it's now plain NAME (although the old form is still recognized - probably).
    – NickD
    Commented Oct 12, 2021 at 19:48
  • 1
    You can also use org-table-iterate-buffer-tables instead: that should allow you to keep the summary table anywhere you want and still update it properly, although that's potentially more expensive than recalculating.
    – NickD
    Commented Oct 12, 2021 at 20:08

1 Answer 1

3

The easiest, but not necessarily the most efficient way to do that, is to use org-table-iterate-buffer-tables: that will try updating all the tables until there is no change in the buffer.

I would add an elisp src block to run that:

#+name: recalc
#+begin_src elisp
(org-table-iterate-buffer-tables)
#+end_src

Pressing C-c C-c on the source block will evaluate it and that in turn will iterate the recalculation of every table in the buffer, until it converges - or after 10 iterations when it decides it is not going to converge. Naming the source block allows you to sprinkle calls to it in the file:

#+call: recalc()

so that you don't have to go far to find a place where you can trigger recalculation: C-c C-c on one of the #+call: lines will do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.