Workflow for manual entries and merge with bank statement

Hi all,

I stumbled across PTA just two weeks a go and as a software developer I don’t have to say how much I love plain text and the advantages of having everything in a git repository.

I used GnuCash for around three years now and it worked quite well so far, but it’s an application and you need to have it installed to work with your data.

I’d like to switch to PTA and I’ve already converted my GnuCash files over to hledger format, which is the tool I decided to start with. I’ve also setup some rules to import my bank account statements, which also work as expected (or even better as I expected).

One thing I can’t get my head around is to merge (or set entries as cleared) with the statement of the bank. As example:

Go to the grocery, buy bread and a t-shirt. Back home I’ll add the receipt manually like this:

2025-11-06 Grocery XYZ
   exp:grocery:food   10 ; Delicious bread
   exp:grocery:cloth  15 ; A new t-shirt for myself
   asset:bank        -25

At the end of the month I’ll get the statement of the bank and import it, with some rules, to my journal, which then may look like this:

2025-11-06=2025-11-07 (UNIQUE_CODE) Grocery XYZ
   exp:grocery   25
   asset:bank   -25

Now I’ve the same entry twice. So I edit it manually, probably work with flags to see which one to check, and then I’d like to have something like this:

2025-11-06=2025-11-07 (UNIQUE_CODE) Grocery XYZ
   exp:grocery:food   10 ; Delicious bread
   exp:grocery:cloth  15 ; A new t-shirt for myself
   asset:bank        -25

Does anyone has a good workflow to achieve this? Maybe it’s already written somewhere and I just used the wrong search terms (Not a native English speaker).

I already thought about a manual entry journal like this:

  1. Collect my receipt of the current month in a manual.journal
  2. Import the statement from the bank to my main.journal
  3. Use a diff tool like meld to merge the entries from the manual.journalto main.journal
  4. Clean up manual.journal to start the new month again

Thanks for any suggestions, idea or hint.

1 Like

Welcome @rba. In my case, it's

  • Boring transactions: don't bother manually recording, I know they'll come from the bank in a day or three, and their date will be a day or more after the event, but it usually doesn't matter.
  • Interesting transactions, eg a complicated groceries purchase with mixed categories: I do as you did there - when I see the imported bank entry show up in my journal a day or three later, I just discard it manually in the editor (sometimes merging possibly useful details from it like the bank's original description), and mark my entry cleared.

I think it's always good have a human in the loop - but probably we could go further with the automation and/or UI here. Interested in your ideas.

Hi @simonmic,

Thank you for your fast reply. I see it the same way. Lot of the transactions are "boring"/clear what the expense was (e.g. mortgage), but for others I've more interesting information, which my bank does not know, of course.

Since I only download my bank statement once a month, there can be a lot of transactions, so import into my main journal and then manual check against my manual entries in the same file could be tricky (maybe). I need to try out how it work and for my first steps, I guess, I'll start with a separate "manual" entries file to merge after import. It feels like it's easier to handle. Let's see how it work.

How do you handle the .latest files? To prevent from loosing all the "already imported" information, I guess, these files should be added to VCS too?! And if I'd like to do the import on another host I need these information too. What's your opinions/experience on this?

I've faced something similar. YMMV.

I too download the bank statements once a month, so I'll I'll have two options setup to identify those interesting transactions by either specific keywords or manually adding the narration to a separate file.

so when my importer runs, it'll skip ( necessarily make a “Note" ) so that I won't lose the transaction or ordering, an entry which I can use when manually reconcile or comparing the statement and the ledger.

A separate , manual.bean file will have the record , enriched with my comments/details etc ..

This works out on VCS too, as you'll know a change happened without losing the context.

ps : ideally, my goal is to froze the ledger files priorr to 6 months.

@rba I don't bother committing .latest files - it would be too much version control noise for me, and they are easy to recreate by hand, or to update with import --catchup, or to delete and then handle the overlap manually one time.

For active accounts, I'd find a monthly cadence unnecessarily hard, because of the volume of data for issues to hide in and the impossibility of remembering relevant details over that period; so for those accounts I import as often as possible, usually ideally daily.

1 Like

I have multiple bank accounts, sometimes with transfers between them. I use assets:transfers:bankabankb as a second account for both. Then I can verify that the transfer accounts sum to 0 at the end of an import.

I got this idea from hledger-flow. Their readme describes it in more detail: GitHub - apauley/hledger-flow: An hledger/ledger-cli workflow focusing on automated statement import and classification

I always found the bank data very ugly. So I do my payee names like you do, something legible, for example:

Now, in Beancount we can have arbitrary metadata (I assume other programs have similar?) so that’s where I stick the ugly bank description, in case I need to reference it for any reason. In my case, I actually do that in an automated fashion at reconciliation time.[0]

I can’t emphasize this enough. IMNSHO, this is one of the keys to finally sticking with PTA on an ongoing basis!

[0] I am also downloading my bank data using the SimpleFIN API, which I can highly recommend.

1 Like

What works well for me is preventing the duplicate from ever being imported.

Before importing a bank statement, I run a small pre-check (in my case from Excel/VBA, but the idea.):

  • If a transaction with the same posting date

  • and the same total amount

  • and the same bank account

already exists in the journal, the import skips it.

So in your example:

Manual entry (already exists):

2025-11-06 Grocery XYZ
   exp:grocery:food   10
   exp:grocery:cloth  15
   asset:bank        -25

When importing the bank statement line:

2025-11-07 Grocery XYZ  -25

The importer (VBA) detects that 2025-11-06 / -25 / asset:bank already exists and does nothing. No second transaction is created, no merge step required.