Emacs org-mode totals table - org-mode

I have an org file, describing a project:
* task1
** task1-1
:PROPERTIES:
:price: 10
:given: <2012-11-08 Thu>
:END:
** task1-2
:PROPERTIES:
:price: 11
:given: <2012-11-08 Thu>
:END:
* task2
** task2-1
:PROPERTIES:
:price: 20
:given: <2012-11-08 Thu>
:END:
** task2-2
:PROPERTIES:
:price: 21
:given: <2012-11-08 Thu>
:END:
I used org-collector to produce a totals table:
#+BEGIN: propview :id global :conds ((not (= price 0))) :cols (ITEM price)
| ITEM | price |
|-----------+-------|
| "task1-1" | 10 |
| "task1-2" | 11 |
| "task2-1" | 20 |
| "task2-2" | 21 |
|-----------+-------|
| | 62 |
#+TBLFM: #6$2=vsum(#2$2..#5$2)
#+END:
But I want to have something like this:
| ITEM | price |
|-----------+-------|
| "task1-1" | 10 |
| "task1-2" | 11 |
| "task2-1" | 20 |
| "task2-2" | 21 |
|-----------+-------|
| Total | 62 |
How to do it?

For the “Total” line, you can add a line |Total| |, press C-u C-c = in the empty cell (to define a formula for it), and enter the formula vsum(#1$2..#4$2). (If you wanna recalc, that's C-u C-c C-c for all.)
I don't know about org-collector, so can't help you with this part. Run it on the entire document (is :id global working?), or shift everything by one level to the right for it to be inside a single tree, maybe.

I just figured this one out this morning. The answer you're looking for with Org-Collector is straightforward. Just put the table formulae two blank lines beneath the beginning of the property view and it'll be calculated automatically when the property view is evaluated (with C-c C-c).
#+BEGIN: propview :scope tree :cols (ITEM CLOCKSUM EFFORT) :match "TODO=\"TODO\"" :noquote ALL
#+TBLFM: #>$1=Totals::#>$2=vsum(#I..#II);t::#>$3=vsum(#I..#II);t
#+END:
If you want to turn this into a generic yasnippet, you need to escape the $ and the \:
#+BEGIN: propview :scope tree :cols (ITEM CLOCKSUM EFFORT) :match "TODO=\\"TODO\\"" :noquote ALL
#+TBLFM: #>\$1=Totals::#>\$2=vsum(#I..#II);t::#>\$3=vsum(#I..#II);t
#+END:
Now, you can add a generic property view that calculates the time so far and effort remaining for each step of a project, as well as the total time overall.

Related

org-mode latex export: wrap text around a table

I can make text wrap around images by adding
#+CAPTION: foo
#+ATTR_LATEX: :float wrap
[[./my_img.png]]
If I do the same to
#+CAPTION: bar
#+ATTR_LATEX: :float wrap
| a | b |
| c | d |
The table will stay centered in its own part of the document, the text being broken above and below it, not auto-flowing around it.
I also tried to do something like
#+CAPTION: baz
#+ATTR_LATEX: :environment wraptable :options {l}{5cm}
| a | b |
| c | d |
or using :position instead of :options, with no results.
Basically I want the table to export to
\begin{wraptable}{l}{5cm}
\begin{tabular}
....
\end{tabular}
\end{wraptable}
in the tex file. The arguments {r|l}{width} are mandatory, so simply #+begin_wraptable won't work either. Is there any way to do that from inside org-mode without manually fiddling with the final .tex?
You have to explicitly add the LaTeX-code for wraptable, using the :center attribute with no value removes the automatic insertion of \beginn{center} in the .tex-file.
#+LaTeX: \begin{wraptable}{r|l}{width}
#+ATTR_LATEX: :center
| A | B | C |
|--------+-------+-------|
| a | b | c |
#+LaTeX: \end{wraptable}

how to use TBLFM combined to results from org-evaluate-time-range

From a previous post (Calculate time range in org-mode table), I was able to use the org-evaluate-time-range function in a table.
I'd like to sum the obtained durations. However, searching for how to do that, I noticed the following behavior of TBLFM mode.
| <2015-12-09 01:29>--<2015-12-09 08:43> | 7 hours 14 minutes | 98 hours minutes |
| <2015-12-09 08:29>--<2015-12-09 08:43> | 14 minutes | 14 minutes |
#+TBLFM: $2='(org-evaluate-time-range)::$3=$2
Here in the third column, it seems that it is the product that is calculated. Any reason for that?
What I would like to is to sum the duration with a macro like that
#+TBLFM: $2='(org-evaluate-time-range)::#3$2=vsum(#1$2..#2$2)
Thanks.
The right-hand side of formulas like $3=$2 is evaluated by calc, and calc knows nothing about the 7 hour 14 minutes syntax. In fact, calc can do symbolic calculations, and it reads 7 hour 14 minutes as the product 7*hour*14*minutes where hour and minutes are variables.
The time syntax that calc understands is HH:MM[:SS]. This is illustrated by the org-mode manual.
TBLFM: has a flag ;T to format numeric values as time this way, but that does not work for timestamp ranges. So if you really want to start from a timestamp range, maybe one way is to write your own function to convert ranges to seconds:
Evaluate this first:
#+BEGIN_SRC emacs-lisp
(defun convert-time-range-to-seconds (range)
(if (string-match org-tr-regexp-both range)
(let ((start (match-string 1 range))
(end (match-string 2 range)))
(round (- (org-time-string-to-seconds end)
(org-time-string-to-seconds start))))
""))
#+END_SRC
| time stamp range | as seconds | as time |
|------------------------------------------------+------------+-----------|
| <2015-12-09 Wed 01:29>--<2015-12-10 Thu 08:42> | 112380 | 31:13:00 |
| <2015-12-28 Mon>--<2015-12-31 Thu> | 259200 | 72:00:00 |
| <2015-12-11 Fri>--<2015-12-13 Sun> | 172800 | 48:00:00 |
|------------------------------------------------+------------+-----------|
| | | 151:13:00 |
#+TBLFM: $2='(convert-time-range-to-seconds $1)::$3=$2;T::#>$3=vsum(#2..#-1);T

No borders in table in org-mode

This is how I wrote my table in org-mode:
| col1 | col2 | col3 |
|------+------+------|
| val1 | val2 | val3 |
| val4 | val5 | val6 |
This is the output I'm getting in org-export-as-pdf :
What I want is the borders for the table. The org-mode version I'm
using is 7.9.3f.
UPDATE:
With #+ATTR_LaTeX: align=|c|c|c|, I get the follwing table:
UPDATE:
Solved that using putting horizontal lines on top and below of the table using C-u C-c - and C-c - respectively.
If you want vertical lines, you need to specify it, hence something like:
#+ATTR_LaTeX: align=|c|c|c|
in your old version of Org mode, or:
#+ATTR_LaTeX: :align |c|c|c|
in Org mode 8.

Compute the duration of appointment in an org-mode table

I have a list of appointments in the style of:
| Appointment | Dur. |
|------------------------------+-------|
| <2014-02-20 Thu 09:30-18:30> | ??? |
| <2014-02-22 Sat 09:00-10:00> | ??? |
| | |
How can I make orgmode calculate the durations of my appointments?
Org mode allows you to specify formulas for calculating values for a given column. You are allowed to execute elisp code in those formulas. We can use feature to achieve what you want first, we will need to define some functions which find difference between times. You can add the following to your org document
#+begin_src emacs-lisp
(defun my-get-number-of-minutes (time)
(+ (* (nth 2 time) 60) (nth 1 time)))
(defun my-get-time-diff (t1 t2)
(- (my-get-number-of-minutes t1) (my-get-number-of-minutes t2)))
(defun my-get-duration (time-string)
(let* ((times (split-string (substring time-string 16 -1) "-"))
(minute-diff (my-get-time-diff (parse-time-string (nth 1 times))
(parse-time-string (nth 0 times)))))
(format "%dhrs %dmins" (/ minute-diff 60) (% minute-diff 60))))
#+end_src
Then do C-cC-c anywhere between the #+begin-src emacs-lisp and #+end-src tags, this will evaluate the elisp.
OR
Simply copy the elisp code (between #+begin_src emacs-lisp #+end-src) to *scratch* buffer and do M-xeval-bufferRET.
Now that we have the functions defined we can tell org-mode the formula to calculate the second column from first column, to do this simply paste the following line below the org-table
#+TBLFM: $2='(my-get-duration $1)
This tells org that value of column 2 ($2) is the function my-get-duration applied 'value of column 1' ($2). Then with point on the line do C-cC-c, if you have done everything well, the second column should be filled with the duration.
NOTE: The code assumes that the datetime will be of the same format as given in your example.
I recommend you read this short article about org-mode's capabilities as a spreadsheet.
UPDATE
If you can reformat your table as follows, you will be able to simplify the formula
| Appointment | Start | End | Duration |
|------------------+-------+-------+----------|
| <2014-02-20 Thu> | 09:30 | 18:30 | ??? |
| <2014-02-22 Sat> | 09:00 | 10:00 | ??? |
The formula for calculating the duration now would simply be
#+TBLFM: $4=$3-$2;T

Org mode spreadsheet programmatic remote references

I keep my budget in org-mode and have been pleased with how simple it is. The simplicity fails, however, as I am performing formulas on many cells; for instance, my year summary table that performs the same grab-and-calculate formulas for each month. I end up with a massive line in my +TBLFM. This would be dramatically shorter if I could programmatically pass arguments to the formula. I'm looking for something like this, but working:
| SEPT |
| #ERROR |
#+TBLFM: #2$1=remote(#1,$tf)
Elsewhere I have a table named SEPT and it has field named "tf". This function works if I replace "#1" with "SEPT" but this would cause me to need a new entry in the formula for every column.
Is there a way to get this working, where the table itself can specify what remote table to call (such as the SEPT in my example)?
Yes, you can't do this with built-in remote and you need to use org-table-get-remote-range. Hopefully this better suits your needs than the answer given by artscan (I used his/her example):
| testname1 | testname2 |
|-----------+-----------|
| 1 | 2 |
#+TBLFM: #2='(org-table-get-remote-range #<$0 (string ?# ?1 ?$ ?1))
#+TBLNAME: testname1
| 1 |
#+TBLNAME: testname2
| 2 |
Note the (string ?# ?1 ?$ ?1): this is necessary because before evaluating table formulae, all substitutions will be done first. If you use "#1$1" directly, it would have triggered the substitution mechanism and be substituted by the contents of the first cell in this table.
There is some ugly hack for same effect without using remote:
1) it needs named variable for remote address
(setq eab/test-remote "#1$1")
2) it uses elisp expression (from org-table.el) instead remote(tablename,#1$1)
(defun eab/test-remote (x)
`(car (read
(org-table-make-reference
(org-table-get-remote-range ,x eab/test-remote)
't 't nil))))
3) worked example
| testname1 | testname2 |
|-----------+-----------|
| | |
#+TBLFM: #2='(eval (eab/test-remote #1))
#+TBLNAME: testname1
| 1 |
#+TBLNAME: testname2
| 2 |
4) result
| testname1 | testname2 |
|-----------+-----------|
| 1 | 2 |