This is a new series I’m starting. Showing different pieces from the history of Business Central.
The first episode is all about Navision 3.56. This is the grandfather of Business Central, and many of the things we take granted today originated in 3.56 back in 1990.
Grab a drink because I’m trying to cover everything, so it’s not a short video 🙂
If there is something from the long history of Navision/NAV/Business Central you would like me to cover, let me know in the comments here or below the video.
In this fascinating video, Erik takes us on a deep dive into Navision 3.56 — the grandfather of what we now know as Microsoft Dynamics 365 Business Central. Originally called “IBM Navigator,” this software first appeared in 1987 as an accounting system designed for IBM PS/2 computers and token ring networks. By 1990, version 3 introduced a built-in development system and programming language, establishing many of the concepts that persist in Business Central today. Erik walks us through the entire application, from the text-mode UI to the object designer, showing just how much of modern Business Central has its roots in this 30-year-old software.
A Brief History
The product that eventually became Business Central started life as “IBM Navigator” in 1987, built specifically for IBM’s PS/2 computers. It was later renamed to Navision. Version 3 arrived in 1990 with a groundbreaking feature: a built-in development system with its own programming language. This was the foundation upon which Navision Financials, Dynamics NAV, and ultimately Business Central were all built.
Running the Software
The entire application fits in just seven and a half megabytes, with the database itself weighing in at only two and a half megabytes. The software shipped with three different executables for three different platforms:
- NAVI.EXE — the DOS client
- NAVI2.EXE — the OS/2 client
- NAVIN.EXE — the Win32 client (added later when Windows 95 arrived)
Similarly, there were three corresponding server executables, because this was a true client-server architecture. The server handled all database operations using what would become known as the “native database” — a technology that survived all the way through Dynamics NAV 2009 R2.
Running 30-year-old software on a modern machine yields lightning-fast performance, as you might expect. The entire application runs in text mode at 80×25 characters.
The Startup Menu
One important caveat: this is a Danish product translated to English by the original team in Denmark, intended as a starting point for international localization. As a result, some terminology feels unfamiliar — “accounts” means companies, “demo” is what later became “Cronus,” and “survey” is what we’d call a list.
The startup menu provides access to several foundational features that still exist in some form today:
- Accounts (Companies) — selecting which company to work in
- Backup and Restore — import and export backups
- Users and Permission Sets — the concept of “SUPER” was born here
- Setup — the predecessor to the .ZUP file from the Classic Client, where you configured your monitor type (VGA, EGA, mono, CGA), keyboard layout (AT keyboard with 12 function keys or PC keyboard with 10), and print screen line counts
- Automatic Logout — a feature that was actually lost in later versions and only recently regained
- Database Maintenance — selecting, creating, or expanding databases. The native database used pre-allocated sizes, and the commit cache concept was already present
The Application Modules
Upon opening a company, the main menu reveals the modules available in the product, organized into five columns that served as predecessors to the structure used in Navision Financials.
Chart of Accounts
The chart of accounts looks remarkably familiar. The “summing up” field (now called “totaling”) works exactly the same way. The keyboard system followed the ISA standard championed by IBM: F1 for help, F3 for insert, F4 for delete, F10 for menu. These standards survived into the Classic Client.
Pressing F6 on a balance field drills down into general ledger entries — the exact same drill-down behavior we have today with FlowFields (though they weren’t called FlowFields yet). Filters worked the same way too.
The Budget Matrix — A Lost Feature
One standout feature that was lost after this version: the budget matrix. It offered true infinity scrolling across time periods. You could scroll left and right through dates endlessly, with a period indicator at the bottom of the screen. Using Ctrl+Left/Right, you could shift the period columns around. No setup screens, no “next period” buttons — just a matrix that simply worked. This was implemented with minimal code (more on that in the designer section).
Customers, Vendors, and Items
Customer cards look almost identical to their modern counterparts. The card/list navigation, filters, calculation filters, and the zoom function (showing all fields) were all present. Many of the fields from this version still exist in Business Central today — even niche fields like the Telex field, despite telex technology being largely obsolete by the late 1980s.
The Search Name field existed because text field searching was not case-insensitive in this version, so the search name provided a normalized lookup value.
Vendors were called “Suppliers,” and the vendor module was intentionally created as a carbon copy of the customer module with reversed financial signs — a pragmatic design decision.
Product Groups — A Mystery
This version included a feature called Product Groups that never made it to Navision Financials. Erik notes that nobody he’s asked knows exactly what happened to them, and invites anyone with knowledge to share in the comments.
Resources and Jobs
Resources and Jobs existed in largely recognizable form, though the job budget was structured quite differently. It used a three-level hierarchy of Main Activity, Secondary Activity, and Part Activity as the primary key — a design that was “really really annoying” for anything beyond the original use case. This structure persisted until Financials 5.0 introduced the new job budget with job tasks.
The Jobs module originated from Danish accounting firms and law offices that needed to track billable time — hence the column label “Time Job” visible in the Danish-influenced English translation.
Sales and Purchase
Creating a sales invoice demonstrates several interesting design choices. When pressing F6 for a lookup, the system asks which window you’d like to use for selection (customer card or customer list), and lets you save that preference. The header and lines were on separate screens — you had to go into the menu and select “Lines” to access the line items.
Posting was done with F8, and in the demo company, transactions were restricted to January and December. The Navigate function was already present, showing related GL entries and ledger entries — though there were no detailed entries or value entries yet; everything posted to regular entries.
Reports — Beautiful Text-Mode Output
The reports menu is a visual delight: it’s styled to look like matrix printer paper with tractor-feed holes on the sides. Reports could be printed to screen, to a printer, or to both simultaneously. Since there was no concept of operating system printer drivers, Navision had to manage printers directly — you’d specify that your IBM ProPrinter was sitting on LPT2 and select from the built-in list of supported printers.
Batch printing was also supported: you could mark multiple reports and print them all in one go — another feature that was lost and only recently approximated with scheduled reports in Business Central.
VAT, Dimensions, and Setup
This version supported only VAT (no sales tax concept). Dimensions were limited to exactly two: Departments and Projects. Period. The GL setup contained all number sequences directly in a single record, which worked fine with the native database’s table-level locking but would become problematic when SQL Server was introduced — hence the eventual move to separate number series records.
The Object Designer
The design environment is where things get really interesting for developers. The available object types were:
- Tables (called “Files”)
- Windows (UI forms/pages)
- Functions (code units)
- Menus
- Reports
- Batch Jobs (process-only reports — a separate object type)
- Imports (predecessor to Dataports)
- Printers (printer driver definitions)
Printers as Objects
Printer definitions were their own object type, containing character conversion tables and formatting commands. For example, to print bold on an IBM ProPrinter required sending Escape 69, and to stop bold required Escape 70. Underline was more complex: 27-45-1 to start, 27-45-0 to stop. PostScript printers had a downloadable setup file, essentially embedding a PostScript programming language within the printer driver. This is the ancestor of today’s PDF — Portable Document Format is, after all, built on PostScript.
Tables — Remarkably Familiar
Table 18 is the Customer table — and it’s still table 18 in Business Central today. The fields are largely the same: Number (1), Name (2), Name 2, and so on. Some field lengths are shorter, but most fields are recognizable. Table relations worked by simply pointing to another table without specifying a field — the system assumed the primary key would match. This convention still works in Business Central.
The last table in the system was 450, but the meaningful business tables start around 220 (Business Unit). As Erik points out, it’s nearly impossible to work in Business Central without touching a table numbered below 220 — these are the foundational tables.
Field Transfer — A Lost Gem
One of the most impressive features that never made it to later versions was Field Transfer. On the Sales Header table (still table 36), you could define a mapping that specified which fields should be transferred from the Customer table when a customer was selected:
Name in Sales Header = Name in Customer, Name 2 = Name 2, and so on. You could also define transfers from the header to general ledger lines, to product ledger lines, and more. This eliminated the need for repetitive “validate and copy” code. Erik expresses a clear wish that Microsoft would bring this feature back.
Post-Processing Code (Code Behind)
The “post-processing” view is the predecessor to triggers and event code. It included triggers for On Insert (called “Created”), On Delete, On Modify, and field-level validate code. There was also a “Special Relations” concept — essentially the grandfather of the OnLookup trigger.
A particularly nice feature: you could filter the post-processing view to show only fields that actually had code, hiding all the empty ones. This made navigation much more efficient.
Here is an example of the post-processing code for the Product Group table, showing the DELETE trigger, SAVE trigger, and field validation code:
{ DELETE trigger for Prod.Gr }
dbLOCKFILE(ProdGrEntry);
dbCALCFIELDS("Stock(CPrice)");
dbTESTFIELD("Stock(CPrice)",0);
dbSELECTKEY(ProdGrEntry."Prod.Gr No.");
dbSETRANGE(ProdGrEntry."Prod.Gr No.","No.");
dbMODIFYALL(ProdGrEntry."Prod.Gr No.",'');
dbSETRANGE(CommLine.File,6);
dbSETRANGE(CommLine."No.","No.");
dbDELALL(CommLine);
dbSELECTKEY(PurchaseLine."Voucher Type",PurchaseLine.Type,
PurchaseLine."No.",PurchaseLine."Deliv.Date");
dbSETRANGE(PurchaseLine."Voucher Type",1);
dbSETRANGE(PurchaseLine.Type,4);
dbSETRANGE(PurchaseLine."No.","No.");
IF dbFINDREC(PurchaseLine,'-') THEN
ERROR('There are purchase orders for product group %1',"No.");
dbSELECTKEY(SalesLine."Voucher Type",SalesLine.Type,
SalesLine."No.",SalesLine."Deliv.Date");
dbSETRANGE(SalesLine."Voucher Type",1);
dbSETRANGE(SalesLine.Type,4);
dbSETRANGE(SalesLine."No.","No.");
IF dbFINDREC(SalesLine,'-') THEN
ERROR('There are sales orders for product group %1',"No.");
{ SAVE trigger for Prod.Gr }
"Edited on" := TODAY;
{ Name field validation for Prod.Gr }
IF (1 < CursorPos) AND (CursorPos < MAXSTRLEN("Search Name")) THEN BEGIN
"Search Name" := DELCHR(COPYSTR(Name,CursorPos),'<>');
"Search Name" := SETSTRLEN("Search Name" + ' ' +
DELCHR(COPYSTR(Name,1,CursorPos-1),'<>'),MAXSTRLEN("Search Name"));
END ELSE
"Search Name" := Name;
{ Superior Prod. Gr field validation }
IF ("Superior Prod. Gr" <> '') THEN BEGIN
dbGETREC(ProdGr2,"Superior Prod. Gr");
"Booking Group" := ProdGr2."Booking Group";
END;
Notice how the syntax maps to modern AL: dbGETREC(Customer, DeliveryNumber) is equivalent to Customer.Get(DeliveryNumber). The dbSETRANGE, dbFINDREC, dbCALCFIELDS, dbTESTFIELD, dbMODIFYALL, and dbDELALL functions all have direct modern equivalents. The syntax changed to appear more object-oriented, but the underlying operations remained identical.
Variables and the Compiler
Only global variables existed in this version — there were no local variables. This explains why some code still in Business Central today is “littered with global variables”: when Navision’s team built the Financials application, they started development in version 3.56 before the new environment was ready, and had no choice but to use globals.
The compiler had an excellent feature: after running “Test AL Code” (yes, the language was originally called AL before it became C/AL in Financials, and is now AL again), the variable list would show marks next to every variable that was actually used in the code. Unused variables were immediately visible. This feature was lost in Financials and Dynamics NAV, and only returned recently with the Code Analyzer in Business Central.
The Language Functions
The available functions were essentially the same as today, just with different naming conventions. The F5 menu provided access to:
- Internal and external variables
- All database functions:
dbFINDREC(equivalent toFind),dbGETREC,dbMODIFYREC,dbSETRANGE,dbSETFILTER,dbCOPYFILTERS,dbGETFILTERS,COMMIT - String functions: identical to modern versions including
MAXSTRLEN,COPYSTR,DELCHR,SETSTRLEN - Conversion functions:
EVALUATE,FORMAT,CLEAR - Date functions:
DATE2DMY,DMY2DATE,WORKDATE,TODAY - Report calling: “Call Report” instead of
Report.Run
Notably, there was only the FIND function with the minus/plus parameter — no FindFirst, FindLast, etc. Those were added later to optimize SQL Server access when the language needed to become SQL-compatible.
Window Designer
The window (form/page) designer was straightforward. For a customer card (Window 21), you defined the table, frame, heading, menu items with keyboard shortcuts, and then entered a visual editor. Placing a cursor and pressing F3 let you insert a field with both its caption and data element. Alignment was done with the space bar. Tab sequences were configurable.
The most impressive example is the budget matrix (Window 113). The entire configuration consisted of: declaring it as a matrix type, specifying the table, setting the date filter field, and placing four fields in the editor — with the last one being a sum field (FlowField). That’s it. The client handled all the scrolling, period shifting, and matrix rendering automatically. Compare this to the enormous amount of code required for page 113 in modern Business Central.
Functions (Code Units)
Code Unit 12 is the “Post General Ledger Line” — still a critical code unit in Business Central. The code supported beautiful ASCII box comments that the compiler recognized as comments, in addition to standard Pascal-style curly bracket comments. Code Unit 80 handled sales posting, 90 handled purchase posting, and the last function added was Code Unit 37 — the Navigate function.
Reports in the Designer
Report design used sections: Request (request page), Header, Blank, File, Import Loop, Transport Top, Transport Bottom, Group Heading, Group Totals, Totals, and Filler. Creating boxes and lines around report elements was incredibly easy — you’d define a block and hit the Frame function, and the designer would draw the box for you, even across multiple sections. Many people struggled to recreate these elegant bordered reports in later versions of the product.
Batch Jobs and Imports
Batch jobs were structurally identical to reports but without printing — essentially process-only reports. Merging them into a single object type (as happened in Financials) was a natural evolution.
Imports (the predecessor to Dataports) had an interesting quirk: they didn’t have object numbers, unlike tables, windows, and functions. Some object types simply had no numbering — an approach that’s relevant to modern discussions about object numbering in Business Central.
General Features
The “General” menu in the upper right corner offered several utilities:
- Working Date — same concept as today
- Color customization and window positioning
- Macros — a keyboard recording/playback system that could be incorporated into menus. Another feature that never made it to later versions
- Calculator — styled like a classic accounting calculator with tape
- Calendar — personal date highlighting
- Debugger
- Operating System — since DOS was single-program, this dropped you to a command prompt (with a charming curtain animation) so you could run other commands before returning to Navision
Features Lost Along the Way
Throughout the walkthrough, Erik highlights several features from Navision 3.56 that were lost in subsequent versions:
- Infinity-scrolling matrix pages — trivial to implement, lost when the matrix page type was removed
- Field Transfer definitions — declarative field mapping between tables, replaced by manual validate-and-copy code
- Unused variable detection — only recently returned with the Code Analyzer
- Batch report printing — marking multiple reports to print in one go
- Automatic logout — lost and later regained
- Easy box/line drawing in reports — never as simple again
- Keyboard macros — never reintroduced
- Product Groups — disappeared without explanation
Conclusion
Navision 3.56 had a tremendous impact on the ERP landscape. It was the first product that made it genuinely easy for customers and partners to customize an accounting system. Erik’s very first job involved integrating this software with an IBM point-of-sale system — a level of customization that was suddenly achievable while still maintaining a standard ERP platform.
What’s remarkable is how much of this 30-year-old software is directly recognizable in modern Business Central: table 18 is still the Customer table, the field structures are largely unchanged, the permission system still uses “SUPER,” the core database functions have the same semantics, and the printer selection table still exists. The language itself was originally called AL, became C/AL in Financials, and has now come full circle back to AL. The syntax evolved to look more object-oriented, but the underlying concepts have remained stable for three decades — a testament to the quality of the original design.