原文Org as a spreadsheet system: using Emacs lisp as formulas, 由 Bastien 編輯,維護(hù)拓萌。本文只做學(xué)習(xí)之用。
序言<a id="sec-"></a>
本教程介紹如何在Org表中使用Emacs Lisp作為公式祷蝌。 如果想要了解如何使用Org作為電子表格系統(tǒng)的一般教程籽御,請(qǐng)閱讀這個(gè)教程。 還可以查看有關(guān)此主題的完整Org文檔。
示例 1: 操縱單元格<a id="sec-"></a>
下面是一個(gè)簡(jiǎn)單的表格:
First name | Last Name | |
---|---|---|
John | Doe | john.doe@emacs.edu |
Jennie | Duh | jennie.duh@emacs.edu |
你會(huì)很容易就注意到第三列模式: [firstname].[lastname]@emacs.edu
榴徐。 給出 First name 和 Last name ,很容易計(jì)算 Email 列的結(jié)果匀归。
首先將光標(biāo)放在第三列中:
現(xiàn)在鍵入 C-c }
顯示表的坐標(biāo)(引用)坑资。
對(duì)于每一行,需要將第一列(使用 $1
訪問(wèn))的內(nèi)容連接到點(diǎn)(".")穆端,然后連接到第二列(使用 $2
訪問(wèn))的單元格, 最后連接到字符串 "@emacs.edu"袱贮。 使用 Emacs Lisp 編寫的公式如下所示:
'(concat (downcase $1) "." (downcase $2) "@emacs.edu")
現(xiàn)在復(fù)制這個(gè)公式,在右下角的字段中鍵入 C-c =
來(lái)插入列公式<a id="fnr.2" class="footref" href="#fn.2">2</a>体啰,然后粘貼公式攒巍。 點(diǎn)擊 RET
將立即將結(jié)果插入此單元格( jack.goody@emacs.edu
),并在表格的底部添加 #+TBLFM
行荒勇。
警告:請(qǐng)注意初始引用 ( initial quote ) :公式是表達(dá)式本身 (expression itself) 柒莉,而不是其值。 當(dāng) $1
和 $2
引用將被正確的字符串替換時(shí)沽翔,該表達(dá)式將只有一個(gè)含義兢孝,然后通過(guò)在 #+TBLFM
上鍵入 C-c C-c
來(lái)應(yīng)用該表達(dá)式。
經(jīng)過(guò)公式計(jì)算表格如下:
在執(zhí)行公式時(shí)仅偎, $1
和 $2
將被解釋并由這些單元格的值替換為字符串:不需要用 "
括起 $1
西潘。
如果需要強(qiáng)制 $1
和 $2
被解釋為數(shù)字,請(qǐng)?jiān)?Emacs lisp 表達(dá)式的末尾添加標(biāo)志 ;N
哨颂。 參見下面表格:
First name | Last Name | Maths | French | Mean |
---|---|---|---|---|
John | Doe | 12 | 16 | 14 |
Jennie | Duh | 15 | 9 | 12 |
使用如下公式計(jì)算第五列:
#+TBLFM: $5='(/ (+ $3 $4) 2);N
作為一個(gè)練習(xí)喷市,嘗試寫出下面表第五列的Emacs lisp公式:
First name | Last Name | Maths | French | Mean |
---|---|---|---|---|
John | Doe | 12 | 16 | John: 14 |
Jennie | Duh | 15 | 9 | Jennie: 12 |
前四列的值是目前已知的,在此基礎(chǔ)上構(gòu)造出第五列威恼。 (提示:參閱 Emacs lisp 函數(shù) string-to-number
和 number-to-string
品姓。)
解決方案 :不能使用 ;N
標(biāo)志,因?yàn)樗鼤?huì)強(qiáng)制將單元格解釋為數(shù)字箫措,如果這樣做腹备,將無(wú)法訪問(wèn)第一行單元格的值。 所以一個(gè)方案就是使用 string-to-number
和 number-to-string
, 如下所示:
#+TBLFM: $5='(concat $1 ": " (number-to-string (/ (+ (string-to-number $3) (string-to-number $4)) 2)))
另一個(gè)解決方案是使用 ;L
標(biāo)志:?jiǎn)卧駜?nèi)容不是被直接解釋成字符串或數(shù)字斤蔓,而是直接插入到 Emacs lisp 表達(dá)式中植酥。 所以上面的公式可以安全地被下面這個(gè)更精簡(jiǎn)的代替:
#+TBLFM: $5='(concat "$1" ": " (number-to-string (/ (+ $3 $4) 2)));L
注意 "$1"
的雙引號(hào):因?yàn)樵谧置嫔喜迦?First name 將意味著 "it is an Emacs lisp symbol" 。 所以,當(dāng)使用 ;L
標(biāo)志時(shí)友驮,添加雙引號(hào)確保引用被解釋為一個(gè)字符串漂羊。
示例 2: 操縱行列區(qū)間<a id="sec-"></a>
假設(shè)有以下表格
Col1 | Col2 | Col3 | Col4 | Col5 |
---|---|---|---|---|
? | ? | in Col1 and Col2 (no duplicates) | only in Col1 | only in Col2 |
? | ? | … | … | … |
? | ? | … | … | … |
Col1
和 Col2
包含字符串。
第三列的第一個(gè)單元格包含一個(gè)字符串卸留,這個(gè)字符串由 Col1
和 Col2
中的所有字符串去重后組成走越。 Col4
包含僅在 Col1
(不在 Col2
)中的字符串,而 Col5
包含僅在 Col2
(不在 Col1
)中的字符串耻瑟。
如何使用Emacs lisp公式來(lái)自動(dòng)計(jì)算出結(jié)果旨指?
首先弄清楚想要的結(jié)果:
Col1 | Col2 | Col3 | Col4 | Col5 |
---|---|---|---|---|
a | a | a b c d | c | d |
a | b | |||
b | a | |||
c | d |
現(xiàn)在從第二行開始獲取第一列的值。
可通過(guò)引用 @2$1
訪問(wèn)左上角單元格中的“a”喳整。 可通過(guò)引用 @5$1
訪問(wèn)左下方單元格上的“c”谆构。 然后可使用 @2$1..@5$1
訪問(wèn)單元格區(qū)間內(nèi)值。
將上面獲取的區(qū)間添加到 Col3
的第一個(gè)單元格中:
Col1 | Col2 | Col3 | Col4 | Col5 |
---|---|---|---|---|
a | a | a a b c | c | d |
a | b | |||
b | a | |||
c | d |
公式如下:
#+TBLFM: @2$3='(mapconcat 'identity (list @2$1..@5$1) " ")
公式要怎么解讀呢?
解釋時(shí)框都,區(qū)間 @2$1..@5$1
由單元格的值替換低淡,并用空格分隔。 所以 (list @2$1..@5$1)
變成 (list "a" "a" "b" "c")
瞬项,整個(gè)公式變成
'(mapconcat 'identity (list "a" "a" "b" "c") " ")
上面的公式大體意味著的連接 ("a" "a" "b" "c")
中元素蔗蹋,并在每個(gè)元素之間添加一個(gè)空格。
把問(wèn)題更一般話囱淋,我很可能不知道表包含多少行猪杭。 區(qū)間 @2$1..@5$1
變成 @2$1..@>$1
其中 @>
表示“最后一行”, @>$1
表示“第一列的最后一行”妥衣。
記自硭薄:我們希望第三列包含一個(gè)字符串,這個(gè)字符串由 Col1
和 Col2
中的所有字符串去重后組成税手。 首先從 Col1
和 Col2
列出所有值 (list =@2$1..@>$1 @2$2..@>$2)
蜂筹, 然后刪除重復(fù)項(xiàng) (delete-dups (list @2$1..@>$1 @2$2..@>$2))
, 最后把這個(gè)表達(dá)式放在上面已有的表達(dá)式中。
#+TBLFM: @2$3='(mapconcat 'identity (delete-dups (list @2$1..@>$1 @2$2..@>$2)) " ")
Col1 | Col2 | Col3 | Col4 | Col5 |
---|---|---|---|---|
a | a | a b c d | c | d |
a | b | |||
b | a | |||
c | d |
好的芦倒。 現(xiàn)在你已經(jīng)知道如何操縱區(qū)間艺挪,你可以用正確的公式替換 "?"了… 記住: Col4
包含僅在 Col1
中而不在 Col2
中的字符串兵扬,而 Col5
包含僅在 Col2
中而不在 Col1
中的字符串麻裳。 (注:可以編寫自己的函數(shù)并在 Emacs lisp 公式中使用它們)
Col4
和 Col5
的公式如下:
#+TBLFM: @2$4='(apply 'concat (delete-if (lambda(e) (member e (list @2$2..@>$2))) (list @2$1..@>$1)))
#+TBLFM: @2$5='(apply 'concat (delete-if (lambda(e) (member e (list @2$1..@>$1))) (list @2$2..@>$2)))
不要忘記,可以通過(guò)在表上的任何位置點(diǎn)擊 C-c '
來(lái)編輯表的公式: 它將打開公式編輯器器钟,并突出顯示光標(biāo)所在的引用(在公式編輯器和表中)津坑。 當(dāng)需要檢查引用是否正確時(shí),公式編輯器非常方便傲霸。 此外疆瑰,在該編輯器中的公式上點(diǎn)擊 TAB
將格式化公式眉反,這樣更有助于公式編輯!
結(jié)論<a id="sec-"></a>
請(qǐng)瀏覽Org手冊(cè)(精簡(jiǎn)但準(zhǔn)確和最新)使用Lisp作為公式的信息:請(qǐng)參閱在線手冊(cè) 和 相關(guān)信息頁(yè)穆役。