Daily
Match bank statements to open invoices every day
Each day your latest bank statement is matched against open invoices in Excel, paid ones are marked, and you get a list of anything that doesn't match.
- Runs
- Daily
- Apps
- Microsoft Excel, OneDrive
- AI
- Yes, uses the built-in AI allowance
- Access
- Files.ReadWrite
Send this to your assistant
Create a ClickRuntime automation: every morning, read the newest bank statement CSV in my OneDrive Statements folder, match payments to open invoices in my Invoices table, mark the matched ones Paid, and email me what didn't match.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
Small businesses that invoice clients spend hours each month ticking payments off against invoices. Customers pay the wrong amount, combine invoices or use a reference that doesn't match, so the job can't be done by simple lookup.
Matching every day, with exact matches by rule and the awkward ones checked by AI, keeps the invoice list current, so you know who has paid before chasing anyone and month end isn't a marathon.
What you get out of it
Know who has paid
Invoices are marked Paid within a day of the money arriving. You never chase a client who already paid.
Messy references handled
Payments with a typo in the reference or a slightly different amount are matched by AI when the rules can't decide.
Short exception list
You only see payments and invoices that didn't match. That's the part that needs a person.
Month end without a marathon
Reconciliation happens a little every day. By the end of the month there's little left to do.
How it works
What happens, step by step
Every morning it reads the newest bank statement in your OneDrive Statements folder.
It reads open invoices from your Invoices table in Excel.
Payments whose reference and amount match an invoice exactly are paired by rule, and AI suggests matches for the rest.
Matched invoices are marked Paid in Excel.
You get an email listing anything that didn't match. Statements already handled are skipped.
Before it runs live
- Connect Microsoft Excel
- Connect OneDrive
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Slack
- Combine it with other Microsoft Excel and OneDrive steps into one automation
Under the hood
The code that runs this automation
GRAPH = "https://graph.microsoft.com/v1.0"
import csv, io
from clickruntime import on_trigger, credentials, http, state, notify, ai
BOOK = "/me/drive/root:/Finance/invoices.xlsx:/workbook/worksheets/Invoices"
@on_trigger
def run(event):
h = {"Authorization": f"Bearer {credentials.connection('microsoft', 'work')}"}
files = http.get(f"{GRAPH}/me/drive/root:/Statements:/children", headers=h, params={"$orderby": "lastModifiedDateTime desc", "$top": 1}).json()["value"]
if not files or files[0]["id"] == state.get("last_file"):
return {"summary": "No new statement"}
lines = list(csv.DictReader(io.StringIO(http.get(f"{GRAPH}/me/drive/items/{files[0]['id']}/content", headers=h).text)))
rows = http.get(f"{GRAPH}{BOOK}/usedRange", headers=h).json()["values"]
open_inv = {r[0]: (i, float(r[2])) for i, r in enumerate(rows[1:], start=2) if r[3] != "Paid"}
unmatched = []
for p in lines:
hit = next((n for n, (_, amt) in open_inv.items() if n in p["description"] and abs(amt - float(p["amount"])) < 0.01), None)
if hit:
http.patch(f"{GRAPH}{BOOK}/range(address='D{open_inv.pop(hit)[0]}')", headers=h, json={"values": [["Paid"]]})
else:
unmatched.append(f"{p['date']} {p['description']} {p['amount']}")
report = "\n".join(unmatched) or "Everything matched."
if unmatched and open_inv:
report += "\n\nSuggested:\n" + ai.generate(f"Payments:\n{report}\nOpen invoices:\n" + "\n".join(f"{n} {a}" for n, (_, a) in open_inv.items()),
system="Suggest likely invoice for each payment, one per line, or 'none'.", max_output_tokens=400).text
notify.email_me("Reconciliation report", report)
state.set("last_file", files[0]["id"])
return {"unmatched": len(unmatched)}FAQ
Common questions
What format does the statement need to be in?
Does AI change anything on its own?
Does it connect to my bank directly?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Import new CSV files into an Excel table
When a CSV lands in your OneDrive folder, its rows are added to your Excel table automatically.
See how it worksAdd form responses to an Excel workbook
Every form submission is added as a row in your Excel workbook on OneDrive, with an email so you see it straight away.
See how it worksSave email attachments to OneDrive and log them in Excel
Attachments from your inbox are saved to OneDrive and each one is listed in an Excel log you can filter and search.
See how it worksKeep exploring
Set up “Match bank statements to open invoices every day” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.