[{"data":1,"prerenderedAt":3099},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger":3,"surround:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger":3064,"ancestors:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger":3073,"children:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger":3078,"related:\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger":3079},{"id":4,"title":5,"body":6,"dateModified":3029,"datePublished":3029,"description":3030,"extension":3031,"faq":3032,"keyword":3041,"kind":3042,"meta":3043,"navigation":98,"path":3053,"seo":3054,"slug":3057,"stem":3058,"topics":3059,"type":3062,"__hash__":3063},"docs\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger\u002Findex.md","Build a Trial Balance from a General Ledger",{"type":7,"value":8,"toc":3016},"minimark",[9,19,24,53,63,67,70,302,305,309,312,629,632,636,639,796,802,1057,1061,1069,1499,1506,1641,1645,1648,2426,2441,2670,2674,2677,2899,2905,2909,2944,2948,2951,2955,2961,2967,2973,2979,2983,3012],[10,11,12,13,18],"p",{},"The trial balance is the first report of every month-end close: every account in the ledger with its balance, debits in one column and credits in the other, and — if the books are in order — the two columns adding up to the same number. Accountants use it to spot problems before anything else is built on top: an account with a balance on the wrong side, a suspense account that should be empty, a journal that was posted to only one side. The ledger system can print one, but the raw journal lines usually end up in Excel anyway, and building the trial balance in Python makes it repeatable and lets you add the checks the accountants actually perform. This page builds it from journal lines with pandas, adds those checks, compares with the prior month, and writes a formatted workbook. It belongs to ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002F","Building Finance and Operations Reports",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47,50],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," pandas",[35,51,52],{"class":45}," openpyxl\n",[10,54,55,58,59,62],{},[32,56,57],{},"gl_lines.xlsx"," holds journal lines — date, journal reference, account number, debit, credit — from the opening balances at the end of July through September. ",[32,60,61],{},"chart_of_accounts.xlsx"," maps each account to a name and type (Asset, Liability, Equity, Revenue, Expense). The trial balance is for September 2026.",[20,64,66],{"id":65},"step-1-load-the-ledger-and-check-it-balances","Step 1 — Load the ledger and check it balances",[10,68,69],{},"Before summarising anything, confirm the raw material is sound: every journal should balance on its own, and every account used should exist in the chart of accounts:",[25,71,75],{"className":72,"code":73,"language":74,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\n\ngl = pd.read_excel(\"gl_lines.xlsx\")\ncoa = pd.read_excel(\"chart_of_accounts.xlsx\")\n\nby_journal = gl.groupby(\"Journal\")[[\"Debit\", \"Credit\"]].sum()\nunbalanced = by_journal[(by_journal[\"Debit\"] - by_journal[\"Credit\"]).abs() > 0.005]\nunknown = sorted(set(gl[\"Account\"]) - set(coa[\"Account\"]))\nprint(\"journals:\", len(by_journal), \"| unbalanced:\", list(unbalanced.index), \"| unknown accounts:\", unknown)\nprint(\"ledger totals:\", gl[\"Debit\"].sum(), gl[\"Credit\"].sum())\n","python",[32,76,77,93,100,118,133,138,167,204,243,279],{"__ignoreMap":30},[35,78,79,83,87,90],{"class":37,"line":38},[35,80,82],{"class":81},"s-kum","import",[35,84,86],{"class":85},"skGVy"," pandas ",[35,88,89],{"class":81},"as",[35,91,92],{"class":85}," pd\n",[35,94,96],{"class":37,"line":95},2,[35,97,99],{"emptyLinePlaceholder":98},true,"\n",[35,101,103,106,109,112,115],{"class":37,"line":102},3,[35,104,105],{"class":85},"gl ",[35,107,108],{"class":81},"=",[35,110,111],{"class":85}," pd.read_excel(",[35,113,114],{"class":45},"\"gl_lines.xlsx\"",[35,116,117],{"class":85},")\n",[35,119,121,124,126,128,131],{"class":37,"line":120},4,[35,122,123],{"class":85},"coa ",[35,125,108],{"class":81},[35,127,111],{"class":85},[35,129,130],{"class":45},"\"chart_of_accounts.xlsx\"",[35,132,117],{"class":85},[35,134,136],{"class":37,"line":135},5,[35,137,99],{"emptyLinePlaceholder":98},[35,139,141,144,146,149,152,155,158,161,164],{"class":37,"line":140},6,[35,142,143],{"class":85},"by_journal ",[35,145,108],{"class":81},[35,147,148],{"class":85}," gl.groupby(",[35,150,151],{"class":45},"\"Journal\"",[35,153,154],{"class":85},")[[",[35,156,157],{"class":45},"\"Debit\"",[35,159,160],{"class":85},", ",[35,162,163],{"class":45},"\"Credit\"",[35,165,166],{"class":85},"]].sum()\n",[35,168,170,173,175,178,180,183,186,189,191,194,197,201],{"class":37,"line":169},7,[35,171,172],{"class":85},"unbalanced ",[35,174,108],{"class":81},[35,176,177],{"class":85}," by_journal[(by_journal[",[35,179,157],{"class":45},[35,181,182],{"class":85},"] ",[35,184,185],{"class":81},"-",[35,187,188],{"class":85}," by_journal[",[35,190,163],{"class":45},[35,192,193],{"class":85},"]).abs() ",[35,195,196],{"class":81},">",[35,198,200],{"class":199},"sP0c6"," 0.005",[35,202,203],{"class":85},"]\n",[35,205,207,210,212,215,218,221,224,227,230,232,235,238,240],{"class":37,"line":206},8,[35,208,209],{"class":85},"unknown ",[35,211,108],{"class":81},[35,213,214],{"class":199}," sorted",[35,216,217],{"class":85},"(",[35,219,220],{"class":199},"set",[35,222,223],{"class":85},"(gl[",[35,225,226],{"class":45},"\"Account\"",[35,228,229],{"class":85},"]) ",[35,231,185],{"class":81},[35,233,234],{"class":199}," set",[35,236,237],{"class":85},"(coa[",[35,239,226],{"class":45},[35,241,242],{"class":85},"]))\n",[35,244,246,249,251,254,256,259,262,265,267,270,273,276],{"class":37,"line":245},9,[35,247,248],{"class":199},"print",[35,250,217],{"class":85},[35,252,253],{"class":45},"\"journals:\"",[35,255,160],{"class":85},[35,257,258],{"class":199},"len",[35,260,261],{"class":85},"(by_journal), ",[35,263,264],{"class":45},"\"| unbalanced:\"",[35,266,160],{"class":85},[35,268,269],{"class":199},"list",[35,271,272],{"class":85},"(unbalanced.index), ",[35,274,275],{"class":45},"\"| unknown accounts:\"",[35,277,278],{"class":85},", unknown)\n",[35,280,282,284,286,289,292,294,297,299],{"class":37,"line":281},10,[35,283,248],{"class":199},[35,285,217],{"class":85},[35,287,288],{"class":45},"\"ledger totals:\"",[35,290,291],{"class":85},", gl[",[35,293,157],{"class":45},[35,295,296],{"class":85},"].sum(), gl[",[35,298,163],{"class":45},[35,300,301],{"class":85},"].sum())\n",[10,303,304],{},"All journals balance and every account is known, so the ledger as a whole balances too. If a journal does not, the trial balance will not either, and it is far easier to find the problem here — by journal reference — than from a difference at the bottom of the report. Comparing with a tolerance of half a cent avoids false alarms from floating-point sums of amounts read from Excel.",[20,306,308],{"id":307},"step-2-opening-movement-and-closing-per-account","Step 2 — Opening, movement and closing per account",[10,310,311],{},"A trial balance at the end of September needs each account's balance brought forward from before the month, the month's movements, and the closing balance:",[25,313,315],{"className":72,"code":314,"language":74,"meta":30,"style":30},"start, end = pd.Timestamp(\"2026-09-01\"), pd.Timestamp(\"2026-09-30\")\ngl[\"Net\"] = gl[\"Debit\"] - gl[\"Credit\"]\n\nopening = gl[gl[\"Date\"] \u003C start].groupby(\"Account\")[\"Net\"].sum()\nmoves = gl[(gl[\"Date\"] >= start) & (gl[\"Date\"] \u003C= end)].groupby(\"Account\")[[\"Debit\", \"Credit\"]].sum()\n\ntb = (coa.set_index(\"Account\")\n        .join(opening.rename(\"Opening\"))\n        .join(moves)\n        .fillna({\"Opening\": 0.0, \"Debit\": 0.0, \"Credit\": 0.0}))\ntb[\"Closing\"] = tb[\"Opening\"] + tb[\"Debit\"] - tb[\"Credit\"]\ntb = tb[(tb[[\"Opening\", \"Debit\", \"Credit\", \"Closing\"]] != 0).any(axis=1)]\nprint(tb[[\"Name\", \"Opening\", \"Debit\", \"Credit\", \"Closing\"]].to_string())\n",[32,316,317,338,365,369,400,448,452,466,477,482,514,551,599],{"__ignoreMap":30},[35,318,319,322,324,327,330,333,336],{"class":37,"line":38},[35,320,321],{"class":85},"start, end ",[35,323,108],{"class":81},[35,325,326],{"class":85}," pd.Timestamp(",[35,328,329],{"class":45},"\"2026-09-01\"",[35,331,332],{"class":85},"), pd.Timestamp(",[35,334,335],{"class":45},"\"2026-09-30\"",[35,337,117],{"class":85},[35,339,340,343,346,348,350,353,355,357,359,361,363],{"class":37,"line":95},[35,341,342],{"class":85},"gl[",[35,344,345],{"class":45},"\"Net\"",[35,347,182],{"class":85},[35,349,108],{"class":81},[35,351,352],{"class":85}," gl[",[35,354,157],{"class":45},[35,356,182],{"class":85},[35,358,185],{"class":81},[35,360,352],{"class":85},[35,362,163],{"class":45},[35,364,203],{"class":85},[35,366,367],{"class":37,"line":102},[35,368,99],{"emptyLinePlaceholder":98},[35,370,371,374,376,379,382,384,387,390,392,395,397],{"class":37,"line":120},[35,372,373],{"class":85},"opening ",[35,375,108],{"class":81},[35,377,378],{"class":85}," gl[gl[",[35,380,381],{"class":45},"\"Date\"",[35,383,182],{"class":85},[35,385,386],{"class":81},"\u003C",[35,388,389],{"class":85}," start].groupby(",[35,391,226],{"class":45},[35,393,394],{"class":85},")[",[35,396,345],{"class":45},[35,398,399],{"class":85},"].sum()\n",[35,401,402,405,407,410,412,414,417,420,423,426,428,430,433,436,438,440,442,444,446],{"class":37,"line":135},[35,403,404],{"class":85},"moves ",[35,406,108],{"class":81},[35,408,409],{"class":85}," gl[(gl[",[35,411,381],{"class":45},[35,413,182],{"class":85},[35,415,416],{"class":81},">=",[35,418,419],{"class":85}," start) ",[35,421,422],{"class":81},"&",[35,424,425],{"class":85}," (gl[",[35,427,381],{"class":45},[35,429,182],{"class":85},[35,431,432],{"class":81},"\u003C=",[35,434,435],{"class":85}," end)].groupby(",[35,437,226],{"class":45},[35,439,154],{"class":85},[35,441,157],{"class":45},[35,443,160],{"class":85},[35,445,163],{"class":45},[35,447,166],{"class":85},[35,449,450],{"class":37,"line":140},[35,451,99],{"emptyLinePlaceholder":98},[35,453,454,457,459,462,464],{"class":37,"line":169},[35,455,456],{"class":85},"tb ",[35,458,108],{"class":81},[35,460,461],{"class":85}," (coa.set_index(",[35,463,226],{"class":45},[35,465,117],{"class":85},[35,467,468,471,474],{"class":37,"line":206},[35,469,470],{"class":85},"        .join(opening.rename(",[35,472,473],{"class":45},"\"Opening\"",[35,475,476],{"class":85},"))\n",[35,478,479],{"class":37,"line":245},[35,480,481],{"class":85},"        .join(moves)\n",[35,483,484,487,489,492,495,497,499,501,503,505,507,509,511],{"class":37,"line":281},[35,485,486],{"class":85},"        .fillna({",[35,488,473],{"class":45},[35,490,491],{"class":85},": ",[35,493,494],{"class":199},"0.0",[35,496,160],{"class":85},[35,498,157],{"class":45},[35,500,491],{"class":85},[35,502,494],{"class":199},[35,504,160],{"class":85},[35,506,163],{"class":45},[35,508,491],{"class":85},[35,510,494],{"class":199},[35,512,513],{"class":85},"}))\n",[35,515,517,520,523,525,527,530,532,534,537,539,541,543,545,547,549],{"class":37,"line":516},11,[35,518,519],{"class":85},"tb[",[35,521,522],{"class":45},"\"Closing\"",[35,524,182],{"class":85},[35,526,108],{"class":81},[35,528,529],{"class":85}," tb[",[35,531,473],{"class":45},[35,533,182],{"class":85},[35,535,536],{"class":81},"+",[35,538,529],{"class":85},[35,540,157],{"class":45},[35,542,182],{"class":85},[35,544,185],{"class":81},[35,546,529],{"class":85},[35,548,163],{"class":45},[35,550,203],{"class":85},[35,552,554,556,558,561,563,565,567,569,571,573,575,578,581,584,587,591,593,596],{"class":37,"line":553},12,[35,555,456],{"class":85},[35,557,108],{"class":81},[35,559,560],{"class":85}," tb[(tb[[",[35,562,473],{"class":45},[35,564,160],{"class":85},[35,566,157],{"class":45},[35,568,160],{"class":85},[35,570,163],{"class":45},[35,572,160],{"class":85},[35,574,522],{"class":45},[35,576,577],{"class":85},"]] ",[35,579,580],{"class":81},"!=",[35,582,583],{"class":199}," 0",[35,585,586],{"class":85},").any(",[35,588,590],{"class":589},"sa561","axis",[35,592,108],{"class":81},[35,594,595],{"class":199},"1",[35,597,598],{"class":85},")]\n",[35,600,602,604,607,610,612,614,616,618,620,622,624,626],{"class":37,"line":601},13,[35,603,248],{"class":199},[35,605,606],{"class":85},"(tb[[",[35,608,609],{"class":45},"\"Name\"",[35,611,160],{"class":85},[35,613,473],{"class":45},[35,615,160],{"class":85},[35,617,157],{"class":45},[35,619,160],{"class":85},[35,621,163],{"class":45},[35,623,160],{"class":85},[35,625,522],{"class":45},[35,627,628],{"class":85},"]].to_string())\n",[10,630,631],{},"Balances are kept as one signed number — debit positive, credit negative — which makes the arithmetic simple: closing equals opening plus debits minus credits. Starting from the chart of accounts and joining the movements on means accounts with an opening balance but no September activity, such as Equipment, still appear; accounts with nothing at all are dropped. Revenue and expense accounts carry balances from August here because this is a year-to-date ledger; at the year end they are closed into retained earnings.",[20,633,635],{"id":634},"step-3-debit-and-credit-columns","Step 3 — Debit and credit columns",[10,637,638],{},"The familiar presentation puts each closing balance in a Debit or a Credit column depending on its sign, and both columns must total the same:",[25,640,642],{"className":72,"code":641,"language":74,"meta":30,"style":30},"tb[\"Dr\"] = tb[\"Closing\"].clip(lower=0)\ntb[\"Cr\"] = (-tb[\"Closing\"]).clip(lower=0)\nprint(tb[[\"Name\", \"Dr\", \"Cr\"]].to_string())\nprint(f\"totals: Dr {tb['Dr'].sum():,.2f}  Cr {tb['Cr'].sum():,.2f}  difference {tb['Dr'].sum() - tb['Cr'].sum():,.2f}\")\n",[32,643,644,672,703,721],{"__ignoreMap":30},[35,645,646,648,651,653,655,657,659,662,665,667,670],{"class":37,"line":38},[35,647,519],{"class":85},[35,649,650],{"class":45},"\"Dr\"",[35,652,182],{"class":85},[35,654,108],{"class":81},[35,656,529],{"class":85},[35,658,522],{"class":45},[35,660,661],{"class":85},"].clip(",[35,663,664],{"class":589},"lower",[35,666,108],{"class":81},[35,668,669],{"class":199},"0",[35,671,117],{"class":85},[35,673,674,676,679,681,683,686,688,690,692,695,697,699,701],{"class":37,"line":95},[35,675,519],{"class":85},[35,677,678],{"class":45},"\"Cr\"",[35,680,182],{"class":85},[35,682,108],{"class":81},[35,684,685],{"class":85}," (",[35,687,185],{"class":81},[35,689,519],{"class":85},[35,691,522],{"class":45},[35,693,694],{"class":85},"]).clip(",[35,696,664],{"class":589},[35,698,108],{"class":81},[35,700,669],{"class":199},[35,702,117],{"class":85},[35,704,705,707,709,711,713,715,717,719],{"class":37,"line":102},[35,706,248],{"class":199},[35,708,606],{"class":85},[35,710,609],{"class":45},[35,712,160],{"class":85},[35,714,650],{"class":45},[35,716,160],{"class":85},[35,718,678],{"class":45},[35,720,628],{"class":85},[35,722,723,725,727,730,733,737,739,742,745,748,751,754,756,758,761,763,765,767,770,772,774,776,779,781,783,785,787,789,791,794],{"class":37,"line":120},[35,724,248],{"class":199},[35,726,217],{"class":85},[35,728,729],{"class":81},"f",[35,731,732],{"class":45},"\"totals: Dr ",[35,734,736],{"class":735},"sSjpA","{",[35,738,519],{"class":85},[35,740,741],{"class":45},"'Dr'",[35,743,744],{"class":85},"].sum()",[35,746,747],{"class":81},":,.2f",[35,749,750],{"class":735},"}",[35,752,753],{"class":45},"  Cr ",[35,755,736],{"class":735},[35,757,519],{"class":85},[35,759,760],{"class":45},"'Cr'",[35,762,744],{"class":85},[35,764,747],{"class":81},[35,766,750],{"class":735},[35,768,769],{"class":45},"  difference ",[35,771,736],{"class":735},[35,773,519],{"class":85},[35,775,741],{"class":45},[35,777,778],{"class":85},"].sum() ",[35,780,185],{"class":81},[35,782,529],{"class":85},[35,784,760],{"class":45},[35,786,744],{"class":85},[35,788,747],{"class":81},[35,790,750],{"class":735},[35,792,793],{"class":45},"\"",[35,795,117],{"class":85},[10,797,798,801],{},[32,799,800],{},"clip(lower=0)"," keeps positive closing balances in the debit column and the negated negative ones in the credit column. The totals agree — a balanced trial balance. A difference here, after Step 1 passed, would mean the period filter or the opening balance calculation dropped lines, which is why the check is printed every run.",[803,804,812,813,812,817,812,821,812,828,812,837,812,841,812,848,812,852,812,856,812,860,812,864,812,866,812,870,812,872,812,875,812,878,812,882,812,884,812,888,812,890,812,893,812,896,812,900,812,902,812,905,812,907,812,910,812,913,812,916,812,918,812,921,812,923,812,926,812,929,812,933,812,935,812,938,812,940,812,943,812,946,812,950,812,955,812,959,812,963,812,967,812,970,812,973,812,977,812,980,812,984,812,987,812,990,812,992,812,994,812,998,812,1001,812,1004,812,1006,812,1008,812,1011,812,1014,812,1017,812,1019,812,1021,812,1023,812,1029,812,1033,812,1040,812,1045,812,1053],"svg",{"viewBox":805,"role":806,"ariaLabelledBy":807,"xmlns":810,"style":811},"4 0 751 220","img",[808,809],"tb-cols-t","tb-cols-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:751px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[814,815,816],"title",{"id":808},"Signed closing balances into debit and credit columns",[818,819,820],"desc",{"id":809},"Each account's closing balance is a signed number, debit positive and credit negative. Positive balances go into the debit column and negative ones, made positive, into the credit column. Both columns total 94,250.",[822,823],"rect",{"x":824,"y":669,"width":825,"height":826,"fill":827},"4","751","220","#ffffff",[822,829],{"x":830,"y":831,"width":832,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"21.0","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[822,838],{"x":839,"y":831,"width":840,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"53.0","153.3",[842,843,847],"text",{"x":844,"y":845,"style":846},"129.6","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[822,849],{"x":850,"y":831,"width":851,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"206.3","68.9",[842,853,855],{"x":854,"y":845,"style":846},"240.7","B",[822,857],{"x":830,"y":858,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"64.0","28.0",[842,861,595],{"x":862,"y":863,"style":846},"37.0","83.0",[822,865],{"x":839,"y":858,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,867,869],{"x":844,"y":863,"style":868},"font-size:10.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Account",[822,871],{"x":850,"y":858,"width":851,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,873,874],{"x":854,"y":863,"style":868},"Closing",[822,876],{"x":830,"y":877,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"92.0",[842,879,881],{"x":862,"y":880,"style":846},"111.0","2",[822,883],{"x":839,"y":877,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,885,887],{"x":844,"y":880,"style":886},"font-size:10.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","1000 Bank",[822,889],{"x":850,"y":877,"width":851,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,891,892],{"x":854,"y":880,"style":886},"35,300",[822,894],{"x":830,"y":895,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"120.0",[842,897,899],{"x":862,"y":898,"style":846},"139.0","3",[822,901],{"x":839,"y":895,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,903,904],{"x":844,"y":898,"style":886},"2000 Accounts payable",[822,906],{"x":850,"y":895,"width":851,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,908,909],{"x":854,"y":898,"style":886},"-4,700",[822,911],{"x":830,"y":912,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"148.0",[842,914,824],{"x":862,"y":915,"style":846},"167.0",[822,917],{"x":839,"y":912,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,919,920],{"x":844,"y":915,"style":886},"4000 Sales",[822,922],{"x":850,"y":912,"width":851,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,924,925],{"x":854,"y":915,"style":886},"-25,000",[822,927],{"x":830,"y":928,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"176.0",[842,930,932],{"x":862,"y":931,"style":846},"195.0","5",[822,934],{"x":839,"y":928,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,936,937],{"x":844,"y":931,"style":886},"5000 Cost of sales",[822,939],{"x":850,"y":928,"width":851,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,941,942],{"x":854,"y":931,"style":886},"10,650",[822,944],{"x":945,"y":831,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},"458.3",[842,947,869],{"x":948,"y":949,"style":868},"535.0","59.0",[822,951],{"x":952,"y":831,"width":953,"height":859,"rx":669,"fill":834,"stroke":835,"style":954},"611.6","63.6","stroke-width:1.5px",[842,956,958],{"x":957,"y":949,"style":868},"643.4","Dr",[822,960],{"x":961,"y":831,"width":962,"height":859,"rx":669,"fill":834,"stroke":835,"style":954},"675.2","63.8",[842,964,966],{"x":965,"y":949,"style":868},"707.1","Cr",[822,968],{"x":945,"y":969,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},"68.0",[842,971,887],{"x":948,"y":972,"style":886},"87.0",[822,974],{"x":952,"y":969,"width":953,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},"#d9f4f1","var(--teal,#0f9488)",[842,978,892],{"x":957,"y":972,"style":979},"font-size:10.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[822,981],{"x":961,"y":969,"width":962,"height":859,"rx":669,"fill":982,"stroke":983,"style":954},"#fdefd8","var(--gold,#b4740a)",[822,985],{"x":945,"y":986,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},"96.0",[842,988,904],{"x":948,"y":989,"style":886},"115.0",[822,991],{"x":952,"y":986,"width":953,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},[822,993],{"x":961,"y":986,"width":962,"height":859,"rx":669,"fill":982,"stroke":983,"style":954},[842,995,997],{"x":965,"y":989,"style":996},"font-size:10.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","4,700",[822,999],{"x":945,"y":1000,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},"124.0",[842,1002,920],{"x":948,"y":1003,"style":886},"143.0",[822,1005],{"x":952,"y":1000,"width":953,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},[822,1007],{"x":961,"y":1000,"width":962,"height":859,"rx":669,"fill":982,"stroke":983,"style":954},[842,1009,1010],{"x":965,"y":1003,"style":996},"25,000",[822,1012],{"x":945,"y":1013,"width":840,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},"152.0",[842,1015,937],{"x":948,"y":1016,"style":886},"171.0",[822,1018],{"x":952,"y":1013,"width":953,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},[842,1020,942],{"x":957,"y":1016,"style":979},[822,1022],{"x":961,"y":1013,"width":962,"height":859,"rx":669,"fill":982,"stroke":983,"style":954},[842,1024,1028],{"x":1025,"y":1026,"style":1027},"148.1","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","closing (signed)",[842,1030,1032],{"x":1031,"y":1026,"style":1027},"598.7","trial balance",[37,1034],{"x1":1035,"y1":1036,"x2":1037,"y2":1036,"stroke":1038,"style":1039},"285.2","110.0","444.3","var(--brand,#5b5cf0)","stroke-width:2px",[1041,1042],"polygon",{"points":1043,"fill":1044},"448.3,110.0 439.3,115.0 439.3,105.0","#5b5cf0",[822,1046],{"x":1047,"y":1048,"width":1049,"height":1050,"rx":1051,"fill":827,"stroke":835,"style":1052},"309.5","77.0","114.5","22.0","11","stroke-width:1.2px",[842,1054,800],{"x":1055,"y":877,"style":1056},"366.8","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace",[20,1058,1060],{"id":1059},"step-4-flag-what-an-accountant-would-question","Step 4 — Flag what an accountant would question",[10,1062,1063,1064,1068],{},"A balanced trial balance can still be wrong. Three checks catch the most common problems: balances on the ",[1065,1066,1067],"em",{},"abnormal"," side for their account type, a balance in the suspense account, and large swings against last month:",[25,1070,1072],{"className":72,"code":1071,"language":74,"meta":30,"style":30},"normal_side = {\"Asset\": \"Dr\", \"Expense\": \"Dr\", \"Liability\": \"Cr\", \"Equity\": \"Cr\", \"Revenue\": \"Cr\"}\n\ndef flags(row):\n    out = []\n    side = \"Dr\" if row[\"Closing\"] > 0 else \"Cr\" if row[\"Closing\"] \u003C 0 else None\n    if side and side != normal_side[row[\"Type\"]]:\n        out.append(f\"abnormal {side} balance\")\n    if row[\"Name\"] == \"Suspense\" and row[\"Closing\"] != 0:\n        out.append(\"suspense not cleared\")\n    return \"; \".join(out)\n\ntb[\"Check\"] = tb.apply(flags, axis=1)\n\nprior_end = start - pd.Timedelta(days=1)\nprior = gl[gl[\"Date\"] \u003C= prior_end].groupby(\"Account\")[\"Net\"].sum()\ntb[\"Prior\"] = prior.reindex(tb.index).fillna(0.0)\ntb[\"Change\"] = tb[\"Closing\"] - tb[\"Prior\"]\nprint(tb.loc[tb[\"Check\"] != \"\", [\"Name\", \"Closing\", \"Check\"]].to_string())\nprint(tb[[\"Name\", \"Prior\", \"Closing\", \"Change\"]].loc[[1000, 1100, 4000]].to_string())\n",[32,1073,1074,1130,1134,1146,1156,1203,1227,1249,1281,1290,1301,1305,1327,1331,1356,1383,1402,1428,1460],{"__ignoreMap":30},[35,1075,1076,1079,1081,1084,1087,1089,1091,1093,1096,1098,1100,1102,1105,1107,1109,1111,1114,1116,1118,1120,1123,1125,1127],{"class":37,"line":38},[35,1077,1078],{"class":85},"normal_side ",[35,1080,108],{"class":81},[35,1082,1083],{"class":85}," {",[35,1085,1086],{"class":45},"\"Asset\"",[35,1088,491],{"class":85},[35,1090,650],{"class":45},[35,1092,160],{"class":85},[35,1094,1095],{"class":45},"\"Expense\"",[35,1097,491],{"class":85},[35,1099,650],{"class":45},[35,1101,160],{"class":85},[35,1103,1104],{"class":45},"\"Liability\"",[35,1106,491],{"class":85},[35,1108,678],{"class":45},[35,1110,160],{"class":85},[35,1112,1113],{"class":45},"\"Equity\"",[35,1115,491],{"class":85},[35,1117,678],{"class":45},[35,1119,160],{"class":85},[35,1121,1122],{"class":45},"\"Revenue\"",[35,1124,491],{"class":85},[35,1126,678],{"class":45},[35,1128,1129],{"class":85},"}\n",[35,1131,1132],{"class":37,"line":95},[35,1133,99],{"emptyLinePlaceholder":98},[35,1135,1136,1139,1143],{"class":37,"line":102},[35,1137,1138],{"class":81},"def",[35,1140,1142],{"class":1141},"s_Opv"," flags",[35,1144,1145],{"class":85},"(row):\n",[35,1147,1148,1151,1153],{"class":37,"line":120},[35,1149,1150],{"class":85},"    out ",[35,1152,108],{"class":81},[35,1154,1155],{"class":85}," []\n",[35,1157,1158,1161,1163,1166,1169,1172,1174,1176,1178,1180,1183,1186,1188,1190,1192,1194,1196,1198,1200],{"class":37,"line":135},[35,1159,1160],{"class":85},"    side ",[35,1162,108],{"class":81},[35,1164,1165],{"class":45}," \"Dr\"",[35,1167,1168],{"class":81}," if",[35,1170,1171],{"class":85}," row[",[35,1173,522],{"class":45},[35,1175,182],{"class":85},[35,1177,196],{"class":81},[35,1179,583],{"class":199},[35,1181,1182],{"class":81}," else",[35,1184,1185],{"class":45}," \"Cr\"",[35,1187,1168],{"class":81},[35,1189,1171],{"class":85},[35,1191,522],{"class":45},[35,1193,182],{"class":85},[35,1195,386],{"class":81},[35,1197,583],{"class":199},[35,1199,1182],{"class":81},[35,1201,1202],{"class":199}," None\n",[35,1204,1205,1208,1211,1214,1216,1218,1221,1224],{"class":37,"line":140},[35,1206,1207],{"class":81},"    if",[35,1209,1210],{"class":85}," side ",[35,1212,1213],{"class":81},"and",[35,1215,1210],{"class":85},[35,1217,580],{"class":81},[35,1219,1220],{"class":85}," normal_side[row[",[35,1222,1223],{"class":45},"\"Type\"",[35,1225,1226],{"class":85},"]]:\n",[35,1228,1229,1232,1234,1237,1239,1242,1244,1247],{"class":37,"line":169},[35,1230,1231],{"class":85},"        out.append(",[35,1233,729],{"class":81},[35,1235,1236],{"class":45},"\"abnormal ",[35,1238,736],{"class":735},[35,1240,1241],{"class":85},"side",[35,1243,750],{"class":735},[35,1245,1246],{"class":45}," balance\"",[35,1248,117],{"class":85},[35,1250,1251,1253,1255,1257,1259,1262,1265,1268,1270,1272,1274,1276,1278],{"class":37,"line":206},[35,1252,1207],{"class":81},[35,1254,1171],{"class":85},[35,1256,609],{"class":45},[35,1258,182],{"class":85},[35,1260,1261],{"class":81},"==",[35,1263,1264],{"class":45}," \"Suspense\"",[35,1266,1267],{"class":81}," and",[35,1269,1171],{"class":85},[35,1271,522],{"class":45},[35,1273,182],{"class":85},[35,1275,580],{"class":81},[35,1277,583],{"class":199},[35,1279,1280],{"class":85},":\n",[35,1282,1283,1285,1288],{"class":37,"line":245},[35,1284,1231],{"class":85},[35,1286,1287],{"class":45},"\"suspense not cleared\"",[35,1289,117],{"class":85},[35,1291,1292,1295,1298],{"class":37,"line":281},[35,1293,1294],{"class":81},"    return",[35,1296,1297],{"class":45}," \"; \"",[35,1299,1300],{"class":85},".join(out)\n",[35,1302,1303],{"class":37,"line":516},[35,1304,99],{"emptyLinePlaceholder":98},[35,1306,1307,1309,1312,1314,1316,1319,1321,1323,1325],{"class":37,"line":553},[35,1308,519],{"class":85},[35,1310,1311],{"class":45},"\"Check\"",[35,1313,182],{"class":85},[35,1315,108],{"class":81},[35,1317,1318],{"class":85}," tb.apply(flags, ",[35,1320,590],{"class":589},[35,1322,108],{"class":81},[35,1324,595],{"class":199},[35,1326,117],{"class":85},[35,1328,1329],{"class":37,"line":601},[35,1330,99],{"emptyLinePlaceholder":98},[35,1332,1334,1337,1339,1342,1344,1347,1350,1352,1354],{"class":37,"line":1333},14,[35,1335,1336],{"class":85},"prior_end ",[35,1338,108],{"class":81},[35,1340,1341],{"class":85}," start ",[35,1343,185],{"class":81},[35,1345,1346],{"class":85}," pd.Timedelta(",[35,1348,1349],{"class":589},"days",[35,1351,108],{"class":81},[35,1353,595],{"class":199},[35,1355,117],{"class":85},[35,1357,1359,1362,1364,1366,1368,1370,1372,1375,1377,1379,1381],{"class":37,"line":1358},15,[35,1360,1361],{"class":85},"prior ",[35,1363,108],{"class":81},[35,1365,378],{"class":85},[35,1367,381],{"class":45},[35,1369,182],{"class":85},[35,1371,432],{"class":81},[35,1373,1374],{"class":85}," prior_end].groupby(",[35,1376,226],{"class":45},[35,1378,394],{"class":85},[35,1380,345],{"class":45},[35,1382,399],{"class":85},[35,1384,1386,1388,1391,1393,1395,1398,1400],{"class":37,"line":1385},16,[35,1387,519],{"class":85},[35,1389,1390],{"class":45},"\"Prior\"",[35,1392,182],{"class":85},[35,1394,108],{"class":81},[35,1396,1397],{"class":85}," prior.reindex(tb.index).fillna(",[35,1399,494],{"class":199},[35,1401,117],{"class":85},[35,1403,1405,1407,1410,1412,1414,1416,1418,1420,1422,1424,1426],{"class":37,"line":1404},17,[35,1406,519],{"class":85},[35,1408,1409],{"class":45},"\"Change\"",[35,1411,182],{"class":85},[35,1413,108],{"class":81},[35,1415,529],{"class":85},[35,1417,522],{"class":45},[35,1419,182],{"class":85},[35,1421,185],{"class":81},[35,1423,529],{"class":85},[35,1425,1390],{"class":45},[35,1427,203],{"class":85},[35,1429,1431,1433,1436,1438,1440,1442,1445,1448,1450,1452,1454,1456,1458],{"class":37,"line":1430},18,[35,1432,248],{"class":199},[35,1434,1435],{"class":85},"(tb.loc[tb[",[35,1437,1311],{"class":45},[35,1439,182],{"class":85},[35,1441,580],{"class":81},[35,1443,1444],{"class":45}," \"\"",[35,1446,1447],{"class":85},", [",[35,1449,609],{"class":45},[35,1451,160],{"class":85},[35,1453,522],{"class":45},[35,1455,160],{"class":85},[35,1457,1311],{"class":45},[35,1459,628],{"class":85},[35,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481,1484,1487,1489,1492,1494,1497],{"class":37,"line":1462},19,[35,1464,248],{"class":199},[35,1466,606],{"class":85},[35,1468,609],{"class":45},[35,1470,160],{"class":85},[35,1472,1390],{"class":45},[35,1474,160],{"class":85},[35,1476,522],{"class":45},[35,1478,160],{"class":85},[35,1480,1409],{"class":45},[35,1482,1483],{"class":85},"]].loc[[",[35,1485,1486],{"class":199},"1000",[35,1488,160],{"class":85},[35,1490,1491],{"class":199},"1100",[35,1493,160],{"class":85},[35,1495,1496],{"class":199},"4000",[35,1498,628],{"class":85},[10,1500,1501,1502,1505],{},"One flag appears: the suspense account holds 350 from the ",[32,1503,1504],{},"ADJ-17"," journal — someone parked a cost they could not classify, and it needs clearing before the books close. Every other balance sits on its normal side. The comparison with the prior month-end shows movements at a glance; Accounts receivable rose from 11,600 to 15,800 as September's invoice exceeded the cash collected. Asset and expense accounts normally carry debit balances and the others credit balances; an asset in credit — a bank account overdrawn, receivables with unapplied cash — is not necessarily wrong, but it is always worth a look.",[803,1507,812,1513,812,1516,812,1519,812,1523,812,1531,812,1542,812,1548,812,1553,812,1557,812,1562,812,1565,812,1568,812,1575,812,1580,812,1583,812,1586,812,1590,812,1593,812,1596,812,1603,812,1609,812,1613,812,1617,812,1620,812,1623,812,1630,812,1635,812,1638],{"viewBox":1508,"role":806,"ariaLabelledBy":1509,"xmlns":810,"style":1512},"4 0 752 142",[1510,1511],"tb-checks-t","tb-checks-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[814,1514,1515],{"id":1510},"The checks before a trial balance is trusted",[818,1517,1518],{"id":1511},"First every journal must balance and every account must exist. Then the debit and credit columns must total the same. Then balances on the abnormal side and uncleared suspense are flagged, and movements against the prior month are reviewed.",[822,1520],{"x":824,"y":669,"width":1521,"height":1522,"fill":827},"752","142",[822,1524],{"x":1525,"y":1526,"width":1527,"height":1528,"rx":1529,"fill":1530,"stroke":1038,"style":1039},"20.0","16.0","153.0","110.5","12","#f0f4ff",[1532,1533,1535],"g",{"transform":1534},"translate(84.5,29.0) scale(1.000)",[1536,1537],"path",{"d":1538,"fill":1539,"stroke":1540,"style":1541},"M5 12.5l4.5 4.5L19 7","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[842,1543,1547],{"x":1544,"y":1545,"style":1546},"96.5","75.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Journals balance",[842,1549,1552],{"x":1544,"y":1550,"style":1551},"95.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","debits = credits per",[842,1554,1556],{"x":1544,"y":1555,"style":1551},"112.5","journal",[37,1558],{"x1":1559,"y1":1560,"x2":1561,"y2":1560,"stroke":1038,"style":1039},"178.0","71.2","200.0",[1041,1563],{"points":1564,"fill":1044},"204.0,71.2 195.0,76.2 195.0,66.2",[822,1566],{"x":1567,"y":1526,"width":1527,"height":1528,"rx":1529,"fill":834,"stroke":835,"style":1039},"209.0",[1532,1569,1571],{"transform":1570},"translate(273.5,29.0) scale(1.000)",[1536,1572],{"d":1573,"fill":1539,"stroke":1574,"style":1541},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","var(--text,#172033)",[842,1576,1579],{"x":1577,"y":1545,"style":1578},"285.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Accounts known",[842,1581,1582],{"x":1577,"y":1550,"style":1551},"all in the chart of",[842,1584,1585],{"x":1577,"y":1555,"style":1551},"accounts",[37,1587],{"x1":1588,"y1":1560,"x2":1589,"y2":1560,"stroke":1038,"style":1039},"367.0","389.0",[1041,1591],{"points":1592,"fill":1044},"393.0,71.2 384.0,76.2 384.0,66.2",[822,1594],{"x":1595,"y":1526,"width":1527,"height":1528,"rx":1529,"fill":975,"stroke":976,"style":1039},"398.0",[1532,1597,1599],{"transform":1598},"translate(462.5,37.8) scale(1.000)",[1536,1600],{"d":1601,"fill":1539,"stroke":1602,"style":1541},"M5 9h14 M4 15h14 M10 4l-2 16 M16 4l-2 16","var(--teal-ink,#0b6157)",[842,1604,1608],{"x":1605,"y":1606,"style":1607},"474.5","84.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Columns agree",[842,1610,1612],{"x":1605,"y":1611,"style":1551},"103.8","total Dr = total Cr",[37,1614],{"x1":1615,"y1":1560,"x2":1616,"y2":1560,"stroke":1038,"style":1039},"556.0","578.0",[1041,1618],{"points":1619,"fill":1044},"582.0,71.2 573.0,76.2 573.0,66.2",[822,1621],{"x":1622,"y":1526,"width":1527,"height":1528,"rx":1529,"fill":982,"stroke":983,"style":1039},"587.0",[1532,1624,1626],{"transform":1625},"translate(651.5,29.0) scale(1.000)",[1536,1627],{"d":1628,"fill":1539,"stroke":1629,"style":1541},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","var(--gold-ink,#7a4e06)",[842,1631,1634],{"x":1632,"y":1545,"style":1633},"663.5","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Review flags",[842,1636,1637],{"x":1632,"y":1550,"style":1551},"abnormal side,",[842,1639,1640],{"x":1632,"y":1555,"style":1551},"suspense, swings",[20,1642,1644],{"id":1643},"step-5-write-the-trial-balance-to-excel","Step 5 — Write the trial balance to Excel",[10,1646,1647],{},"The workbook has one sheet with the trial balance, totals as formulas so they stay right if someone edits a line, and a check cell that turns red if the columns differ:",[25,1649,1651],{"className":72,"code":1650,"language":74,"meta":30,"style":30},"from openpyxl import Workbook\nfrom openpyxl.formatting.rule import FormulaRule\nfrom openpyxl.styles import Font, PatternFill\n\nwb = Workbook()\nws = wb.active\nws.title = \"Trial balance\"\nws[\"A1\"] = \"Trial balance at 30 September 2026\"\nws[\"A1\"].font = Font(bold=True, size=14)\nheaders = [\"Account\", \"Name\", \"Type\", \"Prior\", \"Debit\", \"Credit\", \"Change\", \"Check\"]\nws.append([])\nws.append(headers)\nfor c in ws[3]:\n    c.font = Font(bold=True)\nfor acct, r in tb.iterrows():\n    ws.append([acct, r[\"Name\"], r[\"Type\"], r[\"Prior\"], r[\"Dr\"] or None, r[\"Cr\"] or None, r[\"Change\"], r[\"Check\"] or None])\nlast = ws.max_row\nws.append([\"\", \"Total\", \"\", \"\", f\"=SUM(E4:E{last})\", f\"=SUM(F4:F{last})\"])\nws.append([\"\", \"Difference\", \"\", \"\", f\"=E{last + 1}-F{last + 1}\"])\nfor row in ws.iter_rows(min_row=4, max_row=last + 2, min_col=4, max_col=7):\n    for c in row:\n        c.number_format = \"#,##0.00;[Red]-#,##0.00\"\nfor col, w in zip(\"ABCDEFGH\", (9, 22, 10, 12, 12, 12, 12, 24)):\n    ws.column_dimensions[col].width = w\nfor c in ws[last + 1]:\n    c.font = Font(bold=True)\nred = PatternFill(\"solid\", fgColor=\"FFC7CE\")\nws.conditional_formatting.add(f\"E{last + 2}\", FormulaRule(formula=[f\"ABS(E{last + 2})>0.005\"], fill=red))\nws.conditional_formatting.add(f\"H4:H{last}\", FormulaRule(formula=[\"LEN(H4)>0\"], fill=PatternFill(\"solid\", fgColor=\"FFEB9C\")))\nws.freeze_panes = \"A4\"\nwb.save(\"trial_balance_2026-09.xlsx\")\nprint(\"rows:\", last - 3, \"| totals at row\", last + 1)\n",[32,1652,1653,1666,1678,1690,1694,1704,1714,1724,1739,1773,1815,1820,1825,1844,1861,1873,1929,1939,1994,2048,2104,2117,2128,2186,2197,2215,2232,2258,2321,2373,2384,2395],{"__ignoreMap":30},[35,1654,1655,1658,1661,1663],{"class":37,"line":38},[35,1656,1657],{"class":81},"from",[35,1659,1660],{"class":85}," openpyxl ",[35,1662,82],{"class":81},[35,1664,1665],{"class":85}," Workbook\n",[35,1667,1668,1670,1673,1675],{"class":37,"line":95},[35,1669,1657],{"class":81},[35,1671,1672],{"class":85}," openpyxl.formatting.rule ",[35,1674,82],{"class":81},[35,1676,1677],{"class":85}," FormulaRule\n",[35,1679,1680,1682,1685,1687],{"class":37,"line":102},[35,1681,1657],{"class":81},[35,1683,1684],{"class":85}," openpyxl.styles ",[35,1686,82],{"class":81},[35,1688,1689],{"class":85}," Font, PatternFill\n",[35,1691,1692],{"class":37,"line":120},[35,1693,99],{"emptyLinePlaceholder":98},[35,1695,1696,1699,1701],{"class":37,"line":135},[35,1697,1698],{"class":85},"wb ",[35,1700,108],{"class":81},[35,1702,1703],{"class":85}," Workbook()\n",[35,1705,1706,1709,1711],{"class":37,"line":140},[35,1707,1708],{"class":85},"ws ",[35,1710,108],{"class":81},[35,1712,1713],{"class":85}," wb.active\n",[35,1715,1716,1719,1721],{"class":37,"line":169},[35,1717,1718],{"class":85},"ws.title ",[35,1720,108],{"class":81},[35,1722,1723],{"class":45}," \"Trial balance\"\n",[35,1725,1726,1729,1732,1734,1736],{"class":37,"line":206},[35,1727,1728],{"class":85},"ws[",[35,1730,1731],{"class":45},"\"A1\"",[35,1733,182],{"class":85},[35,1735,108],{"class":81},[35,1737,1738],{"class":45}," \"Trial balance at 30 September 2026\"\n",[35,1740,1741,1743,1745,1748,1750,1753,1756,1758,1761,1763,1766,1768,1771],{"class":37,"line":245},[35,1742,1728],{"class":85},[35,1744,1731],{"class":45},[35,1746,1747],{"class":85},"].font ",[35,1749,108],{"class":81},[35,1751,1752],{"class":85}," Font(",[35,1754,1755],{"class":589},"bold",[35,1757,108],{"class":81},[35,1759,1760],{"class":199},"True",[35,1762,160],{"class":85},[35,1764,1765],{"class":589},"size",[35,1767,108],{"class":81},[35,1769,1770],{"class":199},"14",[35,1772,117],{"class":85},[35,1774,1775,1778,1780,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813],{"class":37,"line":281},[35,1776,1777],{"class":85},"headers ",[35,1779,108],{"class":81},[35,1781,1782],{"class":85}," [",[35,1784,226],{"class":45},[35,1786,160],{"class":85},[35,1788,609],{"class":45},[35,1790,160],{"class":85},[35,1792,1223],{"class":45},[35,1794,160],{"class":85},[35,1796,1390],{"class":45},[35,1798,160],{"class":85},[35,1800,157],{"class":45},[35,1802,160],{"class":85},[35,1804,163],{"class":45},[35,1806,160],{"class":85},[35,1808,1409],{"class":45},[35,1810,160],{"class":85},[35,1812,1311],{"class":45},[35,1814,203],{"class":85},[35,1816,1817],{"class":37,"line":516},[35,1818,1819],{"class":85},"ws.append([])\n",[35,1821,1822],{"class":37,"line":553},[35,1823,1824],{"class":85},"ws.append(headers)\n",[35,1826,1827,1830,1833,1836,1839,1841],{"class":37,"line":601},[35,1828,1829],{"class":81},"for",[35,1831,1832],{"class":85}," c ",[35,1834,1835],{"class":81},"in",[35,1837,1838],{"class":85}," ws[",[35,1840,899],{"class":199},[35,1842,1843],{"class":85},"]:\n",[35,1845,1846,1849,1851,1853,1855,1857,1859],{"class":37,"line":1333},[35,1847,1848],{"class":85},"    c.font ",[35,1850,108],{"class":81},[35,1852,1752],{"class":85},[35,1854,1755],{"class":589},[35,1856,108],{"class":81},[35,1858,1760],{"class":199},[35,1860,117],{"class":85},[35,1862,1863,1865,1868,1870],{"class":37,"line":1358},[35,1864,1829],{"class":81},[35,1866,1867],{"class":85}," acct, r ",[35,1869,1835],{"class":81},[35,1871,1872],{"class":85}," tb.iterrows():\n",[35,1874,1875,1878,1880,1883,1885,1887,1889,1891,1893,1895,1898,1901,1904,1906,1908,1910,1912,1914,1916,1918,1920,1922,1924,1926],{"class":37,"line":1385},[35,1876,1877],{"class":85},"    ws.append([acct, r[",[35,1879,609],{"class":45},[35,1881,1882],{"class":85},"], r[",[35,1884,1223],{"class":45},[35,1886,1882],{"class":85},[35,1888,1390],{"class":45},[35,1890,1882],{"class":85},[35,1892,650],{"class":45},[35,1894,182],{"class":85},[35,1896,1897],{"class":81},"or",[35,1899,1900],{"class":199}," None",[35,1902,1903],{"class":85},", r[",[35,1905,678],{"class":45},[35,1907,182],{"class":85},[35,1909,1897],{"class":81},[35,1911,1900],{"class":199},[35,1913,1903],{"class":85},[35,1915,1409],{"class":45},[35,1917,1882],{"class":85},[35,1919,1311],{"class":45},[35,1921,182],{"class":85},[35,1923,1897],{"class":81},[35,1925,1900],{"class":199},[35,1927,1928],{"class":85},"])\n",[35,1930,1931,1934,1936],{"class":37,"line":1404},[35,1932,1933],{"class":85},"last ",[35,1935,108],{"class":81},[35,1937,1938],{"class":85}," ws.max_row\n",[35,1940,1941,1944,1947,1949,1952,1954,1956,1958,1960,1962,1964,1967,1969,1972,1974,1977,1979,1981,1984,1986,1988,1990,1992],{"class":37,"line":1430},[35,1942,1943],{"class":85},"ws.append([",[35,1945,1946],{"class":45},"\"\"",[35,1948,160],{"class":85},[35,1950,1951],{"class":45},"\"Total\"",[35,1953,160],{"class":85},[35,1955,1946],{"class":45},[35,1957,160],{"class":85},[35,1959,1946],{"class":45},[35,1961,160],{"class":85},[35,1963,729],{"class":81},[35,1965,1966],{"class":45},"\"=SUM(E4:E",[35,1968,736],{"class":735},[35,1970,1971],{"class":85},"last",[35,1973,750],{"class":735},[35,1975,1976],{"class":45},")\"",[35,1978,160],{"class":85},[35,1980,729],{"class":81},[35,1982,1983],{"class":45},"\"=SUM(F4:F",[35,1985,736],{"class":735},[35,1987,1971],{"class":85},[35,1989,750],{"class":735},[35,1991,1976],{"class":45},[35,1993,1928],{"class":85},[35,1995,1996,1998,2000,2002,2005,2007,2009,2011,2013,2015,2017,2020,2022,2024,2026,2029,2031,2034,2036,2038,2040,2042,2044,2046],{"class":37,"line":1462},[35,1997,1943],{"class":85},[35,1999,1946],{"class":45},[35,2001,160],{"class":85},[35,2003,2004],{"class":45},"\"Difference\"",[35,2006,160],{"class":85},[35,2008,1946],{"class":45},[35,2010,160],{"class":85},[35,2012,1946],{"class":45},[35,2014,160],{"class":85},[35,2016,729],{"class":81},[35,2018,2019],{"class":45},"\"=E",[35,2021,736],{"class":735},[35,2023,1933],{"class":85},[35,2025,536],{"class":81},[35,2027,2028],{"class":199}," 1",[35,2030,750],{"class":735},[35,2032,2033],{"class":45},"-F",[35,2035,736],{"class":735},[35,2037,1933],{"class":85},[35,2039,536],{"class":81},[35,2041,2028],{"class":199},[35,2043,750],{"class":735},[35,2045,793],{"class":45},[35,2047,1928],{"class":85},[35,2049,2051,2053,2056,2058,2061,2064,2066,2068,2070,2073,2075,2077,2079,2082,2084,2087,2089,2091,2093,2096,2098,2101],{"class":37,"line":2050},20,[35,2052,1829],{"class":81},[35,2054,2055],{"class":85}," row ",[35,2057,1835],{"class":81},[35,2059,2060],{"class":85}," ws.iter_rows(",[35,2062,2063],{"class":589},"min_row",[35,2065,108],{"class":81},[35,2067,824],{"class":199},[35,2069,160],{"class":85},[35,2071,2072],{"class":589},"max_row",[35,2074,108],{"class":81},[35,2076,1933],{"class":85},[35,2078,536],{"class":81},[35,2080,2081],{"class":199}," 2",[35,2083,160],{"class":85},[35,2085,2086],{"class":589},"min_col",[35,2088,108],{"class":81},[35,2090,824],{"class":199},[35,2092,160],{"class":85},[35,2094,2095],{"class":589},"max_col",[35,2097,108],{"class":81},[35,2099,2100],{"class":199},"7",[35,2102,2103],{"class":85},"):\n",[35,2105,2107,2110,2112,2114],{"class":37,"line":2106},21,[35,2108,2109],{"class":81},"    for",[35,2111,1832],{"class":85},[35,2113,1835],{"class":81},[35,2115,2116],{"class":85}," row:\n",[35,2118,2120,2123,2125],{"class":37,"line":2119},22,[35,2121,2122],{"class":85},"        c.number_format ",[35,2124,108],{"class":81},[35,2126,2127],{"class":45}," \"#,##0.00;[Red]-#,##0.00\"\n",[35,2129,2131,2133,2136,2138,2141,2143,2146,2149,2152,2154,2157,2159,2162,2164,2166,2168,2170,2172,2174,2176,2178,2180,2183],{"class":37,"line":2130},23,[35,2132,1829],{"class":81},[35,2134,2135],{"class":85}," col, w ",[35,2137,1835],{"class":81},[35,2139,2140],{"class":199}," zip",[35,2142,217],{"class":85},[35,2144,2145],{"class":45},"\"ABCDEFGH\"",[35,2147,2148],{"class":85},", (",[35,2150,2151],{"class":199},"9",[35,2153,160],{"class":85},[35,2155,2156],{"class":199},"22",[35,2158,160],{"class":85},[35,2160,2161],{"class":199},"10",[35,2163,160],{"class":85},[35,2165,1529],{"class":199},[35,2167,160],{"class":85},[35,2169,1529],{"class":199},[35,2171,160],{"class":85},[35,2173,1529],{"class":199},[35,2175,160],{"class":85},[35,2177,1529],{"class":199},[35,2179,160],{"class":85},[35,2181,2182],{"class":199},"24",[35,2184,2185],{"class":85},")):\n",[35,2187,2189,2192,2194],{"class":37,"line":2188},24,[35,2190,2191],{"class":85},"    ws.column_dimensions[col].width ",[35,2193,108],{"class":81},[35,2195,2196],{"class":85}," w\n",[35,2198,2200,2202,2204,2206,2209,2211,2213],{"class":37,"line":2199},25,[35,2201,1829],{"class":81},[35,2203,1832],{"class":85},[35,2205,1835],{"class":81},[35,2207,2208],{"class":85}," ws[last ",[35,2210,536],{"class":81},[35,2212,2028],{"class":199},[35,2214,1843],{"class":85},[35,2216,2218,2220,2222,2224,2226,2228,2230],{"class":37,"line":2217},26,[35,2219,1848],{"class":85},[35,2221,108],{"class":81},[35,2223,1752],{"class":85},[35,2225,1755],{"class":589},[35,2227,108],{"class":81},[35,2229,1760],{"class":199},[35,2231,117],{"class":85},[35,2233,2235,2238,2240,2243,2246,2248,2251,2253,2256],{"class":37,"line":2234},27,[35,2236,2237],{"class":85},"red ",[35,2239,108],{"class":81},[35,2241,2242],{"class":85}," PatternFill(",[35,2244,2245],{"class":45},"\"solid\"",[35,2247,160],{"class":85},[35,2249,2250],{"class":589},"fgColor",[35,2252,108],{"class":81},[35,2254,2255],{"class":45},"\"FFC7CE\"",[35,2257,117],{"class":85},[35,2259,2261,2264,2266,2269,2271,2273,2275,2277,2279,2281,2284,2287,2289,2292,2294,2297,2299,2301,2303,2305,2307,2310,2313,2316,2318],{"class":37,"line":2260},28,[35,2262,2263],{"class":85},"ws.conditional_formatting.add(",[35,2265,729],{"class":81},[35,2267,2268],{"class":45},"\"E",[35,2270,736],{"class":735},[35,2272,1933],{"class":85},[35,2274,536],{"class":81},[35,2276,2081],{"class":199},[35,2278,750],{"class":735},[35,2280,793],{"class":45},[35,2282,2283],{"class":85},", FormulaRule(",[35,2285,2286],{"class":589},"formula",[35,2288,108],{"class":81},[35,2290,2291],{"class":85},"[",[35,2293,729],{"class":81},[35,2295,2296],{"class":45},"\"ABS(E",[35,2298,736],{"class":735},[35,2300,1933],{"class":85},[35,2302,536],{"class":81},[35,2304,2081],{"class":199},[35,2306,750],{"class":735},[35,2308,2309],{"class":45},")>0.005\"",[35,2311,2312],{"class":85},"], ",[35,2314,2315],{"class":589},"fill",[35,2317,108],{"class":81},[35,2319,2320],{"class":85},"red))\n",[35,2322,2324,2326,2328,2331,2333,2335,2337,2339,2341,2343,2345,2347,2350,2352,2354,2356,2359,2361,2363,2365,2367,2370],{"class":37,"line":2323},29,[35,2325,2263],{"class":85},[35,2327,729],{"class":81},[35,2329,2330],{"class":45},"\"H4:H",[35,2332,736],{"class":735},[35,2334,1971],{"class":85},[35,2336,750],{"class":735},[35,2338,793],{"class":45},[35,2340,2283],{"class":85},[35,2342,2286],{"class":589},[35,2344,108],{"class":81},[35,2346,2291],{"class":85},[35,2348,2349],{"class":45},"\"LEN(H4)>0\"",[35,2351,2312],{"class":85},[35,2353,2315],{"class":589},[35,2355,108],{"class":81},[35,2357,2358],{"class":85},"PatternFill(",[35,2360,2245],{"class":45},[35,2362,160],{"class":85},[35,2364,2250],{"class":589},[35,2366,108],{"class":81},[35,2368,2369],{"class":45},"\"FFEB9C\"",[35,2371,2372],{"class":85},")))\n",[35,2374,2376,2379,2381],{"class":37,"line":2375},30,[35,2377,2378],{"class":85},"ws.freeze_panes ",[35,2380,108],{"class":81},[35,2382,2383],{"class":45}," \"A4\"\n",[35,2385,2387,2390,2393],{"class":37,"line":2386},31,[35,2388,2389],{"class":85},"wb.save(",[35,2391,2392],{"class":45},"\"trial_balance_2026-09.xlsx\"",[35,2394,117],{"class":85},[35,2396,2398,2400,2402,2405,2408,2410,2413,2415,2418,2420,2422,2424],{"class":37,"line":2397},32,[35,2399,248],{"class":199},[35,2401,217],{"class":85},[35,2403,2404],{"class":45},"\"rows:\"",[35,2406,2407],{"class":85},", last ",[35,2409,185],{"class":81},[35,2411,2412],{"class":199}," 3",[35,2414,160],{"class":85},[35,2416,2417],{"class":45},"\"| totals at row\"",[35,2419,2407],{"class":85},[35,2421,536],{"class":81},[35,2423,2028],{"class":199},[35,2425,117],{"class":85},[10,2427,2428,2429,2432,2433,2436,2437,18],{},"Blank cells instead of zeros (",[32,2430,2431],{},"r[\"Dr\"] or None",") keep the columns readable, as on a printed trial balance. The totals are ",[32,2434,2435],{},"SUM"," formulas and the difference cell has a conditional format that turns it red if it is ever non-zero; the Check column is shaded yellow wherever a flag appears, so the suspense line stands out. The ledger amounts themselves are values — the trial balance reports the ledger; it is not a place to edit it. The same workbook is the natural source for the statements built on top of it, such as ",[14,2438,2440],{"href":2439},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-profit-and-loss-statement-from-a-general-ledger\u002F","Build a Profit and Loss Statement from a General Ledger",[803,2442,812,2448,812,2451,812,2454,812,2459,812,2462,812,2466,812,2470,812,2474,812,2477,812,2481,812,2485,812,2489,812,2493,812,2497,812,2501,812,2503,812,2506,812,2508,812,2511,812,2513,812,2516,812,2518,812,2521,812,2523,812,2526,812,2528,812,2531,812,2533,812,2535,812,2537,812,2539,812,2541,812,2544,812,2546,812,2549,812,2551,812,2553,812,2555,812,2557,812,2559,812,2561,812,2563,812,2566,812,2568,812,2571,812,2573,812,2575,812,2577,812,2579,812,2581,812,2584,812,2586,812,2589,812,2591,812,2593,812,2596,812,2598,812,2601,812,2603,812,2605,812,2607,812,2609,812,2611,812,2614,812,2616,812,2618,812,2621,812,2623,812,2626,812,2630,812,2632,812,2634,812,2637,812,2639,812,2642,812,2644,812,2646,812,2648,812,2651,812,2654,812,2656,812,2658,812,2661,812,2663,812,2666,812,2668],{"viewBox":2443,"role":806,"ariaLabelledBy":2444,"xmlns":810,"style":2447},"93 0 574 252",[2445,2446],"tb-sheet-t","tb-sheet-d","width:100%;max-width:574px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[814,2449,2450],{"id":2445},"The trial balance sheet",[818,2452,2453],{"id":2446},"Accounts with prior balance, debit and credit columns, change and a check column. The suspense account is flagged as not cleared. The debit and credit totals are both 94,250 and the difference cell shows zero.",[822,2455],{"x":2456,"y":669,"width":2457,"height":2458,"fill":827},"93","574","252",[822,2460],{"x":2461,"y":1526,"width":832,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"109.5",[822,2463],{"x":2464,"y":1526,"width":2465,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"141.5","69.7",[842,2467,847],{"x":2468,"y":2469,"style":846},"176.3","33.0",[822,2471],{"x":2472,"y":1526,"width":2473,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"211.2","135.1",[842,2475,855],{"x":2476,"y":2469,"style":846},"278.8",[822,2478],{"x":2479,"y":1526,"width":2480,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"346.3","82.2",[842,2482,2484],{"x":2483,"y":2469,"style":846},"387.4","C",[822,2486],{"x":2487,"y":1526,"width":2488,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"428.5","82.3",[842,2490,2492],{"x":2491,"y":2469,"style":846},"469.7","D",[822,2494],{"x":2495,"y":1526,"width":2496,"height":833,"rx":669,"fill":834,"stroke":835,"style":836},"510.9","139.7",[842,2498,2500],{"x":2499,"y":2469,"style":846},"580.7","E",[822,2502],{"x":2461,"y":831,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},[842,2504,595],{"x":2505,"y":949,"style":846},"125.5",[822,2507],{"x":2464,"y":831,"width":2465,"height":859,"rx":669,"fill":1530,"stroke":1038,"style":954},[842,2509,869],{"x":2468,"y":949,"style":2510},"font-size:10.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[822,2512],{"x":2472,"y":831,"width":2473,"height":859,"rx":669,"fill":1530,"stroke":1038,"style":954},[842,2514,2515],{"x":2476,"y":949,"style":2510},"Name",[822,2517],{"x":2479,"y":831,"width":2480,"height":859,"rx":669,"fill":1530,"stroke":1038,"style":954},[842,2519,2520],{"x":2483,"y":949,"style":2510},"Debit",[822,2522],{"x":2487,"y":831,"width":2488,"height":859,"rx":669,"fill":1530,"stroke":1038,"style":954},[842,2524,2525],{"x":2491,"y":949,"style":2510},"Credit",[822,2527],{"x":2495,"y":831,"width":2496,"height":859,"rx":669,"fill":1530,"stroke":1038,"style":954},[842,2529,2530],{"x":2499,"y":949,"style":2510},"Check",[822,2532],{"x":2461,"y":969,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},[842,2534,881],{"x":2505,"y":972,"style":846},[822,2536],{"x":2464,"y":969,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2538,1486],{"x":2468,"y":972,"style":886},[822,2540],{"x":2472,"y":969,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2542,2543],{"x":2476,"y":972,"style":886},"Bank",[822,2545],{"x":2479,"y":969,"width":2480,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2547,2548],{"x":2483,"y":972,"style":886},"35,300.00",[822,2550],{"x":2487,"y":969,"width":2488,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2552],{"x":2495,"y":969,"width":2496,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2554],{"x":2461,"y":986,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},[842,2556,899],{"x":2505,"y":989,"style":846},[822,2558],{"x":2464,"y":986,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2560,1491],{"x":2468,"y":989,"style":886},[822,2562],{"x":2472,"y":986,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2564,2565],{"x":2476,"y":989,"style":886},"Accounts receivable",[822,2567],{"x":2479,"y":986,"width":2480,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2569,2570],{"x":2483,"y":989,"style":886},"15,800.00",[822,2572],{"x":2487,"y":986,"width":2488,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2574],{"x":2495,"y":986,"width":2496,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2576],{"x":2461,"y":1000,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},[842,2578,824],{"x":2505,"y":1003,"style":846},[822,2580],{"x":2464,"y":1000,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2582,2583],{"x":2468,"y":1003,"style":886},"2999",[822,2585],{"x":2472,"y":1000,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2587,2588],{"x":2476,"y":1003,"style":886},"Suspense",[822,2590],{"x":2479,"y":1000,"width":2480,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2592],{"x":2487,"y":1000,"width":2488,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2594,2595],{"x":2491,"y":1003,"style":886},"350.00",[822,2597],{"x":2495,"y":1000,"width":2496,"height":859,"rx":669,"fill":982,"stroke":983,"style":954},[842,2599,2600],{"x":2499,"y":1003,"style":996},"suspense not cleared",[822,2602],{"x":2461,"y":1013,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},[842,2604,932],{"x":2505,"y":1016,"style":846},[822,2606],{"x":2464,"y":1013,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2608,1496],{"x":2468,"y":1016,"style":886},[822,2610],{"x":2472,"y":1013,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2612,2613],{"x":2476,"y":1016,"style":886},"Sales",[822,2615],{"x":2479,"y":1013,"width":2480,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2617],{"x":2487,"y":1013,"width":2488,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2619,2620],{"x":2491,"y":1016,"style":886},"25,000.00",[822,2622],{"x":2495,"y":1013,"width":2496,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2624],{"x":2461,"y":2625,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"180.0",[842,2627,2629],{"x":2505,"y":2628,"style":846},"199.0","6",[822,2631],{"x":2464,"y":2625,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2633],{"x":2472,"y":2625,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2635,2636],{"x":2476,"y":2628,"style":886},"Total",[822,2638],{"x":2479,"y":2625,"width":2480,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},[842,2640,2641],{"x":2483,"y":2628,"style":979},"94,250.00",[822,2643],{"x":2487,"y":2625,"width":2488,"height":859,"rx":669,"fill":975,"stroke":976,"style":954},[842,2645,2641],{"x":2491,"y":2628,"style":979},[822,2647],{"x":2495,"y":2625,"width":2496,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2649],{"x":2461,"y":2650,"width":832,"height":859,"rx":669,"fill":834,"stroke":835,"style":836},"208.0",[842,2652,2100],{"x":2505,"y":2653,"style":846},"227.0",[822,2655],{"x":2464,"y":2650,"width":2465,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2657],{"x":2472,"y":2650,"width":2473,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2659,2660],{"x":2476,"y":2653,"style":886},"Difference",[822,2662],{"x":2479,"y":2650,"width":2480,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[842,2664,2665],{"x":2483,"y":2653,"style":886},"0.00",[822,2667],{"x":2487,"y":2650,"width":2488,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[822,2669],{"x":2495,"y":2650,"width":2496,"height":859,"rx":669,"fill":827,"stroke":835,"style":836},[20,2671,2673],{"id":2672},"step-6-verify-the-written-totals","Step 6 — Verify the written totals",[10,2675,2676],{},"Recalculate the workbook and confirm the totals Excel computes agree with pandas — a check that the layout code put every line in:",[25,2678,2680],{"className":72,"code":2679,"language":74,"meta":30,"style":30},"import subprocess\nfrom openpyxl import load_workbook\n\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"xlsx\", \"--outdir\", \"recalc\", \"trial_balance_2026-09.xlsx\"],\n               check=True, capture_output=True)\nws = load_workbook(\"recalc\u002Ftrial_balance_2026-09.xlsx\", data_only=True).active\ntotal_row = next(r for r in range(1, ws.max_row + 1) if ws.cell(r, 2).value == \"Total\")\nprint(\"Excel totals:\", ws.cell(total_row, 5).value, ws.cell(total_row, 6).value,\n      \"| difference:\", ws.cell(total_row + 1, 5).value, \"| pandas:\", tb[\"Dr\"].sum(), tb[\"Cr\"].sum())\n",[32,2681,2682,2689,2700,2704,2744,2764,2788,2843,2865],{"__ignoreMap":30},[35,2683,2684,2686],{"class":37,"line":38},[35,2685,82],{"class":81},[35,2687,2688],{"class":85}," subprocess\n",[35,2690,2691,2693,2695,2697],{"class":37,"line":95},[35,2692,1657],{"class":81},[35,2694,1660],{"class":85},[35,2696,82],{"class":81},[35,2698,2699],{"class":85}," load_workbook\n",[35,2701,2702],{"class":37,"line":102},[35,2703,99],{"emptyLinePlaceholder":98},[35,2705,2706,2709,2712,2714,2717,2719,2722,2724,2727,2729,2732,2734,2737,2739,2741],{"class":37,"line":120},[35,2707,2708],{"class":85},"subprocess.run([",[35,2710,2711],{"class":45},"\"soffice\"",[35,2713,160],{"class":85},[35,2715,2716],{"class":45},"\"--headless\"",[35,2718,160],{"class":85},[35,2720,2721],{"class":45},"\"--convert-to\"",[35,2723,160],{"class":85},[35,2725,2726],{"class":45},"\"xlsx\"",[35,2728,160],{"class":85},[35,2730,2731],{"class":45},"\"--outdir\"",[35,2733,160],{"class":85},[35,2735,2736],{"class":45},"\"recalc\"",[35,2738,160],{"class":85},[35,2740,2392],{"class":45},[35,2742,2743],{"class":85},"],\n",[35,2745,2746,2749,2751,2753,2755,2758,2760,2762],{"class":37,"line":135},[35,2747,2748],{"class":589},"               check",[35,2750,108],{"class":81},[35,2752,1760],{"class":199},[35,2754,160],{"class":85},[35,2756,2757],{"class":589},"capture_output",[35,2759,108],{"class":81},[35,2761,1760],{"class":199},[35,2763,117],{"class":85},[35,2765,2766,2768,2770,2773,2776,2778,2781,2783,2785],{"class":37,"line":140},[35,2767,1708],{"class":85},[35,2769,108],{"class":81},[35,2771,2772],{"class":85}," load_workbook(",[35,2774,2775],{"class":45},"\"recalc\u002Ftrial_balance_2026-09.xlsx\"",[35,2777,160],{"class":85},[35,2779,2780],{"class":589},"data_only",[35,2782,108],{"class":81},[35,2784,1760],{"class":199},[35,2786,2787],{"class":85},").active\n",[35,2789,2790,2793,2795,2798,2801,2803,2806,2808,2811,2813,2815,2818,2820,2822,2825,2828,2831,2833,2836,2838,2841],{"class":37,"line":169},[35,2791,2792],{"class":85},"total_row ",[35,2794,108],{"class":81},[35,2796,2797],{"class":199}," next",[35,2799,2800],{"class":85},"(r ",[35,2802,1829],{"class":81},[35,2804,2805],{"class":85}," r ",[35,2807,1835],{"class":81},[35,2809,2810],{"class":199}," range",[35,2812,217],{"class":85},[35,2814,595],{"class":199},[35,2816,2817],{"class":85},", ws.max_row ",[35,2819,536],{"class":81},[35,2821,2028],{"class":199},[35,2823,2824],{"class":85},") ",[35,2826,2827],{"class":81},"if",[35,2829,2830],{"class":85}," ws.cell(r, ",[35,2832,881],{"class":199},[35,2834,2835],{"class":85},").value ",[35,2837,1261],{"class":81},[35,2839,2840],{"class":45}," \"Total\"",[35,2842,117],{"class":85},[35,2844,2845,2847,2849,2852,2855,2857,2860,2862],{"class":37,"line":206},[35,2846,248],{"class":199},[35,2848,217],{"class":85},[35,2850,2851],{"class":45},"\"Excel totals:\"",[35,2853,2854],{"class":85},", ws.cell(total_row, ",[35,2856,932],{"class":199},[35,2858,2859],{"class":85},").value, ws.cell(total_row, ",[35,2861,2629],{"class":199},[35,2863,2864],{"class":85},").value,\n",[35,2866,2867,2870,2873,2875,2877,2879,2881,2884,2887,2890,2892,2895,2897],{"class":37,"line":245},[35,2868,2869],{"class":45},"      \"| difference:\"",[35,2871,2872],{"class":85},", ws.cell(total_row ",[35,2874,536],{"class":81},[35,2876,2028],{"class":199},[35,2878,160],{"class":85},[35,2880,932],{"class":199},[35,2882,2883],{"class":85},").value, ",[35,2885,2886],{"class":45},"\"| pandas:\"",[35,2888,2889],{"class":85},", tb[",[35,2891,650],{"class":45},[35,2893,2894],{"class":85},"].sum(), tb[",[35,2896,678],{"class":45},[35,2898,301],{"class":85},[10,2900,2901,2902,2904],{},"LibreOffice recalculates the formulas while converting, and the cached results show debit and credit totals of 94,250 each, matching pandas, with a zero difference. This kind of check is cheap and catches the layout bugs — an off-by-one range in the ",[32,2903,2435],{},", a row skipped — that look perfectly fine on screen.",[20,2906,2908],{"id":2907},"common-pitfalls","Common pitfalls",[2910,2911,2912,2920,2926,2932,2938],"ul",{},[2913,2914,2915,2919],"li",{},[2916,2917,2918],"strong",{},"Starting from the ledger instead of the chart of accounts."," Accounts with no movement drop out; join movements onto the account list.",[2913,2921,2922,2925],{},[2916,2923,2924],{},"Exact float comparisons."," Compare debits and credits with a small tolerance.",[2913,2927,2928,2931],{},[2916,2929,2930],{},"Ignoring abnormal balances."," A balanced trial balance can still contain a credit bank balance or a debit payable.",[2913,2933,2934,2937],{},[2916,2935,2936],{},"Leaving suspense balances."," They must be cleared before the close.",[2913,2939,2940,2943],{},[2916,2941,2942],{},"Editing amounts in the output."," Fix the ledger, then regenerate.",[20,2945,2947],{"id":2946},"conclusion","Conclusion",[10,2949,2950],{},"A trial balance from journal lines is a few pandas steps: check every journal balances and every account exists, compute opening balances, period debits and credits and closing balances per account starting from the chart of accounts, and split signed closing balances into debit and credit columns that must total the same. Flag balances on the wrong side and uncleared suspense, compare with the prior month, and write the result with formula totals and a red difference cell — then recalculate to prove the totals agree.",[20,2952,2954],{"id":2953},"frequently-asked-questions","Frequently asked questions",[10,2956,2957,2960],{},[2916,2958,2959],{},"How do I make a trial balance from a general ledger in Python?","\nLoad the journal lines, sum debits minus credits per account up to the period end, join onto the chart of accounts, and put positive closing balances in a debit column and negative ones in a credit column. Both columns must total the same.",[10,2962,2963,2966],{},[2916,2964,2965],{},"Why doesn't my trial balance balance?","\nUsually a journal was posted unevenly, or lines were lost by a date filter or an account missing from the chart of accounts. Check each journal's debits equal its credits and that every account in the ledger is known.",[10,2968,2969,2972],{},[2916,2970,2971],{},"What is an abnormal balance?","\nA balance on the opposite side to the account type's normal side, such as a credit balance on an asset or a debit balance on a liability. It is not always an error but should be reviewed.",[10,2974,2975,2978],{},[2916,2976,2977],{},"Should trial balance totals be formulas in Excel?","\nYes. SUM formulas for the debit and credit totals, with a difference cell that is highlighted when non-zero, keep the check visible if anyone edits the sheet.",[20,2980,2982],{"id":2981},"related","Related",[2910,2984,2985,2991,2998,3005],{},[2913,2986,2987,2988,2990],{},"Up one level: ",[14,2989,17],{"href":16}," — finance and operations reports in Excel.",[2913,2992,2993,2997],{},[14,2994,2996],{"href":2995},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bank-reconciliation-report\u002F","Build a Bank Reconciliation Report"," — proving the bank balance in the trial balance.",[2913,2999,3000,3004],{},[14,3001,3003],{"href":3002},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fgenerate-customer-account-statements-from-a-ledger\u002F","Generate Customer Account Statements from a Ledger"," — the receivables detail behind account 1100.",[2913,3006,3007,3011],{},[14,3008,3010],{"href":3009},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-deferred-revenue-schedule\u002F","Build a Deferred Revenue Schedule"," — a schedule that feeds month-end journals.",[3013,3014,3015],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":30,"searchDepth":95,"depth":95,"links":3017},[3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028],{"id":22,"depth":95,"text":23},{"id":65,"depth":95,"text":66},{"id":307,"depth":95,"text":308},{"id":634,"depth":95,"text":635},{"id":1059,"depth":95,"text":1060},{"id":1643,"depth":95,"text":1644},{"id":2672,"depth":95,"text":2673},{"id":2907,"depth":95,"text":2908},{"id":2946,"depth":95,"text":2947},{"id":2953,"depth":95,"text":2954},{"id":2981,"depth":95,"text":2982},"2026-10-02","Produce a month-end trial balance in Excel from general ledger journal lines with pandas: opening balances plus period movements to closing balances for every account, debit and credit columns, a check that the ledger balances, flags for accounts on their wrong side and unmapped or suspense accounts, a prior-month comparison, and an openpyxl layout with live totals.","md",[3033,3035,3037,3039],{"q":2959,"a":3034},"Load the journal lines, sum debits minus credits per account up to the period end, join onto the chart of accounts, and put positive closing balances in a debit column and negative ones in a credit column. Both columns must total the same.",{"q":2965,"a":3036},"Usually a journal was posted unevenly, or lines were lost by a date filter or an account missing from the chart of accounts. Check each journal's debits equal its credits and that every account in the ledger is known.",{"q":2971,"a":3038},"A balance on the opposite side to the account type's normal side, such as a credit balance on an asset or a debit balance on a liability. It is not always an error but should be reviewed.",{"q":2977,"a":3040},"Yes. SUM formulas for the debit and credit totals, with a difference cell that is highlighted when non-zero, keep the check visible if anyone edits the sheet.","build a trial balance from a general ledger",null,{"breadcrumb":3044},[3045,3048,3051],{"name":3046,"item":3047},"Home","\u002F",{"name":3049,"item":3050},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":3052,"item":16},"Building Finance and Operations Reports in Excel with Python","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger",{"title":3055,"description":3056},"Build a Trial Balance from a General Ledger with Python","Create a trial balance from GL journal lines: opening, movement and closing per account, debit and credit columns, balancing checks, abnormal-balance and suspense flags, prior-period comparison and an Excel layout.","build-a-trial-balance-from-a-general-ledger","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-trial-balance-from-a-general-ledger\u002Findex",[3060,3061],"report-layouts","pivots-and-summaries","how-to","tbjlRdTUPtVL7lcNcaSLiiYlZLucplEJlfBi84RfIFs",[3065,3069],{"title":3066,"path":3067,"stem":3068,"children":-1},"Build a Training Compliance Matrix","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-training-compliance-matrix","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-training-compliance-matrix\u002Findex",{"title":3070,"path":3071,"stem":3072,"children":-1},"Build a VAT Return Summary from Transactions","\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-vat-return-summary-from-transactions","automating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-vat-return-summary-from-transactions\u002Findex",[3074,3076],{"path":3075,"title":3052},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports",{"path":3077,"title":3049},"\u002Fautomating-reporting-workflows",[],[3080,3084,3087,3090,3093,3096],{"path":3081,"title":3082,"kind":3083},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards","Building Multi-Sheet Excel Dashboards","guide",{"path":3085,"title":3086,"kind":3062},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-data-dictionary-sheet-to-an-excel-report","Add a Data Dictionary Sheet to an Excel Report",{"path":3088,"title":3089,"kind":3062},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-kpi-summary-block-to-an-excel-dashboard","Add a KPI Summary Block to an Excel Dashboard",{"path":3091,"title":3092,"kind":3062},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-table-of-contents-sheet-with-hyperlinks-in-excel","Add a Table of Contents Sheet with Hyperlinks in Excel",{"path":3094,"title":3095,"kind":3062},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-slicer-style-filters-to-an-excel-dashboard","Add a Dropdown Filter That Drives an Excel Dashboard",{"path":3097,"title":3098,"kind":3062},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-summary-sheet-to-excel-report-python","Add a Summary Sheet to an Excel Report with Python",1790972127412]