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 😉

Anúncios

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: