How do you express the following conditional for an org mode table?
for every cell between the 2nd and 3rd hline:
if the cell is empty,
set the contents of the cell to todays date.
else
leave the cells contents as they are.
so, given the following table, i would like to insert todays date in the empty cell.
|------------------|
| date |
|------------------|
| [2014-05-23 Fri] |
| [2014-05-24 Sat] |
| |
|------------------|
The custom calc function appendToday will do what you want. It handles the case where all fields between the hlines are empty as well.
(defmath appendToday (idx v)
(let ((d (date (month (now)) (day (now))))
(len (vlen v)))
(if (<= idx len)
(if (equal (cadr v) 0)
d
(nth idx v)
)
d
)
)
)
The table before evaluation looks like:
|------------------|
| <2014-05-26 Mon> |
| |
| |
| |
| |
| |
|------------------|
#+TBLFM: #I..#II$1=appendToday(##,#I..#II$1)
The table after evaluation looks like:
|------------------|
| <2014-05-26 Mon> |
| <2014-05-28 Wed> |
| <2014-05-28 Wed> |
| <2014-05-28 Wed> |
| <2014-05-28 Wed> |
| <2014-05-28 Wed> |
|------------------|
#+TBLFM: #I..#II$1=appendToday(##,#I..#II$1)
Related
The following table
#+BEGIN: clocktable :maxlevel 3 :tcolumns 4 :scope file :block 2015-6 :narrow 60
| Headline | Time | | |
|--------------+--------+------+------|
| *Total time* | *3:57* | | |
|--------------+--------+------+------|
| Tasks | 3:57 | | |
| 1 | | 3:57 | |
| 2 | | | 3:57 |
#+TBLFM: #3$5..#>$5=vsum($2..$4)*100
gives me
user-error: Not in table data field
where it should add the total of all previous columns to into a new column and multiply them by 100. Via http://notes.secretsauce.net/notes/2014/10/01_org-mode-for-invoices.html
I see two solutions a) add a command to TBLFM to add an additional
column b) make clocktable generate the additional column, but I don't
know how to do either.
Here is a quick hack that you could bind to a key that adds the extra column if needed and then recalculates:
(defun maybe-add-column-and-update ()
(interactive)
(save-excursion
(end-of-line)
(if (= (org-table-current-column) 5)
(let ((org-table-fix-formulas-confirm
(lambda (arg) nil)))
(org-table-insert-column)))
(org-table-recalculate 'iterate)))
I have a table like this:
#+NAME: ENTRY
|------+--------|
| Item | Amount |
|------+--------|
| A | 100 |
| B | 20 |
| A | 120 |
| C | 40 |
| B | 50 |
| A | 20 |
| C | 16 |
|------+--------|
and then I need to sum each item in another table:
#+NAME: RESULT
|------+-----|
| Item | Sum |
|------+-----|
| A | 240 |
| B | 70 |
| C | 56 |
|------+-----|
I've tried using vlookup and remote reference in this table, but I'm not able to sum the resulting list like:
#+TBLFM: $2=vsum((vconcat (org-lookup-all $1 '(remote(ENTRY,#2$1..#>$1)) '(remote(ENTRY,#2$2..#>$2)))))
But it does not give the answer.
So I have to use a place holder to hold the resulting list then sum it:
#+NAME: RESULT
|------+--------------+-----|
| Item | Placeholder | Sum |
|------+--------------+-----|
| A | [100 120 20] | 240 |
| B | [20 50] | 70 |
| C | [40 16] | 56 |
|------+--------------+-----|
#+TBLFM: $2='(vconcat (org-lookup-all $1 '(remote(ENTRY,#2$1..#>$1)) '(remote(ENTRY,#2$2..#>$2))))::$3=vsum($2)
Is there a better solution for this?
One way to do this is without vsum:
#+TBLFM: $2='(apply '+ (mapcar 'string-to-number (org-lookup-all $1 '(remote(ENTRY,#2$1..#>$1)) '(remote(ENTRY,#2$2..#>$2)))))
If you want to use a calc function, you can always use calc-eval:
#+TBLFM: $2='(calc-eval (format "vsum(%s)" (vconcat (org-lookup-all $1 '(remote(ENTRY,#2$1..#>$1)) '(remote(ENTRY,#2$2..#>$2))))))
Here's an example Org clock table in Emacs:
#+BEGIN: clocktable :maxlevel 1 :scope file :tcolumns 1 :formula %
#+CAPTION: Clock summary at [2014-03-30 Sun 22:47]
| Headline | Time | % |
|--------------+--------+-------|
| *Total time* | *4:31* | 100.0 |
|--------------+--------+-------|
| Item A | 1:07 | 24.7 |
| Item B | 1:06 | 24.4 |
| Item C | 2:18 | 50.9 |
#+TBLFM: $3='(org-clock-time% #2$2 $2..$2);%.1f
#+END:
I want to sort the table by the % column. Is this possible?
Here's a more complex example:
#+BEGIN: clocktable :maxlevel 2 :scope file :tcolumns 1 :formula %
#+CAPTION: Clock summary at [2014-03-30 Sun 22:48]
| Headline | Time | % |
|--------------------+--------+-------|
| *Total time* | *4:31* | 100.0 |
|--------------------+--------+-------|
| Item A | 1:07 | 24.7 |
| \__ Item A1 | 0:07 | 2.6 |
| \__ Item A2 | 1:00 | 22.1 |
| Item B | 1:06 | 24.4 |
| \__ Item B1 | 1:06 | 24.4 |
| Item C | 2:18 | 50.9 |
| \__ Item C1 | 2:18 | 50.9 |
#+TBLFM: $3='(org-clock-time% #2$2 $2..$2);%.1f
#+END:
In this instance, the top level items should be sorted by their % values, but within each subtree, the secondary level items should also be sorted by their % values.
The time clocking code for Org-mode org-clock.el doesn't support any sorting facilities. The function org-clocktable-write-default creates tables by very rigid algorithm with limited variants of tuning, all of them are in the variable org-clocktable-defaults. Thus, dynamic block clocktable generates org tables "as is", http://orgmode.org/manual/The-clock-table.html contains exhaustive list of settings.
You can sort first table manually by placing the cursor in the 3 column and executing M-x org-table-sort-lines [n]umeric.
As to sorting second table with "knowledge about structure of levels" - it seems to be impossible without profound changes in the function org-clocktable-write-default.
The built-in formatter org-clocktable-write-default sorts the entries just row by row with no idea of levels. I was looking for the same functionality and ended up with writing my own formatter (not a formatter really) that sorts the entries with respect to levels. It has a limitation though that it can only sort on name or time, since the result of sorting on time is essentially the same as sorting on percentage, this's acceptable in your case.
I'd like to do something like this:
How to achieve a row index column in Emacs Org Mode using a Calc column rule
but I'd like the rows to be numbered in reverse order. I suspect this should be very easy, and should have something to do with #>, but e.g. $1=#>-## doesn't work.
You can try this example
| row | data |
|-----+------|
| 8 | |
| 7 | |
|-----+------|
| 6 | |
| 5 | |
| 4 | |
| 3 | 5123 |
| 2 | |
| 1 | 4234 |
#+TBLFM: $1='(- (length org-table-dlines) ##)
I convert org-mode table to table.el table. For that I select the table:
| Option | Type | Value | Descr |
| -[no]h | bool | yes | Print |
| -[no]versio | bool | no | Print |
| -nice | int | 0 | Set t |
| -[no]v | bool | no | Be lo |
| -time | real | -1 | Take |
| -[no]rmvsbd | bool | yes | Removvirtual |
| sites | | | |
| -maxwarn | int | 0 | Numbe |
| procenerate | | | |
| unsta | | | |
| -[no]zero | bool | no | Set pthout |
| defau error | | | |
| -[no]renum | bool | yes | Renum |
| atomty | | | |
and press C-c ~. org-mode then asks me
Convert table to table.el table? (y or n)
How do I answer y programmically? I read the docs of that defun -- there's not way to do it with prefix arg.
Similar functionality in bash:
echo y | script-which-asks-y-or-n
C-c ~ calls the command org-table-create-with-table.el, which provides a bunch of wrappers around calling org-table-convert. If you want to use this function when you know you are already in an org-mode table, you don't need the wrappers, you just need the two (and probably only one) commands: org-table-align and org-table-convert.
So if you're doing this interactively, you can just call M-x org-table-convert and you're done. This assumes the table is already aligned. You can do this by hand by tabbing from one cell to the next, which triggers table alignment. Or you can do it with a small function:
(defun my-convert-tables ()
"No questions asked, just convert the table"
(interactive)
(org-table-align)
(org-table-convert))
You can do this programmatically as follows. You would replace the function name test1 with org-table-create-with-table.el in your defadvice functions that would be otherwise the same as those below.
Using defadvice to run some code before and after the function, we can save the function bound to the symbol y-or-n-p to a global variable and rebind it to a function that simply returns true. After the function we then restore the original functionality.
(setq save-y-or-n-p nil)
(defadvice test1 (around always-yes)
(fset 'save-y-or-n-p (symbol-function 'y-or-n-p))
(fset 'y-or-n-p (lambda (s) t))
ad-do-it
(fset 'y-or-n-p (symbol-function 'save-y-or-n-p)))
(defun test1 ()
(interactive)
(if (y-or-n-p "Happy? ")
(insert "Happy day")
(insert "Unhappy day")))