The "heart" of example #1 (ADB_Ex1.Bat)
When all the "smoke and mirrors" are cleared away, the main
part of this example will be done in just one
ADB processing step.
This step will consist of a "join" between the customer and
invoice files.
First, we have to define an Awk script for the
invoice file.
As you recall, invoices are of two types: "open item"
invoices (the invoice type is "O"), and "on account" '
invoices (invoice type is "A"). We're
only interested in the "O" (open item) invoices.
So what we want to do is to filter out the "A" (on account)
invoices.
This is a fairly typical case in which you can use an "input"
Awk script to "select" records:
function ADB_Main()
{ if (Inv_Type == "O") ADB_WriteFnc();
}
Next, we'll define an input Awk script for the
customer file.
This script will perform two important operations.
First, it will fill in the state sales tax multiplier.
For customers who don't have a valid state code, the
tax multiplier field will be equal to Sales_Tax_By_State_BadVal.
We'll write those customers out to the file CustBad.xx,
using ADB's system command. This command lets
us do anything that we could do from the DOS command line.
What we do, in particular, is to write the customer record
to that file.
Now how ADB_BldOutLineFnc is called, to build the
proper (fixed-length) format for customer records.
Since we know for sure that the DOS environmental variable
ADBPROJ is available, we retrieve it's value. That
in turn becomes the file extension.
function ADB_Main( Cmd)
{ Cust_TxMul__ = Get_Sales_Tax(Cust_St);
if (Cust_TxMul__ == Sales_Tax_By_State_BadVal)
{Cmd = sprintf("Echo %s>>CustBad.%s",
ADB_BldOutLineFnc(), ENVIRON["ADBPROJ"]);
system(Cmd);}
ADB_WriteFnc();
}
There's a fair amount going on
here--within just
one line of code--so let's examine it more closely.
ADB_BldOutLineFnc is going to return the fixed-length
format line for a given customer. In this example,
the customer with an unrecognized state code is "222", and the
customer record looks like this (in fixed-length format):
222IN$ 300.00 -0.0100
Note that the sales tax multiplier is precisely the negative
value assigned to customers with unrecognized state codes, in the
function Get_Sales_Tax.
The array access ENVIRON["ADBPROJ"] is just going to return
the value of the DOS environmental variable called ADBPROJ. Of
course, this is the project file suffix, xx.
The sprintf statement will return the following
Echo command (assigned to the local variable Cmd):
@Echo 222IN$ 300.00 -0.0100>> CustBad.xx
The system function will execute this as
if it was run from the DOS command line. The result is
that customers will be writen to CustBad.xx, if they
have bad state codes.
Let's not forget that we still need to call ADB_WriteFnc,
in order to make sure that all customers are brought into
the "join" (AKA the "matching") between customers and invoices.
This is because we still need to identify invoices for customers
who have bad state codes. These invoices will have to
be written out to the file InvBad.xx.
We're finally ready for the "whole enchilada."
This is the massive Awk script that we're going to use for the
M&T output file, i.e. the file that's outputted from the
matching of customer and invoice records. It's all of 35
lines long (not counting blank lines):
function ADB_BOJ()
{ G_Tot_AR = 0;
G_LastCust_No = "NONE";
if ("SVC_MULT" in ENVIRON)
SVC_MULT = ENVIRON["SVC_MULT"];
else ADB_ErrorFnc("DOS Env. Var: \"SVC_MULT\" undefined!");}
function ADB_EOJ( Cmd)
{ Wrt_Cust_If_OK();
Cmd = sprintf("Echo %s>TotAR.%s\n",
Put_Curr(G_Tot_AR), ENVIRON["ADBPROJ"]);
system(Cmd);}
function ADB_Main()
{
if (G_LastCust_No == Cust_Num)
{if (G_LastCust_OKFlag == 0) Wrt_InvBad();
else Add_Inv();
return;}
Wrt_Cust_If_OK();
G_LastCust_No = Cust_Num;
if (Cust_TxMul__ > 0) # Valid cust sales tax mult?
{G_LastCust_OKFlag = 1;
G_LastCust_Bal = Get_Curr(Cust_Bal___) * SVC_MULT;
Add_Inv();}
else {G_LastCust_OKFlag = 0; Wrt_InvBad();}}
function Wrt_InvBad() {printf("0%s\n", ADB_BldOutLineFnc());}
function Wrt_Cust_If_OK()
{ if ((G_LastCust_OKFlag == 1) && (NR != 1))
{G_Tot_AR += G_LastCust_Bal;
printf("1%s\n", LastCust_OutLine);}}
function Add_Inv( Amt)
{ Amt = Get_Curr(Inv_Amt___);
G_LastCust_Bal += Amt*Cust_TxMul__;
Cust_Bal___ = Put_Curr(G_LastCust_Bal);
LastCust_OutLine= ADB_BldOutLineFnc();}
ADB_BOJ initializes the G_Tot_AR global, which
will eventually be written out (the total accounts recievable
from open customers with open item invoices). Note
also that it checks for the DOS environmental variable called
SVC_MULT. If that variable isn't present,
it will call ADB_ErrorFnc, to stop the processing. ADB
will then report an error (signalled by the Awk script). This
variable, SVC_MULT, is our service charge multiplier. As
you may recall, it comes from a global table in the DBMS that
the users can modifuy. Later, we'll see how it
"travels" from the file SvcMult.xx into the DOS variable
SVC_MULT.
ADB_EOJ actually writes the total accounts receivable
variable G_Tot_AR to the file TotAR.xx (and it does
so in with DBMS's own currency format).
The variable LastCust_OutLine serves as a kind of
"record structure holder" the previous customer. As
you can see, ADB_BldOutLineFnc is used in Add_Inv
to store the entire customer/invoice join record. This
is an excellent example of a technique that you can use to
augment a record with accumulated totals in a
one-step process.
There are two other output files (besides the
totals file TotAR.xx.)
Wrt_BadInv outputs records for customers who lack a
valid state code. These records are in the
Cust_Inv_Fil ("joined") format, but they're prefixed with
a "0".
Wrt_Cust_If_OK writes out join records as soon as
there are no more invoices for a customer, but only for customers
with valid state codes. These records are also in
Cust_Inv_Fil ("joined") format, but they're prefixed with
a "1"."
The utilitity FileMux will be used to split the
output file into its two parts. &nbps;We'll need one
step of ADB to "unjoin" each of the parts. Although this
seems like a minor annoyance, the required code consists of
just 2 ADB definitions and one execution of ADB.s
Return
to local table of contents
Return
to global table of contents
Frames mode, or
No frames