1 #+TITLE: Org as a spreadsheet system: a short introduction
3 #+EMAIL: bzg AT altern DOT org
4 #+OPTIONS: H:3 num:nil toc:t \n:nil ::t |:t ^:t -:t f:t *:t tex:t d:(HIDE) tags:not-in-toc
5 #+STARTUP: align fold nodlcheck hidestars oddeven lognotestate
6 #+SEQ_TODO: TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@)
7 #+TAGS: Write(w) Update(u) Fix(f) Check(c)
11 #+CONSTANTS: pi=3.14159265358979323846
13 [[file:../index.org][{Back to Worg's index}]] -- [[file:org-tableur-tutoriel.org][{Ce tutoriel en *français*}]]
17 This short tutorial will go through the basics that you need to know
18 if you want to use Org as a spreadsheet system.
20 Let's start with a this very simple table:
22 | Student | Maths | Physics |
23 |----------+-------+---------|
24 | Bertrand | 13 | 09 |
28 Which is the output of this table in Org:
30 : | Student | Maths | Physics |
31 : |----------+-------+---------|
32 : | Bertrand | 13 | 09 |
34 : | Arnold | 17 | 13 |
36 The purpose of this tutorial is to understand how to get from this
37 simple table to this one, where we have the mean per student and per
40 | Student | Maths | Physics | Mean |
41 |----------+-------+---------+------|
42 | Bertrand | 13 | 09 | 11 |
43 | Henri | 15 | 14 | 14.5 |
44 | Arnold | 17 | 13 | 15 |
45 |----------+-------+---------+------|
46 | Means | 15 | 12 | 13.5 |
48 * Getting acquainted with references
50 Let's start with the mean per student.
52 : | Student | Maths | Physics | Mean |
53 : |----------+-------+---------+-----------|
54 : | Bertrand | 13 | 09 | [Formula] |
55 : | Henri | 15 | 14 | |
56 : | Arnold | 17 | 13 | |
58 Before being able to insert a formula in =[Formula]=, you need to know
59 how to *refer* to a row, a column or a single field.
61 The easiest way to learn about references is to type =C-c ?= while you
64 For example, if you are in the =[Formula]= field, =C-c ?= will tell
65 you: =line @2, col $4, ref @2$4 or D2=, meaning that you are on the
66 second row (or line) of the fourth column, and the reference for this
67 field is either =@2$4= or =D2=.
69 At any moment, if you are lost in rows and columns, you can always
70 turn on the reference visualization grid with =C-c }=:
72 [[file:../images/bzg/reference_visualization.jpg]]
76 Put the cursor in the (empty) =[Formula]= field. Now type
77 =:=vmean($2..$3)= in this field. This formula means: calculate the
78 /mean/ for fields from the second (=$2=) to the third (=$3=) field /in
79 this row/. If you prefer to use the other notation, type
80 =:=vmean(B&..C&)= -- where the =&= character stands for "in this row",
81 which is implicit in the previous notation.
83 While still in the row, hit =C-c C-c= -- you should observe two
84 things: 1) the formula has been replaced by the result of the
85 calculation and 2) a new line starting with =#+TBLFM= has been
86 inserted at the bottom of the table.
88 The =#+TBLFM= line contains all the formulas for the table above, and
89 you should be careful while editing it manually.
91 * Column formulas and field formulas
93 Ok, so now we have this table:
95 : | Student | Maths | Physics | Mean |
96 : |----------+-------+---------+------|
97 : | Bertrand | 13 | 09 | 11 |
98 : | Henri | 15 | 14 | |
99 : | Arnold | 17 | 13 | |
100 : #+TBLFM: @2$4=vmean($2..$3)
102 But what we really want is to compute the formulas for /all fields in
103 the column/ named "Mean". In other words, we really want a =column
104 formula=, not a =field formula=.
106 To replace the formula with a column formula, go back to the field
107 where it has been defined and type ~=vmean($2..$3)~. Note that the
108 only difference with what you've inserted previously is that the
109 formula is prefixed by ~=~ instead of ~:=~. When you're done, do a
110 =C-c C-c= in the field: you should be prompted whether you want to
111 replace the formula with a column formula, which is precisely what we
114 Once you agree with this, the value in the field should be the same
115 than before (namely =11=) and you can now update all the fields in
116 this column by reapplying all formulas with =C-u C-c *= (or =C-c
117 C-c= if you're on the =#+TBLFM= line.)
119 So now we have this table:
121 : | Student | Maths | Physics | Mean |
122 : |----------+-------+---------+------|
123 : | Bertrand | 13 | 09 | 11 |
124 : | Henri | 15 | 14 | 14.5 |
125 : | Arnold | 17 | 13 | 15 |
126 : #+TBLFM: $4=vmean($2..$3)
128 As our single formula in =#+TBLFM= now applies to the entire column,
129 it doesn't contain any reference to a row. The formula was previously
130 applied for the =@2$4= field, and it is now applied for the =$4=
133 Finally, we can add the row for the means per discipline. This row
134 contains two /field formulas/, each one calculating the mean for the
135 fields above in the same column:
137 : | Student | Maths | Physics | Mean |
138 : |----------+-------+---------+------|
139 : | Bertrand | 13 | 09 | 11 |
140 : | Henri | 15 | 14 | 14.5 |
141 : | Arnold | 17 | 13 | 15 |
142 : |----------+-------+---------+------|
143 : | Means | 15 | 12 | |
144 : #+TBLFM: $4=vmean($2..$3)::@5$2=vmean(@2$2..@4$2)::@5$3=vmean(@2$3..@4$3)
146 Which brings up this table:
148 | Student | Maths | Physics | Mean |
149 |----------+-------+---------+------|
150 | Bertrand | 13 | 09 | 11 |
151 | Henri | 15 | 14 | 14.5 |
152 | Arnold | 17 | 13 | 15 |
153 |----------+-------+---------+------|
154 | Means | 15 | 12 | |
155 #+TBLFM: $4=vmean($2..$3)::@5$2=vmean(@2$2..@4$2)::@5$3=vmean(@2$3..@4$3)
157 * Interactively edit formulas
159 For now we have been defining formulas by inserting them directly in
160 the table cells: typing ~=~ in a field starts the definition for a
161 column formula and typing ~:=~ starts a definition for a field
164 If you prefer, you can edit formulas /in the minibuffer/: use =C-c ==
165 for editing column formulas or =C-u C-c == for field formulas.
167 But you can also edit formulas more interactively in a dedicated
168 buffer by typing C-c '. This new buffer lists all the formulas for
169 the table at point and provides facilities to edit the references.
171 When the cursor is above a reference, the corresponding field in the
172 table get highlighted. Nice! But you can do more than that: you can
173 actually select the reference by using the =S-<left/right/up/down>=
176 [[file:../images/bzg/formulas_editor.jpg]]
178 Note: you might worry that moving a table's column with
179 =M-<left/right>= or a table's row with =M-<up/down>= might confuse the
180 references in the =#+TBLFM= line, but each move automagically updates
181 the references in this line.
183 * Calc and Elisp formulas
185 The default syntax for formulas is the one of Calc, the GNU Emacs
186 package for doing computations.
188 Here is an excerpt from the [[http://www.delorie.com/gnu/docs/calc/calc_21.html][Calc manual]] about algebraic-style
191 : Algebraic formulas use the operators `+', `-', `*', `/', and `^'. You
192 : can use parentheses to make the order of evaluation clear. In the
193 : absence of parentheses, `^' is evaluated first, then `*', then `/',
194 : then finally `+' and `-'. For example, the expression
196 : 2 + 3*4*5 / 6*7^8 - 9
200 : 2 + ((3*4*5) / (6*(7^8)) - 9
202 In org tables, you can use references instead of values for performing
203 the computation. Pretty simple.
205 But what if you want to use Emacs lisp code instead of Calc?
207 Lets say for example that you want to associate each student with a
208 decimal of the Pi number, depending on their mean across maths and
211 For this you need to tell Org about the value you consider to be the
212 value of the Pi number. You can do this by adding this line:
214 : #+CONSTANTS: pi=3.14159265358979323846
216 (Don't forget to hit =C-c C-c= on the =#+CONSTANTS= line so that
217 org-mode knows about it.)
219 Then you can define an Emacs lisp formula like this one:
221 : $5='(substring (number-to-string $pi) (round $4) (1+ (round $4)));N
223 Ahem. Let's parse this:
225 - =(substring S A B)=: get a substring of string =S= between =A= and
227 - =(number-to-string $pi)=: convert the constant "Pi" into a string
228 - =(round $4)=: get the rounded value of the value in column =$4=
229 - =;N=: consider the values of fields to be numeric values, not strings.
231 If the mean of a student is 10, this formula returns the tenth decimal
236 So now our table is this one:
238 : | Student | Maths | Physics | Mean | Pi number |
239 : |----------+-------+---------+------+-----------|
240 : | Bertrand | 13 | 09 | 11 | 5 |
241 : | Henri | 15 | 14 | 14.5 | 7 |
242 : | Arnold | 17 | 13 | 15 | 9 |
243 : #+TBLFM: $4=vmean($2..$3)::$5='(substring (number-to-string $pi) (round $4) (1+ (round $4)));N
245 If you come back to this table but feel a bit lazy trying to
246 understand what the Emacs Lisp function does, you might as well want
247 to *debug* the formula and follow the computation step by step.
249 Turn the formulas debugger on with =C-c {= and hit =C-c C-c= in a
250 field (or =C-u C-c *= anywhere on this table.) This will perform the
251 computations of the formulas one by one, and display details about the
252 steps of the computation for each formula in a separate buffer.
254 Here is what such a buffer looks like:
256 : Substitution history of formula
257 : Orig: '(substring (number-to-string $pi) (round $4) (1+ (round $4)));N
258 : $xyz-> '(substring (number-to-string 3.14159265358979323846) (round $4) (1+ (round $4)))
259 : @r$c-> '(substring (number-to-string 3.14159265358979323846) (round $4) (1+ (round $4)))
260 : $1-> '(substring (number-to-string 3.14159265358979323846) (round 11) (1+ (round 11)))
265 Once you're done checking the formulas, you can switch the debugger
266 off by hitting =C-c {= again.
270 Using Org as a spreadsheet system turns to be really handy.
272 But you can do a lot more than that! You can use relative references,
273 define names for columns and parameters for formulas, define fields that
274 should be automatically recalculated, etc. You can also use Emacs lisp in
275 formulas ([[file:org-spreadsheet-lisp-formulas.org][read this tutorial]]).
277 Have a look to the [[https://orgmode.org/org.html#Advanced-features][advanced features]] in Org-mode manual, it will give you a
278 quick overlook on this...
298 <div id="disqus_thread"></div>
299 <script type="text/javascript">
300 var disqus_shortname = 'worg'; // required: replace example with your forum shortname
302 var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
303 dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
304 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);