ACCT-341 · Lesson 2 of 12 · 30 min

Accounting data: sources, structures and quality

Before any analysis, an accountant has to know where the data live, how they are structured and how far they can be trusted. This lesson surveys the sources of accounting data, from the general ledger to e-mail, explains how transaction data are organized in an ERP system, and introduces the dimensions of data quality. It ends with two techniques that every analysis should begin with: profiling the data to find problems, and reconciling the data to independent control totals to prove they are complete. Lesson 3 then turns to fixing the problems that profiling uncovers.

Where accounting data live

Most of a company's financial data originates in its ERP system and the specialized applications around it. An ERP system integrates modules for sales, purchasing, inventory, payroll and the general ledger in a single database, so that one business event, such as shipping goods to a customer, updates every affected record at once. Around the ERP there are usually other systems: a point-of-sale or e-commerce platform, a payroll provider, a bank portal, an expense management app, a customer relationship management (CRM) system, spreadsheets maintained by individual staff, and documents such as contracts, invoices and e-mails.

Cedarbrook's ERP holds its general ledger, receivables, payables, inventory and order management. Payroll is run by an outside payroll provider and summarized into the ledger each pay period. Customer contracts and rebate agreements are PDF files on a shared drive, and the sales team tracks quotes in a separate CRM. Bank transactions arrive daily as an electronic file from Cedarbrook's bank.

Categories of data an accountant meets. Each needs different checks before it is used.
Kind of dataWhat it describesCedarbrook examplesHow often it changes
Master dataThe relatively stable entities the business deals withCustomers, vendors, items, employees, chart of accountsOccasionally; changes should be controlled and logged
Transaction dataBusiness events, each with a date and amountSales invoices, purchase orders, receipts, payments, journal entriesContinuously; high volume
Reference dataCodes and lookup values used by other dataBranch codes, payment terms, tax codes, currency ratesRarely
Audit and log dataWho did what and when in the systemUser logins, master file change logs, approval historiesContinuously
Unstructured dataContent without a fixed table layoutContracts, e-mails, scanned receipts, meeting notesVaries

The distinction between master and transaction data matters for analytics because errors behave differently in each. A single wrong transaction affects one entry. A wrong master record, such as a vendor with the wrong bank account or a customer with an excessive credit limit, affects every transaction that uses it. That is why changes to master data are a favorite target for both controls and fraud, and why lesson 11 includes tests of the vendor master file.

How transaction data are structured

ERP systems store data in relational tables, which ACCT-240 introduced. Each table holds one kind of thing, each row is one instance, and each column is one attribute. A primary key uniquely identifies each row, and foreign keys link rows in one table to rows in another. A sales invoice, for example, is usually stored as a header row (invoice number, customer, date, terms) in one table and several line rows (item, quantity, price) in another, linked by the invoice number.

Journal entries follow the same header-and-line pattern. The header records the entry number, the posting date, the effective date, the source (such as sales, payables or manual), the user who created it and who approved it. The lines record the account, the debit or credit amount, and often dimensions such as branch, department or project. Every journal entry must balance: total debits equal total credits. Analysts who understand this structure can test it directly, for example by checking that every entry balances or that no manual entry was approved by the person who created it.

An entity diagram of five related tables. The journal entry header table, with entry number, posting date, source and user, links to the journal entry lines table, which holds line number, account, debit, credit and branch. The lines table links to the chart of accounts table by account number. Separately, the invoice header table links to invoice lines and to the customer master by customer number. Primary keys are marked with a key symbol and foreign keys with arrows.
Simplified tables behind Cedarbrook's journal entries and sales invoices. Keys link the tables; analytics depends on joining them correctly.

Granularity is the level of detail in each row. An invoice line table is more granular than an invoice header table, which is more granular than a monthly sales summary. Analysts should use the finest granularity they need and no finer, and they must be careful never to mix levels in one calculation. Adding header-level freight charges to every line of an invoice, for instance, counts the freight once per line rather than once per invoice. Lesson 4 returns to this trap when it covers joins.

File formats

Data reach the analyst in many formats. Each has quirks that can corrupt the data on the way in.

Common file formats and the problems they introduce.
FormatDescriptionWatch out for
CSV (comma-separated values)Plain text, one row per line, fields separated by commasCommas inside fields; leading zeros dropped from codes; dates read in the wrong order; text encoding
Excel workbookSpreadsheet file with sheets, formatting and formulasMerged cells, subtotals mixed with data, hidden rows, numbers stored as text
Fixed-width textFields in fixed character positions, common in older systemsWrong column boundaries; implied decimal points
JSON and XMLNested text formats used by APIs and web servicesNested records must be flattened; missing keys
XBRLXML-based tagged financial statementsTaxonomy versions; extension elements; sign conventions
PDF reportsFormatted documents meant for people, not machinesExtraction errors; page headers and footers inside the data
Database extract or APIDirect read from the systemAccess rights; query parameters that silently filter records

A classic example is the loss of leading zeros. Cedarbrook's general ledger account codes are four-digit strings, and its vendor numbers start with zeros, such as 00417. When a CSV file is opened in a spreadsheet, the program may treat these as numbers and display 417, which no longer matches the vendor master. Dates are another trap: 03/04/2025 is March 4 in the United States and 3 April in much of the world. The safe practice is to import data with explicit types, reading codes as text and dates with a stated format, rather than letting software guess.

Audit data standards

Because every ERP system stores data differently, extracting comparable data for analysis can take more time than the analysis itself. To reduce that effort, the AICPA's Assurance Services Executive Committee published voluntary Audit Data Standards that define a common layout for general ledger, accounts receivable, accounts payable, inventory and other data, with standard field names and formats. Some software vendors and firms use these layouts so that one set of tests can run on data from many clients. You do not need to memorize the standards, but you should recognize that agreeing a data layout and a data dictionary up front makes analysis faster and more reliable.

A data dictionary describes each field: its name, meaning, data type, allowed values, source system and owner. When Maya receives a new extract, the first thing she asks for is the data dictionary, or she writes one herself. Knowing that the field called date is the posting date and not the document date, or that amounts are stored in cents, prevents some of the most embarrassing analytical errors.

Dimensions of data quality

Data quality is usually described along several dimensions. Different sources list slightly different sets, but the following six are widely used and map naturally onto accounting concerns. Note how closely they resemble the financial statement assertions you know from auditing: completeness, accuracy, occurrence and cut-off all have data quality counterparts.

Six dimensions of data quality and how each could be tested.
DimensionMeaningExample test on Cedarbrook data
CompletenessAll expected records and values are presentRecord counts and totals agree to the ledger; no missing account codes
AccuracyValues correctly describe the real-world eventInvoice amounts agree to shipping records and price lists
ValidityValues conform to rules and allowed formatsDates are real dates; account codes exist in the chart of accounts
ConsistencyThe same thing is recorded the same way across records and systemsCustomer names match between ERP and CRM; one sign convention
UniquenessEach real-world item is recorded onceNo duplicate invoice numbers or duplicate vendor records
TimelinessData are available and current when neededBank feed loaded daily; month-end entries posted before reporting

Poor data quality has direct costs, such as duplicate payments and mispriced invoices, and indirect costs, such as decisions based on wrong numbers and time spent fixing reports. For analytics, the most dangerous problems are the silent ones: errors that do not cause a program to fail but quietly change the result. A missing account code may drop a line from a total. A duplicated row may double a sale. The defense is to test data quality explicitly, before analyzing, rather than trusting that an extract is clean.

Profiling the data

Data profiling is a systematic first look at a data set to understand its structure and spot quality problems. A basic profile counts rows and distinct values, finds missing values in each column, checks that dates and numbers parse, looks for duplicate keys, and tests simple business rules. For a journal entry extract, the most important business rule is that each entry balances.

Maya profiles a small extract of journal entry lines from Cedarbrook's ERP. Real extracts have thousands or millions of rows, but the same checks apply.

# Profiling a general ledger extract before using it (invented data)
import pandas as pd
gl = pd.DataFrame({
    "je_id":   ["J1001", "J1001", "J1002", "J1002", "J1003", "J1003",
                "J1004", "J1004", "J1004", "J1005", "J1005", "J1005"],
    "line":    [1, 2, 1, 2, 1, 2, 1, 2, 3, 1, 2, 2],
    "posted":  ["2025-03-02", "2025-03-02", "2025-03-05", "2025-03-05",
                "2025-03-31", "2025-03-31", "2025-13-01", "2025-13-01",
                "2025-13-01", "2025-03-09", "2025-03-09", "2025-03-09"],
    "account": ["4000", "1100", "5000", "2000", "6100", "2000",
                "1100", "4000", None, "6200", "1000", "1000"],
    "debit":   [0, 1250, 830, 0, 410, 0, 990, 0, 0, 75, 0, 0],
    "credit":  [1250, 0, 0, 830, 0, 410, 0, 900, 90, 0, 75, 75],
    "user":    ["mokafor", "mokafor", "jli", "jli", "dreyes", "dreyes",
                "jli", "jli", "jli", "batch", "batch", "batch"],
})
print("rows:", len(gl), " journal entries:", gl["je_id"].nunique())
print("missing values by column:")
print(gl.isna().sum()[lambda s: s > 0].to_string())
dates = pd.to_datetime(gl["posted"], errors="coerce")
print("unparseable dates:", dates.isna().sum())
dup = gl.duplicated(["je_id", "line"], keep=False)
print("duplicate je_id/line keys:", dup.sum())
bal = gl.groupby("je_id")[["debit", "credit"]].sum()
bal["diff"] = bal["debit"] - bal["credit"]
print("unbalanced entries:")
print(bal[bal["diff"] != 0].to_string())
Output
rows: 12  journal entries: 5
missing values by column:
account    1
unparseable dates: 3
duplicate je_id/line keys: 2
unbalanced entries:
       debit  credit  diff
je_id                     
J1005     75     150   -75

The profile finds four problems in twelve rows. One line has no account code. Three lines carry the date 2025-13-01, which is not a real date: month 13 may be how the system records a year-end adjustment period, a common ERP practice, or it may be an error, and Maya must find out which before treating these lines as invalid. Two rows share the key J1005 line 2, a duplicate that makes entry J1005 appear unbalanced by 75 dollars. Entry J1004 balances, so its missing account is a separate problem. None of these problems would stop a program from producing a total. All of them would make the total wrong.

Worked problem

Interpreting a profile

Maya's profile of a full year of Cedarbrook journal lines shows 1.84 million rows, 212 lines with no branch code, 3,406 lines dated in period 13, and 41 duplicate entry-and-line keys. What should she do with each finding?

Show solution
  1. Missing branch codes: check whether they belong to balance sheet accounts that are not tracked by branch; if so they are valid, and the profile rule should be refined.
  2. Period 13 lines: confirm with the controller that period 13 is the year-end adjustment period; if so, map it to December for monthly analysis and keep a flag so these entries can be examined separately.
  3. Duplicate keys: determine whether the duplicates are in the ERP itself or were created by the extraction, for example by an overlapping date range; re-extract if necessary.
  4. Record the findings and their resolution in a data preparation log.

Answer: Each finding needs an explanation before the data are used; some will turn out to be valid features of the system rather than errors.

Reconciling to control totals

Profiling finds problems inside the data. It cannot tell you whether records are missing altogether. For that you need an independent total to compare against. The standard practice is to reconcile an extract to control totals from the source system: the trial balance, a subledger total, a record count from the system, or a bank statement balance. If the extract does not reconcile, something is missing or duplicated, and any analysis of it will be wrong.

# Reconciling an extract to control totals from the ERP (invented data)
import pandas as pd
extract = pd.DataFrame({
    "account": ["1100", "1100", "4000", "4000", "4000", "5000", "5000"],
    "net":     [52_340.00, 18_115.50, -61_200.00, -9_455.50, 200.00,
                40_110.00, 6_950.00],
})                                    # debit positive, credit negative
tb = pd.DataFrame({                   # trial balance printed from the ERP
    "account": ["1100", "4000", "5000"],
    "tb_net":  [70_455.50, -70_455.50, 48_420.00],
})
by_acct = extract.groupby("account", as_index=False)["net"].sum()
rec = tb.merge(by_acct, on="account", how="outer").fillna(0)
rec["difference"] = (rec["net"] - rec["tb_net"]).round(2)
print(rec.to_string(index=False))
print("records:", len(extract),
      " hash total of accounts:", extract["account"].astype(int).sum())
Output
account   tb_net      net  difference
   1100  70455.5  70455.5         0.0
   4000 -70455.5 -70455.5         0.0
   5000  48420.0  47060.0     -1360.0
records: 7  hash total of accounts: 24200

Two accounts agree exactly, but account 5000, cost of goods sold, is short by 1,360 dollars in the extract. The most likely causes are an extraction cut-off that missed entries posted late, a filter that excluded a source code, or entries in a period the query did not include. Maya should find the cause and re-extract rather than analyze data she knows to be incomplete. The program also prints a record count and a hash total, the sum of a field that has no meaning on its own, such as account numbers. If the source system reports the same count and hash total, the analyst has extra assurance that no records were lost or altered in transfer.

Reconciliation is so central that auditing standards build it into the use of company data. PCAOB AS 1105, Audit Evidence, and the AICPA's AU-C 500 require the auditor to evaluate whether information produced by the company is sufficiently reliable, including its accuracy and completeness. In practice, that means reconciling extracts to the general ledger and understanding how they were produced, which is exactly the habit this lesson recommends for every analysis.

Getting the data out

There are several ways to obtain data from an ERP, each with trade-offs. Standard reports are easy to run and familiar to users but are formatted for people, often include subtotals and page breaks, and may apply hidden filters. Ad hoc queries written by IT staff can return exactly the fields needed but depend on the query being correct. Direct read-only access to the database or a data warehouse gives the analyst full control but requires knowledge of the table structure and appropriate access rights. Application programming interfaces (APIs) let programs request data in a structured way and are common for cloud systems.

Whatever the method, the analyst should document what was requested, who ran the extraction, when, with what parameters, and what control totals were provided. This record, sometimes called the chain of custody, lets someone else repeat the extraction and lets a reviewer confirm the data were not altered. It is also the first line of the data preparation log that lesson 3 describes.

Common mistakes

  • MistakeOpening a CSV file in a spreadsheet and accepting the defaults.

    InsteadImport with explicit types: codes as text, dates with a stated format.

  • MistakeAssuming an extract is complete because the program ran without errors.

    InsteadReconcile record counts and totals to the source system or trial balance.

  • MistakeTreating every profile exception as an error.

    InsteadInvestigate first; some exceptions, such as period 13 entries, are valid features of the system.

  • MistakeMixing header-level and line-level amounts in one calculation.

    InsteadKeep track of granularity and aggregate to a common level before combining.

  • MistakeStarting analysis without a data dictionary.

    InsteadObtain or write one, so the meaning, type and source of every field are clear.

Summary and key terms

  • Accounting data come from ERP modules, surrounding applications, spreadsheets and unstructured documents.
  • Master data are stable entities, transaction data are events, reference data are codes, and log data record system activity.
  • Transaction data are stored in related header and line tables linked by keys; every journal entry must balance.
  • File formats introduce errors such as lost leading zeros and misread dates; import with explicit types.
  • Six common data quality dimensions are completeness, accuracy, validity, consistency, uniqueness and timeliness.
  • Profiling finds problems within the data; reconciliation to control totals finds missing or extra records.
  • Document how data were extracted so the work can be repeated and reviewed.
Master data
Relatively stable records of entities such as customers, vendors, items and accounts.
Transaction data
Records of business events, each with a date and amount.
Primary key
A field or combination of fields that uniquely identifies each row in a table.
Foreign key
A field in one table that refers to the primary key of another.
Granularity
The level of detail represented by each row of a data set.
Data dictionary
A description of each field's meaning, type, allowed values and source.
Data profiling
A systematic examination of a data set to understand its structure and quality.
Control total
An independent total, such as a record count or ledger balance, used to check completeness.
Hash total
A sum of a field with no meaning of its own, used to detect lost or altered records.
Audit Data Standards
Voluntary AICPA layouts for common accounting data extracts.

Practice problems

Work each problem on paper first, then reveal the answer to check.

  1. Is a vendor's bank account number master data or transaction data?

    Show answer

    Master data.

  2. Why is an error in master data often more serious than an error in one transaction?

    Show answer

    It affects every transaction that uses that master record.

  3. An invoice header holds a freight charge of 50 and the invoice has four lines. What goes wrong if the header is joined to the lines and freight is summed?

    Show answer

    Freight is counted four times, giving 200 instead of 50.

  4. Name the data quality dimension tested by checking that every account code exists in the chart of accounts.

    Show answer

    Validity.

  5. In the profile program, why does J1005 appear unbalanced?

    Show answer

    Its line 2 appears twice, so its credits are double counted.

  6. Remove the duplicated J1005 row in the program. What does the unbalanced list show?

    Show answer

    Nothing; every remaining entry balances.

  7. In the reconciliation program, what is the difference for account 5000 and what might cause it?

    Show answer

    1,360 short; a cut-off, filter or period omitted from the extraction.

  8. What is a hash total?

    Show answer

    The sum of a field with no meaning on its own, compared before and after transfer to detect lost or altered records.

  9. Give one weakness of using a standard ERP report as a data source.

    Show answer

    Formatting, subtotals, page breaks or hidden filters.

  10. What should a chain of custody record include?

    Show answer

    What was requested, who extracted it, when, with which parameters, and the control totals.

Lesson quiz · 5 questions

Score 60% or more to complete this lesson.

Take the quiz