# Business Logic — modUtil.GetNextBatchNumber() [14 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `modUtil.GetNextBatchNumber` |
| Layer | Utility |
| Module | `(unknown)` (Package: `vba-source/modUtil.bas`) |

## 1. Role

### modUtil.GetNextBatchNumber()

This method generates a unique, monotonically increasing batch identifier for data import operations. It queries the `tblImportBatch` table to find the maximum existing `BatchID` and returns the next sequential value (i.e., `Max(BatchID) + 1`). If no records exist in the table — indicating this is the first batch or the table has been truncated — it returns `1` as the starting batch number.

The method acts as a shared utility function within the `modUtil` module, called by `modImport.RunImport()` to assign a new batch ID before a data import operation begins. Each import run receives its own distinct batch number, which serves as a foreign-key reference for tracing all rows and error logs associated with that import session. This enables rollback, auditing, and per-batch error tracking across the import pipeline.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["GetNextBatchNumber()"])
    A["Set db = CurrentDb()"]
    B["Open recordset: SELECT Max(BatchID) FROM tblImportBatch"]
    C{"rs!MaxID is NULL?"}
    D["GetNextBatchNumber = 1"]
    E["GetNextBatchNumber = rs!MaxID + 1"]
    F["rs.Close / Set rs = Nothing"]
    G["Set db = Nothing"]
    END(["Return Long: next batch number"])

    START --> A --> B --> C
    C -->|Yes| D
    C -->|No| E
    D --> F --> G --> END
    E --> F --> G --> END
```

**Requirements:**
- The method opens a `DAO.Database` connection via `CurrentDb()`.
- It executes a simple `SELECT Max(BatchID)` aggregation over `tblImportBatch`.
- If the result is `NULL` (no rows exist), it returns `1`.
- Otherwise, it returns the current maximum `BatchID` incremented by `1`.
- It always cleans up the recordset and database objects.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This method takes no parameters. It generates the next batch ID purely from the current state of the `tblImportBatch` table. |
| 1 | `db` (internal) | `DAO.Database` | Internal DAO database object obtained via `CurrentDb()`. Provides access to the Access database for querying `tblImportBatch`. |
| 2 | `rs` (internal) | `DAO.Recordset` | Internal DAO recordset holding the result of the `SELECT Max(BatchID)` query. Used to determine whether a prior batch exists. |

## 4. CRUD Operations / Called Services

### Database Tables (code↔DB map, from the code graph)

| Access Table | Foreign-key reference → |
|---|---|
| tblImportBatch | — |

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `GetNextBatchNumber` | — | `tblImportBatch` | Reads the maximum `BatchID` from the import batch table to compute the next sequential batch number. |

**Classification:** This method performs a single **Read (R)** operation. It does not modify any data; it only queries the `tblImportBatch` table to determine the highest existing batch ID.

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

No screen/batch entry points found within 8 hops. Direct callers found: 1 methods.
Terminal operations from this method: -

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Module: `modImport` | `modImport.RunImport()` → `GetNextBatchNumber()` | `SELECT Max(BatchID) [R] tblImportBatch` |

**Notes:**
- The method is called by `modImport.RunImport()`, which likely serves as the entry point for data import operations.
- No screen (`KKSV*`) or batch (`KKBT*`) entry points were found within 8 hops of the call chain.
- This is a pure utility method with no downstream service component (SC) or business component (CBS) calls.

## 6. Per-Branch Detail Blocks

**Block 1** — SET (Initialize database connection) (L8)

> Opens the current Access database and prepares a recordset to query the maximum batch ID.

| # | Type | Code |
|---|------|------|
| 1 | SET | `db = CurrentDb()` | Get reference to the current Access database |
| 2 | SET | `rs = db.OpenRecordset("SELECT Max(BatchID) AS MaxID FROM tblImportBatch")` | Query the maximum existing batch ID from tblImportBatch |

**Block 2** — IF (Check if no prior batches exist) (L10)

> If `tblImportBatch` is empty (the `Max(BatchID)` aggregation returns `NULL`), this branch assigns `1` as the first batch number. Otherwise, it increments the existing maximum.

| # | Type | Code |
|---|------|------|
| 1 | IF | `If IsNull(rs!MaxID)` [Condition: the Max(BatchID) field is NULL, meaning no records exist in tblImportBatch] |
| 2 | SET | `GetNextBatchNumber = 1` [Branch: first batch — no prior records exist, so start at 1] |
| 3 | ELSE | `Else` |
| 4 | SET | `GetNextBatchNumber = rs!MaxID + 1` [Branch: subsequent batch — increment the current maximum by 1] |
| 5 | END | `End If` |

**Block 3** — CLEANUP (Release resources) (L14)

> Always executes: closes the recordset and releases all object references to prevent memory leaks in VBA.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `rs.Close` | Close the recordset |
| 2 | SET | `Set rs = Nothing` | Release the recordset object |
| 3 | SET | `Set db = Nothing` | Release the database object |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `BatchID` | Field | Batch identifier — a unique, sequential number assigned to each import operation session |
| `tblImportBatch` | Table | Import batch tracking table — stores batch metadata for data import operations; each import run inserts a row with its assigned BatchID |
| `CurrentDb()` | VBA API | DAO function that returns a reference to the current Microsoft Access database |
| `DAO.Recordset` | VBA/DAO type | Data access object representing a set of rows returned from a SQL query; used here to read the aggregate `Max(BatchID)` result |
| `IsNull()` | VBA function | Returns `True` if the given expression has no valid value (i.e., is SQL `NULL`) |
| `modUtil` | Module | Shared VBA utility module containing cross-cutting helper functions (batch ID generation, error logging, date/number formatting for SQL) |
| `modImport` | Module | VBA module that implements the data import workflow; calls `GetNextBatchNumber()` at the start of each import run to obtain a unique batch ID |
| `RunImport()` | Method | Entry point for the data import process; orchestrates batch creation, row-by-row processing, and error logging |

---

## FINAL STEP (MANDATORY)
You MUST call the `write_file` tool to save the completed document to `.codewiki/dd/modUtil/GetNextBatchNumber.md`.
Do NOT output the document as plain text. A plain-text response is invalid.
The task is ONLY complete after `write_file` succeeds.