Publicado por: lezz | dezembro 28, 2010

Função que ordena os registros do cartão de crédito

O problema

Eu uso o moneylog já há algum tempo e desenvolvi algumas funções para facilitar a minha vida, e algo que estava me incomodando era o fato de ter que organizar todos os canhotos do cartão de crédito para depois lançá-los no meu registro.

Tá, eu sei que no HTML o moneylog mostra ordenado os registros no browser, mas eu queria eles organizados no texto tb😉

O que eu queria era poder lançar os registros na ordem em que fosse pegando os registros e que depois “uma função mágica” ordenasse eles pra mim😉 (fácil né?!)

A solução

Como eu uso o emacs para lançar os registros, nada mais natural que fosse dentro do emacs que fosse feita essa organização.

Os meus registros tem o seguinte formato:

AAAA-MM-DD -X.XX tag1, tag2| @MM.DD Descrição do gasto

Imaginei várias soluções, desde a mais simples: ordenar as linhas alfabéticamente, até outras mais complexas, onde preencheria hash tables com a data do gasto para poder organizar o conjunto de linhas.

Como cada registro é uma única linha, eu já tinha uma idéia de como seriam os registros.

O problema para a solução mais simples é que, como eu coloco a data de lançamento para a data de vencimento do meu cartão ordenar as entradas pelo primeiro campo (AAAA-MM-DD) não iria adiantar nada, pois as entradas teriam a mesma data😦

Para a abordagem de colocar todas as entradas em hash tables há o problema de que posso ter várias entradas no mesmo dia, independente de usar o campo AAAA-MM-DD ou @MM.DD e sendo assim eu perderia entradas😦

A solução acabou sendo a mais simples (ou segunda mais simples), copiar a data de compra @MM.DD para o início da linha, onde meu registro temporário ficaria assim:

@MM.DD AAAA-MM-DD -X.XX tag1, tag2| @MM.DD Descrição do gasto

E depois mandar ordenar as linhas com (sort-lines nil (point-min) (point-max)).

Pronto, os registros já estavam ordenados, porém agora eu não tinha mais o formato do moneylog, mas estava fácil voltar ao formato original.

Bastava recortar a primeira parte do texto com (kill-rectangle minr maxr) e voi-lá, estaria de volta no formato certo.

Uso

Para usar a função, basta selecionar a região e digitar M-x i-ordena-ccredit.

O resultado esperado é que os registros apareçam ordenados e com o texto #ordenado na linha logo antes do primeiro registro.

Antes

2011-01-17  -1.25   ccred11_01, diversos, mercadorama| @12.20 1 refri Cini no mercadorama sabor gengibirra
2011-01-17  -1.20   ccred11_01, bapka| @12.23 2 picolés de morango na bapka
2011-01-17  -1.20   ccred11_01, bapka| @12.27 2 picolés de morango na bapka
2011-01-17  -0.60   ccred11_01, bapka| @12.21 Sorvete de Morango na Bapka

Depois

# ordenado
2011-01-17  -1.25   ccred11_01, diversos, mercadorama| @12.20 1 refri Cini no mercadorama sabor gengibirra
2011-01-17  -0.60   ccred11_01, bapka| @12.21 Sorvete de Morango na Bapka
2011-01-17  -1.20   ccred11_01, bapka| @12.23 2 picolés de morango na bapka
2011-01-17  -1.20   ccred11_01, bapka| @12.27 2 picolés de morango na bapka

O Código

;; Selecione ANTES a região com as linhas a serem ordenadas
;; muito provavelmente os registros do cartão de crédito ;-)

;; A função Ordena os registros do seguinte tipo com base na data colocada em @mm.dd

;;--------------------------------------------------------------------------
2011-01-17  -0.60   ccred11_01, bapka| @12.21 Sorvete de Morango na Bapka
2011-01-17  -60.00  ccred11_01, carro| @12.21 Gasolina para o Carro
2011-01-17  -6.30   ccred11_01| @12.21 Carpetes e Velcro de Proteção para Árvore na Tecidos Avenida
2011-01-17  -10.50  ccred11_01, estac| @12.22 Estacionamento Almoço
2011-01-17  -36.00  ccred11_01, presente| @12.21 Camisetas
;;---------------------------------------------------------------------------

(defun i-ordena-ccredit ()
"Ordena os registros de data do cartão de crédito."
(interactive)
;; discover point-min and point-max from the selected region, or use the next word
(let (pos1 pos2 bds)
  (if (and transient-mark-mode
           mark-active)
      (setq start (region-beginning) end (region-end))
    (progn
      (setq bds (bounds-of-thing-at-point 'symbol))
      (setq start (car bds) end (cdr bds))
      ))
; idiom for string replacement in region
;; restrict the atuation of the next commands to the selected region
(with-output-to-temp-buffer "*registros*"
  (save-restriction
    (narrow-to-region start end)
    (goto-char (point-min))
    (while (< (point) (point-max))
;; reads the buffer line
      (setq linha (buffer-substring (line-beginning-position) (line-end-position)))
;; matches the date field 
      (string-match "\\(@[0-9][0-9].[0-9][0-9]\\)" linha)
;; puts the date matched in the data variable
      (setq data-compra (match-string 0 linha))
;; prints the line with the buy date's first
      (princ (format "%s %s\n" data-compra linha))
      (forward-line 1)
      )
    ;; repeat for other string pairs
    )
  )
;; creates a new buffer called *registros to manipulate the strings
(let ((oldbuf (current-buffer)))
  (set-buffer "*registros*")
;; let we modify the buffer
  (setq buffer-read-only nil)
;; as the buffer already has the lines in the right format, we sort them all
;; @12.21 2011-01-17    -36.00  ccred11_01, presente| @12.21 Camisetas 
  (sort-lines nil (point-min) (point-max))
;; we need to define the region that will be killed (the @mm.dd part at the front of the line)
;; that was inserted before
  (setq minr (point-min))
  (goto-char (point-max))
  (forward-line -1)
  (re-search-forward "\\(@[0-9][0-9].[0-9][0-9] \\)")
  (setq maxr (point))
;; kill the rectangle
  (kill-rectangle minr maxr)
;; now we kill the whole region to put it into the kill ring
  (kill-region (point-min) (point-max))
;; kill the temporary buffer
  (kill-buffer (current-buffer)) 
  (set-buffer oldbuf))
;; we'll kill the old region to put the new sorted lines
(kill-region (region-beginning) (region-end))
(goto-char (region-end))
(forward-line)
(insert (format "# ordenado\n"))
;; as we have killed the selected region, the ordered lines are in the 2nd position of the kill ring
(yank 2)
  )
)

Ah, o mesmo código acima pode ser encontrado no pastebin.

E é isso😉


Responses

  1. Hello. And Byehh

  2. Hello. And Byehh

  3. Hello. And Byehh

  4. rumour reports almost extreme recess

  5. news reports almost extreme keep

  6. Olá,
    Como você está? , Só queria dizer Olá a todos fórum lezz.wordpress.com
    Este é meu primeiro post, eu estou escrevendo do meu novo iPad.
    Parece fácil , mas eu estou mais acostumado com o pc .
    Uma saudação.


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Categorias

%d blogueiros gostam disto: