【问题标题】:org-mode review clocked time by multiple tagsorg-mode 查看多个标签的时钟时间
【发布时间】:2022-06-16 21:07:13
【问题描述】:

我想通过标签查看我的计时时间,例如回答本周我在健康、工作、客户或社会关系上花了多少时间?

我正在使用标签,因为我想要查看我的时钟时间的项目可以分布在多个文件中并隐藏在不同的子树中。也许这就是问题所在,我需要重组?例如。 “写日记”应该放在“笔记”下面,但归结为“健康”,当然“笔记”下面还有“财务”之类的笔记……

任何其他解决方案,例如也非常欢迎使用自定义议程视图或类别而不是标签。

到目前为止,我已经尝试使用按多个标签分组的org mode clocktable。为了使用时钟表,我使用了这个测试数据:

* Take out the trash                                                :private:
:LOGBOOK:
CLOCK: [2021-03-12 Fri 11:24]--[2021-03-12 Fri 11:30] =>  0:06
:END:
* Update document for client                                        :client1:
:LOGBOOK:
CLOCK: [2021-03-12 Fri 12:45]--[2021-03-12 Fri 13:30] =>  0:45
:END:
* Create my awesome note for work                                      :work:
:LOGBOOK:
CLOCK: [2021-03-13 Sat 11:24]--[2021-03-13 Sat 12:53] =>  1:29
:END:
* Fill in timesheet                                                    :work:
:LOGBOOK:
CLOCK: [2021-03-12 Fri 11:24]--[2021-03-12 Fri 11:40] =>  0:16
:END:

我找到了以下解决方案,但似乎都不适用于我的系统。

Here 我的问题已经完美描述了。我已经下载了the code,它会创建一个表格,但不会显示总和。不幸的是,被剪断的代码似乎太旧了,我无法修复它。我找到了一个a fork of that snipped,它给了我这个结果:

#+BEGIN: clocktable-by-tag :tags ("work" "client1")
| Tag     | Headline   | Time (h) |
|         |            |      <r> |
|---------+------------+----------|
| work    | *Tag time* |   *0.00* |
|---------+------------+----------|
| client1 | *Tag time* |   *0.00* |    
#+END:

Here我找到了另一个解决方案。作者使用函数来格式化时间,然后orgaggregate 使用。不幸的是,已经迈出了第一步,似乎无法正常工作:

 #+BEGIN: clocktable :scope file :maxlevel 3 :tags t :match "work|client1" :header "#+TBLNAME: timetable\n"
#+TBLNAME: timetable
| Tags    | Headline                        |   Time | T      |
|---------+---------------------------------+--------+--------|
|         | *Total time*                    | *2:30* | #ERROR |
|---------+---------------------------------+--------+--------|
| client1 | Update document for client      |   0:45 | #ERROR |
| work    | Create my awesome note for work |   1:29 | #ERROR |
| work    | Fill in timesheet               |   0:16 | #ERROR |
#+TBLFM: $4='(convert-org-clocktable-time-to-hhmm $3)::@1$4='(format "%s" "T")
#+END:

这真的不应该那么难,我想要达到的目标。目前我最好的解决方案是使用多个表,每个标签一个:

#+BEGIN: clocktable :scope file :maxlevel 3 :match "work"
#+CAPTION: Clock summary at [2022-01-03 Mon 16:55]
| Headline                        |   Time |
|---------------------------------+--------|
| *Total time*                    | *1:45* |
|---------------------------------+--------|
| Create my awesome note for work |   1:29 |
| Fill in timesheet               |   0:16 |
#+END:


#+BEGIN: clocktable :scope file :maxlevel 3 :match "client1"
#+CAPTION: Clock summary at [2022-01-03 Mon 16:55]
| Headline                   | Time   |
|----------------------------+--------|
| *Total time*               | *0:45* |
|----------------------------+--------|
| Update document for client | 0:45   |
#+END:

【问题讨论】:

    标签: emacs org-mode


    【解决方案1】:

    您找到的第一个解决方案几乎就在那里。它有两个问题给了你错误的结果:

    1. 它只考虑议程文件,而不是当前文件作为表格的输入。这就是您得到空结果的原因。
    2. 要将分钟转换为格式良好的显示,可以使用函数org-duration-from-minutes

    有了这些更新,你的测试文件给了我这个结果:

      #+BEGIN: clocktable-by-tag :tags ("work" "client1")
      | Tag     | Headline                          | Time (h) |      |
      |---------+-----------------------------------+----------+------|
      | work    | *Tag time*                        |     1:29 |      |
      |         | File *test.org*                   |     1:29 |      |
      |         | . Create my awesome note for work |          | 1:29 |
      |---------+-----------------------------------+----------+------|
      | client1 | *Tag time*                        |     0:45 |      |
      |         | File *test.org*                   |     0:45 |      |
      |         | . Update document for client      |          | 0:45 |
      
      #+END:
    

    使用:summary t可以得到更好的总结(我个人更喜欢这个选项):

      #+BEGIN: clocktable-by-tag :tags ("work" "client1") :summary t
      | Tag     | Headline   | Time (h) |
      |---------+------------+----------|
      | work    | *Tag time* |     1:29 |
      |---------+------------+----------|
      | client1 | *Tag time* |     0:45 |
      
      #+END:
    

    :scope 标记也可以使用,只是我没有实现比当前文件更严格的范围(例如 subtree)。

    您可以在gist 中找到代码,或从下面复制并粘贴:

    (require 'org-clock)
    
    (defun clocktable-by-tag/shift-cell (n)
      (let ((str ""))
        (dotimes (i n)
          (setq str (concat str "| ")))
        str))
    
    (defun clocktable-by-tag/insert-tag (files params)
      (let ((tag (plist-get params :tags))
            (summary-only (plist-get params :summary))
            (total 0))
        (insert "|--\n")
        (insert (format "| %s | *Tag time* |\n" tag))
        (mapcar
         (lambda (file)
           (let ((clock-data (with-current-buffer (find-buffer-visiting file)
                               (org-clock-get-table-data (buffer-name) params))))
             (when (> (nth 1 clock-data) 0)
               (setq total (+ total (nth 1 clock-data)))
               (if (not summary-only)
                   (progn
                     (insert (format "| | File *%s* | %s |\n"
                                     (file-name-nondirectory file)
                                     (org-duration-from-minutes (nth 1 clock-data))))
                     (dolist (entry (nth 2 clock-data))
                       (insert (format "| | . %s%s | %s %s |\n"
                                       (org-clocktable-indent-string (nth 0 entry))
                                       (nth 1 entry)
                                       (clocktable-by-tag/shift-cell (nth 0 entry))
                                       (org-duration-from-minutes (nth 4 entry))))))))))
         files)
        (save-excursion
          (re-search-backward "*Tag time*")
          (org-table-next-field)
          (org-table-blank-field)
          (insert (org-duration-from-minutes total))))
      (org-table-align))
    
    (defun org-dblock-write:clocktable-by-tag (params)
      (insert "| Tag | Headline | Time (h) |\n")
      (let ((params (org-combine-plists org-clocktable-defaults params))
            (base-buffer (org-base-buffer (current-buffer)))
              (files (pcase (plist-get params :scope)
                         (`agenda
                          (org-agenda-files t))
                         (`agenda-with-archives
                          (org-add-archive-files (org-agenda-files t)))
                         (`file-with-archives
                          (let ((base-file (buffer-file-name base-buffer)))
                            (and base-file
                                   (org-add-archive-files (list base-file)))))
                         ((or `nil `file)
                          (list (buffer-file-name)))
                         (_ (user-error "Unknown scope: %S" scope))))
            (tags (plist-get params :tags)))
        (mapcar (lambda (tag)
                  (clocktable-by-tag/insert-tag files (org-combine-plists params `(:match ,tag :tags ,tag))))
                tags)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多