3

Suppose our cursor/point it located on the first line of Parent Task in the following:

* Parent Task
:PROPERTIES:
:END:

** Sub-Task A
:PROPERTIES:
:TALLY: 2
:END:

** Sub-Task B
:PROPERTIES:
:TALLY: 8
:END:

Question: Is there a way to write a function which (i) sums the :TALLY sub-properties from Sub-Task A and Sub-Task B and (ii) inserts them into the :TALLY_SUM property of Parent Task?

I know that for part (ii) we can use the org-mode property API function (org-entry-put "TALLY_SUM" <sum>).

3

The following function should do the job:

(defun org-sum-tally-in-subtree ()
  "Add up all the TALLY properties of headings underneath the current one
The total is written to the TALLY_SUM property of this heading"
  (interactive)
  (org-entry-put (point) "TALLY_SUM"
                 (number-to-string 
                  (let ((total 0))
                    (save-excursion
                      (org-map-tree
                       (lambda ()
                         (let ((n (org-entry-get (point) "TALLY")))
                           (when (stringp n)
                             (setq total (+ total (string-to-number n))))))))
                    total))))

Two points to note:

  1. All sub-headings below the current point are searched, not just the next level down
  2. The code does not enforce that TALLY should be an integer, so it also works for float values

Example:

** Parent Task
:PROPERTIES:
:TALLY_SUM: 22.201
:END:

Do =M-x org-sum-tally-in-subtree= here

*** Sub-Task A
:PROPERTIES:
:TALLY: 4
:END:

**** Sub-sub task
:PROPERTIES:
:TALLY:    10.001
:END:

*** Sub-Task B
:PROPERTIES:
:TALLY: 8.2
:END:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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