Ejemplos Compilación de paramétricos

Inicio  Anterior  Siguiente

Base de datos ejemplo: base.dll

Archivos para distribución de la base de datos:

Para distribuir la base datos que se construyera con este ejemplo, se deberían proporcionar los siguientes archivos:

base.dll DLL que contiene tanto las descripciones paramétricas y como el interfaz estándar con aplicaciones (API).

base.bc3 Archivo ASCII de la base de datos en formato FIEBDC-3/98. En el ejemplo, la base incluye en esta DLL el paramétrico global de la base, así como las descripciones paramétricas de los conceptos “ABPH.1$”, “SBRG.1$” y “EADR.3$”, por lo que al menos debe contar con los registros

~P| | | BASE.DLL |

~P| ABPH.1$ | |

~P| SBRG.1$ | |

~P| EADR.3$ | |

Archivos necesarios para la construcción de la base de datos:

Este ejemplo está preparado para compilarse con Microsoft Visual C++ versión 2.2 o posterior como DLL de 32 bits. Sin apenas modificaciones, sería posible compilarlo como DLL de 16 bits o utilizar el compilador Borland C++.

Para construir la DLL, son necesarios los siguientes archivos:

fiebdc.h Archivo que define el formato, con el contenido ya especificado.

base.h Definición de variables y defines útiles para la definición de las descripciones paramétricas.

interfaz.cpp Implementación de las funciones del API.

aplicat.cpp Implementación de las funciones de la descripción paramétrica.

base.cpp Implementación de las descripciones paramétricas de la base de datos en formato C++. Es la única parte que escribirían los redactores de las bases de datos. En el ejemplo se incluyen dos descompuestos y un elemental. En el elemental se ha utilizado la posibilidad que posee el formato de que el código del derivado paramétrico no refleje directamente el valor de sus parámetros. Se ha utilizado una sintaxis similar a la descripción paramétrica del formato FIEBDC-3/95, para facilitar así el intercambio entre ambos formatos.

base.def Definición de las funciones de exportación del API.

Archivo ‘base.h’

#define BASE

#include "Fiebdc.h"

#define PAR     par.parametro

#define PRE     par.precio

#define DES     par.descompuesto

#define RES     par.resumen

#define TEX     par.texto

#define PLI     par.pliego

#define ROT     par.lee_rotulo

#define ERR     par.error

#define COD     par.codigo

#define SIN     par.sinonimo

#define CLA     par.claves

#define COM     par.comentario

#define INI(Op) par.inicializa(Op)

#define ROTA    ROT(0)

#define ROTB    ROT(1)

#define ROTC    ROT(2)

#define ROTD    ROT(3)

// Parámetros de cada concepto

#define A       par.lee_opcion(0)

#define B       par.lee_opcion(1)

#define C       par.lee_opcion(2)

#define D       par.lee_opcion(3)

// Parámetros del paremétrico Global

#define O       Cglobal->lee_opcion(0)

#define P       Cglobal->lee_opcion(1)

#define Q       Cglobal->lee_opcion(2)

#define R       Cglobal->lee_opcion(3)

// Valores de status

#define ST_VACIO     0

#define ST_FAMILIA   1

#define ST_DERIVADO  2

// Valores de operación

#define BORRA        0

#define LEE          1

#define CALCULA      2

#define BUSCA        3

#define VALIDA       4

// Valores BOOL de devolución

#define CORRECTO     0

#define ERRONEO      -1

#define MAX_PARAM    12       // Máximo número de parámetros

#define MAX_TXT      30000    // Longitud máxima de los textos

class Cfiebdc;

typedef short (*PRECIO)(Cfiebdc &, short operacion);

extern Cfiebdc  *Cglobal;                            // Paramétrico Global

extern PRECIO   precios[];                           // Lista de precios (conceptos) de la base

extern short    Global (Cfiebdc &, short operacion); // Función del paramétrico Global

class Cfiebdc {

private:

    long    parnum;               // Nº de parámetros

    long    opcnum[MAX_PARAM];    // Nº de opciones por parámetro

    char    *parrot[MAX_PARAM];   // Texto de los rótulos de cada parámetro

    char    **opcrot[MAX_PARAM];  // Texto de las opciones de cada parámetro

    long    opc[MAX_PARAM];       // Valores de cada parámetro

    char    *err;                 // Texto de error

    double  pre;                  // Precio unitario (precio simple)

    long    desnum;               // Nº de descompuestos

    char    **descod;             // Códigos de cada concepto de la descomposición

    double  *desren;              // Rendimiento de cada concepto de la descomposición

    char    *res, *tex, *pli;     // Texto resumido, Completo y Pliego

    char    *cla, *com;           // Claves y comentario

    char    *codfam;              // Código del concepto paramétrico (familia)

    char    *subcod;              // Parte variable del código automática

    char    *codder;              // Código completo del derivado

    BOOL    status;               // Estado: ST_VACIO, ST_FAMILIA, ST_DERIVADO

    long    coderr;               // Código de error

    long    sinnum;               // Nº de sinónimos

    char    **codsin[2];          // Textos [0] subcódigos automáticos [1] sinónimos

public:

    PRECIO  funcion;                                      // Puntero a la función del precio

    BOOL    parametro       (char *Rot, ...);             // Crea un parámetro

    BOOL    precio          (double Pre);                 // Fija el precio unitario

    BOOL    descompuesto    (double Ren, char *cod, ...); // Crea un elemento de la descomposición

    BOOL    resumen         (char *Res, ...);             // Fija el texto resumido

    BOOL    texto           (char *Tex, ...);             // Fija el texto de descripción

    BOOL    pliego          (char *Pli, ...);             // Fija el texto del pliego

    BOOL    comentario      (char *Com, ...);             // Fija el texto del comentario

    BOOL    claves          (char *Cla, ...);             // Fija el texto de las claves

    BOOL    error           (char *Err, ...);             // Fija el texto de error

    BOOL    codigo          (char *Cod, ...);             // Fija el código (familia o el derivado)

    void    estado          (BOOL Status) {status  = Status; };

    void    cod_error       (BOOL CodErr) {coderr |= CodErr; };

    BOOL    subcodigo       (void);                       // Calcula el subcódigo

    BOOL    opciones        (long *Opc);                  // Fija los valores de los parámetros

    BOOL    opciones_glo    (long ParGNum, long *OpcG);   // Fija los valores de los parámetros globales

    BOOL    sinonimo        (char *Subcod, char *Codsin); // Fija el sinónimo se Subcod

    long    lee_num_par     (void) { return parnum; };

    long    lee_num_des     (void) { return desnum; };

    long    lee_num_opc     (long id_par) { return opcnum[id_par];};

    char    *lee_rot_par    (long id_par);

    char    *lee_rot_opc    (long id_par, long id_opc);

    char    *lee_cod_des    (long id_des);

    double  lee_ren_des     (long id_des);

    double  lee_precio      (void) { return pre; };

    char    *lee_codigo     (void);

    char    *lee_resumen    (void);

    char    *lee_texto      (void);

    char    *lee_pliego     (void);

    char    *lee_claves     (void);

    char    *lee_comentario (void);

    char    *lee_error      (void);

    long    lee_opcion      (long Par);  // Devuelve la opción fijada en el parámetro Par

    char    *lee_rotulo     (long Par);  // Devuelve el rótulo de la opción fijada en el parámetro Par

    BOOL    lee_opciones    (char *Cod, long *Opc);     // Devuelve las opciones de un código

    BOOL    lee_estado      (void) { return status; };

    BOOL    lee_cod_error   (void) { return coderr; };

    int     inicializa      (short operacion);

    Cfiebdc ();

    ~Cfiebdc ();

};

Archivo ‘inferfaz.cpp’

#define STRICT

#include <windows.h>

#include <string.h>

#include "Base.h"

Cfiebdc *Cglobal;

/////////////////////////////////////////////////////////////////////////////

// FUNCIONES GENERALES Y DE INICIALIZACIÓN

BOOL APIENTRY

DllMain (    // Específico de Microsoft. Borland utiliza ‘DllEntryPoint’

HANDLE   hModule,

DWORD    tipo_llamada,

LPVOID   lpReserved )

{

    switch (tipo_llamada) {

    case DLL_PROCESS_ATTACH:

    case DLL_THREAD_ATTACH:

        // Inicialización

        Cglobal = new Cfiebdc;

        Global (*Cglobal, LEE);

        Cglobal->funcion = &Global;

        break;

    case DLL_THREAD_DETACH:

    case DLL_PROCESS_DETACH:

        // Liberación

        Cglobal->inicializa (BORRA);

        Cglobal->Cfiebdc::~Cfiebdc();

    }

    return TRUE;

}

LONG EXPORTA

BdcCodificacion (VOID)

{

    return 1; // La codificación es indipendiente de los valores de los parámetros

}

/////////////////////////////////////////////////////////////////////////////

// FUNCIONES REFERENTES AL PARAMÉTRICO GLOBAL

// Obtención de sus parámetros

LONG EXPORTA

BdcGloParNumero (VOID)

{

    return BdcParNumero (Cglobal);

}

LONG EXPORTA

BdcGloOpcNumero (

LONG    par )

{

    return BdcOpcNumero (Cglobal, par);

}

LPCSTR EXPORTA

BdcGloParRotulo (

LONG    par )

{

    return BdcParRotulo (Cglobal, par);

}

LPCSTR EXPORTA

BdcGloOpcRotulo (

LONG    par,

LONG    opc )

{

    return BdcOpcRotulo (Cglobal, par, opc);

}

BOOL EXPORTA

BdcGloCalcula (

LPLONG    opcl)

{

    return BdcCalcula (Cglobal, opcl);

}

BOOL EXPORTA

BdcGloError (

LPCSTR    *err)

{

    return BdcError (Cglobal, err);

}

////////////////////////////////////////////////////////////////////////////

//    FUNCIONES REFERENTES AL RESTO DE PARAMÉTRICOS

// Lectura de un concepto paramétrico

HANDLE EXPORTA

BdcLee (

LPCSTR cod) {

    int i;

    Cfiebdc *Cpar = new Cfiebdc();

    for (i=0;;i++) {

        Cpar->inicializa(BORRA);

        if (!((precios [i])(*Cpar, BUSCA)) )

            break;

        if (strcmp (Cpar->lee_codigo(), cod) == 0) {

            (precios [i])(*Cpar, LEE);

            Cpar->funcion = precios[i];

            return (HANDLE)Cpar;

        }

    }

    BdcCierra ( (HANDLE)Cpar );

    return (HANDLE) 0; // El precio no existe

}

// Lectura de un concepto paramétrico a partir del código del derivado paramétrico

HANDLE EXPORTA

BdcDecodifica (

LPCSTR    cod,

LPLONG    opcl )

{

    int   i,j;

    char  cod_fam[8];

    if (strlen(cod)<7) return (HANDLE)0;

    strncpy (cod_fam, cod, 6);

    cod_fam[6]='$';

    cod_fam[7]='\0';

    for (i=0; i<7; i++)

        if (cod_fam[i]<=' ') cod_fam[i]='_';

    Cfiebdc *Cpar = new Cfiebdc();

    for (i=0;;i++) {

        Cpar->inicializa(BORRA);

        if (!((precios [i])(*Cpar, BUSCA)) )

            break;

        if (strcmp (Cpar->lee_codigo(), cod_fam) == 0) {

            //Se encontró el paramétrico

            (precios [i])(*Cpar, LEE);

            Cpar->funcion = precios[i];

            j=Cpar->lee_num_par();

            if (!Cpar->lee_opciones((char *)cod+6, opcl)) {

                break;

            }

            return (HANDLE)Cpar;

        }

    }

    BdcCierra ( (HANDLE)Cpar );

    return (HANDLE) 0; // El precio no existe

}

// Obtención de sus parámetros

LONG EXPORTA

BdcParNumero (

HANDLE    h )

{

    Cfiebdc    *Cpar;

    if (!h)    return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    } else

        return Cpar->lee_num_par();

}

LONG EXPORTA

BdcOpcNumero (

HANDLE  h,

LONG    par)

{

    Cfiebdc    *Cpar;

    if (!h)    return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    } else

        return Cpar->lee_num_opc (par);

}

LPCSTR EXPORTA

BdcParRotulo (

HANDLE  h,

LONG    par)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    } else

        return (LPCSTR)Cpar->lee_rot_par(par);

}

LPCSTR EXPORTA

BdcOpcRotulo (

HANDLE  h,

LONG    par,

LONG    opc)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    } else

        return (LPCSTR)Cpar->lee_rot_opc (par, opc);

}

// Asignación de opciones de los parámetros y comprobación de su validez

BOOL EXPORTA

BdcValida (

HANDLE    h,

LPLONG    opcl )

{

    Cfiebdc *Cpar;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    }

    if (!Cpar->opciones (opcl)) return FALSE;

    return ((Cpar->funcion) (*Cpar, VALIDA)) ? CORRECTO : ERRONEO;

}

// Asignación de opciones de los parámetros y cálculo del derivado

BOOL EXPORTA

BdcCalcula (

HANDLE    h,

LPLONG    opcl )

{

    Cfiebdc *Cpar;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    }

    if (!Cpar->opciones (opcl)) return FALSE;

    return ((Cpar->funcion) (*Cpar, CALCULA)) ? CORRECTO : ERRONEO;

}

// Liberación de memoria

BOOL EXPORTA

BdcCierra (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    Cpar->inicializa (BORRA);

    Cpar->Cfiebdc::~Cfiebdc();

    return CORRECTO;

}

// Obtención del derivado paramétrico

LONG EXPORTA

BdcDesNumero (

HANDLE    h )

{

    Cfiebdc *Cpar;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return ERRONEO;

    }

    return Cpar->lee_num_des();

}

LPCSTR EXPORTA

BdcDesCodigo (

HANDLE  h,

LONG    des )

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_cod_des (des);

}

BOOL EXPORTA

BdcRendimiento (

HANDLE      h,

LONG        des,

double FAR  *ren)

{

    Cfiebdc    *Cpar;

    *ren = 0.0;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return ERRONEO;

    }

    *ren = Cpar->lee_ren_des(des);

    return CORRECTO;

}

BOOL EXPORTA

BdcPrecio (

HANDLE      h,

double FAR  *pre)

{

    Cfiebdc *Cpar;

    *pre=0.0;

    if (!h) return ERRONEO;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return ERRONEO;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return ERRONEO;

    }

    *pre = Cpar->lee_precio();

    return CORRECTO;

}

LPCSTR EXPORTA

BdcCodigo (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_codigo();

}

LPCSTR EXPORTA

BdcResumen (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_resumen();

}

LPCSTR EXPORTA

BdcTexto (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_texto();

}

LPCSTR EXPORTA

BdcPliego (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_pliego();

}

LPCSTR EXPORTA

BdcComentario (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_comentario();

}

LPCSTR EXPORTA

BdcClaves (

HANDLE    h)

{

    Cfiebdc *Cpar;

    if (!h) return NULL;

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        return NULL;

    }

    if (Cpar->lee_estado() != ST_DERIVADO) {

        Cpar->cod_error (BDCERR_NO_CALCULADO);

        return NULL;

    }

    return (LPCSTR)Cpar->lee_claves();

}

BOOL EXPORTA

BdcError (

HANDLE    h,

LPCSTR    *err)

{

    Cfiebdc *Cpar;

    BOOL    ret;

    if (!h) { *err=""; return BDCERR_CONCEPTO_NULO; }

    else    Cpar = (Cfiebdc *)h;

    if (Cpar->lee_estado() == ST_VACIO) {

        Cpar->cod_error (BDCERR_NO_LEIDO);

        *err = "";

        return Cpar->lee_cod_error();

    }

    *err = (LPCSTR)Cpar->lee_error();

    ret = Cpar->lee_cod_error();

    Cpar->cod_error (BDCERR_CORRECTO);

    return ret;

}

Archivo ‘aplicat.cpp’

#define STRICT

#include <windows.h>

#include <stdio.h>

#include <stdarg.h>

#include <string.h>

#include <math.h>

#include "Base.h"

Cfiebdc::Cfiebdc (void) {

    int    i,j;

    estado (ST_VACIO);

    coderr =BDCERR_CORRECTO;

    // parámetros y opciones por parámetro

    for (i=0; i<MAX_PARAM; i++) {

        parrot[i] = (char *)0;

        opcrot[i] = (char **)0;

    }

    parnum=0;

    pre=0.;

    // sinónimos

    for (j=0; j<2; j++) {

        codsin[j]= (char **)0;

    }

    sinnum=0;

    // descomposición

    desren = (double *)0;

    descod = (char **)0;

    desnum=0;

    // textos

    err    = (char *)0;

    res    = (char *)0;

    tex    = (char *)0;

    pli    = (char *)0;

    com    = (char *)0;

    cla    = (char *)0;

    codfam = (char *)0;

    subcod = (char *)0;

    codder = (char *)0;

}

Cfiebdc::~Cfiebdc (void) {

    estado (ST_VACIO);

}

Cfiebdc::inicializa (

short    operacion )

{

    int i,j;

    coderr = BDCERR_CORRECTO;

    if (operacion == BORRA) {

        estado (ST_VACIO);

        // parámetros y opciones por parámetro

        for (i=0; i<parnum; i++) {

            if (parrot[i]) {

                delete[] parrot[i];

                parrot[i] = (char *)0;

            }

            for (j=0; j< opcnum[i]; j++) {

                if (opcrot[i][j]) {

                    delete[] opcrot[i][j];

                    opcrot[i][j]= (char *)0;

                }

            }

            if (opcrot[i]) {

                delete[] opcrot[i];

                opcrot[i]= (char **)0;

            }

        }

        parnum=0;

        pre=0.;

        // sinónimos

        for (j=0; j<2; j++) {

            for (i=0; i<sinnum; i++) {

                if (codsin[j][i]) {

                    delete[] codsin[j][i];

                    codsin[j][i]= (char *)0;

                }

            }

            if (codsin[j]) {

                delete[] codsin[j];

                codsin[j]= (char **)0;

            }

        }

        sinnum=0;

        // descomposición

        if (desren) {

            delete[] desren;

            desren = (double *)0;

        }

        for (i=0; i<desnum; i++) {

            if (descod[i]) {

                delete[] descod[i];

                descod[i] = (char *)0;

            }

        }

        if (descod) {

            delete[] descod;

            descod = (char **)0;

        }

        desnum=0;

        // textos

        if (err)    { delete[] err;    err    = (char *)0; }

        if (res)    { delete[] res;    res    = (char *)0; }

        if (tex)    { delete[] tex;    tex    = (char *)0; }

        if (pli)    { delete[] pli;    pli    = (char *)0; }

        if (cla)    { delete[] cla;    cla    = (char *)0; }

        if (com)    { delete[] com;    com    = (char *)0; }

        if (codfam) { delete[] codfam; codfam = (char *)0; }

        if (subcod) { delete[] subcod; subcod = (char *)0; }

        if (codder) { delete[] codder; codder = (char *)0; }

    }

    else if (operacion == LEE) {

        estado (ST_FAMILIA);

    }

    else if (operacion==CALCULA) {

        estado (ST_DERIVADO);

        pre=0.;

        // descomposición

        if (desren) {

            delete[] desren;

            desren = (double *)0;

        }

        for (i=0; i<desnum; i++) {

            if (descod[i]) {

                delete[] descod[i];

                descod[i] = (char *)0;

            }

        }

        if (descod) {

            delete[] descod;

            descod = (char **)0;

        }

        desnum=0;

        if (err)    { delete[] err;     err     = (char *)0; }

        if (res)    { delete[] res;     res     = (char *)0; }

        if (tex)    { delete[] tex;     tex     = (char *)0; }

        if (pli)    { delete[] pli;     pli     = (char *)0; }

        if (cla)    { delete[] cla;     cla     = (char *)0; }

        if (codfam) { delete[] codfam;  codfam  = (char *)0; }

        if (subcod) { delete[] subcod;  subcod  = (char *)0; }

        if (codder) { delete[] codder;  codder  = (char *)0; }

    }

    return TRUE;

}

BOOL

Cfiebdc::parametro (

char    *rot, ... )

{

    int     i, len;

    long    Opcnum=0;

    char    *s;

    va_list marker;

    if (parnum>=MAX_PARAM) return FALSE;

    len = strlen(rot);

    parrot[parnum] = new char[len+1];

    strcpy (parrot[parnum], rot);

    va_start( marker, rot );

    do {

        s = va_arg( marker, char *);

        len = strlen (s);

        if (len==0) break;

        Opcnum++;

    } while ( s[0] != '\0' );

    va_start( marker, rot );

    opcrot[parnum] = new char* [Opcnum];

    for (i=0; i<Opcnum; i++) {

        s = va_arg( marker, char *);

        len = strlen (s);

        opcrot[parnum][i] = new char[len+1];

        strcpy (opcrot[parnum][i], s);

    }

    va_end( marker );

    opcnum[parnum]=Opcnum;

    parnum++;

    return TRUE;

}

BOOL

Cfiebdc::precio (

double    Pre )

{

    pre=Pre;

    return TRUE;

}

BOOL

Cfiebdc::descompuesto (

double  Ren,

char    *Cod,... )

{

    int     i, len;

    char    s[255], **Descod;

    va_list marker;

    double  *Desren;

    if (fabs(Ren)<0.0005) return FALSE;

    Desren = new double [desnum+1];

    memcpy (Desren, desren, desnum*sizeof(double));

    delete[] desren;

    desren = Desren;

    desren [desnum] = Ren;

    Descod = new char *[desnum+1];

    for (i=0; i<desnum; i++)

        Descod[i] = descod[i];

    delete[] descod;

    descod = Descod;

    va_start( marker, Cod );

    vsprintf (s,Cod,marker);

    len = strlen (s);

    descod[desnum] = new char[len+1];

    strcpy (descod[desnum], s);

    va_end( marker );

    desnum++;

    return TRUE;

}

BOOL

Cfiebdc::resumen (

char    *Res, ... )

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Res );

    vsprintf (s,Res,marker);

    len = strlen (s);

    res = new char[len+1];

    strcpy (res, s);

    delete[] (s);

    va_end( marker );

    return TRUE;

}

BOOL

Cfiebdc::texto (

char    *Tex, ...)

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Tex );

    vsprintf (s,Tex,marker);

    len = strlen (s);

    tex = new char[len+1];

    strcpy (tex, s);

    delete[] (s);

    va_end( marker );

    return TRUE;

}

BOOL

Cfiebdc::pliego (

char    *Pli, ...)

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Pli );

    vsprintf (s,Pli,marker);

    len = strlen (s);

    pli = new char[len+1];

    strcpy (pli, s);

    delete[] (s);

    va_end( marker );

    return TRUE;

}

BOOL

Cfiebdc::claves (

char    *Cla, ...)

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Cla );

    vsprintf (s,Cla,marker);

    len = strlen (s);

    pli = new char[len+1];

    strcpy (cla, s);

    delete[] (s);

    va_end( marker );

    return TRUE;

}

BOOL

Cfiebdc::comentario (

char    *Com, ...)

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Com );

    vsprintf (s,Com,marker);

    len = strlen (s);

    pli = new char[len+1];

    strcpy (com, s);

    delete[] (s);

    va_end( marker );

    return TRUE;

}

BOOL

Cfiebdc::error (

char    *Err, ...)

{

    char    *s = new char [MAX_TXT];

    int     len;

    va_list marker;

    va_start( marker, Err );

    vsprintf (s,Err,marker);

    len = strlen (s);

    err = new char[len+1];

    strcpy (err, s);

    delete[] (s);

    va_end( marker );

    cod_error (BDCERR_BASE_DATOS);

    return FALSE;

}

long

Cfiebdc::lee_opcion (

long    Par)

{

    if (Par>=parnum) {

        cod_error (BDCERR_PARAMETRO);

        return -1;

    }

    return opc[Par];

}

char

*Cfiebdc::lee_rotulo (

long    Par)

{

    if (Par>=parnum || opc[Par]>=opcnum[Par]) {

        cod_error (BDCERR_PARAMETRO);

        return NULL;

    }

    return opcrot[Par][opc[Par]];

}

BOOL

Cfiebdc::codigo (

char    *Cod, ...)

{

    char    *s = new char [MAX_TXT];

    int     i,len;

    va_list marker;

    va_start( marker, Cod );

    vsprintf (s,Cod,marker);

    len = strlen (s);

    for (i=0; i<len; i++)

        if (s[i] == '$') break;

    if (codfam) delete[] codfam;

    if (i<len) {

        codfam = new char[len+1];

        strcpy (codfam, s);

    } else {

        codfam = new char[len+2];

        sprintf (codfam, "%s%c", s, '$');

    }

    delete[] s;

    va_end( marker );

    if (status==ST_DERIVADO)

        return subcodigo();

    return TRUE;

}

BOOL

Cfiebdc::opciones (

long    *Opc )

{

    int     i;

    BOOL    ret=TRUE;

    for (i=0; i<parnum; i++) {

        if (Opc[i]<0 || Opc[i]>=opcnum[i]) {

            cod_error (BDCERR_OPCION);

            opc[i] = 0;

            ret=FALSE;

        } else {

            opc[i] = Opc[i];

        }

    }

    return ret;

}

BOOL

Cfiebdc::sinonimo (

char    *Subcod,

char    *Codsin )

{

    char    **Sin[2];

    int     i,j,len1,len2;

    len1 = strlen (Subcod);

    len2 = strlen (Codsin);

    if (!len1 || !len2) return FALSE;

    for (i=0; i<2; i++) {

        Sin[i] = new char *[sinnum+1];

        for (j=0; j<sinnum; j++) {

            Sin[i][j] = codsin[i][j];

        }

        if (codsin[i]) delete[] codsin[i];

    }

    Sin[0][sinnum] = new char [len1+1];

    Sin[1][sinnum] = new char [len2+1];

    strcpy (Sin[0][sinnum], Subcod);

    strcpy (Sin[1][sinnum], Codsin);

    codsin[0]=Sin[0];

    codsin[1]=Sin[1];

    sinnum++;

    return TRUE;

}

char

*Cfiebdc::lee_rot_par (

long    id_par)

{

    if (id_par >= parnum || !parrot[id_par]) {

        cod_error (BDCERR_PARAMETRO);

        return "";

    }

    else

        return parrot[id_par];

}

char

*Cfiebdc::lee_rot_opc

(long    id_par,

long    id_opc) {

    if (id_par >= parnum) {

        cod_error (BDCERR_PARAMETRO);

        return NULL;

    } else if (id_opc >= opcnum[id_par] || !opcrot[id_par] || !opcrot[id_par][id_opc]) {

        cod_error (BDCERR_OPCION);

        return NULL;

    } else

        return opcrot[id_par][id_opc];

}

char

*Cfiebdc::lee_cod_des (

long    id_des )

{

    if (id_des >= desnum || !descod[id_des]) {

        cod_error (BDCERR_DESCOMPOSICION);

        return NULL;

    } else

        return descod[id_des];

}

double

Cfiebdc::lee_ren_des (

long    id_des )

{

    if (id_des >= desnum) {

        cod_error (BDCERR_DESCOMPOSICION);

        return -1.0;

    } else

        return desren[id_des];

}

char

*Cfiebdc::lee_codigo (void) {

    if (codder)

        return codder;

    else if (codfam)

        return codfam;

    else {

        cod_error (BDCERR_SIN_CODIGO);

        return NULL;

    }

}

char

*Cfiebdc::lee_resumen (void) {

    if (res)    return res;

    else        return "";

}

char

*Cfiebdc::lee_texto (void) {

    if (tex)    return tex;

    else        return "";

}

char

*Cfiebdc::lee_pliego (void) {

    if (pli)    return pli;

    else        return "";

}

char

*Cfiebdc::lee_claves (void) {

    if (pli)    return cla;

    else        return "";

}

char

*Cfiebdc::lee_comentario (void) {

    if (pli)    return com;

    else        return "";

}

char

*Cfiebdc::lee_error (void) {

    if (err)    return err;

    else        return "";

}

BOOL

Cfiebdc::subcodigo (void) {

    int     i, az='z'-'a', AZ='Z'-'A';

    BOOL    ret=TRUE;

    char    *s = new char [MAX_TXT];

    // Obtención del subcódigo automático

    subcod = new char [parnum+1];

    for (i=0; i<parnum; i++) {

        if (opc[i]>=0 && opc[i]<=0+az)

            subcod[i]=opc[i]+'a';

        else if (opc[i]>0+az && opc[i]<=0+az+AZ)

            subcod[i]=opc[i]-az+'A';

        else if (opc[i]>0+az+AZ && opc[i]<=9+az+AZ)

            subcod[i]=opc[i]-az-AZ;

        else {

            subcod[i]='_';

            cod_error (BDCERR_MAX_OPCIONES);

            ret = FALSE;

        }

    }

    subcod[i]='\0';

    // Comprobar lista de sinónimos

    for (i=0; i<sinnum; i++) {

        if (strcmp(subcod,codsin[0][i]) == 0) {

            delete [] subcod;

            subcod = new char [strlen (codsin[1][i])+1];

            strcpy (subcod, codsin[1][i]);

        }

    }

    // Rellenar codfam y codder

    strcpy (s, codfam);

    for (i=0; i<(int)strlen(codfam); i++)

        if (codfam[i]=='$') break;

    strcpy (s+i, subcod);

    codder = new char [strlen(s)+1];

    strcpy (codder, s);

    return ret;

}

BOOL

Cfiebdc::lee_opciones (

char    *Cod,    // parte variable del código

long    *Opc )    // opciones a devolver

{

    int     i, len, az='z'-'a', AZ='Z'-'A';

    char    *s;

    BOOL    ret=TRUE;

    for (i=0; i<sinnum; i++) {

        if (strcmp(Cod, codsin[1][i])==0) {

            len = strlen (codsin[0][i]);

            s = codsin[0][i];

            break;

        }

    }

    if (i==sinnum) {

        s = Cod;

        len = strlen (s);

    }

    for (i=0; i<len; i++) {

        if (s[i] >= 'a' && s[i] <= 'z')

            Opc[i] = s[i]-'a';

        else if (s[i] >= 'A' && s[i] <= 'Z')

            Opc[i] = s[i]-'A' + az;

        else if (s[i] >= '0' && s[i] <= '9')

            Opc[i] = s[i]-'0' + az + AZ;

        else {

            // excedida capacidad

            Opc[i] = az + AZ + 11;

            cod_error (BDCERR_MAX_OPCIONES);

            ret = FALSE;

        }

    }

    return ret;

}

Archivo ‘base.cpp’

#define STRICT

#include <windows.h>

#include <stdio.h>

#include <stdarg.h>

#include <math.h>

#include "Base.h"

//////////////////////////////////////////////////////////////////////////////

//    Concepto Global

//

short Global (Cfiebdc &par, short operacion) {

    INI (operacion);

    switch (operacion) {

    case LEE:

        PAR ("ÁMBITO","España","Madrid","Barcelona","Valencia","Bilbao","Sevilla","");

        return TRUE;

    }

    return TRUE;

}

//////////////////////////////////////////////////////////////////////////////

//    Conceptos

//

short fABPH_1 (Cfiebdc &par, short operacion) {

    INI (operacion);

    COD ("ABPH.1$");

    switch (operacion) {

    case LEE:

        PAR ("RESISTENCIA", "H-50", "H-100", "H-125", "H-150", "H-175", "");

        PAR ("CONSISTENCIA", "plástica", "blanda", "");

        PAR ("Tmax", "18", "38", "78", "");

        return TRUE;

    case CALCULA:

    case VALIDA:

        // plástica              H50     H100     H125     H150     H175

        double T[2][3][5] ={    .180,    .255,    .290,    .330,    .365,    //18

                                .160,    .225,    .260,    .290,    ..325,    //38

                                .140,    .200,    .225,    .255,    ..285,    //78

        // blanda

                                .210,    .290,    .330,    .375,    ..000,

                                .185,    .260,    .300,    .335,    ..375,

                                .165,    .235,    .265,    .300,    ..335 };

        if (!T[B][C][A]) return ERR ("Combinación no permitida");

        if (operacion == VALIDA) return TRUE;

        double U[2][3]= {       .180,    .160,    .140,

                                .205,    .185,    .165 };

        double V[2][3][5]= {    .695,    .675,    .665,    .650,    .640,

                                .720,    .700,    .690,    .680,    ..670,

                                .740,    .725,    .720,    .710,    ..700,

                                .665,    .640,    .630,    .615,    ..0,

                                .690,    .670,    .665,    .645,    ..635,

                                .715,    .695,    .685,    .775,    ..665 };

        DES (T[B][C][A],   "SBAC.5ccaa");       // Cemento

        DES (U[B][C],      "SBAA.1a");          // Agua

        DES (V[B][C][A],   "SBRA.5ab");         // Arena

        DES (V[B][C][A]*2, "SBRG.1%c", 'a'+C);  // Grava

        DES (1,            "MAMA19a");          // Hormigonera

        DES (2,            "MOOC13a");          // Peón ordinario

        RES ("%s C/%s Tmax=%s mm", ROTA, ROTB, ROTC);

        int G[5]= { 50, 100, 125, 150, 175 };

        TEX (   "Hormigón %s, resistencia característica %d Kg/cm2, "

                "consistencia %s, cemento tipo II-Z/35-A, arena silícea "

                "(0/6) y grava silícea rodada, tamaño máximo %s mm, "

                "confeccionado en obra con hormigonera de 300 l de capacidad. "

                "Según RC-93 y EH-91.", ROTA, G[A], ROTB, ROTC );

        return TRUE;

    }

    return TRUE;

}

short fSBRG_1 (Cfiebdc &par, short operacion) {

    INI (operacion);

    COD ("SBRG.1$");

    switch (operacion) {

    case LEE:

        PAR ("Tmax", "18", "38", "78", "");

        // Sinónimos

        SIN ("a", "_18");

        SIN ("b", "_38");

        SIN ("c", "_78");

        return TRUE;

    case CALCULA:

            // ÁMBITO (Primer parámetro global. Parámetro 'O'

            //          España    Madrid  Barcelona    Valencia    Bilbao    Sevilla

        double I [] = { 123.5,    135.1,    130.0,      129.8,     127.8,    125.9 };

        PRE (I[O]+0.25*A);

        RES ("Grava de Tmáx. %s", ROTA);

        return TRUE;

    }

    return TRUE;

}

short fEADR_3 (Cfiebdc &par, short operacion) {

    INI (operacion);

    COD ("EADR.3$");

    switch (operacion) {

    case LEE:

        PAR ("MATERIAL","yeso","cemento","cal","cal y cemento","");

        PAR ("PARAMENTOS","verticales","horizontales","");

    case CALCULA:

        char *cF;

                // $A    yeso     cemento     cal   cal y cemento    $B

        double

        pdT[2][4]= {{    0.350,    0.500,    0.400,    0.450},     // vertical

                    {    0.550,    0.800,    0.600,    0.650}};    // horizontal

        DES (pdT[B][A], "MOOA.1d");  // peón ordinario

        DES (0.02, "%%");            // maux

        if (A==0)  cF = "guarnecido";

        else       cF = "enfoscado";

        char *pcG[4]= {"yeso", "cto", "cal", "cal y cto"};

        char *pcH[2]= {"vert", "hrz"};

        RES ("Picado %s param %s",pcG[A],pcH[B]);

        TEX ("Picado de %s de %s en paramentos %s, retirada de escombros y carga, "

             "sin transporte a vertedero.", cF, ROTA, ROTB);

    }

    return TRUE;

}

short fFIN (Cfiebdc &par, short operacion) {

    return FALSE;

}

//////////////////////////////////////////////////////////////////////////////

//    Lista de Conceptos

//

PRECIO precios[] = {fABPH_1, fSBRG_1, fEADR_3, fFIN};

Archivo ‘dase.def’

LIBRARY     BASE

DESCRIPTION 'Formato Fiebdc-3/98. Ejemplo de Definiciones paramétricas'

CODE        PRELOAD MOVEABLE DISCARDABLE

DATA        PRELOAD SINGLE

HEAPSIZE    1024

EXPORTS

    BdcCodificacion

    BdcGloParNumero

    BdcGloOpcNumero

    BdcGloParRotulo

    BdcGloOpcRotulo

    BdcGloCalcula

    BdcGloError

    BdcLee

    BdcDecodifica

    BdcParNumero

    BdcOpcNumero

    BdcParRotulo

    BdcOpcRotulo

    BdcComentario

    BdcValida

    BdcCalcula

    BdcCierra

    BdcDesNumero

    BdcDesCodigo

    BdcRendimiento

    BdcPrecio

    BdcCodigo

    BdcResumen

    BdcTexto

    BdcPliego

    BdcClaves

    BdcError

Aplicación ejemplo: programa.exe

Esta sencilla aplicación, lee los conceptos que se incluyen en el propio fuente de la base BASE.DLL (en una aplicación real, los conceptos se definen en los registros ~P de base.bc3), y escribe en el archivo 'SALIDA.TXT' los rótulos de todos sus parámetros así como todos los datos de todas sus combinaciones paramétricas.

Archivos necesarios para la construcción del programa ejemplo:

Este ejemplo está preparado para compilarse con Microsoft Visual C++ versión 2.2 o posterior como aplicación Windows 95 de 32 bits en modo consola. Sin apenas modificaciones, sería posible compilarlo como aplicación de 16 bits o utilizar el compilador Borland C++.

Para construir la aplicación, son necesarios los siguientes archivos:

fiebdc.hArchivo que define el formato.

programa.hDeclaración de variables y funciones.

program0.cFunciones auxiliares de apertura y cierre de la base de datos y tratamiento de los mensajes de error.

programa.cPrograma ejemplo.

Archivo ‘programa.h’

#include "Fiebdc.h"

#define CORRECTO    0

#define ERRONEO    -1

BDCGLOPARNUMERO    pGloParNumero;

BDCGLOOPCNUMERO    pGloOpcNumero;

BDCGLOPARROTULO    pGloParRotulo;

BDCGLOOPCROTULO    pGloOpcRotulo;

BDCGLOCALCULA      pGloCalcula;

BDCGLOERROR        pGloError;

BDCLEE             pLee;

BDCDECODIFICA      pDecodifica;

BDCPARNUMERO       pParNumero;

BDCOPCNUMERO       pOpcNumero;

BDCPARROTULO       pParRotulo;

BDCOPCROTULO       pOpcRotulo;

BDCVALIDA          pValida;

BDCCALCULA         pCalcula;

BDCCIERRA          pCierra;

BDCDESNUMERO       pDesNumero;

BDCDESCODIGO       pDesCodigo;

BDCRENDIMIENTO     pRendimiento;

BDCPRECIO          pPrecio;

BDCCODIGO          pCodigo;

BDCRESUMEN         pResumen;

BDCTEXTO           pTexto;

BDCPLIEGO          pPliego;

BDCCOMENTARIO      pComentario;

BDCCLAVES          pClaves;

BDCERROR           pError;

BOOL AbreDll (char *nDll, HINSTANCE *hDll, char **Err);

BOOL CierraDll (HMODULE hDll, char **Err);

BOOL ChequeaError (HANDLE Precio, FILE *f, BOOL EsGlobal);

Archivo ‘program0’

#define STRICT

#include <windows.h>

#include <stdio.h>

#include "programa.h"

BOOL

AbreDll (

char      *nDll,

HINSTANCE *hDll,

char      **Err )

{

    *hDll = LoadLibrary (nDll);

    if ( ! (*hDll) ) {

        *Err = "IMPOSIBLE ABRIR LA LIBRERIA DE LA BASE";

        return FALSE;

    }

    if( (pGloParNumero =    (BDCGLOPARNUMERO)   GetProcAddress (*hDll, "BdcGloParNumero")) &&

        (pGloOpcNumero =    (BDCGLOOPCNUMERO)   GetProcAddress (*hDll, "BdcGloOpcNumero")) &&

        (pGloParRotulo =    (BDCGLOPARROTULO)   GetProcAddress (*hDll, "BdcGloParRotulo")) &&

        (pGloOpcRotulo =    (BDCGLOOPCROTULO)   GetProcAddress (*hDll, "BdcGloOpcRotulo")) &&

        (pGloCalcula =      (BDCGLOCALCULA)     GetProcAddress (*hDll, "BdcGloCalcula")) &&

        (pGloError =        (BDCGLOERROR)       GetProcAddress (*hDll, "BdcGloError")) &&

        (pLee =             (BDCLEE)            GetProcAddress (*hDll, "BdcLee")) &&

        (pDecodifica =      (BDCDECODIFICA)     GetProcAddress (*hDll, "BdcDecodifica")) &&

        (pParNumero =       (BDCPARNUMERO)      GetProcAddress (*hDll, "BdcParNumero")) &&

        (pOpcNumero =       (BDCOPCNUMERO)      GetProcAddress (*hDll, "BdcOpcNumero")) &&

        (pParRotulo =       (BDCPARROTULO)      GetProcAddress (*hDll, "BdcParRotulo")) &&

        (pOpcRotulo =       (BDCOPCROTULO)      GetProcAddress (*hDll, "BdcOpcRotulo")) &&

        (pValida =          (BDCVALIDA)         GetProcAddress (*hDll, "BdcValida")) &&

        (pCalcula =         (BDCCALCULA)        GetProcAddress (*hDll, "BdcCalcula")) &&

        (pCierra =          (BDCCIERRA)         GetProcAddress (*hDll, "BdcCierra")) &&

        (pDesNumero =       (BDCDESNUMERO)      GetProcAddress (*hDll, "BdcDesNumero")) &&

        (pDesCodigo =       (BDCDESCODIGO)      GetProcAddress (*hDll, "BdcDesCodigo")) &&

        (pRendimiento =     (BDCRENDIMIENTO)    GetProcAddress (*hDll, "BdcRendimiento")) &&

        (pPrecio =          (BDCPRECIO)         GetProcAddress (*hDll, "BdcPrecio")) &&

        (pCodigo =          (BDCCODIGO)         GetProcAddress (*hDll, "BdcCodigo")) &&

        (pResumen =         (BDCRESUMEN)        GetProcAddress (*hDll, "BdcResumen")) &&

        (pTexto =           (BDCTEXTO)          GetProcAddress (*hDll, "BdcTexto")) &&

        (pPliego =          (BDCPLIEGO)         GetProcAddress (*hDll, "BdcPliego")) &&

        (pComentario =      (BDCCOMENTARIO)     GetProcAddress (*hDll, "BdcComentario")) &&

        (pClaves =          (BDCCLAVES)         GetProcAddress (*hDll, "BdcClaves")) &&

        (pError =           (BDCERROR)          GetProcAddress (*hDll, "BdcError")) ) {

        *Err = "";

        return TRUE;

    } else {

        *Err = "FUNCION INEXISTENTE EN LA LIBRERIA";

        return FALSE;

    }

}

BOOL

CierraDll (

HMODULE hDll,

char    **Err )

{

    if (hDll) {

        if ( !FreeLibrary (hDll) ) {

            *Err = "ERROR AL CERRAR LA LIBRERIA";

            return FALSE;

        } else {

            *Err = "";

            return TRUE;

        }

    } else {

        *Err = "NO HAY LIBRERIA QUE CERRAR";

        return FALSE;

    }

}

BOOL

ChequeaError (

HANDLE  Precio,

FILE    *f,

BOOL    EsGlobal )

{

    char    *MensajeError;

    BOOL    CodigoError;

    CodigoError= EsGlobal ? pGloError (&MensajeError) : pError (Precio, &MensajeError);

    if (CodigoError & BDCERR_CORRECTO)

        return TRUE;

    if (CodigoError & BDCERR_BASE_DATOS)

        fprintf (f,"ERROR: %s\n",MensajeError);

    if (CodigoError & BDCERR_PARAMETRO)

        fprintf (f,"ERROR: El parámetro no existe\n");

    if (CodigoError & BDCERR_OPCION)

        fprintf (f,"ERROR: La opción no existe\n");

    if (CodigoError & BDCERR_MAX_OPCIONES)

        fprintf (f,"ERROR: Se alcanzó el máximo número de opciones (62)\n");

    if (CodigoError & BDCERR_NO_LEIDO)

        fprintf (f,"ERROR: El concepto paramétrico no fue leído\n");

    if (CodigoError & BDCERR_NO_CALCULADO)

        fprintf (f,"ERROR: El derivado paramétrico no fue calculado\n");

    if (CodigoError & BDCERR_DESCOMPOSICION)

        fprintf (f,"ERROR: No existe un elemento de la descomposición\n");

    if (CodigoError & BDCERR_SIN_CODIGO)

        fprintf (f,"ERROR: El concepto no tiene código definido\n");

    if (CodigoError & BDCERR_SIN_MEMORIA)

        fprintf (f,"ERROR: Memoria insuficiente\n");

    if (CodigoError & BDCERR_CONCEPTO_NULO)

        fprintf (f,"ERROR: El concepto es erróneo\n");

    return FALSE;

}

Archivo ‘programa.c’

#define STRICT

#include <windows.h>

#include <stdio.h>

#include <conio.h>

#include "programa.h"

int main (void) {

    HANDLE      Precio=(HANDLE)0, PrecioTmp=(HANDLE)0;

    HINSTANCE   hLib=(HINSTANCE)0;

    FILE        *fSalida;

    char        *err, codigo[20];

    const char  *texto;

    char        *Precios [] = {"ABPH.1$", "SBRG.1$", "EADR.3$", "NoExiste"};

    int         nPrecios = 4;

    int         i,j,k;

    long        limite,nParGlobales=0,ListaOpcGlobales[20];

    long        nPar,nOpc[20],ListaOpc[20],ListaOpc2[20];

    double      numero;

    printf ("\nEJEMPLO DE PROGRAMA QUE ACCEDE A LA BASE \"BASE.DLL\"\n");

    printf ("LOS RESULTADOS SE ESCRIBEN EN EL ARCHIVO \"SALIDA.TXT\"\n");

    if ( !(fSalida = fopen ("SALIDA.TXT", "wt")) ) {

        printf ("\nERROR: Imposible crear el archivo de salida\n");

        printf ("\n\nPROGRAMA FINALIZADO\nPulse una tecla\n");

        getch();

        return FALSE;

    }

    fprintf (fSalida,"\nEJEMPLO DE PROGRAMA QUE ACCEDE A LA BASE \"BASE.DLL\"\n");

    if (!AbreDll("BASE.DLL", &hLib, &err)) {

        fprintf (fSalida,"\nERROR: %s\n", err);

        printf ("\n\nPROGRAMA FINALIZADO\nPulse una tecla\n");

        getch();

        return FALSE;

    }

    // Lectura del Paramétrico Global

    printf ("\nBUSCANDO EL PARAMETRICO GLOBAL...");

    if ( !(ChequeaError ((HANDLE)0, fSalida, TRUE)) ) {

        printf ("\nLEYENDO EL PARAMETRICO GLOBAL...");

        nParGlobales = pGloParNumero();

        if (nParGlobales==ERRONEO)

            ChequeaError ((HANDLE)0, fSalida, TRUE);

        fprintf (fSalida,"\nPrecio Global: Número de parámetros: %ld\n", nParGlobales);

        for (j=0; j<nParGlobales; j++) {

            ListaOpcGlobales[j]=0;

            if (!(texto=pGloParRotulo(j)))

                ChequeaError ((HANDLE)0, fSalida, TRUE);

            else

                fprintf (fSalida,"\nParámetro %d: Rótulo: %s\n", j+1, texto);

            limite=pGloOpcNumero(j);

            if (limite==ERRONEO)

                ChequeaError ((HANDLE)0, fSalida, TRUE);

            for (k=0; k<limite; k++) {

                if (!(texto=pGloOpcRotulo(j,k)))

                    ChequeaError ((HANDLE)0, fSalida, TRUE);

                else

                    fprintf (fSalida,"\tOpción %d: Rótulo: %s\n", k, texto);

            }

        }

        pGloCalcula (ListaOpcGlobales);

    }

    // Lectura de los precios

    for (i=0; i<nPrecios; i++) {

        printf ("\n\nBUSCANDO EL PRECIO \"%s\"...", Precios[i]);

        if ( (Precio = pLee (Precios[i])) == (HANDLE) 0 ) {

            fprintf (fSalida,"\nERROR: El precio \"%s\" no existe\n", Precios[i]);

            continue;

        }

        // Rótulos de Parámetros y Opciones

        printf ("\nLEYENDO EL PRECIO \"%s\"...", Precios[i]);

        nPar = pParNumero(Precio);

        if (nPar==ERRONEO)

            ChequeaError (Precio, fSalida, FALSE);

        else

            fprintf (fSalida,"\nPrecio \"%s\": Número de parámetros: %ld\n", Precios[i], nPar);

        for (j=0; j<nPar; j++) {

            if (!(texto=pParRotulo(Precio,j)))

                ChequeaError (Precio, fSalida, FALSE);

            else

                fprintf (fSalida,"\nParámetro %d: Rótulo: %s\n", j+1, texto);

            nOpc[j]=pOpcNumero(Precio,j);

            if (nOpc[j]==ERRONEO)

                ChequeaError (Precio, fSalida, FALSE);

            ListaOpc[j]=0;

            for (k=0; k<nOpc[j]; k++) {

                if (!(texto=pOpcRotulo(Precio,j,k)))

                    ChequeaError (Precio, fSalida, FALSE);

                else

                    fprintf (fSalida,"\tOpción %d: Rótulo: %s\n", k+1, texto);

            }

        }

        //Listado de todas las combinaciones paramétricas

        printf ("\nCALCULANDO EL PRECIO \"%s\"...", Precios[i]);

        do {

            if (pValida (Precio, ListaOpc)==ERRONEO) {

                fprintf (fSalida,"\n");

                ChequeaError (Precio, fSalida, FALSE);

                fprintf (fSalida,"(CODIGO : %s)\n", pCodigo(Precio));

                goto siguiente;

            }

            pCalcula (Precio, ListaOpc);

            if (!(texto=pCodigo(Precio))) {

                ChequeaError (Precio, fSalida, FALSE);

                sprintf (codigo,"");

            } else

                strcpy (codigo, texto);

            if ((PrecioTmp=pDecodifica (codigo, ListaOpc2)) == (HANDLE)0)

                ChequeaError (Precio, fSalida, FALSE);

            pCierra (PrecioTmp);

            fprintf (fSalida,"\nCODIGO: %s\n", codigo);

            fprintf (fSalida,"OPCIONES: ");

            for (j=0; j<nPar; j++)

                fprintf (fSalida,"%d ",ListaOpc2[j]);

            if (!(texto=pResumen(Precio)))

                ChequeaError (Precio, fSalida, FALSE);

            else

                fprintf (fSalida,"\nRESUMEN:%s\n", texto);

            if (!(texto=pTexto(Precio)))

                ChequeaError (Precio, fSalida, FALSE);

            else

                fprintf (fSalida,"TEXTO:%s\n", texto);

            if (!(texto=pPliego(Precio)))

                ChequeaError (Precio, fSalida, FALSE);

            else

                fprintf (fSalida,"PLIEGO:%s\n", texto);

            limite=pDesNumero(Precio);

            if (limite==ERRONEO)

                ChequeaError (Precio, fSalida, FALSE);

            else if (limite) {

                fprintf (fSalida,"DESCOMPOSICION:\n");

                for (j=0; j<limite; j++) {

                    if (!(texto=pDesCodigo(Precio,j)))

                        ChequeaError (Precio, fSalida, FALSE);

                    else if (pRendimiento(Precio,j,&numero)==ERRONEO)

                        ChequeaError (Precio, fSalida, FALSE);

                    else

                        fprintf (fSalida,"\t%2d %-10s \t%10.3lf\n", j+1, texto, numero);

                }

            } else {

                if (pPrecio(Precio, &numero)==ERRONEO)

                    ChequeaError (Precio, fSalida, FALSE);

                else

                    fprintf (fSalida,"PRECIO:%.2lf\n", numero);

            }

siguiente:

            for (j=nPar-1; j>=0; j--) {

                if (ListaOpc[j]<nOpc[j]-1) {

                    ListaOpc[j]++;

                    break;

                } else {

                    ListaOpc[j]=0;

                }

            }

            if (j<0) break;

        } while (TRUE);

        pCierra (Precio);

    }

    //Ejemplo de decodificar

    printf ("\n\nDECODIFICANDO EL PRECIO \"SBRG.1_38\"...");

    if ((Precio=pDecodifica("SBRG.1_38",ListaOpc2))==(HANDLE)0)

        ChequeaError (Precio, fSalida, FALSE);

    else {

        if (!(texto=pCodigo(Precio))) {

            ChequeaError (Precio, fSalida, FALSE);

            sprintf (codigo,"");

        } else

            strcpy (codigo, texto);

        nPar = pParNumero(Precio);

        if (nPar==ERRONEO)

            ChequeaError (Precio, fSalida, FALSE);

        fprintf (fSalida,"\n\nDecodificando SBRG.1_38:");

        fprintf (fSalida,"\nCODIGO DEL CONCEPTO PARAMETRICO: %s\n", codigo);

        fprintf (fSalida,"OPCIONES: ");

        for (j=0; j<nPar; j++)

            fprintf (fSalida,"%d ",ListaOpc2[j]);

    }

    pCierra (Precio);

    fcloseall();

    if (!CierraDll ((HMODULE)hLib, &err) ) {

        fprintf (fSalida,"\nERROR: %s\n", err);

        printf ("\n\nPROGRAMA FINALIZADO\nPulse una tecla\n");

        getch();

        return FALSE;

    }

    printf ("\n\nPROGRAMA FINALIZADO\nPulse una tecla\n");

    getch();

    return TRUE;

}