MANUAL PROGRAMACIÓN EXPERTIS

Transcripción

MANUAL PROGRAMACIÓN EXPERTIS
MANUAL
PROGRAMACIÓN
EXPERTIS
Versión Expertis 5 R2
Solmicro Organización y Software S.L.
Versión 1.4 / Mayo 2014
Manual Programación Expertis
ÍNDICE
1. INTRODUCCIÓN A EXPERTIS
Información de Expertis ............................................................................................................................................5
Estructura de Expertis ...............................................................................................................................................5
2. CONFIGURACIÓN PUESTO DESARROLLO
Herramientas y Componentes...................................................................................................................................6
Esquema de Directorio ..............................................................................................................................................6
Diseñador de Expertis ...............................................................................................................................................7
GAC de Windows ......................................................................................................................................................9
Templates y Snippets de Expertis .............................................................................................................................10
3. DISTRIBUCIÓN DE CAPAS
3.1. CAPA DE DATOS
Introducción Capa de Datos...............................................................................................................................16
Tipificación de Campos......................................................................................................................................16
Base de Datos de Sistema y de Usuario ............................................................................................................17
Actualización de Metadatos ...............................................................................................................................17
Campos de Auditoría Automáticos .....................................................................................................................19
Tablas Satélites .................................................................................................................................................19
Consideraciones Generales ...............................................................................................................................21
3.2. CAPA DE NEGOCIO
Introducción Capa de Negocio ...........................................................................................................................22
Entidad
1.
Metodo AddNew ..................................................................................................................................23
2.
Método AddNewForm ..........................................................................................................................23
3.
Método Delete......................................................................................................................................23
4.
Método Validate ...................................................................................................................................23
5.
Método Update ....................................................................................................................................23
6.
Método Filter ........................................................................................................................................24
7.
Método SelOnPrimaryKey ...................................................................................................................24
8.
Método GetItemRow ............................................................................................................................24
9.
Método ApplyBusinessRules ...............................................................................................................24
Tarea .................................................................................................................................................................25
Documento
1.
Concepto .............................................................................................................................................26
2.
Creación y Manejo ...............................................................................................................................26
Proceso
1.
Concepto .............................................................................................................................................27
2.
Bucles y Condicionales ........................................................................................................................28
3.
Control de Excepciones .......................................................................................................................29
4.
Llamadas a Procesos ..........................................................................................................................30
1/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
5.
Ejemplo Creación Proceso ..................................................................................................................30
Programación General en la Capa de Negocio
1.
Creación/Configuración de Proyectos de Negocio ...............................................................................36
2.
Creación de Entidades en Negocio......................................................................................................41
3.
Creación de Tareas .............................................................................................................................43
4.
Llamada a Tareas en Capa Negocio ...................................................................................................44
5.
Procesos de Entidades
1.
Proceso RegisterValidateTasks ....................................................................................................46
2.
Proceso RegisterUpdateTasks .....................................................................................................47
3.
Proceso RegisterAddNewTasks ...................................................................................................50
4.
Proceso RegisterDeleteTasks.......................................................................................................51
5.
Proceso GetBusinessRules ..........................................................................................................52
Componentes de Motor en Capa Negocio
1.
AdminData ....................................................................................................................................54
2.
BusinessHelper ............................................................................................................................56
3.
ApplicationService ........................................................................................................................57
4.
IPropertyAccessor ........................................................................................................................57
5.
UpdatePackage ............................................................................................................................58
6.
ServiceProvider ............................................................................................................................58
7.
ContextBoundObject ....................................................................................................................59
Configuración del Manager para procesar Capa Negocio .................................................................................60
Extensibilidad de Procesos y Tareas
1.
Sobreescritura de Clases .............................................................................................................62
2.
Sobreescritura de Documentos ....................................................................................................63
3.
Ejemplos.......................................................................................................................................66
3.3. CAPA DE PRESENTACIÓN
Introducción Capa de Presentación ...................................................................................................................76
Creación / Configuración de Proyectos de Presentación ...................................................................................77
Llamada a Tareas de Negocio desde Presentación...........................................................................................83
Tipos de Formularios Expertis
1.
Formas de Creación de Formularios ............................................................................................83
2.
Formulario Tipo Tabla ..................................................................................................................88
3.
Formulario Tipo Ficha ...................................................................................................................90
4.
Formulario Tipo Mantenimiento Simple ........................................................................................93
5.
Formulario Tipo Consulta Interactiva ............................................................................................97
6.
Formulario Tipo Consulta Interactiva Padre .................................................................................101
Controles de Expertis en Presentación
1.
Agregar Controles de Expertis a Barra de Herramientas ..............................................................102
2.
AdvSearch ....................................................................................................................................104
3.
CounterTextBox............................................................................................................................107
4.
ComboBox ....................................................................................................................................108
5.
CalendarBox .................................................................................................................................114
6.
NumericTextBox ...........................................................................................................................115
7.
TextBox ........................................................................................................................................116
8.
Grid ...............................................................................................................................................117
2/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
9.
UnderLineLabel ............................................................................................................................125
10. Label.............................................................................................................................................125
11. RadioButton ..................................................................................................................................126
12. CheckBox .....................................................................................................................................127
13. Otros Controles
a.
Panel ..............................................................................................................................128
b.
Frame .............................................................................................................................128
c.
Tab .................................................................................................................................128
Acciones Locales ...............................................................................................................................................130
Acciones Globales .............................................................................................................................................131
Parametros Formularios .....................................................................................................................................134
Componentes de Motor en Presentación
1.
BE.DataEngine ....................................................................................................................................135
2.
ExpertisApp .........................................................................................................................................135
Configuración del Manager de Datos de la Capa de Presentación ....................................................................136
4. PROGRAMACIÓN GENERAL
Enumerados ..............................................................................................................................................................138
Filter ..........................................................................................................................................................................140
Contadores ...............................................................................................................................................................142
Parámetros ...............................................................................................................................................................145
Agrupaciones ............................................................................................................................................................146
ProviderNeededData.................................................................................................................................................148
Login en Expertis para Ejecutables Externos ............................................................................................................149
Cambio de Base de Datos en MultiEmpresa .............................................................................................................150
Transacciones ...........................................................................................................................................................150
Filtrado Horizontal .....................................................................................................................................................151
Extensibilidad en Mensajería y Alertas de Expertis ...................................................................................................154
5. PROYECTOS EXPERTIS
Proyectos Presentación ............................................................................................................................................154
Proyectos Negocio ....................................................................................................................................................163
Proyectos Motor ........................................................................................................................................................165
6. VARIOS
Objeto Datatable .......................................................................................................................................................167
Modificadores de Métodos ........................................................................................................................................167
Atributo Shared .........................................................................................................................................................168
Genéricos ..................................................................................................................................................................168
? Atributo Nulo en Variables......................................................................................................................................168
Componente BackgroundWorker ..............................................................................................................................168
LINQ To SQL ............................................................................................................................................................171
7. REMOTING
3/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Consideraciones .......................................................................................................................................................172
Errores Comunes ......................................................................................................................................................172
Configuración Remoting Puesto Cliente y Servidor ..................................................................................................173
8. INFORMES
Introducción a Informes en Expertis ..........................................................................................................................175
Tipos de Informes
Registro Actual...................................................................................................................................................175
Criterio Selección ...............................................................................................................................................177
Tabla Auxiliar .....................................................................................................................................................178
RecordSet ..........................................................................................................................................................179
Sin Filtro .............................................................................................................................................................179
Personalizado ....................................................................................................................................................179
Configuración del Manager de Datos de Informes ....................................................................................................179
Servicio de Informes .................................................................................................................................................180
Tipos de Conexión ....................................................................................................................................................181
Eventos Informes ......................................................................................................................................................183
9. HERRAMIENTAS DE EXPERTIS
Consola de Administración .......................................................................................................................................185
DataBase Comparer .................................................................................................................................................195
Expertis.Tools.Translator ..........................................................................................................................................198
Expertis.Tools.CRConnectionUpdater ......................................................................................................................199
Federated Search & SmartTags ................................................................................................................................ 202
Doble Expertis Host en Servidor ...............................................................................................................................204
4/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
1. INTRODUCCIÓN A EXPERTIS
Información de Expertis
Expertis es una aplicación desarrollada en plataforma Windows. Se basa en el componente de Microsoft de
.NetFrameWork 3.5.
La aplicación está estructurada en varias capas aprovechando esta tecnología de Microsoft. Para la comunicación
entre capas se usa la tecnología de remoting.
La parte de base de datos nos apoyamos en versiones de SQL Server 2000 o posteriores.
Para los informes presentados en la aplicación usamos Crystal Reports en su versión 11 Release 2 para la versión
5.0 de Expertis.
Nos servimos también para la parte de presentación de eXpertis de controles de Windows de Janus.
Es importante entender cómo está estructurado eXpertis en las diferentes capas, qué función tiene cada capa y qué
debemos programar en qué una de ellas.
Volver al Índice
Estructura de Expertis
Expertis es una aplicación distribuida a 3 capas: Datos -> Negocio -> Presentación. En las cuales está presente en
todas ellas el motor de eXpertis para su manejo. Para las partes de negocio y presentación nos apoyamos en el
.NetFrameWork de Microsoft.
Iremos viendo a lo largo de este manual esta distribución a 3 capas de eXpertis y qué funcionalidades tendremos en
cada capa.
Tenemos que tener claro que para el manejo en cualquiera de los niveles / capas tendremos presente el motor de
eXpertis en todo momento para darnos la funcionalidad necesaria. Esto nos ayudará tanto en fiabilidad de la
ejecución de la funcionalidad, como rapidez, tanto en ejecución, como en el desarrollo funcional.
Volver al Índice
5/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
2. CONFIGURACIÓN PUESTO DESARROLLO
Herramientas y Componentes
Para la configuración de un puesto de desarrollo se deben instalar las siguientes aplicaciones y componentes:
1.
SQL Server 2008 - 2012: Las base de datos de Expertis 5 son suministradas en SQL2008, pudiendo
funcionar en superiores.
2.
Microsoft Visual Studio .Net 2008 Development Edition: La instalación de Microsoft Visual Studio .Net 2008
instala Microsoft Framework 3.5.
3.
Microsoft Visual Studio .NET 2008 Service Pack 1: Este service pack se puede encontrar en la web de
actualizaciones de Microsoft.
4.
Net Framework 3.5 SP1: Este service pack se puede descargar a través de Windows Update de Microsoft
5.
Janus Winforms Controls Suite v3.0 for .NET: Se recomienda, aunque no es obligatorio, agregar los
ensamblados de Janus a la GAC. Ver agregar ensamblados a la cache global. Esto lo suele hacer de manera
automática el propio instalador de Janus pero asegurarse de que lo hace así efectivamente.
6.
Janus Controls v3 Patch 35109: JanusWinFormsV35Patch.msi instala la versión 3.5.1.09 de los ensamblados
de Janus.
7.
Crystal Reports XI Release 2 / Msi Crystal Reports XIII
8.
Diseñador de Expertis R2: En el paquete de distribución de Expertis se incluye el paquete de instalación del
diseñador (ExpertisDesignerSetup.msi). Ver el apartado Diseñador de Expertis.
9.
Snippets y Templates de Expertis: instalable con fragmentos de código y plantillas de objetos de expertis para
la programación.
10. Windows Update: Ejecutar y revisar los Windows Update del Sistema Operativo.
11. DataBase Comparer: programa de solmicro para poder llevar a cabo comparaciones de estructura de datos
entre bases de datos, para poder extraer scripts de actualizaciones. Se dispone tanto de una versión 2000
como de 2008.
12. Expertis Tools Translator R2: herramienta de expertis para poder procesar del código fuente de origen todos
los textos y mensajes para llevar a cabo la traducción,
13. Expertis Tools CRConnectionUpdater: herramienta de reconexión de informes de cristal reports. Se usa
generalmente para reconectar los informes contra la BD final del cliente final para una mayor velocidad de
procesamiento.
Volver al Índice
Esquema de Directorios
La ubicación de las fuentes de desarrollo y los ensamblados compilados es importante, sobre todo si en el proceso de
desarrollo interviene más de un desarrollador y además se utiliza un sistema de control de código fuente.
El hecho de que todos los componentes de un grupo de desarrollo compartan un mismo esquema de directorios
agiliza las pruebas que tiene que realizar cada programador, y facilita la posterior compilación y distribución de los
ensamblados, además evita posibles confusiones entre las diferentes versiones que se pueden manejar para un
mismo proyecto.
NOTA: Como ejemplo se propone la estructura de carpetas que se utiliza en los proyectos de Solmicro.
El esquema de directorios de trabajo se compone de los siguientes directorios:
C:\ExpertisNet50\Main\Source\Application
C:\ExpertisNet50\Main\Source\Business
C:\ExpertisNet50\Main\Reports
C:\ExpertisNet50\Bin
C:\ExpertisNet50\Bin\Informes
C:\ExpertisNet50\Bin\Recursos\Imagenes
El directorio Bin contiene todos los archivos necesarios para ejecutar la aplicación en desarrollo:

Ensamblados del Engine de Expertis (Expertis.Engine.*).
6/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis














Ensamblados de Presentación de Expertis (Expertis.Application.ERP.*).
Ensamblados de Negocio de Expertis (Expertis.Business.*)
Archivo de Configuración de Sistema (System.Config)
Archivo de Configuración de Carcasa de Expertis (Expertis.Engine.UI.Shell.exe.config)
Ensamblados de Janus WinControls (Janus.Windows.*.v3.dll)
Ensamblados de Infragistics Controls (Infragistics3.*)
Fichero de Licencia de Expertis (Expertis.Lic)
Ensamblado de Plataforma GAIA (CegaiaDll.dll)
Ensamblado de Diseñador para equipos de desarrollo ( Expertis.Engine.UI.Design.dll)
Ensamblados de Firma Electrónica de XML Facturae (BouncyCastle.Crypto.dll y Xades.dll)
Ensamblado de Firma Electrónica PDF (PDFSignDll.dll)
Ensamblado de Microsoft Point of Service para TPV (Microsoft.PointOfService.dll)
Directorio de informes (Reports)
Directorio de recursos (Recursos de Imágenes y Iconos)
Volver al Índice
Diseñador de Expertis
El diseñador de eXpertis es un Add-in que se integra en el entorno de desarrollo de Visual Studio. Se ha creado con el
objeto de facilitar ciertas tareas en tiempo de diseño como, por ejemplo, la creación de controles consumidores de
datos o la carga de columnas de los controles grid.
En el paquete de distribución de eXpertis se proporciona el paquete de instalación ExpertisDesignerSetup.msi. Una
vez instalado el complemento se abre desde el menú Herramientas -> Diseñador de Expertis.
La primera vez que arranquemos el diseñador de eXpertis tendremos un aspecto parecido a este:
Como primer paso pulsaremos el botón de Sistema para establecer la conexión con una base de datos de Sistema.
7/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Esta configuración se guarda en el fichero Expertis.Designer.config en
programa\Solmicro\Expertis Designer Tool\VS2008 (Ruta por defecto del Instalador).
la
ruta
C:\Archivos
de
A continuación tendremos disponible en el despegable de Aplicación todas las bases de datos dadas de alta en el
sistema que nos hemos conectado. Seleccionamos la base de datos con la que queremos trabajar.
Para refrescar los datos obtenidos por el diseñador de la base de datos dispondremos del botón de Actualizar.
Como último botón tendremos la Opción de MetaDatos que nos permite regenerar la información de tablas, vistas,
campos, etc.. de la base de datos de usuario que estamos en la base de datos de sistema a la que estamos
conectados. La ventana tendría este aspecto y bastaría con pulsar el botón de Actualizar tablas de campos y
relaciones. Esta utilidad sería la misma que utilizar el procedimiento almacenado de sistema de xCargarSistema
disponible en las bases de datos de Sistema.
8/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
NOTA: si tenemos fallos o problemas con el diseñador de eXpertis puede ser necesario introducir las Dlls del Engine en la GAC de
Windows quedando de la siguiente manera:
NOTA: tener en cuenta que si actualizamos las dll’s de motor de eXpertis en nuestro bin, tendríamos que reactualizar estas dll’s
metidas en la GAC de Windows.
NOTA: para el correcto funcionamiento y diseño de proyectos de de presentación, debemos tener en nuestro Bin de eXpertis la dll
de Expertis.Engine.UI.Design.dll. Esto es muy importante, ya que si no la tenemos presente, puede que nos haga cambios no
deseados en proyectos de presentación.
Volver al Índice
GAC de Windows
Para poder usar correctamente el Diseñador de eXpertis y sin errores, es necesario y obligatorio el llevar a la GAC de
Windows las dlls del motor de eXpertis del Bin que trabajemos. Con esto tenemos que tener en cuenta que si
actualizamos el motor de eXpertis a una nueva versión, éstas dlls hay que actualizarlas también en la GAC.
Para ello basta con que arastremos las dlls del motor de expertis de nuestro bien a la carpeta: C:\Windows\Assembly.
Conviene tener abiertas dos ventanas del explorador de Windows, la primera ventana con el directorio donde están
los ensamblados que se quieren agregar a la GAC, y la segunda ventana con el directorio C:\Windows\assembly, que
es la ubicación del sistema que utiliza el framework de .NET para la cache de ensamblados.
Una vez seleccionadas las DLL que se quieren agregar, arrastrarlas a la ventana del explorador de la carpeta
C:\Windows\Assembly y soltar los archivos en ella.
9/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En la siguiente imagen se puede ver que se han agregado los ensamblados de Janus a la GAC. Se puede comprobar
también que la versión de dichos ensamblados es la 3.5.109.
10/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
Snippets y Templates
Los Snippets serían fragmentos de código para poder escribir de una manera más rápida y segura ciertos
procesos y funciones de Expertis.
El listado de fragmentos de código disponibles serían:
1. t -> Escribe código de Tipo: <Task()> Friend Shared Sub....
2. ft -> Escribe Código de Tipo <Task()> Friend Shared Function....
3. et -> Escribe código en Presentación de Tipo: ExpertisApp.ExecuteTask....
4. pt -> Escribe código en Negocio de Tipo: ProcessServer.ExecuteTask....
5. rvt -> Escribe código en Negocio de Tipo: ValidateProcess.AddTask....
6. rut -> Escribe código en Negocio de Tipo: UpdateProcess.AddTask....
7. rdt -> Escribe código en Negocio de Tipo: DeleteProcess.AddTask....
8. adt -> escribe código en Negocio de Tipo: AddNewProcess.AddTask.....
9. AS -> escribe código en Negocio de Tipo: ApplicationService.GenerateError.....
10. AL -> escribe código en Presentación de Tipo: Acción Local de Expertis.....
11. EAP -> escribe código en Presentación de Tipo: ExpertisApp.GenerateMessage.....
12. EAPIF -> escribe código en Presentación de Tipo: Mensaje con Condición.....
13. FIL -> escribe código de Tipo: Filter de Expertis.....
14. EAPOF -> escribe código en Presentación de Tipo: ExpertisApp.OpenForm.....
15. EAPOR -> escribe código en Presentación de Tipo: ExpertisApp.OpenReport…..
16. FILCOM -> escribe código de Tipo: Filtro Complejo de AND + OR + AND….
17. ADGET -> escribe código en Negocio de Tipo: AdminData.GetAutonumeric....
18. BEFIL -> escribe código de Tipo: BE.DataEngine.Filter….
19. ASL -> escribe código para crear una conexión de Login con Expertis…
20. BRT -> escribe código para crear una Tarea para reglas de Negocio…
21. RDTD -> escribe código para escribir las Tareas necesarias para mandar borrar un registro en un
RegisterDeleteTasks…
22. RUTUD -> escribe código para escribir las Tareas necesarias para mandar grabar un documento de
Expertis en un RegisterUpdateTask con Document…
23. RUTUR -> escribe código para escribir las Tareas necesarias para mandar grabar un datarow en un
RegisterUpdateTask con Datarow...
24. RUTUT -> escribe código para escribir las Tareas necesarias para mandar grabar un datatable en
un RegisterUpdateTask con Datatable…
Estos pueden ser escritos directamente en el Código de pantalla escribiendo las letras descritas anteriormente
seguida de una “?” y luego pulsando dos veces la tabulación.
11/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Otra manera de acceder a estos fragmentos de código, es posicionarnos con el cursor donde queremos insertar el
código. Pulsar con el botón derecho del ratón y darn en la opción de Insertar fragmento de código:
Seguidamente seleccionaremos Mis Fragmentos de Código:
12/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Seguidamente tendremos disponibles los fragmentos de código fuente personalizados para eXpertis disponibles
hasta este momento. Seleccionaremos el que queramos y pasaremos a completar la información para el fragmento
de código fuente seleccionada.
Item Templates
Los Templates serían las plantillas personalizadas para poder agregar de manera fácil los diferentes tipos
de formularios de eXpertis, de Clase de Negocio.
El listado de plantillas personalizadas de objetos / formularios disponibles serían:
- ClassExpertis: Clase de negocio genérica.
- SimpleMntoExpertis: Formulario de tipo Mantenimiento Simple.
- CIMntoExpertis: Formulario de tipo Consulta Interactiva.
- CIMntoBaseExpertis: Formulario de tipo Consulta Interactiva Padre.
- GridMntoExpertis: Formulario de tipo Mantenimiento en Grid.
- FormBaseExpertis: Formulario de tipo Base de eXpertis.
- DocumentExpertis: Clase de negocio de Documento de Expertis para Procesos.
- ProfileExpertis: Clase de Profile de Expertis para Filtrado Horizontal.
- GlobalActionExpertis: Clase de Acción Global de Expertis.
Para agregar elementos de los templates de Expertis iremos en un proyecto ya existente al menú: Proyecto
-> Agregar Nuevo Elemento.
13/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En la nueva pantalla que se nos abre, nos posicionaremos en Elementos Comunes dentro de Categorías, y
en la sección de Expertis veremos las diferentes plantillas de elementos disponibles dependiendo de la
capa en la que necesitemos dicho elemento.
Project Templates
El listado de proyectos personalizados disponibles serían:
- ProjectBusinessExpertis: Proyecto con Clase de negocio genérica.
- ProjectSimpleMntoExpertis: Proyecto con Formulario de tipo Mantenimiento Simple.
- ProjectCIMntoExpertis: Proyecto con Formulario de tipo Consulta Interactiva.
14/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
- ProjectCIMntoBaseExpertis: Proyecto con Formulario de tipo Consulta Interactiva Padre.
- ProjectGridMntoExpertis: Proyecto con Formulario de tipo Mantenimiento en Grid.
- ProjectProcessOverrideTasks: Proyecto con Clase de negocio para sobrescribir un Proceso de otra
entidad de Expertis.
- ProjectExecutableLogin: Proyecto con Formulario con código para hacer login y logout en expertis.
En primer lugar accedemos en el entorno de visual studio a crear un nuevo proyecto. Para ello
Accederemos a través de Archivo -> Nuevo -> Proyecto.
Una vez que nos salga la ventana de Nuevo Proyecto, elegiremos en el menú -> Visual Basic y luego ya tendremos
disponibles en la sección de Expertis las diferentes plantillas disponibles según en la capa que necesitemos
15/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
16/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
3. DISTRIBUCIÓN DE CAPAS
3.1. CAPA DE DATOS
Introducción Capa de Datos
El nivel de capa de datos es el nivel más bajo y básico de eXpertis, siendo el nivel final donde almacenaremos todos
los datos de eXpertis.
En Expertis 5 se almacenan en sistema de SQL Server, de versión 2008 en adelante. La versión más común con la
que trabajamos es sobre todo versión 2008.
Interacción con esta capa a través de los objetos de motor. Dispondremos de un serie de dlls del motor de eXpertis
para interaccionar con la base de datos. Será la encargada de velar por la correcta gestión de transacciones y evitar
posibles errores de concurrencia. Por eso es conveniente que actualicemos los datos pasando siempre por los
objetos de motor para garantizar la fiabilidad de todo el proceso.
Veremos en los siguientes apartados cómo para el sistema expertis funcionaremos obligatoriamente con 2 bases de
datos como mínimo. Siendo una de sistema que registrará toda la información del sistema de eXpertis y otra con los
datos finales de una empresa/cliente/usuario_final.
Volver al Índice
Tipificación de Campos
NVarchar
Se utiliza para almacenar valores alfanuméricos no Unicode/Unicode. Si admiten nulos o no depende del significado
funcional que tiene el campo. Se definen sin valor predeterminado.
Numeric
Se utiliza para almacenar valores numéricos con decimales (cantidades fraccionarias, precios, importes, etc.). Se
definen con una precisión de 23 y una escala de 8, con un valor predeterminado, que generalmente es 0, y no
admiten nulos.
Int
Se utiliza para almacenar valores enteros. Puede aparecer como tipo de dato para un campo que actúa como clave
extranjera (de un campo que generalmente es auto numérico en la tabla principal). También se utilizan para
almacenar valores que están relacionados con enumerados de la aplicación.
Se suelen definir con un valor predeterminado, excepto cuando actúan como clave extranjera. El valor
predeterminado generalmente es 0, aunque dependiendo del significado funcional puede convenir otro valor por
defecto.
No suelen admitir nulos si el campo representa valores enteros en general, o enumerados. Si el campo es una clave
extranjera, el que admita nulos o no, dependerá de la relación funcional que define el propio campo entre las dos
tablas.
Bit
Se utiliza para almacenar valores de tipo booleano. No admiten nulos y se definen con valor predeterminado, 0 ó 1.
Datetime
Se utiliza para almacenar valores de tipo fecha-hora. En general admiten nulos y sin valor predeterminado. Cuando es
necesario un valor por defecto, en algunas bases de datos, se utiliza dbo.Fecha que realiza una llamada a la función
de GETDATE() de SQL para obtener la fecha-hora actual.
Autonumerico (int)
Se utiliza como tipo de dato para la clave principal de algunas tablas. El tipo de dato autonumeric propio de SQL
Server no se utiliza en eXpertis. En su lugar, se utiliza este tipo “auto numérico”, que básicamente, es un alias del tipo
int, propio de SQL.
En eXpertis los valores auto numéricos no se mantienen a nivel de tabla, si no que se mantienen a nivel de base de
datos. Se puede decir que todas las tablas que poseen un campo de este tipo, comparten un mismo origen para sus
valores auto numérico.
Dado que SQL Server no asigna los valores a estos campos, el mantenimiento de estos campos auto numéricos se
hace por código, unas veces de forma automatizada por el engine de eXpertis, y otras veces por medio de código que
es responsabilidad del propio programador.
17/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Ntext
Se suelen utilizar para almacenar datos no Unicode/Unicode de gran tamaño.
Image
Se utilizan para almacenar datos de gran tamaño en formato binario, como por ejemplo campos que contienen fotos o
ficheros.
Uniqueidentifier
Se utilizan para almacenar valores de tipo GUID. Se utiliza como tipo de dato para la clave principal de algunas
tablas. Para asignar un valor predeterminado se utiliza la función NEWID () de SQL.
Volver al Índice
Base de Datos de Sistema y de Usuario
Habitualmente, el desarrollo debe contar con:
-
Una base de datos de sistema (sxExpertisXXXX).
Al menos una base de datos de usuario (xExpertisXXXX).
La base de datos de sistema almacena los metadatos de la aplicación, esto es, información referente a usuarios,
menús, bases de datos, programas, entidades de negocio, informes, campos de las tablas funcionales, etc.
La base de datos de usuario contiene la estructura y toda la información funcional que utiliza la aplicación.
Tanto la base de datos de sistema como la de aplicación se proporcionan en el CD de distribución de eXpertis.
A efectos de desarrollo, no es necesario realizar modificaciones en el esquema o la estructura de la base de datos de
sistema, aunque habitualmente, si es necesario modificar cierto contenido de la misma. Para realizar modificaciones
en las tablas de la base de datos de sistema se utiliza la Consola Administración de Expertis.
NOTA: Para abrir la consola de administración de Expertis ejecutar Expertis.Engine.UI.Manager.exe, que se encuentra en el
directorio de desarrollo.
El desarrollo funcional afecta única y exclusivamente a la base de datos de usuario. Por lo tanto el primer trabajo
consiste en analizar la estructura de tablas, datos y objetos de la base de datos que se van a utilizar.
Volver al Índice
Actualización de MetaDatos
Cuando se crean tablas nuevas, la información de su esquema (campos, tipo de los campos, relaciones entre tablas,
etc.) debe incluirse en el conjunto de metadatos de la base de datos de sistema.
Para realizar esta acción se cuenta con un procedimiento almacenado, xCargarSistema, en la base de datos de
sistema.
Este procedimiento almacenado recibe dos parámetros: el primero es obligatorio y es el nombre de la base de datos
de usuario de la que se quieren extraer los metadatos; el segundo parámetro es opcional y puede ser 0 o 1. Si es 0, el
proceso de carga solo tiene en cuenta campos y relaciones nuevas. Si es 1, el proceso tiene en cuenta todos los
campos de la base de datos pudiendo actualizar aquellos que han cambiado. El valor por defecto es 1.
El procedimiento habitual consiste en abrir un analizador de consultas de SQL, y desde la base de datos de sistema,
ejecutar el procedimiento almacenado
Otra alternativa a este método manual de actualización de los metadatos tendremos la posibilidad de hacerlo a través
del diseñador de eXpertis.
18/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
Campos de Auditoría Automáticos
En Expertis tenemos un sistema automático de auditoría de registros a nivel de SQL-Server.
Este sistema consiste en crear 3 campos en una tabla para que el Engine de Expertis se encargue de manera
automática de rellenarlos y con ello poseer una pequeña información de qué es lo que ha pasado un registro en la
base de datos.
Para ello bastaría con crear los siguientes 3 campos, con los nombres exactos descritos y con los tipos de datos
descritos:



FechaCreacionAudi: Campo fecha que rellenará automáticame el motor solo cuando se crea el nuevo
registro, quedando para siempre esta fecha y no modificándose nunca mas.
FechaModificacionAudi: Campo fecha que rellenará automáticamente el motor solo cuando se modifique el
registro, actualizándose cada vez que se modifique alguna información de dicho registro.
UsuarioAudi: Nombre de Usuario de Expertis que ha llevado a cabo la ultima operación sobre el registro.
Bien sea si la última operación ha sido de añadir un nuevo registro o bien sea por una modificación. Cada
vez que ocurra una modificación se actualiza esta información de manera automática.
Volver al Índice
Tablas Satélites
Descripción de Tablas Satélites
La definición de Tablas Satélites en eXpertis nos permite desarrollar los cambios que necesitamos a nivel de bases
de datos sobre tablas ya existentes, de manera que no tengamos que modificar las tablas en sí sino crear nuevas con
los campos que necesitamos.
Creación de la Tabla y Relaciones
Creamos la tabla con los campos que necesitemos y con el nombre de tabla que queramos.
El requisito fundamental de la configuración de la tabla sería que tuviera un campo clave principal llamado igual que el
campo clave de la tabla principal de la que vamos a hacer una tabla satélite. En este caso sería el campo IDArtículo
porque vamos a hacer una satélite de la tabla tbMaestroArtículo, creándonos una tabla nueva llamada tbExtra.
19/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez creada la tabla configuramos las relaciones de la tabla. Para ello damos de alta una nueva y relacionamos la
tabla tbMaestroArticulo con tbExtra a través del campo IDArtículo. Con esta relación tenemos que ver y entender que
se establece una relación de 1 a 1.
Tendríamos que llevar a cabo una vez realizado esto, el que se carguen en la tabla satélite todos los registros que
contenga la tabla principal. Esto es necesario para que tengamos los registros equivalentes en la tabla satélite con los
existentes ya en nuestra base de datos. Sobre todo estar presentes las claves primarias de relación, en el caso del
ejemplo, sería tener todos los IDArtículo presentes en la tabla satélite. Esto si no hacemos notaremos que cuando
modificamos un dato de la tabla satélite no se grabará por expertis, ya que no existe la relación. Si damos de alta
nuevos registros no tendríamos ningún problema.
Después de todo esto configurado y grabado, ejecutamos el procedimiento de xCargarSistema en nuestra BD de
sistema con BD de datos que hayamos configurado esto.
Alta y Configuración en Manager de Tablas Satélites
Una vez hecho todos los pasos y cambios a nivel de Base de datos, acudimos al manager de eXpertis y hemos de
buscar en la sección de Objetos -> Entidades, la entidad principal padre de la que hemos desarrollado una tabla
satélite, en nuestro caso la entidad de Artículo de la tabla tbMaestroArtículo.
20/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Teniendo esta entidad seleccionada, acudimos a la pestaña de Tablas Satélite. En ella damos al botón de añadir de la
barra de herramientas de arriba. Nos aparecerá una ventana con muchos nombres de tablas, lo que hacemos es
buscar nuestra tabla satélite tbExtra.
Una vez hecho esto ya veremos entonces que para nuestra entidad de Artículo tiene una tabla satélite que se llama
tbExtra. Grabamos los cambios.
21/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Como último paso importante sería editar la parte del campo de Sentencia de Selección de la entidad principal, en
este caso Artículo. Debemos rellenar este campo una sentencia SQL en la que se seleccionen todos los registros de
la tabla principal y asimismo todos los de la tabla satélite. Esto es para que por defecto cuando obtengamos datos de
la entidad Artículo nos vengan sus datos y de sus tablas satélites.
Es importante en este punto que si tenemos los campos de Auditoría en la tabla satélite, estos si que no se
seleccionen ya que tendríamos problemas. Los campos de Auditoría que pueden estar presentes son de la tabla
principal.
Es recomendable revisar la sentencia de búsqueda de la búsqueda avanzada, si vamos a necesitar que estos
campos nuevos estén disponibles en las búsquedas de artículos.
Para ello en la entidad correspondiente, en nuestro caso Artículo damos a configurar la sentencia de búsqueda y
añadiríamos nuestra tabla satélite con los campos que queramos visualizar.
22/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Desarrollo e implementación de funcionalidad de campos de la Tabla Satélite
Después de haber llevado cabo toda la configuración de las tablas satélites, lo más seguro es que necesitemos dar
más funcionalidad a nuestros nuevos campos de la tabla, bien sea validaciones nuevas antes de grabados, o reglas
nuevas para antes del grabado en la base de datos, etc…
Para ello simplemente nos serviremos de la extensibilidad de eXpertis. Programando tareas antes o después de
otras, sobre-escribiendo tareas, etc.. Para ello ver manuales y referencias de Extensibilidad de eXpertis de Solmicro.
Volver al Índice
Consideraciones Generales
A la hora de crear tablas nuevas en la base de datos de desarrollo se siguen una serie de convenios en la definición
de campos nuevos. Los convenios se refieren al tipo de dato y a ciertas propiedades como los valores por defecto, si
admite nulos, etc.
Se han de crear todas las tablas siempre con una clave primaria, sea simple o compuesta pero siempre presente una
en cada tabla.
Recomendamos indexar los campos más habituales de búsqueda, para una mayor rapidez en los accesos a la
información, teniendo siempre en mente buscar el equilibrio, ya que abusar de estos índices podría provocar el efecto
contrario y que la tabla fuera lenta en las búsquedas.
Para los tipos de datos autonuméricos recordemos poner este tipo de dato el de eXpertis y no el autonumeric de sql.
Este tipo de datos nos daría problemas a la larga en nuestra ejecución con eXpertis.
Recordemos que a partir de la versión de SQL2005 los ORDER By de las vistas no se hacen caso cuando se
ejecutan externamente. Con lo cual no contemos con estos ordenamientos que dejemos hecho en diseño.
No construyamos vistas con SELECT * de alguna tabla ya que esto también puede perjudicarnos en la ejecución con
eXpertis.
También tenemos que tener en consideración que cuando creemos tablas nuevas, aunque sean temporales o de
paso de datos, éstas tengan siempre una clave primaria en tabla, bien sea sencilla o compuesta. Esto es que si
usamos la versión de expertis en Azure, es un requisito por parte de Microsoft en su SQL en Azure que dispongan las
tablas de clave primaria siempre.
NOTA: Habitualmente el siguiente paso a la creación de nuevas tablas, o a la modificación del diseño de las mismas, es actualizar
los metadatos de la base de datos de sistema con estas nuevas modificaciones. Ver Actualización de los metadatos asociados a la
estructura de la base de datos de usuario.
Volver al Índice
23/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
3.2. CAPA DE NEGOCIO
Introducción Capa de Negocio
La capa de Negocio de eXpertis es la capa en la que estableceremos una relación de tablas con clases de .Net. De
manera que el manejo de una tabla (inserciones, modificaciones, borrados,…) sea a través de estas clases que están
relacionadas con tablas.
Igualmente las clases de Negocio nos sirven para definir funciones o procesos auxiliares que podamos necesitar en
relación con la Clase – Tabla relacionada. De esta manera establecemos un orden en el código.
Asimismo en el entorno remoting, la capa de negocio sirve para que se ejecute puramente en el parte servidor, de
manera que procesos pesados, ya sea de acceso a datos como de procesamiento en sí, lo lleve a cabo un equipo
servidor y no la parte cliente del mismo.
Volver al Índice
Entidad
El concepto de Entidad de eXpertis hay que entenderla como un manejador de una tabla de sql server. De manera que
una entidad de eXpertis representa realmente a una tabla de nuestra base de datos.
De esta manera la idea es que las tablas de usuario las manejemos a través de este concepto de entidad que iremos
viendo a lo largo de esta manual. Con ello la comunicación de la tabla, bien sea para obtener datos o bien sea para
actualizaciones lo realizaríamos a través de la entidad de eXpertis asociada.
Lo que nos permitirá esta entidad de eXpertis es establecer reglas de validación y ejecución de procesos en las
inserciones , modificaciones y borrados de registros contra esta tabla.
Asimismo se gestiona el concepto de reglas de negocio de eXpertis, el cual nos permitirá definir una serie de
validaciones y actualizaciones cada vez que modifiquemos un campo relacionado con una tabla/entidad de expertis.
También con este concepto de entidad lo que intentamos es tener aglutinado todo el código fuente relacionado con la
entidad/tabla de expertis y toda la programación en esta capa de negocio.
Public Class ClassExpertis1
#Region "Constructor"
Inherits Solmicro.Expertis.Engine.BE.BusinessHelper
Public Sub New()
MyBase.New(cnEntidad)
End Sub
Private Const cnEntidad As String = "NOMBRE_TABLA"
#End Region
End Class
Las entidades, una vez que las tenemos creadas, aportan una serie de métodos paor defecto. Para ello bastaría con
instanciarse un objeto de tipo la entidad que buscamos y acceder a sus métodos.
24/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
A continuación marcamos los métodos más habiltuales en una entidad de eXpertis.
1.
Método AddNew
El Método AddNew devuelve la estructura de campos y tipos que conforman la tabla que maneja dicha
entidad. Para ello el motor solicita a la base de datos la configuración de campos, tipos y valores por defecto
que hayamos configurado en dicha tabla en base de datos. Esto nos permite obtener un DataTable con la
estructura de datos que compone dicha tabla pero sin ningún registro.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.AddNew
Volver al Índice
2.
Método AddNewForm
El Método AddNewForm lo usaremos para obtener un nuevo registro de la entidad que estamos con una
serie de datos mínimos. Esto nos permite invocar a las tareas asociadas al proceso de
RegisterAddNewTasks que tenga la entidad a la que hacemos referencia. Si de todos modos no tuviéramos
tareas en dicho proceso lo que hace el motor es conforman un DataTable con un registro que contiene todos
los valores por defecto y restricciones configuradas a nivel de tabla de la base de datos. También en el
proceso de RegisterAddNewTasks la información que se va manejando en las tareas es este DataTable con
un registro. Por ello siempre recibiriremos de este método un DataTable con un registro conformado con la
información de la base de datos y si lo hubiera con lo programado en las tareas del RegisterAddNewTasks.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.AddNewForm
DtNewArt.Rows(0)("IDArticulo") = "ART001"
Volver al Índice
3.
Método Delete
El Método Delete lo usaremos para borrar uno o varios registros de la entidad que estamos. Esto nos
permite invocar last areas asociadas al proceso de RegisterDeleteTasks que tenga la entidad a la que
hacemos referencia. Si no tuviera tareas sobreescritas se llevaría a cabo el borrado contra la base de datos
del/los registro/s mandados. Para ello usaremos este método pasándole un datatable con los registros que
deseamos eliminar y cuyos registros estén en estado de Saved. No pueden ir en estado Deleted los registros
que enviamos en este datatable.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.SelOnPrimaryKey("ART001")
ClsArticulo.Delete(DtNewArt)
Volver al Índice
4.
Método Validate
El Método Validate lo usaremos para llevar a cabo la validación de un datatable contra las tareas
programadas en el proceso de RegisterValidateTasks. Se trata de ejecutar una serie de validaciones previas
con el objetivo de que los datos vayan correctos a la actualización.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.SelOnPrimaryKey("ART001")
DtNewArt.Rows(0)(“PrecioA”) = 100.5
ClsArticulo.Validate(DtNewArt)
Volver al Índice
5.
Método Update
El Método UpdateValidate lo usaremos para llevar a cabo actualizaciones de datos contra la tabla de la
entidad que usemos. Bien sea para registros nuevos o registros modificados. Invocando este método
haremos que se ejecuten las tareas asociadas al proceso de RegisterUpdateTasks o bien si no hubiera se
25/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
llevaría a cabo el grabado de datos directo contra la base de datos. Para ello entonces tendremos que enviar
a este método un DataTable con registros con estado Added o algunos de los de tipo Modified.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.SelOnPrimaryKey("ART001")
DtNewArt.Rows(0)(“PrecioA”) = 100.5
ClsArticulo.Update(DtNewArt)
Volver al Índice
6.
Método Filter
El Método Filter es uno de los métodos de una entidad que nos permite obtener datos de la entidad
asociada. Éste método debería de utilizarse con el objeto Filter de eXpertis para conformar un filtro contra la
tabla. Como resultado nos devolverá un objeto DataTable con todos los datos que concuerden con el filtro
que hayamos pasado.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim FilArt As New Filter
FilArt.Add("PrecioA", FilterOperator.GreaterThanOrEqual, 100.5)
FilArt.Add("IDTipo", FilterOperator.Equal, "FAB")
Dim DtNewArt As DataTable = ClsArticulo.Filter(FilArt)
Nota: Para más información del objeto Filter de eXpertis ver el apartado del manual de Objeto Filter de
eXpertis.
Volver al Índice
7.
Método SelOnPrimaryKey
El Método SelOnPrimaryKey nos permite obtener datos de una entidad pero a diferencia del método Filter,
sólo tendremos que pasar el valor o valores que conformen la clave primaria de dicha entidad / tabla. Es un
método más directo y rápido para obtener datos cuando se quieren filtrar por dicho/s campo/s de la clave
Primaria. Como resultado devolverá un datatable con el registro solicitado.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtNewArt As DataTable = ClsArticulo.SelOnPrimaryKey("Art001")
Volver al Índice
8.
Método GetItemRow
El Método GetItemRow nos permite al igual que el SelOnPrimaryKey obtener datos de la entidad
especificando solo los valores del/os campo/s que conforman la clave primaria, pero el objeto devuelto será
un DataRow. Sería para usar porque buscamos un valor muy concreto del registro buscado de la entidad.
Dim ClsArticulo As New Solmicro.Expertis.Business.Negocio.Articulo
Dim DtArt As DataRow = ClsArticulo.GetItemRow("Art001")
Nota: éste método se debe de usar solamente a nivel de la capa de negocio de eXpertis y entre negocios de
eXpertis, puesto que el objeto DataRow no es un objeto serializable y no está preparado para viajar por
remoting entra la capa de presentación y de negocio de eXpertis.
Volver al Índice
9.
Método ApplyBusinessRule
El Método ApplyBusinessRules nos permite invocar a las reglas de negocio asociadas de una entidad, con
ello invocamos a las tareas asociadas a los campos programados en el proceso GetBusinessRules de la
entidad. Es por ello que si no existieran tareas programadas en el GetBusinessRules no se ejecutaría nada y
tampoco daría ningún error.
Dim ClsArticulo As New Articulo
Dim DtArticuloNew As New DataTable
Dim DrNew As DataRow = DtArticuloNew.NewRow
DrNew("IDArticulo") = "00"
Dim StData As New BusinessData(DrNew)
26/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
StData = ClsArticulo.ApplyBusinessRule("IDArticulo", "00", StData)
For Each Dc As DataColumn In DtArticuloNew.Columns
DrNew(Dc.ColumnName) = StData(Dc.ColumnName)
Next
Volver al Índice
Tarea
Son métodos que cumplen ciertas características.
Se identifican por la etiqueta <Task> y tienen siempre 2 parámetros, el primero con los datos de entrada y el segundo
un parámetro de tipo ServiceProvider. También tienen la peculiaridad que deben ser shared.
<Task()> Public Shared Function GetContadorPredeterminadoCGestionUsuario(ByVal data As
CentroGestion.ContadorEntidad, ByVal services As ServiceProvider) As String
Dim CentroEnt As CentroEntidad
CentroEnt.CentroGestion = New UsuarioCentroGestion().CentroGestionUsuario()
CentroEnt.ContadorEntidad = data
Return ProcessServer.ExecuteTask(Of CentroEntidad, String)(AddressOf
GetContadorPredeterminado, CentroEnt, services)
End Function
Dentro de una misma clase no puede haber más de una tarea con el mismo nombre.
Por ejemplo, MantenimientoValoresAyB. Antes teníamos bastantes métodos con distintas firmas dependiendo del
tipo de entrada,.. Ahora estas se reducen a 2:
<Task()> Public Shared Function MantenimientoValoresAyB(ByVal dataAB As ValoresAyB, ByVal services
As ServiceProvider) As IpropertyAccessor
Para los casos en los que tenemos un Datarow o un BusinessData (debemos reducir los tipos de datos a unos de
estos 2) y para los casos en los que tenemos un Double:
<Task()> Public Shared Function MantenimientoValoresImporteAyB(ByVal dataAB As ValoresAyB, ByVal
services As ServiceProvider) As fImporte
Como vemos ambas funciones tienen distinto nombre, aunque el tipo de datos de entrada es el mismo, (ya que
además de indicar el importe o el registro, debemos indicarle la moneda, los cambios,….) Nos encontraremos bastante
con esta situación, de tener varios parámetros de entrada y sólo podemos tener 2, y que debemos introducir “todo” lo
que necesitemos dentro del primer parámetro, mediante una clase.
Se utilizan de manera un tanto especial, y dependiendo desde donde se haga la llamada a la tarea se hace de una
manera u otra. Por ejemplo, desde negocio:
Dim IDContador As String = ProcessServer.ExecuteTask(Of ContadorEntidad, String)(AddressOf
CentroGestion.GetContadorPredeterminadoCGestionUsuario, ContadorEntidad.FacturaCompra, services)
(la tarea CentroGestion.GetContadorPredetermindadoCGestionUsuario se ejecuta con ProcessServer.ExecuteTask,
indicando el tipo del parámetro de entrada, en este caso ContadorEntidad, seguido del tipo del elemento de salida
(sólo en el caso de funciones), se le pasa el parámetro de entrada y un objeto del tipo ServiceProvider)
Desde presentación:
Dim IDContador As String = ExpertisApp.ExecuteTask(Of ContadorEntidad,
String)(AddressOf CentroGestion.GetContadorPredeterminadoCGestionUsuario,
CentroGestion.ContadorEntidad.FacturaCompra)
(la tarea CentroGestion.GetContadorPredetermindadoCGestionUsuario se ejecuta con ExpertisApp.ExecuteTask,
indicando el tipo del parámetro de entrada, en este caso ContadorEntidad, seguido del tipo del elemento de salida
(sólo en el caso de funciones), se le pasa el parámetro de entrada y NO se le pasa el objeto del tipo ServiceProvider)
Volver al Índice
Documento
27/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
1.
Concepto
Ante los problemas derivados por el hecho de que unas entidades precisen de modificaciones en otras,
como pueden ser problemas de concurrencia, o bien, hacer el Update en 2 partes (Update+Updated) para
hacer cálculos (p.ej: recalculo de cabeceras de facturas, por cambios en la líneas), ha surgido un nuevo tipo
de datos Document (en Expertis.Business.General), que nos servirá para agrupar varias entidades como si
fueran una única entidad, y procesarlas de manera conjunta.
2.
Creación y Manejo
Vamos a ver a través de un ejemplo, cómo hacer un Documento, para ellos nos fijaremos en las Facturas.
Document:
Clase genérica para crear Documentos
Sobre ella iremos añadiendo (mediante herencia) elementos que nos permitirán adaptarla a nuestras
necesidades.
DocumentCabLin:
En todos los elementos del circuito logístico tenemos, una cabecera, unas líneas y existe la posibilidad de
tener Analítica, esto es lo que se contempla en DocumentCabLin, así como la información de las Monedas (la
del cliente/proveedor, la MonedaA y la MonedaB)
Además, contiene también información del origen del que partimos para crear el Documento. (P.Ej: en el
caso de las facturas generadas desde albaranes, contiene la información de los albaranes) – campo
Cabecera. Esta información se incluye dentro del documento, porque a lo largo del proceso el parámetro de
entrada de las tareas va a ser el documento, y en alguna de ellas se necesita la información del albarán. (El
equivalente en 4.1 son las cabeceras y lineas que nos devolvían las agrupaciones)
DocumentoComercial, DocumentoCompra:
Tanto en Compras como en Ventas hay elementos comunes al Pedido, Albarán y Factura, por lo que se han
creado otros 2 documentos que tienen la información específica de cada circuito, como puede ser la
información del Cliente, del Proveedor o los representantes.
DocumentoPedidoVenta, DocumentoPedidoCompra,….:
En estos documentos hay información específica de cada uno, así como cierta configuración que se necesita
especificar (indicar cuál es la primarykey de las entidades de cabecera, líneas,…..)
Constructores de los documentos
Importante especificar en cada uno de los distintos documentos los constructores de cada uno. P. Ej. Los de
albarán compra serían los siguientes:
Public Sub New(ByVal Cabecera As AlbCabCompra, ByVal services As ServiceProvider)
MyBase.New(Cabecera, services)
End Sub
Public Sub New(ByVal UpdtCtx As Engine.BE.UpdatePackage)
MyBase.New(UpdtCtx)
End Sub
Public Sub New(ByVal ParamArray PrimaryKey() As Object)
MyBase.New(PrimaryKey)
End Sub
Se necesitan 3 constructores para crear los documentos desde distintos sitios:
- El primero se utiliza desde el proceso de recepción de pedidos (por ejemplo), y se le pasa un objeto del
tipo AlbCabCompra, que tiene la información necesaria para crear un Albaran de Compra desde pedidos (por
ejemplo). Con ésta información es suficiente para montar un Documento con la información mínima y a lo
largo del proceso éste documento se irá completando a medida que pasa por las distintas tareas.
- El segundo es el que utiliza el motor, para hacernos llegar a Negocio la información modificada en
presentación
documento cuando se han hecho cambios desde presentación. La primera tarea de un
28/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
RegisterUpdateTask que recibe un UpdatePackage, será un CrearDocumento, en el cual mezclaremos los
registros modificados que vienen en el UpdatePackage, con lo que tenemos en la BBDD (método
MergeData de la clase Document). Una vez hecho esto tendremos en el documento todo lo referente al
Pedido (por ejemplo) y podremos operar sobre el documento
- En ocasiones necesitamos obtener un documento a través de la clave primaria de la entidad de
cabecera, esto es para lo que se utiliza el tercer constructor.
Métodos sobre-escribibles
Es posible que tengamos que sobrescribir los métodos
LoadEntityHeader, LoadEntitiesChilds y
LoadEntitiesGrandChilds para poder cargar la información de cabecera y de las entidades hijas o nietas de
la cabecera. P.EJ. En el DocumentoFacturaCompra cargamos los Vencimientos y las Bases Imponibles
como hijas.
También tendremos que sobrescribir métodos como EntidadCabecera, EntidadLineas,… para indicar el
nombre de la entidad que estamos tratando.
Otros métodos
Otros métodos que podemos tener en estas clases, son métodos para proporcionar transparencia a la hora
de hacer algunas modificaciones sobre elementos de la entidad. Por.Ej: en el caso de los Albaranes al
Facturarlos, se debe indicar en el Albarán la Qfacturada y las líneas del albarán cambiarán de estado en
función de esa cantidad. De manera que desde la facturación se indica la cantidad facturada en ese
momento y el método en cuestión se encarga de sumarla en las líneas del albarán y de actualizar el estado
de la líneas.(método SetQFacturada (en DocumentoAlbaranCompra/DocumentoAlbaranVenta))
Uso
Estos documentos los utilizamos en procesos creados por nosotros (p.ej: PrcCrearFacturaCompra) , en los
procesos RegisterUpdateTask,….
Al registro de cabecera haremos referencia a través de la propiedad HeaderRow, y las entidades hijas y
nietas se accederán mediante datatables.
En las entidades hijas/nietas que estén bajo un Documento, no hay que programar sus RegisterUpdateTask,
ya que se van a tratar siempre ligadas a la cabecera,… se guardarán en el Documento que las agrupa. Por
ejemplo, el RegisterUpdateTask de FacturaCompraLinea no está programado, porque ya está incluida en el
de FacturaCompraCabecera, ya que este último lo trata como un Documento.
Volver al Índice
Proceso
1.
Concepto
Los procesos son una lista de tareas que dado un objeto de entrada lo transforma en otro objeto a la salida.
Pudiendo ser el mismo objeto de entrada con más cosas añadidas, o bien, otro objeto completamente
diferente.
En esa lista de tareas el objeto de salida de una tarea es la entrada para la siguiente tarea.
Algunos de estos procesos, son propios del motor, como son RegisterDeleteTask, RegisterValidateTask,
RegisterUpdateTask, GetBusinessRules y RegisterAddNewTasks. En la definición de estos procesos,
construimos la lista de tareas, pero dichas tareas no se ejecutarán en ese momento. Los procesos
RegisterDeleteTask y RegisterUpdateTask tienen, además, otra peculiaridad (DeleteProcessContext y
UpdateProcessContext, respectivamente).
Volver al Índice
2.
Bucles y Condicionales
Además de estos procesos básicos, podremos crear nuestros propios procesos. Que podrán formarse
mediante una serie de tareas y/o procesos, pudiendo incluirlos de manera iterativa(AddForEachTask),
condicional (AddIfThenTask) y/o simple(AddTask). Se asume que la entrada de una tarea es la salida de la
anterior.
Los procesos deberán heredar de la clase Process y le podremos indicar cuales son los tipos de entrada y
salida del proceso.
29/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Ejemplo 1: (proceso Facturación de Compra)
Este proceso tiene como entrada un objeto del tipo DataPrcFacturacionCompra y devuelve un objeto de tipo
ResultFacturacion.
Está formado por varias tareas.
También se incluye mediante una iteración, la llamada a otro proceso. Que se ejecutará tantas veces como
elementos tenga el array que devuelve la tarea anterior. Es decir, que el proceso PrcCrearFraCompra tendrá
como entrada un elemento de tipo FraCabCompra, ya que le llegarán los elementos de uno en uno.
Public Class PrcFacturacionCompra
Inherits Process(Of DataPrcFacturacionCompra, ResultFacturacion)
'Lista de tareas a ejecutar
Public Overrides Sub RegisterTasks()
Me.AddTask(Of DataPrcFacturacionCompra)(AddressOf DatosIniciales)
Me.AddTask(Of DataPrcFacturacionCompra, FraCabCompra())(AddressOf
ProcesoFacturacionCompra.AgruparAlbaranesCompra)
Me.AddTask(Of FraCabCompra())(AddressOf ProcesoFacturacionCompra.Ordenar)
'Bucle para recorrer todos los documentos a factura a generar
Me.AddForEachTask(Of PrcCrearFraCompra)(OnExceptionBehaviour.NextLoop)
Me.AddTask(Of Object, ResultFacturacion)(AddressOf
ProcesoFacturacionCompra.Resultado)
End Sub
'Registar en el services la información que vamos a compartir durante el proceso, para
evitar accesos innecesarios
<Task()> Public Shared Sub DatosIniciales(ByVal data As DataPrcFacturacionCompra,
ByVal services As ServiceProvider)
Dim TipoLineaDef As String = New TipoLinea().TipoLineaPorDefecto
services.RegisterService(New ProcessInfoFra(data.IDContador, TipoLineaDef,
data.SuFactura))
Dim Facturas As DataTable = New FacturaCompraCabecera().AddNew
services.RegisterService(New ResultFacturacion(Facturas))
End Sub
End Class
Ejemplo 2: (Proceso de Contabilización de Remesa)
Este proceso tiene como entrada un objeto del tipo DataPrcContabilizacionRemesa y devuelve un objeto de
tipo ResultContabilizacion.
Está formado por varias tareas.
También se incluye mediante una condición la llamada a otro proceso. Si la tarea RemesaAlCobro devuelve
el valor True (esta tarea se introduce mediante un delegado), se ejecuta el proceso
PrcContabilizacionRemesaAlCobro
Public Class PrcContabilizacionRemesa
Inherits Process(Of DataPrcContabilizacionRemesa, ResultContabilizacion)
'Lista de tareas a ejecutar
Public Overrides Sub RegisterTasks()
Me.AddTask(Of DataPrcContabilizacionRemesa)(AddressOf
ProcesoContabilizacion.DatosIniciales)
Me.AddIfThenTask(Of PrcContabilizacionRemesaAlCobro,
DataPrcContabilizacionRemesa)(New BooleanTaskDelegate(Of
DataPrcContabilizacionRemesa)(AddressOf RemesaAlCobro))
Me.AddIfThenTask(Of PrcContabilizacionRemesaAlDescuento,
DataPrcContabilizacionRemesa)(New BooleanTaskDelegate(Of
DataPrcContabilizacionRemesa)(AddressOf RemesaAlDescuento))
Me.AddTask(Of Object, ResultContabilizacion)(AddressOf
ProcesoContabilizacion.GetResultado)
End Sub
<Task()> Public Shared Function RemesaAlCobro(ByVal data As
DataPrcContabilizacionRemesa, ByVal services As ServiceProvider) As Boolean
Return data.TipoRemesa = enumTipoRemesa.RemesaAlCobro
End Function
<Task()> Public Shared Function RemesaAlDescuento(ByVal data As
DataPrcContabilizacionRemesa, ByVal services As ServiceProvider) As Boolean
Return data.TipoRemesa = enumTipoRemesa.RemesaAlDescuento
End Function
30/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Class
Volver al Índice
3.
Control de Excepciones
Cuando se produce una excepción en un proceso, salta el evento OnException que capturaremos si
queremos realizar un tratamiento de la excepción. Este retornará un valor que indicará como debe
comportarse el proceso tras finalizar la tarea que ha producido la excepción. Los valores posibles a retornar,
son :
OnExceptionBehaviour.ThrowException
(valor predeterminado) Propaga la
excepción
OnExceptionBehaviour.NextTask
Ejecuta la siguiente tarea
OnExceptionBehaviour.NextLoop
Ejecuta la siguiente iteración
OnExceptionBehaviour.Exit
Sale de la iteración, proceso, …
Protected Overrides Function OnException(ByVal exceptionArgs As
Engine.BE.BusinessProcesses.ProcessExceptionArgs) As
Engine.BE.BusinessProcesses.OnExceptionBehaviour
Dim Datafvr As DataPrcActualizarFactura = exceptionArgs.Services.GetService(Of
DataPrcActualizarFactura)()
Dim fvr As ResultFacturacion = Datafvr.RstFacturacion
Dim log As LogProcess = fvr.Log
ReDim Preserve log.Errors(log.Errors.Length)
Dim fra As FraCab = CType(exceptionArgs.TaskData, DocumentoFacturaVenta).Cabecera
If TypeOf fra Is FraCabAlbaran Then
Dim FraAlb As FraCabAlbaran = CType(fra, FraCabAlbaran)
Select Case FraAlb.Agrupacion
Case enummcAgrupFactura.mcAlbaran
log.Errors(log.Errors.Length - 1) = New ClassErrors(" Albarán: " &
FraAlb.NAlbaran, exceptionArgs.Exception.Message)
Case enummcAgrupFactura.mcCliente
log.Errors(log.Errors.Length - 1) = New ClassErrors(" Cliente: " &
FraAlb.IDCliente, exceptionArgs.Exception.Message)
End Select
ElseIf TypeOf fra Is FraCabObra Then
Dim FraObra As FraCabObra = CType(fra, FraCabObra)
Select Case FraObra.AgrupacionObra
Case enummcAgrupFacturaObra.mcCliente
log.Errors(log.Errors.Length - 1) = New ClassErrors(" Cliente: " &
FraObra.IDCliente, exceptionArgs.Exception.Message)
Case enummcAgrupFacturaObra.mcObra
log.Errors(log.Errors.Length - 1) = New ClassErrors(" Obra: " &
FraObra.NObra, exceptionArgs.Exception.Message)
Case enummcAgrupFacturaObra.mcObraPedidoClte
log.Errors(log.Errors.Length - 1) = New ClassErrors("
Obra/PedidoCliente: " & FraObra.NObra & "/" & FraObra.NumeroPedido,
exceptionArgs.Exception.Message)
Case enummcAgrupFacturaObra.mcObraTrabajo
log.Errors(log.Errors.Length - 1) = New ClassErrors(" Obra/Trabajo: "
& FraObra.NObra & "/" & FraObra.IDTrabajo, exceptionArgs.Exception.Message)
End Select
End If
Return MyBase.OnException(exceptionArgs)
End Function
4.
Llamada a Procesos
Para hacer la llamada a un proceso fuera de una lista de tareas, lo haremos de la siguiente manera.
Desde Negocio:
Dim dataAddAptes As New Financiero.DataPrcAddApuntes(DtAsientoReg, Nothing)
Dim ResultAddApuntes As DataResultadoAddApuntes =
ProcessServer.RunProcess(GetType(PrcAddApuntes), dataAddAptes)
Desde Presentación:
31/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Dim dataAddAptes As New Financiero.DataPrcAddApuntes(Me.Asientos, Me.Analitica)
ResultAddApuntes = New BE.DataEngine().RunProcess(GetType(PrcAddApuntes), dataAddAptes)
Volver al Índice
5.
Ejemplo Creación Proceso
COMO CREAR UN ALBARAN DE VENTA
Queremos generar un Albarán de Venta partiendo de una información mínima como puede ser, por ejemplo,
un cliente, un artículo, una cantidad y un precio.
Sabemos que el Albarán ahora se almacena en el sistema a través de un ‘DocumentoAlbaranVenta’, por lo
que nos surgirán algunas dudas. ¿Tenemos que construir un objeto del tipo ‘DocumentoAlbaranVenta’?
¿cómo? ¿tendremos que crear un proceso específico para crear un Albarán? La primera tarea del
RegisterUpdateTask es un UpdatePackage ¿cómo lo construimos? ¿Qué información debe llevar este
objeto?
Vamos a intentar solventar estas dudas a través de unos ejemplos.
Detalles a tener en cuenta:
-
El objeto UpdatePackage NO es SERIALIZABLE
-
Vínculos entre tablas (la información del Albarán se guarda en el origen desde el que se genera el
albarán, o bien, la información del origen se guarda en el Albarán)
Visión de un solo cliente o adaptación de nuestro procesos a otros posibles clientes. (procesos)
-
Utilizaremos la clase DataCrearAlbaranVenta para pasar la información suficiente a Negocio.
<Serializable()> _
Public Class DataCrearAlbaranVenta
Public IDCliente As String
Public IDArticulo As String
Public Cantidad As Double
Public Precio As Double
Public Sub New(ByVal IDCliente As String, ByVal IDArticulo As String, ByVal Cantidad
As Double, ByVal Precio As Double)
Me.IDCliente = IDCliente
Me.IDArticulo = IDArticulo
Me.Cantidad = Cantidad
Me.Precio = Precio
End Sub
End Class
Opción 1
La primera opción y más sencilla, nos permite generar un albarán tal cual. Pero tiene el inconveniente que no
podemos saber qué albarán se ha generado, aunque podemos asegurarnos que se graba a través del
Update, con lo que las tareas que estén inventariadas en el RegisterUpdateTask de AlbaranVentaCabecera
las ejecutará.
Sin vínculos con la tabla de la provienen los datos del Albarán, o bien, con un vínculo a dicha tabla,
guardando el identificador del registro origen en alguna tabla del albarán, ya sea la cabecera, líneas,…
En Negocio tendremos una tarea:
'// Opción 1
<Task()> Public Shared Sub CrearAlbaranVenta(ByVal data As DataCrearAlbaranVenta, ByVal
services As ServiceProvider)
'//Rellenamos un registro de Cabecera
Dim AVC As New AlbaranVentaCabecera
Dim dtCab As DataTable = AVC.AddNewForm
AVC.ApplyBusinessRule("IdCliente", data.IDCliente, dtCab.Rows(0))
AVC.ApplyBusinessRule("FechaAlbaran", Today, dtCab.Rows(0))
'//Rellenamos un registro de Lineas
Dim context As New BusinessData(dtCab.Rows(0))
32/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Dim AVL As New AlbaranVentaLinea
Dim dtLin As DataTable = AVL.AddNewForm
AVL.ApplyBusinessRule("IdArticulo", data.IDArticulo, dtLin.Rows(0), context)
AVL.ApplyBusinessRule("QServida", data.Cantidad, dtLin.Rows(0), context)
dtLin.Rows(0)("Regalo") = 0
Dim upg As New UpdatePackage
upg.Add(dtCab)
upg.Add(dtLin)
AVC.Update(upg)
End Sub
En presentación la utilizaremos de la siguiente manera:
Private Sub btnOpcion1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnOpcion1.Click
Dim data As New DataCrearAlbaranVenta
data.IDCliente = Me.advCliente.Value
data.IDArticulo = Me.advArticulo.Value
data.Cantidad = Me.nbxCantidad.Value
data.Precio = Me.nbxPrecio.Value
ExpertisApp.ExecuteTask(Of DataCrearAlbaranVenta)(AddressOf
GenerarAlbaranVenta.CrearAlbaranVenta, data)
ExpertisApp.GenerateMessage("Albarán generado.")
End Sub
Opción 2
Si varios clientes nos piden una funcionalidad similar, que no está en eXpertis, con pequeñas peculiaridades
para cada cliente, podemos desarrollarla de manera que, utilizando la sobreescritura de procesos, podamos
adaptar la funcionalidad a las necesidades del cliente. En este caso utilizaremos un proceso para generar el
Albarán.
Por otro lado, según las necesidades del proceso, el tratamiento que el proceso RegisterUpdateTask da a los
datos, puede no ser exactamente igual que lo requerido en el proceso de generación del albarán. Por
ejemplo, puede que tengamos que generar un albarán que a través del proceso no tenga que calcular cierta
información, por ejemplo, los representantes, por lo que no sería necesario utilizar la tarea que calcule los
representantes.
Para el ejemplo, vamos a partir de una tabla de estas características. (la llamaremos tbMaestroEjemplo)
En la que tenemos unos datos de origen a través de los cuales generaremos un albarán con una línea, la
cual vincularemos a la tabla origen e indicaremos al usuario qué albarán se ha generado. Suponemos los
siguientes datos:
La Razón Social ha sido modificada por el usuario y le asignaremos un precio fijo de 15€.
33/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Entonces, para hacer ese ejemplo, necesitaremos crear 2 tipos AlbCabVentaEjemplo y AlbLinVentaEjemplo.
Estos tipos serán los que contengan la información mínima a rellenar para crear el Albarán, heredarán de los
tipos base para crear el albarán (AlbCabVenta y AlbLinVenta). Por el hecho de heredar de AlbCabVenta y
AlbLinVenta se rellenará cierta información en estas clases nuevas.
Public Class AlbCabVentaEjemplo
Inherits AlbCabVenta
Public RazonSocial As String
Public Overrides Function FieldNOrigen() As String
Return String.Empty
'''Indicamos el campo cual es el campo NOrigen, en caso
de que exista (en este ejemplo no existe)
End Function
Public Overrides Function PrimaryKeyCabOrigen() As String
Return New String("IDOrigen")
'''Indicamos cual es el campo IDOrigen de la
cabecera (en este ejemplo, será el mismo que ls líneas)
End Function
Public Sub New(ByVal row As DataRow)
MyBase.New(row)
MyBase.Origen = -1 'enumOrigenAlbaranVenta.Ejemplo
'''El campo Razón social del origen tenemos que trasladarlo al campo PedidoCliente
de la cabecera del albarán
Me.RazonSocial = row("RazonSocial") & String.Empty
End Sub
End Class
Public Class AlbLinVentaEjemplo
Inherits AlbLinVenta
Public Overrides Function PrimaryKeyLinOrigen() As String
Return New String("IDOrigen") '''Indicamos cual es el campo IDOrigen de las
lineas (en este ejemplo, será el mismo que de la cabecera)
End Function
Public Sub New(ByVal oRow As DataRow)
MyBase.New(oRow) '//Aquí se rellena el IDLineaOrigen de AlbLinVenta
Me.QaServir = Nz(oRow("Cantidad"), 0)
'''Como no vamos a modificar la cantidad
del registro, la podemos asignar en este punto.
End Sub
End Class
AlbCabVentaEjemplo contendrá la información mínima para crear una cabecera y, lo mismo ocurre con
AlbLinVentaEjemplo para las líneas. (En la versión 4.1 de eXpertis, estas clases equivalen a los DataTables
de cabeceras y líneas que surgían de hacer las agrupaciones ).
Y nos quedará crear una clase que será un proceso con algunas tareas específicas para realizar la
funcionalidad del nuevo proceso (Se creará un albarán en el que se trasladan los campos de la tabla
tbMaestroEjemplo; IDCliente, IDArticulo, Cantidad tal cual se esperan y el campo RazonSocial se lleva al
campo PedidoCliente de la cabecera del albarán, así como el precio será fijo 15€. Una vez generado el
albarán, se llevará el IDLineaAlbaran a la tabla tbMaestroEjemplo y se mostrará en presentación cuál es el
albarán generado)
En este ejemplo, le pasamos el IDOrigen del registro a partir del cual vamos a generar el albarán.
Tendremos que crearnos una tarea (DatosIniciales) para convertir dicha información al tipo AlbCabVenta,
que necesitamos para crear un documento, luego tendremos utilizar las tareas de Expertis para crear el
DocumentoAlbaranVenta y otras para ir completando el documento con la información necesaria para crear
el Albarán según la funcionalidad requerida. Dado que tenemos que asignar la Razón Social al campo
PedidoCliente crearemos una tarea (AsignarFuncionalidadEjemplo) para ello. La tarea para crear las líneas
también tendremos que personalizarla (CrearLineasDesdeEjemplo), para montar las líneas con nuestra
funcionalidad, y más tarde incluiremos una tarea para actualizar el Origen y retornar los datos del albarán
creado (tarea ActualizarOrigen).
(Los accesos a la tabla tbMaestroEjemplo están hechos de manera que no haya que crear una entidad para
ello, aunque lo programado en la tarea ActualizarOrigen también requiera crear la entidad)
Public Class PrcAlbaranarEjemplo
34/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Inherits Process(Of Integer, CreateElement)
'Lista de tareas a ejecutar
Public Overrides Sub RegisterTasks()
Me.AddTask(Of Integer, AlbCabVenta)(AddressOf DatosIniciales)
'EJEMPLO
Me.AddTask(Of AlbCabVenta, DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.CrearDocumentoAlbaranVenta)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarValoresPredeterminadosGenerales)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarDatosCliente)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf AsignarFuncionalidadEjemplo)
'EJEMPLO
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarDireccion)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf ProcesoAlbaranVenta.AsignarBanco)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoComercial.AsignarObservacionesComercial)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoComunes.AsignarCentroGestion)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf ProcesoComunes.AsignarAlmacen)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarContador)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoComunes.AsignarNumeroAlbaran)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf ProcesoComercial.AsignarEjercicio)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoComunes.AsignarCambiosMoneda)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf CrearLineasDesdeEjemplo)
'EJEMPLO
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.GestionArticulosKit)
'Sin Kits
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarDireccionFacturaEnLineas)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarClienteBancoEnLineas)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarEstadoFacturaEnLineas)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AsignarCondicionesEnLineas)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoComunes.CalcularImporteLineasAlbaran)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVentaPedidos.CalcularAnalitica)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.CalcularBasesImponibles)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf ProcesoComunes.TotalDocumento)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf ProcesoAlbaranVenta.TotalPesos)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.ActualizarEstadoAlbaran)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.GrabarDocumento)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.AñadirAResultado)
Me.AddTask(Of DocumentoAlbaranVenta)(AddressOf
ProcesoAlbaranVenta.ActualizacionAutomaticaStock)
Me.AddTask(Of DocumentoAlbaranVenta, CreateElement)(AddressOf ActualizarOrigen)
'EJEMPLO
End Sub
<Task()> Public Shared Function DatosIniciales(ByVal IDOrigen As Integer, ByVal services
As ServiceProvider) As AlbCabVenta
Dim AppParamsGeneral As ParametroTesoreria = services.GetService(Of
ParametroTesoreria)()
Dim ProcInfo As New ProcessInfoAV(Nothing, AppParamsGeneral.TipoAlbaranPorDefecto,
Today, -1)
services.RegisterService(ProcInfo)
'//Para no dar de alta la entidad de ejemplo en el sistema, accedemos a la tabla a
través del Admindata.
Dim dtOrigen As DataTable = AdminData.GetData("tbMaestroEjemplo", New
NumberFilterItem("IDOrigen", IDOrigen))
If dtOrigen.Rows.Count > 0 Then
35/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Dim AVC As New AlbCabVentaEjemplo(dtOrigen.Rows(0))
Dim AVL As New AlbLinVentaEjemplo(dtOrigen.Rows(0))
ReDim Preserve AVC.LineasOrigen(AVC.LineasOrigen.Length)
AVC.LineasOrigen(AVC.LineasOrigen.Length - 1) = AVL
Return AVC
End If
End Function
<Task()> Public Shared Sub AsignarFuncionalidadEjemplo(ByVal data As
DocumentoAlbaranVenta, ByVal services As ServiceProvider)
data.HeaderRow("PedidoCliente") = CType(data.Cabecera,
AlbCabVentaEjemplo).RazonSocial
End Sub
<Task()> Public Shared Sub CrearLineasDesdeEjemplo(ByVal data As DocumentoAlbaranVenta,
ByVal services As ServiceProvider)
Dim AVL As New AlbaranVentaLinea
For Each alblin As AlbLinVentaEjemplo In data.Cabecera.LineasOrigen
Dim dtDatosOrigen As DataTable = AdminData.GetData("tbMaestroEjemplo", New
NumberFilterItem("IDOrigen", alblin.IDLineaOrigen))
If dtDatosOrigen.Rows.Count > 0 Then
Dim context As New BusinessData(data.HeaderRow)
Dim linea As DataRow = data.dtLineas.NewRow
linea("IDAlbaran") = data.HeaderRow("IDAlbaran")
ProcessServer.ExecuteTask(Of DataRow)(AddressOf
ProcesoAlbaranVenta.AsignarValoresPredeterminadosLinea, linea, services)
linea = AVL.ApplyBusinessRule("IDArticulo",
dtDatosOrigen.Rows(0)("IdArticulo"), linea, context)
linea = AVL.ApplyBusinessRule("Cantidad",
dtDatosOrigen.Rows(0)("Cantidad"), linea, context)
linea("IDFormaPago") = data.HeaderRow("IDFormaPago")
linea = AVL.ApplyBusinessRule("IDCondicionPago ",
data.HeaderRow("IDCondicionPago"), linea, context)
linea = AVL.ApplyBusinessRule("Precio", 15, linea, context)
data.dtLineas.Rows.Add(linea.ItemArray)
End If
Next
End Sub
<Task()> Public Shared Function ActualizarOrigen(ByVal data As DocumentoAlbaranVenta,
ByVal services As ServiceProvider) As CreateElement
'//Código de ejemplo, por no tener una Entidad Asociada a la tabla
tbMaestroEjemplo
Dim dtOrigen As DataTable = AdminData.GetData("tbMaestroEjemplo", New
NumberFilterItem("IDOrigen", data.Cabecera.IDOrigen))
dtOrigen.TableName = "Ejemplo"
If dtOrigen.Rows.Count > 0 AndAlso data.dtLineas.Rows.Count > 0 Then
dtOrigen.Rows(0)("IDLineaAlbaran") = data.dtLineas.Rows(0)("IDLineaAlbaran")
End If
AdminData.SetData(dtOrigen)
Dim e As New CreateElement
e.IDElement = data.HeaderRow("IDAlbaran")
e.NElement = data.HeaderRow("NAlbaran")
Return e
End Function
Desde presentación:
Private Sub btnOpcion2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnOpcion2.Click
Dim ID As Integer = 11111
Dim info As CreateElement = ExpertisApp.RunProcess(Of PrcAlbaranarEjemplo)(ID)
If Not info Is Nothing Then
ExpertisApp.GenerateMessage("Se la creado el Albarán {0}.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information,
info.NElement)
End If
End Sub
Opción 3
36/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Usando extensibilidad, podemos hacer un proceso utilizando el Update para crear el Albarán (similar al caso
1) y poder recuperar cuál es el Albarán creado.
Public Class DataAlbaran
Public IDAlbaran As Integer
Public NAlbaran As String
Public Sub New(ByVal IDAlbaran As Integer, ByVal NAlbaran As String)
Me.IDAlbaran = IDAlbaran
Me.NAlbaran = NAlbaran
End Sub
End Class
Public Class AlbaranesCreados
Public Albaranes As Hashtable
Public Sub New()
Albaranes = New Hashtable
End Sub
End Class
'// Opción 3
<Task()> Public Shared Function CrearAlbaranVentaConAlbaran(ByVal data As
DataCrearAlbaranVenta, ByVal services As ServiceProvider) As CreateElement()
'//Rellenamos un registro de Cabecera
Dim AVC As New AlbaranVentaCabecera
Dim dtCab As DataTable = AVC.AddNewForm
AVC.ApplyBusinessRule("IdCliente", data.IDCliente, dtCab.Rows(0))
AVC.ApplyBusinessRule("FechaAlbaran", Today, dtCab.Rows(0))
'//Rellenamos un registro de Lineas
Dim context As New BusinessData(dtCab.Rows(0))
Dim AVL As New AlbaranVentaLinea
Dim dtLin As DataTable = AVL.AddNewForm
AVL.ApplyBusinessRule("IdArticulo", data.IDArticulo, dtLin.Rows(0), context)
AVL.ApplyBusinessRule("QServida", data.Cantidad, dtLin.Rows(0), context)
dtLin.Rows(0)("Regalo") = 0
Dim upg As New UpdatePackage
upg.Add(dtCab)
upg.Add(dtLin)
AVC.Update(upg, services)
Return ProcessServer.ExecuteTask(Of Object, CreateElement())(AddressOf
RecuperarElementoCreado, Nothing, services)
End Function
'//Tarea que intercalaremos en el RegisterUpdateTask del Albaran de Venta, tras el
MarcarComoActualizado, por ejemplo.
<Task()> Public Shared Sub CachearElementoCreado(ByVal data As DocumentoAlbaranVenta,
ByVal services As ServiceProvider)
If data.HeaderRow.RowState = DataRowState.Added Then
Dim alb As New DataAlbaran(data.HeaderRow("IDAlbaran"),
data.HeaderRow("NAlbaran"))
Dim htAlb As AlbaranesCreados = services.GetService(Of AlbaranesCreados)()
htAlb.Albaranes(data.HeaderRow("IDAlbaran")) = alb
End If
End Sub
<Task()> Public Shared Function RecuperarElementoCreado(ByVal data As Object, ByVal
services As ServiceProvider) As CreateElement()
Dim Elems(-1) As CreateElement
Dim htAlb As AlbaranesCreados = services.GetService(Of AlbaranesCreados)()
For Each item As DataAlbaran In htAlb.Albaranes.Values
Dim e As New CreateElement
e.IDElement = item.IDAlbaran
e.NElement = item.NAlbaran
ReDim Preserve Elems(Elems.Length)
Elems(Elems.Length - 1) = e
Next
Return Elems
End Function
37/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Y desde presentación:
Private Sub btnOpcion3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnOpcion3.Click
Dim data As New DataCrearAlbaranVenta(Me.advCliente.Value, Me.advArticulo.Value,
Me.nbxCantidad.Value, Me.nbxPrecio.Value)
Dim elem As CreateElement() = ExpertisApp.ExecuteTask(Of DataCrearAlbaranVenta,
CreateElement())(AddressOf GenerarAlbaranVenta.CrearAlbaranVentaConAlbaran, data)
If Not elem Is Nothing AndAlso elem.Length > 0 Then
ExpertisApp.GenerateMessage("Se ha creado el Albarán {0}.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information,
elem(0).NElement)
End If
End Sub
Volver al Índice
Programación General Capa Negocio
1.
Creación / Configuración de Proyectos de Negocio
Método Manual Creación Proyecto
Para crear un componente de la capa de negocio, crear un nuevo proyecto de Windows -> Visual Basic, del
tipo Biblioteca de clases en VS2008. Establecer el nombre y la ubicación del proyecto como en la imagen.
Así mismo asegurarnos de elegir la Opción de Arriba que esté en .NetFrameWork 3.5.
En la página de propiedades del proyecto se puede comprobar cómo el nombre del proyecto define por
defecto un espacio de nombres.
El framework de .NET utiliza los espacios de nombres para definir ámbitos de objetos relacionados. Estos
ámbitos permiten organizar el código y proporciona una forma de crear tipos globalmente únicos.
Para diferenciar el componente de negocio nuevo del resto de componentes de negocio estándares,
podemos cambiar el espacio de nombres de la raíz como aparece en la imagen
38/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
NOTA: El espacio de nombres de la raíz de los proyectos de negocio estándar de Expertis tiene la forma
Solmicro.Expertis.Business.nombre_negocio
Opciones de Compilación y Depuración del Proyecto
Para la compilación de un proyecto de negocio hay que tener en cuenta la ubicación final de los
ensamblados.
Existen varias opciones pero lo más habitual es:
A. Compilar directamente en el directorio de desarrollo (en este caso C:\ExpertisNet50t\Bin)
Para ello, desde la página de propiedades del proyecto, en la sección Compilar se establece la Ruta
de acceso de los resultados
B. La segunda opción es compilar en el directorio bin del proyecto (el que está establecido por
defecto), y después copiar “a mano” los ensamblados actualizados al directorio de desarrollo.
NOTA: Existe un inconveniente en esta opción que consiste en que mientras se compila el proyecto no es posible tener
abierto ningún otro proyecto que lo tenga referenciado. Durante la compilación se muestra un error que nos avisa de que el
archivo está siendo utilizado por otro proceso. Esto es debido a que el directorio de compilación y al que apuntan las
referencias del resto de proyectos es, habitualmente, el mismo. No tiene por qué suceder esto en el 100% de los casos. A
veces el visual studio 2008 es inteligente y se entera de los cambios que ha habido, pero no es la mayoría de los casos.
Si queremos compilar correctamente debemos cerrar todos los proyectos que tengan referenciado el proyecto que se
quiere compilar.
Referencias del Proyecto
39/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En la mayoría de los casos las clases de negocio tienen que utilizar los servicios que les proporcionan los
componentes de negocio y de datos del framework de eXpertis. Para utilizar dichos servicios es necesario
referenciar los siguientes componentes del Engine de eXpertis
Expertis.Engine.BE.BusinessEngine
Expertis.Engine.DAL
Expertis.Engine.Global
Para agregar una referencia al proyecto, accedemos a las propiedades del proyecto y vamos a la pestaña de
Referencias.
O bien desde el menú Proyecto -> Agregar referencia
40/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez agregadas las referencias tenemos que asegurarnos en las propiedades de cada una de las dlls del
motor que tienen las propiedades de Copia Local y Copia Específica a False. Hay que recordar que estas
dos propiedades en todas las dlls que tenga nuestro proyecto siempre estén a falso. Tanto dlls del Engine de
Expertis, como dlls de capa de negocio, de capa de presentación, de las de janus en presentación, etc.…
todas las referencias sin excepción.
El componente Expertis.Engine.BE.BusinessEngine permite establecer un vínculo entre la capa de
presentación y la capa de negocio. La clase BusinessHelper que se encuentra en esta librería se utiliza como
clase base para la gran mayoría de los componentes funcionales de la capa de negocio.
La clase base BusinessHelper hereda de la clase ContextBoundObject propia del framework de .NET, y tiene
asociado el atributo TransactionalAttribute (también propia de .NET), todo ello permite que todas las clases
que heredan de BusinessHelper se puedan integrar en un contexto transaccional, y en particular, en el
contexto transaccional de eXpertis.
Además, BusinessHelper, define una interfaz común que permite la comunicación entre los componentes del
Engine de la capa de presentación y los componentes de negocio. A menudo el desarrollo funcional se basa
en sobrescribir los métodos que proporciona la clase BusinessHelper.
El componente Expertis.Engine.DAL proporciona una interfaz de programación que permite acceder a la
base de datos, utilizando la capa de datos desde la capa de negocio.
NOTA: La clase más utilizada de este componente es la clase AdminData. Casi todos los métodos de esta clase son
Shared, con lo que en la gran mayoría de los casos utilizaremos directamente el nombre AdminData para utilizar sus
métodos, y no será necesario crear una instancia de la clase.
En muchos casos será suficiente con utilizar los componentes de negocio del Engine de eXpertis
Expertis.Engine.BE.BusinessEngine, pero en ciertos desarrollos es necesario invocar los métodos de la
clase AdminData para actualizar datos, realizar consultas, gestionar transacciones, gestionar la conexión con
diferentes bases de datos de usuario, etc.
El ensamblado Expertis.Engine.Global es una componente de uso general, tanto en la parte cliente, como en
la parte de negocio, y dispone de un conjunto de clases publicas útiles en desarrollo.
También es muy común encontrar en los proyectos de negocio una referencia a
Expertis.Business.BusinessEnum. Este es un componente de negocio que contiene exclusivamente la
definición de los enumerados que se utilizan en la aplicación. De esta manera la definición de los
enumerados queda englobada en el mismo ámbito y se pueden utilizar en el resto de los componentes de la
capa de negocio.
En principio, no es obligatorio agregar una referencia a otros componentes externos de negocio. Solo
agregar la referencia cuando sea necesario. De esta manera, en la medida de lo posible, se evita la
dependencia entre los distintos componentes de negocio, hecho que facilita la compilación y posterior
distribución de ensamblados.
41/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
NOTAS: A parte de los componentes del Engine, los componentes de negocio funcionales pueden referenciar a otros
componentes de negocio. Por ejemplo, en el estándar de eXpertis el ensamblado Expertis.Business.Negocio.dll contiene
la mayoría de las clases funcionales centrales de la aplicación (Artículo, Cliente, Proveedor, Moneda, etc.), el resto de
componentes de negocio necesitan utilizar en mayor o menor medida dichas clases, y por ello poseen una referencia a
dicha DLL.
Método Template Creación Proyecto
Otro método para la creación de un proyecto de eXpertis de tipo Negocio. Tendremos la posibilidad de seleccionar un
template / plantilla personalizado de expertis para este fin (sistema de templates anteriormente descrito).
Para ello bastará con que abramos el visual studio. Damos a la opción de Archivo -> Nuevo -> Proyecto.
En el nuevo menú nos aseguraremos de dar a la opción de .NetFrameWork 3.5. y elegiremos en la opción de la izquierda
VisualBasic, para que efectivamente ya en plantillas nos cargue las plantillas para aplicaciones en VisualBasic. Como
últimos nos fijamos que en la sección Mis Plantillas tendremos una personalizada de Solmicro llamada:
ProjectBusinessExpertis.
Una vez realizado esto bastará con que demos un nombre personalizado al proyecto y aceptemos.
Con este paso ya tendríamos creado un proyecto de negocio de eXpertis y con una clase minima ya existente que
podremos cambiar su nombre y editarla para darle forma a una entidad de expertis
42/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Si pasásemos a ver las propiedades del proyecto y sus referencias tendremos las ya comentadas y necesarias en el
proceso manual de creación de un proyecto de negocio de eXpertis.
Volver al Índice
2.
Creación de Entidades de Negocio
Método Manual Creación Entidad
Agregar una clase nueva al proyecto desde la acción Agregar nuevo elemento del menú contextual del
proyecto:
El código básico para crear una clase de negocio tiene esta forma
Public Class CursoArticulo
Inherits Solmicro.Expertis.Engine.BE.BusinessHelper
Private Const cnEntidad As String = "tbCursoMaestroArticulo"
43/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Public Sub New()
MyBase.New(cnEntidad)
End Sub
End Class
En este ejemplo se crea la clase de negocio CursoArticulo que está asociada a la tabla
tbCursoMaestroArticulo. Esta clase deberá contener la lógica de negocio que se corresponde con la
funcionalidad que se le da a la información con la cual se asocia la clase, en este caso, los datos de la tabla.
A partir de este código de ejemplo, crear las clases (entre paréntesis se define la constante cnEntidad):
CursoFacturaVentaAnalitica (tbCursoFacturaVentaAnalitica)
CursoFacturaVentaCabecera (tbCursoFacturaVentaCabecera)
CursoFacturaVentaLinea (tbCursoFacturaVentaLinea)
CursoArticulo (tbCursoMaestroArticulo)
CursoCliente (tbCursoMaestroCliente)
CursoMoneda (tbCursoMaestroMoneda)
CursoTipoIva (tbCursoMaestroTipoIva)
Cuando se crea el componente de negocio, el siguiente paso es actualizar la base de datos de sistema, para
que las nuevas clases se incluyan en el conjunto de metadatos de dicha base de datos.
Método Template Creación Entidad
Para agregar una entidad de expertis usando template iremos a: Proyecto -> Agregar Nuevo elemento
Después de este menú accederemos en el siguiente en la sección de la izquierda a Elementos Comunes y
después en el centro abajo del todo buscamos en la sección de mis plantillas una personalizado de solmicro
de ClassExpertis.
44/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Con esto nos agregará un fichero de clase tipo Entidad de eXpertis. Lo que tendríamos que hacer ahora es
editar el contenido de esta clase para reflejar lo que necesitemos e ir mirando las anotaciones de ayuda de lo
que tenemos que tener en cuenta.
Volver al Índice
3.
Creación de Tareas
Una Tarea en eXpertis sería una función o proceso definido en una clase de Negocio de eXpertis, que posea
el atributo de Task(). Al especificar este atributo dicha función o proceso debe poseer la siguiente forma:
<Task()> Private Shared Sub ProcesoTask(ByVal data As Object, ByVal services As ServiceProvider)
End Sub
La tarea de eXpertis además de este atributo ha de recibir siempre 2 parámetros. Uno el del tipo que
necesitemos y el segundo parámetro siempre un ServiceProvider y llamándolo si se puede como Services.
Asimismo es obligatorio que las funciones o procesos, ya sean privados o públicos o del tipo que
necesitemos, que se definan del tipo Shared. Siempre y obligatoriamente tendremos que definirlas como
Shared.
Para concretar la creación de Tareas en la Capa de negocio dividiríamos en tres tipos las tareas
dependiendo de las necesidades.
A.
Tareas que reciban sólo un parámetro de entrada:
<Task()> Private Shared Sub ProcesoTask(ByVal data As String, ByVal services As
ServiceProvider)
End Sub
B.
Tareas que reciban más de un parámetro de entrada:
<Serializable()> _
Public Class Datos
Public Valor1 As Double
Public Valor2 As String
Public Valor3 As Integer
Public Sub New()
End Sub
End Class
<Task()> Private Shared Sub ProcesoTask(ByVal Data As Datos, ByVal services As
ServiceProvider)
End Sub
C.
Tareas que no reciban parámetros de entrada (si no se recibe parámetro de entrada se deja de
tipo object por defecto):
<Task()> Private Shared Sub ProcesoTask(ByVal data As Object, ByVal services As
ServiceProvider)
45/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
4.
Llamada a Tareas en Capa Negocio
Para llamar a otras Tareas de Negocio desde Negocio lo haremos con el objeto ProcessServer,
perteneciente
al
dll
de
Expertis.Engine.BE,
y
en
el
espacio
de
nombres
de
Expertis.Business.BE.BusinessProcessess. Es de tipo Shared con lo cual haciendo una importación a este
espacio de nombres nos permitirá usarlo sin necesidad de instanciarlo.
Este objeto ProcessServer posee el método de ExecuteTask con el que podremos llamar y configurar la
tarea que deseamos llamar. Especificando los parámetros de entrada, salida y dirección de la función.
Vemos en el siguiente ejemplo la llamada a una tarea con un parámetro de entrada y llamándolo desde otra
función de Negocio.
<Task()> Public Shared Sub LlamarSuma(ByVal Data As Object, ByVal Services As ServiceProvider)
Dim StData As DatosSuma
StData.Valor1 = 1 : StData.Valor2 = 2
Dim DblResultado As Double = ProcessServer.ExecuteTask(Of DatosSuma, Double)(AddressOf
CalcularSuma, StData, Services)
End Sub
Private Class DatosSuma
Public Valor1 As Double
Public Valor2 As Double
Public Sub New()
End Sub
End Class
<Task()> Private Shared Function CalcularSuma(ByVal data As DatosSuma, ByVal services As
ServiceProvider) As Double
Dim DblResultado As Double
DblResultado = data.Valor1 + data.Valor2
Return DblResultado
End Function
NOTA: siempre se ha de pasar el parámetro de Services del tipo ServiceProvider al llamar a tareas de negocio desde
negocios.
Volver al Índice
5.
Procesos Entidades
46/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Los procesos son una lista de tareas que dado un objeto de entrada lo transforma en otro objeto a la salida.
Pudiendo ser el mismo objeto de entrada con más cosas añadidas, o bien, otro objeto completamente
diferente.
En esa lista de tareas el objeto de salida de una tarea es la entrada para la siguiente tarea, y esto se asume
si no especificamos el tipo de salida.
Algunos de estos procesos, son propios del motor, como son RegisterDeleteTask, RegisterValidateTask,
RegisterUpdateTask, GetBusinessRules y RegisterAddNewTasks. En la definición de estos procesos,
construimos la lista de tareas, pero dichas tareas no se ejecutarán en ese momento. Los procesos
RegisterDeleteTask y RegisterUpdateTask tienen, además, otra peculiaridad (DeleteProcessContext y
UpdateProcessContext, respectivamente).
El orden de ejecución de los procesos de una entidad cuando enviamos en algún caso la demanda de varios
estados: insertados, actualizados y borrados, sería:
DELETE
(RegisterDeleteTasks)
VALIDATE
(RegisterValidateTasks)
UPDATE
(RegisterUpdateTasks)
Como se puede apreciar siempre se ejecutarían primero la demanda de los registros borrados y a
continuación se ejecutaría la validación de los registros nuevos y modificaciones y por último la inserción y
modificación de dichos registros.
a.
Proceso RegisterValidateTasks [Validaciones Generales]
El proceso RegisterValidateTasks sería el evento de una clase de negocio que usaríamos para concretar
una lista de tareas a ejecutar, cuya labor sea efectivamente realizar validaciones de los datos antes de
grabarlos en la base de datos, y antes de llamar al evento RegisterUpdateTasks. Ejecutaría este método
automáticamente el motor de eXpertis cuando hagamos actualizaciones de una clase, ya sea inserciones
o modificaciones.
En el Proceso RegisterValidateTasks sólo se admite como parámetro de entrada de tipo Datarow. Si se
usase otro tipo no funcionaría correctamente este evento.
Este proceso lo llama automáticamente el motor en caso de ser llamada de actualización de datos desde
formularios u objetos de presentación enlazados a formularios.
En caso de invocar manualmente a un update de una entidad se llamaría unicamente al
RegisterUpdateTasks omitiendo el RegisterValidateTasks. Para ello debemos llamar manualmente al
RegisterValidateTasks a través de método Validate de una entidad
Dim DtArticuloNew As New DataTable
Dim ClsArticulo As New Articulo
ClsArticulo.Validate(DtArticuloNew)
El aspecto general que tendría el Proceso RegisterValidateTasks sería la siguiente:
Protected Overrides Sub RegisterValidateTasks(ByVal validateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterValidateTasks(validateProcess)
validateProcess.AddTask(Of DataRow)(AddressOf ValidarDatosObligatorios)
End Sub
La primera línea de mybase es siempre así y obligatoria para el correcto funcionamiento. Las siguientes
lineas usaríamos el objeto de ValidateProcess en el cual añadiríamos las tareas correspondientes.
47/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el Proceso RegisterValidateTasks sólo se admite como parámetro de entrada de tipo Datarow. Si se
usase otro tipo no funcionaría correctamente este evento.
A.
Campos No Nulos
Validación de campos que no admiten valores nulos. Para evitar que se muestre el error de SQL se
suelen validar en el método RegisterValidateTasks de las clases de negocio.
El código de la validación dependerá del tipo de dato. Por ejemplo, para un tipo de dato cadena una
forma habitual seria
Protected Overrides Sub RegisterValidateTasks(ByVal validateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterValidateTasks(validateProcess)
validateProcess.AddTask(Of DataRow)(AddressOf ValidarCampoNulo)
End Sub
<Task()> Friend Shared Sub ValidarCampoNulo(ByVal data As DataRow, ByVal services As
ServiceProvider)
If Length(data("IDArticulo")) = 0 Then ApplicationService.GenerateError("El campo
IDArticulo es obligatorio.")
End Sub
Donde Data es un objeto DataRow del DataTable que se quiere actualizar.
Usamos el objeto Length que es propio del FrameWork de Expertis. Este método nos comprueba
cualquier tipo de dato (sea tipo texto, numérico, ….) y nos devuelve la longitud de lo comprobado.
Siendo 0 en caso de que lo comprobado sea con valor Nulo.
Otros métodos que tenemos disponibles del framework de .NET: IsDBNull para campos de todo tipo
en general; la función IsNumeric para campos de tipo numérico; la función IsDate para campos de
tipo fecha. Además, dado que la mayoría de las veces la validación se hace sobre un objeto
DataRow, también es frecuente el uso de la función IsNull del objeto DataRow, como en el ejemplo.
NOTA: Todos los mensajes de error se ejecutan utilizando el método GenerateError de la clase
ApplicationService, que está en el componente Solmicro.Expertis.Engine.BE. No es válido utilizar
Windows.Forms para mostrar mensajes desde la capa de negocio.
B.
Claves Primarias Repetidas
La validación de claves repetidas también se programa en el método RegisterValidateTasks de la
clase, y se suele hacer utilizando el método SelOnPrimaryKey de la propia clase. Por ejemplo
Protected Overrides Sub RegisterValidateTasks(ByVal validateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterValidateTasks(validateProcess)
validateProcess.AddTask(Of DataRow)(AddressOf ValidarClavePrimaria)
End Sub
<Task()> Friend Shared Sub ValidarClavePrimaria(ByVal data As DataRow, ByVal services As
ServiceProvider)
Dim Dt As DataTable = New Articulo().SelOnPrimaryKey(data("IDArticulo"))
If Dt.Rows.Count > 0 Then
ApplicationService.GenerateError("El artículo introducido ya existe.")
End If
End Sub
C.
Existencia y Comprobación de Claves Extranjeras
Esta validación también se programa en el método RegisterValidateTasks de la clase, y se suele
hacer utilizando el método SelOnPrimaryKey de la clase correspondiente a la clave extranjera, o
bien con el método GetItemRow, también de la misma clase. Hay dos diferencias entre ambas: la
primera es que el método GetItemRow devuelve un DataRow en lugar de un DataTable, y la
segunda es que GetItemRow lanza directamente una excepción si el registro correspondiente a la
clave no existe. Por ejemplo
Protected Overrides Sub RegisterValidateTasks(ByVal validateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterValidateTasks(validateProcess)
validateProcess.AddTask(Of DataRow)(AddressOf ValidarClavePrimaria)
End Sub
<Task()> Friend Shared Sub ValidarClavePrimaria(ByVal data As DataRow, ByVal services As
ServiceProvider)
Dim Dt As DataTable = New CursoTipoIVA().SelOnPrimaryKey(data("IDTipoIVA"))
If Dt.Rows.Count > 0 Then
ApplicationService.GenerateError("El tipo iva | no existe.”, data("IDTipoIVA"))
48/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End If
End Sub
Alternativamente
Dim ti As New CursoTipoIva
ti.GetItemRow(dr("IDTipoIva"))
NOTA: es recomendable el uso de la primera opción, ya que permite mostrar un mensaje personalizado. Es
preferible utilizar GetItemRow en otros procesos.
Volver al Índice
b.
Proceso RegisterUpdateTasks [Reglas de Actualización]
El proceso RegisterUpdateTasks sería el evento de una clase de negocio que usaríamos para
concretar una lista de tareas a ejecutar, cuya labor sea comprobaciones y actualizaciones previas al
grabado en base de datos. Este evento se llamaría de manera automática por parte del motor
después de haber pasado previamente por el RegisterValidateTasks.
El aspecto general que tendría el proceso RegisterUpdateTasks sería la siguiente:
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarClavePrimaria)
End Sub
La primera línea de mybase es siempre así y obligatoria para el correcto funcionamiento. Las
siguientes líneas usaríamos el objeto de UpdateProcess en el cual añadiríamos las tareas
correspondientes.
En el Proceso RegisterUpdateTasks se admiten como parámetros de entrada de tipo Datarow,
DataTable, UpdatePackage y Document. Si se usase otro tipo no funcionaría correctamente este
evento.
El evento update de la entidad NO devuelve un datatable con los datos cambiados (esto era en
versión 4.1 no ahora en 5.0)
i.
Generar Claves Autonuméricas
Para asegurar un comportamiento correcto de los campos auto numérico que se manejan en
eXpertis, estos campos precisan de un mantenimiento especial.
NOTA: El campo auto numérico incremental de SQL no se utiliza en eXpertis, los campos declarados
como auto numéricos comparten contador de manera que no se pueden repetir en distintas tablas.
En primer lugar, se establece el valor por defecto del campo en el método AddNewForm de la
clase correspondiente con el método GetAutoNumeric de AdminData.
En segundo lugar, es necesario validar en el método RegisterUpdateTasks que el auto
numérico es válido, y si no lo es, se le proporciona un valor valido con el método
GetAutoNumeric de AdminData.
El código ejemplo de los dos casos se muestra a continuación, en los que se da valor al campo
auto numérico de la tabla tbCursoFacturaVentaLinea.
Protected Overrides Sub RegisterAddnewTasks(ByVal addnewProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterAddnewTasks(addnewProcess)
addnewProcess.AddTask(Of DataRow)(AddressOf FillDefaultValues)
End Sub
<Task()> Friend Shared Sub FillClavePrimaria(ByVal data As DataRow, ByVal services As
ServiceProvider)
data("IDLineaFactura") = AdminData.GetAutoNumeric
End Sub
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarClavePrimaria)
End Sub
49/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Friend Shared Sub AsignarClavePrimaria(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added Then
If Length(data("IDLineaFactura")) = 0 Then data("IDLineaFactura") =
AdminData.GetAutoNumeric()
End If
End Sub
ii.
Generar Valores de Campos con Contador:
Como en el caso de los campos auto numéricos, los campos cuyos valores provienen de un
contador precisan de un programación adicional. Para ello, se utiliza la clase Contador, que
está en el componente Solmicro.Expertis.Business.Negocio (será necesario añadir una
referencia a dicho componente, si no la tiene).
NOTA: En las tablas donde se utilice un campo cuyo valor proviene de un contador es obligatorio que
exista un campo con el nombre IDContador, de tipo varchar, de longitud 10, y que admita nulos.
Primero, en el método AddNewForm de la clase correspondiente hay que comprobar si la
entidad tiene un contador predeterminado. Si lo tiene, se asignan los valores a los campos
IDContador, con el identificador del contador y el campo que contendrá el valor provisional del
contador.
En segundo lugar, en el método RegisterUpdateTasks de la clase, se comprueba si el registro
necesita un valor de contador (se comprueba si el campo IDContador no es nulo), y si es así,
se le asigna un valor definitivo.
El código ejemplo se muestra a continuación, en los que se da valor al campo NFactura de la
tabla tbCursoFacturaVentaCabecera.
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarContador)
End Sub
<Task()> Friend Shared Sub AsignarContador(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added Then
If Length(data("IDContador")) > 0 Then
Dim StData As New Contador.DatosCounterValue(data("IDContador"), New
OrdenFabricacion, "NFactura", "", "")
data("NFactura") = ProcessServer.ExecuteTask(Of
Contador.DatosCounterValue, String)(AddressOf Contador.CounterValue, StData, services)
End If
End If
End Sub
NOTA: Es obligatorio llamar al método CounterValue de la clase Contador en el momento de actualizar el
registro, ya que es el método que se encarga de actualizar e incrementar los valores de los contadores en
la tabla maestra de contadores.
En el Proceso RegisterUpdateTasks admite como parámetro de entrada de tipo Datarow ,DataTable
y Document. Pudiendo definir para todo el proceso si se desea con datatable, con datarow o con
document, no se pueden mezclar tareas con diferentes tipos.
UpdateEntity y MarcarComoActualizado
En el desarrollo de tareas del proceso de RegisterUpdateTasks, es posible que un desarrollador vea
necesario el poder ejecutar una serie de procesos después de que se grabase un registro de la
entidad. Para ello se han desarrollado dos tareas para llevar a cabo el guardado de datos y
marcarlos como actualizados para el motor mientras podemos seguir ejecutando tareas después.
Para llevar a cabo esto comentando tendremos en el proyecto de: Expertis.Business.General.Comunes todas
estas tareas que vamos a comentar.
Para ello y dependiendo del tipo de entrada de objeto que estemos usando en las tareas del proceso tendremos:
-
UpdateEntityRow
UpdateEntityDataTable
UpdateEntityDocument
Después de ejecutar cualquiera de estas tareas, hay que ejecutar la tarea de marcarlos como actualizados
(MarcarComoActualizado) para que el motor al terminar el listado de tareas del RegisterUpdateTasks no trate de
nuevo de crearnos / actualizarnos los mismos registros:
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
50/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf
updateProcess.AddTask(Of DataRow)(AddressOf
updateProcess.AddTask(Of DataRow)(AddressOf
updateProcess.AddTask(Of DataRow)(AddressOf
AsignarClavePrimaria)
Comunes.UpdateEntityRow)
Comunes.MarcarComoActualizado)
ProcesoPostUpdate)
End Sub
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataTable)(AddressOf AsignarClavePrimaria)
updateProcess.AddTask(Of DataTable)(AddressOf Comunes.UpdateEntityDataTable)
updateProcess.AddTask(Of DataTable)(AddressOf Comunes.MarcarComoActualizado)
updateProcess.AddTask(Of DataTable)(AddressOf ProcesoPostUpdate)
End Sub
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of Document)(AddressOf AsignarClavePrimaria)
updateProcess.AddTask(Of Document)(AddressOf Comunes.UpdateDocument)
updateProcess.AddTask(Of Document)(AddressOf Comunes.MarcarComoActualizado)
updateProcess.AddTask(Of Document)(AddressOf ProcesoPostUpdate)
End Sub
Estas tareas especiales su uso más común es usarlas dentro de este proceso RegisterUpdateTasks pero
pueden usarse en cualquier ámbito.
UpdateDelegatedOn
Cuando tenemos que manejar datos de una entidad en un formulario, cuya entidad se maneja en
negocio a través de un Documento de Expertis, pero el formulario tiene como entidad principal una
tabla que no está relacionada para nada con el documento, tenemos la propiedad
UpdateDelegatedOn.
Esta propiedad nos permite especificar para una entidad hija dentro de un documento cuál es su
padre y guiar así al motor de eXpertis para cuando demandemos actualización de datos de la
entidad, sepa a qué entidad cabecera tiene que ir para llevar a cabo el grabado con el documento
configurado.
Public Class ObraVariosControl
Inherits Solmicro.Expertis.Engine.BE.BusinessHelper
Public Sub New()
MyBase.New(cnEntidad)
End Sub
Private Const cnEntidad As String = "tbObraVariosControl"
Public Overrides ReadOnly Property UpdateDelegatedOn() As
Engine.BE.BusinessHelper
Get
Return BusinessHelper.CreateBusinessObject("ObraCabecera")
End Get
End Property
…………..
End Class
A un Update también se le pueden enviar registros eliminados. Para ello tendrían que ir los registros
del DataTable que enviamos en estado Deleted. En este tipo estado de los rows el motor se
encarga de borrarlos.
Volver al Índice
c.
Proceso RegisterAddNewTasks [Valores por Defecto Nuevo Registro]
Los valores por defecto se programan en el Proceso RegisterAddNewTasks. Sería el evento que el
motor llamaría automáticamente al añadir un nuevo registro en los formularios de tipo SimpleMnto.
En este ejemplo se establecen por defecto los campos FechaAlta, PrecioEstandarA y
PrecioEstandarB
Protected Overrides Sub RegisterAddnewTasks(ByVal addnewProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterAddnewTasks(addnewProcess)
addnewProcess.AddTask(Of DataRow)(AddressOf FillDefaultValues)
End Sub
51/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Friend Shared Sub FillDefaultValues(ByVal data As DataRow, ByVal services As
ServiceProvider)
data("FechaAlta") = Date.Today
data("PrecioEstandarA") = 0
data("PrecioEstandarB") = 0
End Sub
En muchos casos los valores por defecto de ciertos campos están parametrizados a nivel general
en la aplicación. La tabla que contiene estos parámetros es la tabla tbParametro, y la clase de la
capa de negocio que se utiliza para el mantenimiento de esta información es la clase Parámetro,
que está en el componente Solmicro.Expetis.Business.Negocio. Dicha clase posee métodos
específicos para la obtención de los valores correspondientes a cada parámetro.
En este ejemplo los valores de los campos IDFormaEnvio e IDFormaPago se obtienen de los
parámetros de la aplicación
Protected Overrides Sub RegisterAddnewTasks(ByVal addnewProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterAddnewTasks(addnewProcess)
addnewProcess.AddTask(Of DataRow)(AddressOf FillDefaultValues)
End Sub
<Task()> Friend Shared Sub FillDefaultValues(ByVal data As DataRow, ByVal services As
ServiceProvider)
data("FechaAlta") = Date.Today
data("PrecioEstandarA") = 0
data("PrecioEstandarB") = 0
Dim IDHoraPredeterminada As String = New Parametro().HoraPred
If Len(IDHoraPredeterminada) = 0 Then
ApplicationService.GenerateError("El parámetro 'PR_T_HORA' no existe o no está
correctamente configurado.")
Else : data("IdHora") = IDHoraPredeterminada
End If
End Sub
En el Proceso RegisterAddNewTasks se admite sólo como parámetro de entrada de tipo Datarow.
Si se usase otro tipo no funcionaría correctamente este evento.
La llamada a este RegisterAddNewTasks se hace automáticamente en el motor a través de la
entidad configurada en un formulario de tipo SimpleMnto y pulsando en el botón de Nuevo Registro.
Para una llamada manual al proceso de RegisterAddNewTasks llamaríamos al método
AddNewForm de la entidad.
Dim DtArticuloNew As New DataTable
Dim ClsArticulo As New Articulo
DtArticuloNew = ClsArticulo.AddNewForm
Volver al Índice
d.
Proceso RegisterDeleteTasks [Reglas de Borrado]
El Proceso RegisterDeleteTasks sería el evento de una clase que nos serviría para hacer
validaciones previas o llamadas a otras funciones o procesos antes que el motor lleve a cabo el
borrado de datos en la base de datos.
El aspecto general que tendría el Proceso RegisterDeleteTasks sería la siguiente:
Protected Overrides Sub RegisterDeleteTasks(ByVal deleteProcess As
Engine.BE.BusinessProcesses.Process)
MyBase.RegisterDeleteTasks(deleteProcess)
deleteProcess.AddTask(Of DataRow)(AddressOf ComprobarEstado)
End Sub
<Task()> Friend Shared Sub ComprobarEstado(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data("Estado") <> enumofEstado.ofePlanificada Then
ApplicationService.GenerateError("Sólo se permiten eliminar órdenes de fabricación
en estado 'Planificado'")
End If
End Sub
La primera línea de mybase es siempre así y obligatoria para el correcto funcionamiento. Las
siguientes lineas usaríamos el objeto de DeleteProcess en el cual añadiríamos las tareas
correspondientes.
52/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el Proceso RegisterDeleteTasks se admite sólo como parámetro de entrada de tipo Datarow. Si
se usase otro tipo no funcionaría correctamente este evento.
DeleteEntityRow y MarcarComoEliminado
En el desarrollo de tareas del proceso de RegisterDeleteTasks, es posible que un desarrollador vea
necesario el poder ejecutar una serie de procesos después de que se borre un registro de la
entidad. Para ello se han desarrollado dos tareas para llevar a cabo el borrado de datos y marcarlos
como borrados para el motor y podemos seguir ejecutando tareas después.
Tendremos en el proyecto de: Expertis.Business.General.Comunes todas estas tareas que vamos a comentar.
DeleteEntityRow.
Después de ejecutar cualquier de estas tareas hay que ejecutar la tarea de marcarlos como eliminados
(MarcarComoEliminado) para que el motor al terminar el listado de tareas del RegisterDeleteTasks no trate de
nuevo de borrar los mismos registros:
Protected Overrides Sub RegisterDeleteTasks(ByVal deleteProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterDeleteTasks(deleteProcess)
deleteProcess.AddTask(Of DataRow)(AddressOf BorrarRelacionados)
deleteProcess.AddTask(Of DataRow)(AddressOf Comunes.DeleteEntityRow)
deleteProcess.AddTask(Of DataRow)(AddressOf Comunes.MarcarComoEliminado)
deleteProcess.AddTask(Of DataRow)(AddressOf ProcesoPostDelete)
End Sub
Estas tareas especiales su uso más común es usarlas dentro de este proceso RegisterDeleteTasks pero pueden
usarse en cualquier otro ámbito.
DeleteRowCascade
Cuando queremos borrar registros relacionados en una entidad dentro de las tareas de borrado de
una entidad, no podemos usar simplemente la llamada Delete de la entidad para esos registros,
puesto que no hay garantía de que el motor nos llame en cascada al resto de RegisterDeleteTasks
de las entidades relacionadas.
Para ello disponemos del método DeleteRowCascade para garantizar que el registro que queremos
borrar recursivamente y se llamen a sus entidades relacionadas y se tenga en cuenta la
configuración de borrados en cascada programados en el manager.
<Task()> Public Shared Sub EliminarComponentes(ByVal Linea As System.Data.DataRow,
ByVal services As ServiceProvider)
'KITS Y SUBCONTR. que no vienen de producción
If Linea(_ACL.EstadoStock) = enumaclEstadoStock.aclSinGestion And _
((Linea(_ACL.TipoLineaAlbaran) =
enumaclTipoLineaAlbaran.aclSubcontratacion And IsDBNull(Linea(_ACL.IDOrdenRuta))) _
Or Linea(_ACL.TipoLineaAlbaran) =
enumaclTipoLineaAlbaran.aclKit) Then
Dim ACL As New AlbaranCompraLinea
Dim componentes As DataTable = ACL.Filter(New
NumberFilterItem("IDLineaPadre", Linea("IDLineaAlbaran")))
For Each drv As DataRow In componentes.Rows
ACL.DeleteRowCascade(drv, services)
Dim listaEliminados As LineasAlbaranCompraEliminadas =
services.GetService(Of LineasAlbaranCompraEliminadas)()
listaEliminados.IDLineas.Add(drv("IDLineaAlbaran"),
drv("IDLineaAlbaran"))
Next
'BusinessHelper.UpdateTable(componentes)
Else
ProcessServer.ExecuteTask(Of DataRow)(AddressOf DeleteComponentes,
Linea, services)
End If
End Sub
Volver al Índice
e.
Proceso GetBusinessRules [Reglas de Negocio]
El proceso GetBusinessRules se utiliza para la codificación de parte de la lógica de negocio. Este método
pertenece a la clase BusinessHelper y está disponible en todas las clases de negocio que heredan de
dicha clase. El objetivo de este método es el de centralizar ciertas operaciones que den sentido funcional
a los datos manejados, independientemente de cuál sea el entorno donde se estén utilizando dichos
53/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
datos (presentación o negocio), es decir, lo que se intenta con esto, es que parte de la lógica de negocio
esté localizada en un solo método y que sea reutilizable, esto facilita el mantenimiento del código. Las
clases de presentación llaman automáticamente a este método (siempre que la clase de presentación
tenga conocimiento de la clase de negocio que puede utilizar), y de la misma forma, el Proceso
GetBusinessRule podría utilizarse desde cualquier otro componente de negocio.
La forma habitual del método es la siguiente
Public Overrides Function GetBusinessRules() As Engine.BE.BusinessRules
Dim OBrl As New BusinessRules
OBrl.Add("Nombre_Columna1", AddressOf TareaColumna1)
OBrl.Add("Nombre_Columna2", AddressOf TareaColumna2)
OBrl.Add("...", AddressOf ...)
Return OBrl
End Function
<Task()> Friend Shared Sub TareaColumna1(ByVal data As BusinessRuleData, ByVal services As
ServiceProvider)
If data.ColumnName = "Nombre_Columna1" Then
If data.Context("Columna_Especial") = True Then
data.Current("Columna") = data.Value
End If
End If
End Sub
De la tarea a la que llamamos desde el listado de tareas del proceso GetBusinessRules, recibe un
parámetro de tipo BusinessRuleData. Éste se compone de los siguientes campos:
ColumnName:
Nombre de la columna sobre la cual se está aplicando la regla de negocio.
Value:
Valor actual.
Current:
Objeto BusinessData que contiene todos los valores del registro actual, incluido el de la columna
que es objeto de la regla de negocio.
Context:
Objeto BusinessData que establece el contexto donde se aplica la regla de negocio.
La clase BusinessData pertenece al Engine de eXpertis y deriva de la clase Hashtable del framework de
.NET. Esta clase permite el paso de información entre las capas de presentación y negocio.
Las clases de presentación disponen de dos eventos, BusinessCalling y BusinessCalled, que permiten
programar las llamadas automáticas que realiza el motor de eXpertis.
En el método GetBusinessRule no debe programarse código que actualice en la base de datos, la
codificación debe centrarse exclusivamente en la aportación de información funcional y devolución de
dicha información.
El proceso GetBusinessRules se utiliza para la codificación de parte de la lógica de negocio. Este método
pertenece a la clase BusinessHelper y está disponible en todas las clases de negocio que heredan de
dicha clase. El objetivo de este método es el de centralizar ciertas operaciones que den sentido funcional
a los datos manejados, independientemente de cuál sea el entorno donde se estén utilizando dichos
datos (presentación o negocio), es decir, lo que se intenta con esto, es que parte de la lógica de negocio
este localizada en un solo método y que sea reutilizable, esto facilita el mantenimiento del código. Las
clases de presentación llaman automáticamente a este método (siempre que la clase de presentación
tenga conocimiento de la clase de negocio que puede utilizar), y de la misma forma, el Proceso
GetBusinessRule podría utilizarse desde cualquier otro componente de negocio.
54/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
La clase BusinessData pertenece al Engine de eXpertis y deriva de la clase Hashtable del framework de
.NET. Esta clase permite el paso de información entre las capas de presentación y negocio.
Las clases de presentación disponen de dos eventos, BusinessCalling y BusinessCalled, que permiten
programar las llamadas automáticas que realiza el motor de eXpertis.
En el método GetBusinessRule no debe programarse código que actualice en la base de datos, la
codificación debe centrarse exclusivamente en la aportación de información funcional y devolución de
dicha información.
Las reglas de negocio de una entidad las llamará de manera automática el motor de eXpertis cuando sea
desde las entidades configuradas en los formularios de presentación u objetos de datos como el
DataGrid.
Para llamar manualmente nosotros a las reglas de negocio de una entidad desde donde queramos lo
podremos hacer de la siguiente manera y dependiendo de la capa en la que estemos y del tipo de objeto
para invocar / actualizar estos datos:
-
Para llamar manualmente a las reglas de negocio de una entidad entre capas de negocio y
teniendo como origen de datos un DataTable con su respectivo DataRow, lo haríamos de la
siguiente manera:
Dim ClsArticulo As New Articulo
Dim DtArticuloNew As New DataTable
Dim DrNew As DataRow = DtArticuloNew.NewRow
DrNew("IDArticulo") = "00"
DrNew = ClsArticulo.ApplyBusinessRule("IDArticulo", "00", DtArticuloNew.Rows(0))
O también alternativamente se puede realizar de esta manera:
Dim ClsArticulo As New Articulo
Dim DtArticuloNew As New DataTable
Dim DrNew As DataRow = DtArticuloNew.NewRow
DrNew("IDArticulo") = "00"
Dim StData As New DataRowPropertyAccessor(DrNew)
StData = ClsArticulo.ApplyBusinessRule("IDArticulo", "00", StData)
For Each Dc As DataColumn In DtArticuloNew.Columns
DrNew(Dc.ColumnName) = StData(Dc.ColumnName)
Next
-
Para llamar manualmente a las reglas de negocio de una entidad entre la capa de presentación y
negocio teniendo como origen de datos un DataTable con su respectivo DataRow, lo haríamos de
la siguiente manera:
Dim ClsArticulo As New Articulo
Dim DtArticuloNew As New DataTable
Dim DrNew As DataRow = DtArticuloNew.NewRow
DrNew("IDArticulo") = "00"
Dim StData As New BusinessData(DrNew)
StData = ClsArticulo.ApplyBusinessRule("IDArticulo", "00", StData)
For Each Dc As DataColumn In DtArticuloNew.Columns
DrNew(Dc.ColumnName) = StData(Dc.ColumnName)
Next
-
Para llamar a las reglas de negocio de una entidad de un DataGrid por cambios llevados a cabo
en los campos de un Grid, lo haríamos de la siguiente manera:
Grid1.EntityName = "Articulo"
Grid1.InvokeBusinessRules("IDArticulo", "00", Grid1.GetValue("IDArticulo"))
Grid1.SetValue("IDArticulo", "00")
Éste último caso es necesario cuando nosotros introducimos y modificamos valores en un
DataGrid a través de código fuente, puesto que en este caso el motor no tiene control y no es
capaz de llamar él a las reglas de negocio, mientras que en la introducción manual por parte del
usuario final si llama de manera automática a las reglas de negocio de la entidad del DataGrid.
55/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
SynonymousBusinessRules
Cuando queramos desarrollar reglas de negocio compartidas entre diferentes entidades de eXpertis,
tenemos la utilidad de SynonymousBusinessRules. Esta utilidad nos permite el establecer la relación de
campos que queramos para llevar a cabo unas reglas de negocio genéricas. De esta manera podemos
establecer que en nuestra entidad manejamos el campo FechaAlbaran y que se traducirá en campo
Fecha cuando llamemos a las reglas de negocio compartida.
Public Overrides Function GetBusinessRules() As Engine.BE.BusinessRules
Dim services As New ServiceProvider
Dim oBRL As New SynonymousBusinessRules
oBRL.AddSynonymous("FechaAlbaran", "Fecha")
oBRL = ProcessServer.ExecuteTask(Of BusinessRules, BusinessRules)(AddressOf
ProcesoCompra.DetailBusinessRulesCab, oBRL, services)
oBRL("IDProveedor") = AddressOf CambioProveedor
oBRL.Add("Fecha", AddressOf ProcesoComunes.CambioFechaAlbaran)
oBRL.Add("IDAlmacen", AddressOf ProcesoComunes.CambioAlmacen)
oBRL.Add("IDTipoCompra", AddressOf CambioTipoCompra)
oBRL.Add("IDCentroGestion", AddressOf ProcesoComunes.CambioCentroGestion)
Return oBRL
End Function
Volver al Índice
Componentes de Motor en Capa Negocio
1.
AdminData
AdminData objeto de Motor de la capa de Negocio y sólo disponible en la capa de Negocio. Nos brinda de
diversos métodos y propiedades para administrar eXpertis.
Los más importante y usados serían los siguientes.
AdminData.ComposeFilter:
Método que nos traduce las condiciones configuradas en un objeto Filter a una cadena de texto. Esta
conversión se haría con nomenclatura de SQL.
Dim FilSelec As New Filter
FilSelec.Add("IDArticulo", FilterOperator.Equal, "Tuerca")
Dim StrFiltro As String = AdminData.ComposeFilter(FilSelec)
AdminData.GetAutoNumeric.
Método que nos dato numérico único para establecer así valores numéricos de campos de clave primaria de
tablas. Es un dato numérico que siempre genera un nuevo número el Engine de eXpertis y permitiéndonos
tener números inequívocos para este tipo de campos de tablas.
Dim Dr As DataRow
Dr("IDArticulo") = AdminData.GetAutoNumeric
AdminData.GetData
Método que nos permite obtener datos de una tabla o vista, con una serie de parámetros para poder
especificar la sentencia select, where, si queremos obtener datos de la base de datos de sistema, etc.….
Dim DtArt As DataTable = AdminData.GetData()
AdminData.Filter
Método para obtener datos de bases de datos ya sea una tabla o una vista y con una serie de parámetros de
entrada para configurar la sentencia select, where, etc…
Dim DtArt As DataTable = AdminData.Filter()
AdminData.Execute
Método que nos permite ejecutar scripts de SQL contra bases de datos. Este comando nos permite ejecutar
una sentencia tal cual de SQL o bien mandar un comando de ejecución de un procedimiento almacenado,
56/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
etc... Este comando nos permite como parámetros de entrada o bien una instrucción en texto o bien un
objeto DbCommand.
Dim StrSQL As String = "SELECT IDArticulo FROM CursoArticulo WHERE DescArticulo"
Dim DtArt As DataTable = AdminData.Execute(StrSQL)
Además este método sería el principal para llevar a cabo la ejecución de Procedimientos almacenados en
eXpertis. Para ello se aconsejo 2 maneras de realizarlo:

La primera manera que tendríamos sería de una manera directa invocando al nombre del
procedimiento almacenado, pasándole los parámetros de entrada de dicho procedimiento en orden:
AdminData.Execute("sp_PROCEDURE", False, PARAMETRO1, PARAMETRO2)

La segunda manera que tendríamos sería configurar un objeto de tipo DBCommand en el que
configuremos todo los necesario para la llamada del procedimiento y pasándole los parámetros
necesarios. Sería de la siguiente manera:
Dim cmmComando As Common.DbCommand = AdminData.GetCommand
cmmComando.CommandText = "sp_PROCEDURE"
cmmComando.CommandType = CommandType.StoredProcedure
Dim cmmParam As Common.DbParameter = cmmComando.CreateParameter
cmmComando.Parameters.Add(cmmParam)
cmmParam.ParameterName = "@Param1"
cmmParam.Value = VALUEPARAM1
Dim prmEjercicio As Common.DbParameter = cmmComando.CreateParameter
cmmComando.Parameters.Add(prmEjercicio)
prmEjercicio.ParameterName = "@ParamEjercicio"
prmEjercicio.Direction = ParameterDirection.Output
AdminData.Execute(cmmComando)
AdminData.ExecuteNonQuery
Método que nos permite ejecutar scripts de SQL contra bases de datos. Este comando nos permite ejecutar
una sentencia tal cual de SQL sin esperar ningún tipo de respuesta por parte de la Base de Datos. Es similar
al comando de AdminData.Execute pero con esta salvedad de que no esperamos ninguna resputa, bien sea
de conjunto de datos o de un total.
AdminData.ExecuteNonQuery("sp_PROCEDURE",False, PARAMETRO1, PARAMETRO2)
AdminData.SetSessionConnection
Método que usaremos cuando queremos establecer la conexión de expertis actual con otra base de datos de
Expertis para llevar a cabo diversos procesos.
AdminData.SetSessionConnection("Nombre_Base_Datos_Destino")
Para ver mas información consulta apartado de Programación General -> Cambio de Base de datos en
MultiEmpresa.
AdminData.BeginTx
Método para comenzar una transacción en el punto que creamos oportuno de Expertis.
AdminData.BeginTx()
AdminData.CommitTx
Método para llevar a cabo un Commit de la transacción abierta que tengamos de Expertis.
AdminData.CommitTx()
AdminData.RollBackTx
Método para llevar a cabo un RollBack de la transacción abierta que tengamos de expertis.
AdminData.RollBackTx()
NOTA: además de estos métodos descritos existen más propiedades y métodos para otras gestiones de información que
necesitemos. Los descritos serían los más habituales en el uso de eXpertis.
Volver al Índice
57/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
2.
BusinessHelper
El componente de BusinessHelper del Engine de eXpertis nos permite tener un objeto de tipo entidad de una
tabla o entidad correspondiente. Lo que nos brinda es de los métodos básicos y estándar que posee una
entidad de eXpertis. Esto lo usaríamos para casos en los que no deseamos o no podemos referenciar una Dll
que contenga dicha entidad que queramos manejar. Bien sea por temas de diseño o bien por provocar
referencias cíclicas.
Sus formas de uso tendríamos, el instanciar el objeto pasando un nombre de tabla:
Y la otra sería pasando un nombre de entidad ya existente. Atención que este método sólo nos daría los
métodos básicos de la entidad y no nos permite acceder a las funciones o procesos públicos de dicha
entidad:
Además de esta utilidad nos permite actualizar en base de datos el contenido de un datatable o de un
updatepackage en base de datos. Éste método es obligatorio utilizar cuando no usemos el método Update
de actualización de datos de una entidad y queramos grabar datos de tablas pero no pasando por las reglas
del valídate y del Update de dicha entidad. Para ello tendremos el método de UpdateTable (con varias
sobrecargas) o bien UpdatePackage.
Volver al Índice
3.
ApplicationService
58/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El ApplicationService sobre todo lo usamos por el método de ApplicationService.GenerateError para mostrar
mensajes de error en expertis provocados en el parte de Negocio.
If IsNothing(dt) OrElse dt.Rows.Count = 0 Then
ApplicationService.GenerateError("No se han encontrado Datos de |.", "Articulos")
Else
Return True
End If
Volver al Índice
4.
IPropertyAccesor
En ocasiones nos surge la necesidad de tener una misma tarea para tratar un objeto de tipo DataRow y otras
un objeto de tipo BusinessData. Por ello y con la restricción que tenemos (dentro de una misma clase no
podemos tener 2 tareas con el mismo nombre), así como para facilitar el mantenimiento del código, podemos
identificar ese tipo de datos de entrada como IPropertyAccesor. Esto, tanto para identificar el tipo de entrada
y/o salida de una tarea, como para utilizar los 2 tipos mencionados en cualquier otra parte del código
(variables, propiedades,…). Si utilizamos este objeto para contener un DataRow, deberemos utilizar una clase
que lo convertirá en este nuevo tipo: (DataRowPropertyAccesor). Destacar, que este tipo no se podrá utilizar
desde presentación, ya que no es serializable, en tal caso utilizaremos el BusinessData.
<Task()> Friend Shared Sub CalcularImporteLineasAlbaran(ByVal doc As DocumentCabLin, ByVal services As
ServiceProvider)
For Each linea As DataRow In doc.dtLineas.Rows
Dim ILinea As New DataRowPropertyAccessor(linea)
ILinea("Cantidad") = linea("QServida")
ProcessServer.ExecuteTask(Of IPropertyAccessor)(AddressOf General.CalcularPrecioImporte,
ILinea, services)
Dim lineaIProperty As New ValoresAyB(ILinea, doc.IDMoneda, doc.CambioA, doc.CambioB)
ProcessServer.ExecuteTask(Of ValoresAyB)(AddressOf General.MantenimientoValoresAyB,
lineaIProperty, services)
Next
End Sub
Volver al Índice
5.
UpdatePackage
En los RegisterUpdateTask en los que viaja un Documento, en todos ellos la primera tarea recibe como
parámetro un objeto del tipo UpdatePackage. Este tipo es una lista de DataTables de distintas entidades con
los registros modificados. Es un tipo no serializable.
Volver al Índice
6.
ServiceProvider
Objeto que nos servirá para cachear la infomación a lo largo de un proceso. Con él reduciremos accesos a la
BBDD. Se accede al mismo a través de los tipos de datos, por lo que tendremos que prestar especial
atención a los objetos que introducimos en él. Cuando queremos recuperar un objeto del mismo y hacemos
referencia al objeto en cuestión, el ServiceProvider nos dará el elemento si lo tiene almacenado. Si no lo
tiene almacenado, creará una instancia del tipo y la retornará.
El uso de este elemento, normalmente, está relacionado con las clases EntityInfoCache, ClassEntityInfo, que
funcionan de manera similar al ServiceProvider. Y lo hacen porque las clases X que nos retornará el objeto
de tipo EntityInfoCache, heredan de la clase ClassEntityInfo, que nos rellena de forma “automática” las
variables de la clase X, que tengan el mismo nombre que en la vista o en la tabla que será origen de datos
de estas clases. Lo vemos con un ejemplo.
NOTA: El ServiceProvider accede a la “cache” por tipo de datos y el EntityInfoCache lo hace por el valor de la PrimaryKey.
Si hay herencia de clases. Se registrarán en el services las instancias de todas las clases en la jerarquía de la herencia.
Además, tenemos también el objeto DocumentInfoCache, que funciona de manera similar al
EntityInfoCache, pero con Documentos (instancias del objeto Document, que veremos más adelante).
Ejemplo 1: Esta tarea puede ser llamada en un proceso varias veces con un mismo cliente, por ejemplo, en
la Recepción de Pedidos. Le pedimos al services que nos de un objeto de tipo EntityInfoCache, que a su vez,
contenga objetos del tipo ClienteInfo (que hereda de ClassEntityInfo). Si no lo tiene, lo creará en el services
antes de retornarlo, con lo cual siempre nos devolverá un objeto de ese tipo. Este objeto retornado, actuará
de forma similar al darnos un objeto de tipo ClienteInfo a través del data(“IDCliente”), si no tiene la
información registrada, accede a la BBDD para obtenerla.
59/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Public Shared Sub ValidarClienteBloqueado(ByVal data As DataRow, ByVal services
As ServiceProvider)
Dim Clientes As EntityInfoCache(Of ClienteInfo) = services.GetService(Of
EntityInfoCache(Of ClienteInfo))()
Dim ClteInfo As ClienteInfo = Clientes.GetEntity(data("IDCliente"))
If ClteInfo.Bloqueado Then ApplicationService.GenerateError("El Cliente está
Bloqueado.")
End Sub
Ejemplo 2: En ocasiones necesitamos cachear información que el usuario nos ha proporcionado al lanzar un
proceso, para tener acceso desde cualquiera de las tareas, pero no podemos identificarla bajo un tipo de
datos. En este caso, nos creamos una clase (tipo de datos), que nos permita cachear esa información. Y
deberemos registrarla en el services. En la Recepción de Pedidos, el usuario puede indicar un contador o
una fecha de albarán, esto lo introduciremos en una clase ProcessInfoAlbCompra que registraremos en el
services y luego accederemos a ella desde otro punto del proceso.
<Task()> Public Shared Sub PrepararInformacionProceso(ByVal data As DataInfoProceso, ByVal
services As ServiceProvider)
If Length(data.IDTipoCompra) = 0 Then
Dim ParamsAC As ParametroAlbaranCompra = services.GetService(Of
ParametroAlbaranCompra)()
data.IDTipoCompra = ParamsAC.TipoCompraNormal
End If
If data.FechaAlbaran Is Nothing OrElse data.FechaAlbaran = cnMinDate Then
data.FechaAlbaran = Today
services.RegisterService(New ProcessInfoAlbCompra(data.IDContador,
data.IDTipoCompra, data.FechaAlbaran))
End Sub
<Task()> Friend Shared Sub AsignarValoresPredeterminadosGenerales(ByVal alb As
DocumentoAlbaranCompra, ByVal services As ServiceProvider)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf
ProcesoComunes.AsignarIdentificadorAlbaran, alb.HeaderRow, services)
Dim InfoProc As ProcessInfoAlbCompra = services.GetService(Of
ProcessInfoAlbCompra)()
If alb.HeaderRow.IsNull("FechaAlbaran") Or alb.HeaderRow("FechaAlbaran") =
cnMinDate Then
If InfoProc.FechaAlbaran <> cnMinDate Then
alb.HeaderRow("FechaAlbaran") = InfoProc.FechaAlbaran
Else
ProcessServer.ExecuteTask(Of DataRow)(AddressOf
ProcesoComunes.AsignarFechaAlbaran, alb.HeaderRow, services)
End If
Dim data As New DataEjercicio(New DataRowPropertyAccessor(alb.HeaderRow),
alb.HeaderRow("FechaAlbaran"))
ProcessServer.ExecuteTask(Of DataEjercicio)(AddressOf
General.AsignarEjercicioContable, data, services)
End If
If alb.HeaderRow.IsNull("Estado") Then alb.HeaderRow("Estado") =
enumaccEstado.accNoFacturado
If alb.HeaderRow.IsNull("Automatico") Then alb.HeaderRow("Automatico") = False
If alb.HeaderRow.IsNull("IDTipoCompra") Then alb.HeaderRow("IDTipoCompra") =
InfoProc.IDTipoCompra
End Sub
Ejemplo 3
En ocasiones necesitamos cachear un Documento completo, para en sucesivas iteraciones actualizar el
mismo Documento, la idea es la misma que con el EntityInfoCache. Le pedimos al services que nos dé un
objeto de tipo DocumentInfoCache, que a su vez, contenga objetos del tipo DocumentoAlbaranCompra (que
hereda de Document). Si no lo tiene, lo creará en el services antes de retornarlo, con lo cual siempre nos
devolverá un objeto de ese tipo. Este objeto retornado, actuará de forma similar al darnos un objeto de tipo
DocumentoAlbaranCompra a través del lineaAlbaran(“IDAlbaran”), si no tiene la información registrada,
accede a la BBDD para obtenerla.
<Task()> Friend Shared Sub ActualizarQServidaLineaPedido(ByVal lineaAlbaran As DataRow,
ByVal services As ServiceProvider)
If Length(lineaAlbaran("IDLineaPadre")) = 0 AndAlso
Nz(lineaAlbaran("TipoLineaAlbaran"), enumaclTipoLineaAlbaran.aclNormal) <>
enumaclTipoLineaAlbaran.aclComponente Then
If lineaAlbaran.RowState <> DataRowState.Modified OrElse
lineaAlbaran("QServida") <> lineaAlbaran("QServida", DataRowVersion.Original) Then
60/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Dim Albaranes As DocumentInfoCache(Of DocumentoAlbaranCompra) =
services.GetService(Of DocumentInfoCache(Of DocumentoAlbaranCompra))()
Dim DocAlb As DocumentoAlbaranCompra =
Albaranes.GetDocument(lineaAlbaran("IDAlbaran"))
If Length(lineaAlbaran("IDLineaPadre")) = 0 AndAlso
Nz(lineaAlbaran("TipoLineaAlbaran"), enumaclTipoLineaAlbaran.aclNormal) <>
enumaclTipoLineaAlbaran.aclComponente Then
Dim Pedidos As DocumentInfoCache(Of DocumentoPedidoCompra) =
services.GetService(Of DocumentInfoCache(Of DocumentoPedidoCompra))()
Dim DocPed As DocumentoPedidoCompra =
Pedidos.GetDocument(lineaAlbaran("IDPedido"))
Dim OriginalQServida As Double
Dim ProposedQServida As Double = Nz(lineaAlbaran("QServida"), 0)
If lineaAlbaran.RowState = DataRowState.Modified Then
OriginalQServida = lineaAlbaran("QServida",
DataRowVersion.Original)
End If
DocPed.SetQServida(lineaAlbaran("IDLineaPedido"), ProposedQServida OriginalQServida, services)
End If
End If
End If
End Sub
Volver al Índice
7.
ContextBoundObject
Al usar el sistema de tareas de Expertis no hace falta si tenemos una Clase de Negocio que no es entidad y
que alberga tareas públicas el definirla con la Herencia con ContextBoundObject. Esto solo haría falta si
tuviésemos una clase de Negocio de Expertis con Procesos o Funciones públicas pero sin ser tareas. Para
ello necesitaríamos de establecer la herencia con ContextBoundObject y con el atributo Transactional.
Public Class ClassTasks
<Task()> Public Shared Function GiveAutonumeric(ByVal data As Object, ByVal services
As ServiceProvider) As Integer
Return AdminData.GetAutoNumeric
End Function
<Task()> Public Shared Sub EjecutarProceso(ByVal data As Integer, ByVal services As
ServiceProvider)
'Proceso de ejecución
End Sub
End Class
<Transactional()> _
Public Class ClassFunctions
Inherits ContextBoundObject
Public Function GiveAutonumeric() As Integer
Return AdminData.GetAutoNumeric
End Function
Public Sub EjecutarProceso(ByVal data As Integer)
'Procesos de Ejecución
End Sub
End Class
Volver al Índice
Configuración del Manager para procesar Capa Negocio
Debemos recordar en todo momento que después de generar nuestras nuevas entidades de negocio de Expertis,
debemos de registrarlas en el manager de expertis para que consten inventariadas en su sistema, para un correcto
funcionamiento de la aplicación y disponibilidad de uso de las entidades en cualquier punto de expertis.
Para ello acudiremos al manager de expertis e iremos a la sección: Objetos -> Entidades. En el menú superior de
Procesos tendremos un proceso automático de agregado de entidades indicándole en qué dll tenemos alojada la/s
clase/s que queremos pasar. Si no siempre tendremos la opción manual de inserción de una nueva entidad.
61/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Para mayor información sobre las propiedades de una entidad acudir al manual de la Consola de Administración de
Expertis 5.0.
Por último si hemos editado la dll de Negocio de Enumerados, bien sea por actualización o creación de nuevos,
acudiremos al manager de expertis para incluir en el sistema estos cambios. Para ello acudiremos al manager de
expertis e iremos a la sección: Objetos -> Enumerados. En el menú superior de Procesos tendremos un proceso
automático de agregado de enumerados indicándole la dll de enumerados de Expertis. Si no siempre tendremos la
opción manual de inserción de un nuevo enumerado.
Volver al Índice
62/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Extensibilidad de Procesos y Tareas
Sobreescritura de Clases
A veces para llevar a cabo la extensibilidad de Expertis sobre tareas, vemos que las tareas que vamos a llevar este a
cabo reciben un tipo de objeto de clase (anteriormente estructura) y que a dicha clase también necesitamos tocar
porque vamos a enviar más datos de los que originalmente recibe el objeto de Solmicro.
Por ello vamos a explicar los pasos de cómo llevar a cabo esto descrito
Con esto disponemos entonces de una tarea de origen que tiene configurado un objeto clase con una serie de
variables y constructores iniciales como los descritos a continuación:
<Serializable()> _
Public Class DataClass
Public IDBase As Integer
Public DescBase As String
Public Sub New()
End Sub
Public Sub New(ByVal IDBase As Integer, ByVal DescBase As String)
Me.IDBase = IDBase
Me.DescBase = DescBase
End Sub
End Class
<Task()> Public Shared Sub ClassTest(ByVal data As DataClass, ByVal services As ServiceProvider)
If Length(data.IDBase) = 0 Then
ApplicationService.GenerateError("No se puede dejar a nulo el: |", data.DescBase)
End If
End Sub
Ahora lo que necesitamos es que esta clase ClassTest la vamos a sobreescribir por una nuestra propia pero
necesitamos tocar el objeto de entrada de la tarea de tipo DataClass para insertarle mas variables.
Para ello lo que tendriamos que hacer es escribir en nuestro proyecto propio dicha tarea que vamos a sobrescribir
creandonos un objeto clae nuevo de la tarea base que recibe y haciendo que este objeto clase nuevo nuestro herede
de la clase base de solmicro. Entonces creamos el objeto clase nuevo haciendo un Inherits con la clase base:
<Serializable()> _
Public Class DataClassNew
Inherits ProjectBase.PrBase.DataClass
Public Estado As Boolean
Public NewDesc As String
Public Sub New()
End Sub
Public Sub New(ByVal IDBase As Integer, ByVal DescBase As String, ByVal Estado As Boolean,
ByVal NewDesc As String)
Me.IDBase = IDBase
Me.DescBase = DescBase
Me.Estado = Estado
Me.NewDesc = NewDesc
End Sub
End Class
Como se puede observar se hereda del objeto y añadimos las variables que necesitemos y otros constructores new
que queramos sin problemas
Con este objeto heredado creado creamos nuestra tarea que va a sobreescribir la tarea de solmicro. Para ello
haremos que la firma de la tarea tiene que tener la misma que la de origen. Poniendo en este caso DataClass de la
clase Prbase del proyecto ProjectBase.
A continuación lo que hacemos y como medida de control de errores es que comprobamos que el objeto data que se
recibe de entrada sea de nuestro tipo nuevo creado. A pesar de que en la tarea especificamos que es un DataClass
nosotros vamos a enviar realmente nuestro nuevo DataClassNew y para ello comprobamos a ver si el data de
entrada es de este tipo. Siendo asi podemos acceder a nuestras variables reconvirtiendo el objeto Data de tipo
DataClass a nuestro DataClassNew.
<Task()> Public Shared Sub ClassTestNew(ByVal data As ProjectBase.PrBase.DataClass, ByVal services
As ServiceProvider)
63/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
If data.GetType Is GetType(DataClassNew) Then
If Length(data.IDBase) = 0 Then
If CType(data, DataClassNew).Estado = 1 Then
ApplicationService.GenerateError("No se puede dejar nulo el: |", CType(data,
DataClassNew).NewDesc)
End If
End If
End If
End Sub
Para terminar de ver cómo sería esto, habría que localizar dónde se realizar la llamada a la tarea de origen para
convertir el tipo de objeto clase antiguo al nuestro y metiendo los valores nuevos. Luego la llamada a la tarea sería
igual y marcando como tipo de entrada de la tarea el tipo de objeto Clase de origen pero enviando nuestro objeto
clase nuevo.
Dim StDataNew As New PrNew.DataClassNew(101, "Prueba de Acceso", 1, "Prueba nueva")
ExpertisApp.ExecuteTask(Of PrBase.DataClass)(AddressOf PrBase.ClassTest, StDataNew)
De ésta manera podemos sobrescribir tareas de Expertis que reciben un tipo especial de datos siendo una clase
propia, pero reconvertirla en extensibilidad para que se use con un objeto clase nuevo hecho por nosotros.
Volver al Índice
Sobreescritura de Documentos
Cuando nos encontramos con el caso de necesitar aplicar extensibilidad sobre procesos o tareas relacionadas que
manejan documentos de Expertis, vamos a marcar a continuación como lo llevaríamos a cabo.
Para ello partimos de un documento Origen DocumentBase que estaría en un proyecto de origen de Solmicro y al
que vamos a necesitar aplicar extensibilidad porque necesitamos agregar una tabla más hija a sus tablas hijas
existentes.
Por ello vemos cómo sería este DocumentBase:
Public Class DocumentBase
Inherits Document
#Region "Datos Documento Base"
'Datatables de CabeceraBase
Public Precios As DataTable
Public Lineas As DataTable
Public Function EntidadCabecera() As String
Return GetType(CabeceraBase).Name
End Function
Public Function EntidadPrecios() As String
Return GetType(PreciosBase).Name
End Function
Public Function EntidadLineas() As String
Return GetType(LineasBase).Name
End Function
Public ReadOnly Property dtPrecios() As DataTable
Get
Return MyBase.Item(EntidadPrecios)
End Get
End Property
Public ReadOnly Property dtLineas() As DataTable
Get
Return MyBase.Item(EntidadLineas)
End Get
End Property
#End Region
#Region "PrimaryKeys de DocumentBase"
Public Function PrimaryKeyCab() As String()
64/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Return New String() {"IDBase"}
End Function
Public Function PrimaryKeyPrecios() As String()
Return New String() {"IDPrecioBase"}
End Function
Public Function PrimaryKeyLineas() As String()
Return New String() {"IDLineaBase"}
End Function
#End Region
#Region " Creación de instancias "
'//New a utilizar desde presentación (utilizado por el motor para realizar las actualizaciones
de los elementos cabecera/lineas)
Public Sub New(ByVal UpdtCtx As UpdatePackage)
'// al crearse la bola desde el updatepackage, se debieran eliminar los conjuntos de datos
que se van a tratar
'// y dejar que el motor trate el resto
LoadEntityHeader(False, UpdtCtx)
LoadEntitiesChilds(False, UpdtCtx)
End Sub
'//New utilizado para obtener un Documento alamacenado en la BBDD.
Public Sub New(ByVal ParamArray PrimaryKey() As Object)
LoadEntityHeader(False, Nothing, PrimaryKey)
LoadEntitiesChilds(False)
End Sub
Protected Overridable Sub LoadEntityHeader(ByVal AddNew As Boolean, Optional ByVal UpdtCtx As
UpdatePackage = Nothing, Optional ByVal PrimaryKey() As Object = Nothing)
If AddNew Then '//New de Procesos
Dim oBusinessEntity As BusinessHelper =
BusinessHelper.CreateBusinessObject(EntidadCabecera)
Dim dtCabeceras As DataTable = oBusinessEntity.AddNew
dtCabeceras.Rows.Add(dtCabeceras.NewRow)
MyBase.AddHeader(EntidadCabecera, dtCabeceras)
'//Creamos el HeaderRow
ElseIf UpdtCtx Is Nothing Then '//New de PrimaryKey
Dim oBusinessEntity As BusinessHelper =
BusinessHelper.CreateBusinessObject(EntidadCabecera)
Dim dtCabeceras As DataTable = oBusinessEntity.SelOnPrimaryKey(PrimaryKey)
MyBase.AddHeader(Me.GetType.Name, dtCabeceras)
Else '//New del formulario
MyBase.AddHeader(Me.GetType.Name, UpdtCtx(EntidadCabecera).First)
Dim PKCabecera() As String = PrimaryKeyCab()
MergeData(UpdtCtx, EntidadCabecera, PKCabecera, PKCabecera, True)
End If
End Sub
Protected Overridable Sub LoadEntitiesChilds(ByVal AddNew As Boolean, Optional ByVal UpdtCtx
As UpdatePackage = Nothing)
LoadEntityChild(AddNew, EntidadPrecios, UpdtCtx)
LoadEntityChild(AddNew, EntidadLineas, UpdtCtx)
End Sub
Protected Overridable Sub LoadEntityChild(ByVal AddNew As Boolean, ByVal Entidad As String,
Optional ByVal UpdtCtx As UpdatePackage = Nothing)
Dim oEntidad As BusinessHelper = BusinessHelper.CreateBusinessObject(Entidad)
Dim Dt As DataTable
If AddNew Then '//New de Procesos
Dt = oEntidad.AddNew
ElseIf UpdtCtx Is Nothing Then '//New de PrimaryKey
Dim PKCabecera() As String = PrimaryKeyCab()
Dt = oEntidad.Filter(New FilterItem(PKCabecera(0), HeaderRow(PKCabecera(0))))
Else '//New del formulario
'// al crearse la bola desde el updatepackage, se debieran eliminar los conjuntos de
datos que se van a tratar
'// y dejar que el motor trate el resto (MergeData)
Dim PKCabecera() As String = PrimaryKeyCab()
Dt = MergeData(UpdtCtx, Entidad, PKCabecera, PKCabecera, True)
End If
Me.Add(oEntidad.GetType.Name, Dt)
End Sub
#End Region
65/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Class
Para este punto es importante que los eventos de LoadEntityHeader, LoadEntitiesChild y LoadEntityChild estén
marcados como protected overridable Sub para que podamos disponer de ellos en el documento hijo que vamos a
crear.
Partiendo de este documento de origen creamos un nuevo documento hijo en nuestro proyecto de extensibilidad. Su
principal pecurialidad es que nuestro documento herede del documento proyecto Base. Luego ya a este documento
agregamos todo el sistema normal para que tenga reflejado la nueva tabla que estamos asociando al documento de
origen.
Public Class DocumentBaseNew
Inherits ProjectBase.DocumentBase
Public HijoNew1 As DataTable
Public Function EntidadHijoNew1() As String
Return GetType(HijoNew1).Name
End Function
Public ReadOnly Property dtHijoNew1() As DataTable
Get
Return MyBase.Item(EntidadHijoNew1)
End Get
End Property
'//New a utilizar desde presentación (utilizado por el motor para realizar las actualizaciones
de los elementos cabecera/lineas)
Public Sub New(ByVal UpdtCtx As UpdatePackage)
'// al crearse la bola desde el updatepackage, se debieran eliminar los conjuntos de datos
que se van a tratar
'// y dejar que el motor trate el resto
LoadEntityHeader(False, UpdtCtx, Nothing)
LoadEntitiesChilds(False, UpdtCtx)
End Sub
'//New utilizado para obtener un Documento alamacenado en la BBDD.
Public Sub New(ByVal ParamArray PrimaryKey() As Object)
LoadEntityHeader(False, Nothing, PrimaryKey)
LoadEntitiesChilds(False)
End Sub
Protected Overrides Sub LoadEntityHeader(ByVal AddNew As Boolean, Optional ByVal UpdtCtx As
UpdatePackage = Nothing, Optional ByVal PrimaryKey() As Object = Nothing)
MyBase.LoadEntityHeader(AddNew, UpdtCtx, PrimaryKey)
End Sub
Protected Overrides Sub LoadEntitiesChilds(ByVal AddNew As Boolean, Optional ByVal UpdtCtx As
UpdatePackage = Nothing)
MyBase.LoadEntitiesChilds(AddNew, UpdtCtx)
LoadEntityChild(AddNew, EntidadHijoNew1, UpdtCtx)
End Sub
End Class
Como último punto sobreescribiriamos los procesos de LoadEntityHeader llamando al proceso padre del
documento Base y sobreescribiríamos también el LoadEntitiesChild, llamando al proceso base del documento base
y añadiendo nuestras llamadas a cargar nuestras nuevas tablas.
A continuación tenemos cómo se vería una tarea que usa el DocumentBase dentro de un proceso relacionado con
dicho documento.
Public Class ProcesoBase
<Task()> Public Shared Sub ProcessDocBase(ByVal data As DocumentBase, ByVal services As
ServiceProvider)
If Not data.dtLineas Is Nothing AndAlso data.dtLineas.Rows.Count > 0 Then
For Each Dr As DataRow In data.dtLineas.Select
'Proceso
Next
End If
End Sub
66/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Class
En caso de necesitar sobrescribir esta tarea lo haremos con una nueva tarea en un proyecto nuestro. Tendremos que
respetar que el tipo de entrada de la tarea sea el mismo que la de origen, en este caso de DocumentBase. Lo que
haremos luego y como medida de control de errores es ver si el tipo de entrada de la tarea es nuestro tipo de
documento DocumentBaseNew y en ese caso usar ya nuestro objeto DocumentBaseNew reconvirtiendolo cuando
haga falta. De esta manera accedemos a la información mas concreta de nuestro nuevo documento.
Public Class ProcesoBaseNew
<Task()> Public Shared Sub ProcessDocNew(ByVal data As ProjectBase.DocumentBase, ByVal
services As ServiceProvider)
If Not data.dtLineas Is Nothing AndAlso data.dtLineas.Rows.Count > 0 Then
If data.GetType Is GetType(DocumentBaseNew) Then
If CType(data, DocumentBaseNew).dtHijoNew1 Is Nothing AndAlso CType(data,
DocumentBaseNew).dtHijoNew1.Rows.Count > 0 Then
For Each Dr As DataRow In CType(data, DocumentBaseNew).dtHijoNew1.Select
'Proceso
Next
End If
End If
End If
End Sub
End Class
A continuación tendríamos un ejemplo de creación y llamada a la anterior tarea con estos documentos y con
extensibilidad. Hay que fijarse que el tipo de documento que creamos es el nuestro DocumentBaseNew y que luego
la llamada a la tarea sería como estaríamos haciendo y pasando como tipo de objeto de entrada el DocumentBase.
Dim DocNew As New DocumentBaseNew(101)
ExpertisApp.ExecuteTask(Of DocumentBase)(AddressOf ProcesoBase.ProcessDocBase, DocNew)
Volver al Índice
Ejemplos
A continuación marcamos una serie de ejemplos de escritura y manejo de tareas y procesos de cara a la
extensibilidad. Para ello se han creado dos proyectos de ejemplo: uno de origen simulando el proyecto de origen de
uno estándar de expertis y otro nuevo siendo uno específico para nuestro cliente / proyecto.
Para ello se han creado previamente las tareas y todos los datos y se han procesado contra el manager de expertis a
través de la opción de Añadir Procesos y Tareas.
67/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Ejemplo de Sobreescritura de Tarea
Tarea Origen: Localizada en una dll estándar de Expertis [Expertis.Business.ProjectBase]
<Task()> Public Shared Sub AsignarValoresPorDefecto(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added OrElse data.RowState = DataRowState.Modified Then
data("PrecioA") = 100
data("FechaAlta") = Today.Date
End If
End Sub
Tarea Nueva: Localizada en una dll nuestra dedicada al proyecto [Expertis.Business.ProjectNew]
<Task()> Public Shared Sub TaskOverWriteValoresPorDefecto(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added OrElse data.RowState = DataRowState.Modified Then
data("PrecioA") = 200
data("FechaAlta") = Today.Date.AddDays(1)
End If
End Sub
En el manager localizamos la tarea de origen y pulsamos en Sobrescritura y buscamos nuestra tarea nueva.
68/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez hecho esto podemos guardar los datos y tendríamos hecha ya nuestra sobreescritura de tarea.
69/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Ejemplo de Tarea Después de Tarea
Tarea Nueva: Localizada en una dll nuestra dedicada al proyecto [Expertis.Busines.ProjectNew]
<Task()> Public Shared Sub TaskAfterValoresPorDefecto(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added OrElse data.RowState = DataRowState.Modified Then
data("Tipo") = 0
data("Importe") = data("PrecioA") * 100
End If
End Sub
En el manager localizamos la tarea de origen en la que queremos establecer una nueva tarea después y la
seleccionamos. Damos al botón de – para establecer la tarea después para esta tarea.
70/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez hecho esto podemos guardar los datos y tendríamos hecha ya nuestra nueva tarea después de la tarea de
origen dicha.
Ejemplo de Nueva Tarea en Proceso
Proceso Origen: Localizada en dll estándar de Expertis [Expertis.Business.ProjectBase]
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarClavePrimaria)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarValoresPorDefecto)
End Sub
Tarea Nueva: Localizada en una dll nuestra dedicada al proyecto [Expertis.Business.ProjectNew]
71/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Public Shared Sub TaskNewTaskOnProcess(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added OrElse data.RowState = DataRowState.Modified Then
If data("Tipo") = 1 Then
Dim StData As New StPublic(data("IDClave"), data("PrecioA"))
ProcessServer.ExecuteTask(Of StPublic)(AddressOf TaskPublicTask, StData, services)
End If
End If
End Sub
Para agregar la nueva tarea en el listado de un proceso vamos al manager para localizar el proceso en cuestión. Y
accedemos a su listado de tareas.
Añadimos nuestra nueva tarea en el listado
72/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez hecho esto podemos guardar los datos y tendríamos hecha ya nuestra nueva tarea en el proceso.
Ejemplo de Sobrescritura de un Proceso de Entidad
Proceso Origen: Localizada en dll estándar de Expertis [Expertis.Business.ProjectBase]
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As
Solmicro.Expertis.Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarClavePrimaria)
updateProcess.AddTask(Of DataRow)(AddressOf AsignarValoresPorDefecto)
End Sub
Proceso Nuevo: Localizada en una dll nuestra dedicada al proyecto [Expertis.Business.ProjectNew]
73/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Public Class PrNew
Inherits Process(Of DataRow)
Public Overrides Sub RegisterTasks()
Me.AddTask(Of DataRow)(AddressOf AsignarClavePrimariaNew)
Me.AddTask(Of DataRow)(AddressOf AsignarValoresPorDefectoNew)
End Sub
<Task()> Public Shared Sub AsignarClavePrimariaNew(ByVal data As DataRow, ByVal services As
ServiceProvider)
If data.RowState = DataRowState.Added Then
If Length(data("IDClave")) = 0 Then data("IDClave") = AdminData.GetAutoNumeric
End If
End Sub
<Task()> Public Shared Sub AsignarValoresPorDefectoNew(ByVal data As DataRow, ByVal services
As ServiceProvider)
If data.RowState = DataRowState.Added OrElse data.RowState = DataRowState.Modified Then
data("PrecioA") = 200
data("FechaAlta") = Today.Date.AddDays(1)
End If
End Sub
End Class
Buscamos el proceso de origen que deseamos sobrescribir y pulsamos sobre el botón de sobrescritura.
Seleccionamos nuestra dll con nuestro proceso nuevo para sobrescribir.
74/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez hecho esto podemos guardar los datos y tendríamos hecha la sobreescritura de un proceso de entidad con
uno nuevo nuestro.
Consideraciones Generales
El parámetro de Extensibilidad del manager de Expertis debe estar activo para que se lea la información funcional de
las tablas de sobrescritura de procesos y tareas. Sólo debe de activarse este parámetro en caso de desear usar la
extensibilidad de expertis. Si para el desarrollo para nuestro cliente solo hacemos cambios a nivel de presentación o
bien no hacemos uso de la extensibilidad es mejor desactivar este parámetro.
75/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Funciona actualmente con BBDD de sistema, tablas xProcess y xProcessTask, tanto con datos como sin datos
(vacías).
Las tareas devuelven automáticamente como objeto el objeto que reciben en la entrada de la misma tarea.
La primera tarea de los procesos, con el tipo de entrada que tenga establecido dictamina qué tipo de objeto manejará
en el resto de las tareas de los procesos, no pudiendo mezclar tipos.
Tipo de datos de envío a las tareas y retorno usaremos objetos de clase.
Una clase si tiene embebido un DataRow da error en Remoting aunque esté configurada como Serializable la clase.
Volver al Índice
76/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
3.3. CAPA DE PRESENTACIÓN
Introducción Capa de Presentación
Las clases de mantenimiento son los componente centrales de la parte cliente, ya que proporcionan la interfaz de
usuario, y se encargan de la gestión de datos en la parte cliente, complementándose con las operaciones que realiza
Expertis.Engine.BE.BusinessEngine en la capa de negocio.
Las clases de mantenimiento recopilan la información de todos los objetos que deben mantener y solicitan los datos
necesarios a la capa de negocio. Como proveedor de datos, una clase de mantenimiento realiza el enlace a datos de
todos los objetos y prepara la información para realizar las operaciones básicas con la base de datos (inserciones,
actualizaciones y borrados).
Todos los registros se manejan de forma desconectada y de forma genérica, las clases de mantenimiento utilizan
objetos de los componentes Expertis.Engine.BE.BusinessEngine y Expertis.Engine.Global para realizar sus
operaciones.
Las clases SimpleMnto, CIMntoBase (o su clase derivada CIMnto) y GridMnto, se encuentran en el componente
Expertis.Engine.UI.CommonClasses. Todas estas clases heredan de la clase base FormBase que se encuentra en el
componente Expertis.Engine.UI.WinControls. Estas clases componen la mayor parte de la interfaz de presentación,
de hecho en el fondo son clases que heredan de Windows.Form a las que se les incorpora una barra de herramientas
(excepto la clase FormBase, que no tiene barra de herramientas).
Las distintas clases de mantenimiento que heredan de FormBase particularizan su funcionamiento y se ajustan a las
necesidades de cada tipo de mantenimiento creando nuevas propiedades y métodos, o sobrescribiendo parte de la
interfaz que heredan de la propia clase FormBase.
FormBase:
Se utiliza, por ejemplo, en el desarrollo de formularios modales (esto permite tener formularios modales vinculados a
datos). Por ser la clase base del resto de las clases de mantenimiento, no posee una barra de herramientas propia.
SimpleMnto:
Se utiliza para el desarrollo de mantenimientos tipo ficha o cabecera-líneas. Este tipo de mantenimiento presenta los
datos de una tabla (principal) registro a registro. Dichas tablas suelen tener un gran número de registros.
Estableciendo la propiedad EntityName permite realizar las operaciones básicas (inserciones, modificaciones y
borrados). La propiedad NavigationFields establece el nombre del campo del origen de datos por el cual se van a
realizar los movimientos entre registros. La propiedad ViewName establece el nombre del origen de datos, que por
defecto es la tabla relacionada con la clase EntityName.
Habitualmente este tipo de mantenimientos presenta información adicional de una o varias tablas relacionadas con la
principal, que por lo general se mantienen en objetos de tipo Grid.
Una barra de comandos estándar permite moverse de registro, buscar registros, insertar, actualizar y eliminar
registros, etc.
CIMnto:
77/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Se utiliza para el desarrollo de consultas interactivas. En general, este tipo de mantenimientos está compuesto
básicamente por dos regiones: la primera región contiene los controles que conformarán el criterio de selección de la
consulta; la segunda, contiene un Grid para presentar los resultados de la consulta. Opcionalmente, el Grid de
presentación, puede presentar una columna de marcas, que permite la selección de registros.
Una barra de comandos estándar permite realizar las acciones básicas de este tipo de mantenimiento: filtrar, limpiar
los criterios de filtrado, exportar, ejecutar acción e imprimir.
La clase CIMnto, hereda de CIMntoBase, y solo puede implementar consultas simples, es decir, de un solo Grid y
unos criterios de selección. En la mayoría de los casos el desarrollo con CIMnto será suficiente.
CIMntoBase:
La clase CIMntoBase es más general y puede mantener en el mismo formulario varias consultas, cada una con su
Grid, sus criterios de selección, etc., sin más que establecer su propiedad CIPrimaryObject. Requiere un mayor
trabajo de programación que la utilización de la clase CIMnto.
GridMnto:
Esta clase implementa la interfaz necesaria para el desarrollo de mantenimiento de tipo tabla (o tipo Grid), en los que
se muestra un conjunto de registros de tablas maestras, generalmente, de unas decenas registros, con la posibilidad
de realizar inserciones, actualizaciones y borrados. La barra de comandos estándar permite realizar estas
operaciones y algunas más, como imprimir y exportar datos.
Volver al Índice
Creación / Configuración de Proyectos de Presentación
1.
Creación del Proyecto Forma Manual
Para crear un componente de la Capa de Presentación, crear un nuevo de Proyecto de Windows -> Visual
Basic, del tipo Biblioteca de Clases en VS2008. Establecer el nombre y la ubicación del Proyecto como en la
imagen. Así mismo asegurarnos de elegir la Opción de Arriba que esté en .NetFrameWork 3.5
En la página de propiedades del proyecto se puede comprobar cómo el nombre del proyecto define por
defecto un espacio de nombres.
El framework de .NET utiliza los espacios de nombres para definir ámbitos de objetos relacionados. Estos
ámbitos permiten organizar el código y proporciona una forma de crear tipos globalmente únicos.
78/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Para diferenciar el componente de negocio nuevo del resto de componentes de negocio estándares,
podemos cambiar el espacio de nombres de la raíz como aparece en la imagen
NOTA: El espacio de nombres de la raíz de los proyectos de negocio estándar de Expertis tiene la forma
Solmicro.Expertis.Application.ERP.Nombre_Programa.
Opciones de Compilación y Depuración del Proyecto
Para la compilación de un proyecto de presentación hay que tener en cuenta la ubicación final de los
ensamblados.
Existen varias opciones pero lo más habitual es:
A.
B.
Compilar directamente en el directorio de desarrollo (en este caso C:\ExpertisNet50t\Bin)
Para ello, desde la página de propiedades del proyecto, en la sección Compilar se establece la Ruta
de acceso de los resultados
La segunda opción es compilar en el directorio bin del proyecto (el que está establecido por
defecto), y después copiar “a mano” los ensamblados actualizados al directorio de desarrollo.
NOTA: Existe un inconveniente en esta opción que consiste en que mientras se compila el proyecto no es posible tener
abierto ningún otro proyecto que lo tenga referenciado. Durante la compilación se muestra un error que nos avisa de que el
archivo está siendo utilizado por otro proceso. Esto es debido a que el directorio de compilación y al que apuntan las
referencias del resto de proyectos es, habitualmente, el mismo. No tiene por qué suceder esto en el 100% de los casos. A
veces el visual studio 2008 es inteligente y se entera de los cambios que ha habido, pero no es la mayoría de los casos.
79/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Si queremos compilar correctamente debemos cerrar todos los proyectos que tengan referenciado el proyecto que se
quiere compilar.
Referencias del Proyecto:
En la mayoría de los casos las clases de presentación tienen que utilizar los servicios que les proporcionan
los componentes de negocio y de datos, y de configuración de presentación del framework de Expertis. Para
utilizar dichos servicios es necesario referenciar los siguientes componentes del Engine de Expertis
Expertis.Engine.BE.BusinessEngine
Expertis.Engine.Global
Expertis.Engine.UI.CommonClasses
Expertis.Engine.UI.Resources
Expertis.Engine.UI.WinControls
Además de éstas también necesitaremos referenciar las dlls de Janus. De las siguientes descritas tampoco
harían falta referenciarlas todas, si alguna no tendríamos introducida en nuestro proyecto enseguida el visual
Studio nos Avisa de la necesidad de esas referencias.
Janus.Data.v3
Janus.Windows.ButtonBat.v3
Janus.Windows.CalendarCombo.v3
Janus.Windows.Common.v3
Janus.Windows.ExplorerBar.v3
Janus.Windows.GridEX.v3
Janus.Windows.TimeLine.v3
Janus.Windows.UI.v3
Para agregar una referencia al proyecto, accedemos a las propiedades del proyecto y vamos a la pestaña de
Referencias.
O bien desde el menú Proyecto -> Agregar referencia
80/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez agregadas las referencias tenemos que asegurarnos en las propiedades de cada una de las dlls del
motor que tienen las propiedades de Copia Local y Copia Específica a False. Hay que recordar que estas
dos propiedades en todas las dlls que tenga nuestro proyecto siempre estén a falso. Tanto dlls del Engine de
Expertis, como dlls de capa de negocio, de capa de presentación, de las de janus en presentación, etc.…
todas las referencias sin excepción.
El componente Expertis.Engine.BE.BusinessEngine permite establecer un vínculo entre la capa de
presentación y la capa de negocio.
81/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El componente Expertis.Engine.UI.CommonClasses contiene todos los tipos diferentes de formularios que
nos aporta el Engine de Expertis.
El componente Expertis.Engine.UI.WinControls contiene todos los controles secundarios del Engine de
Expertis además de otros objetos y métodos para administrar Expertis, tales como búsquedas avanzadas, o
el objeto ExpertisApp, etc.…
El componente Expertis.Engine.UI.Resources contiene recursos propios del Engine de Expertis y que es
necesitada de las anteriores dlls. Por ello es necesaria su referencia en los proyectos.
El ensamblado Expertis.Engine.Global es una componente de uso general, tanto en la parte cliente, como en
la parte de negocio, y dispone de un conjunto de clases publicas útiles en desarrollo.
2.
Creación del Proyecto Forma Template
Para crear nuestro proyecto de Presentación de Expertis nuevo partiendo de las plantillas personalizadas
creadas por Solmicro, tendríamos que abrir el visual Studio y acudir a: Archivo -> Nuevo -> Proyecto.
82/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En la ventana siguiente que tendríamos disponible. Nos posicionamos en tipos de proyecto en Visual Basic y luego nos
fijamos que en las sección de Mis Plantillas dentro de Plantillas, tendremos disponibles los diferente tipos de proyectos de
presentación, cada uno con un nombre descriptivo y del tipo que veremos luego a continuación.
Volver al Índice
83/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Llamada a Tareas de Negocio desde Presentación
Para llamar a Tareas de Negocio desde Presentación lo haremos con el objeto ExpertisApp, perteneciente al DLL de
Expertis.Engine.UI.WinControls, y en el espacio de nombres de Expertis.Engine.UI. Es de tipo Shared con lo cual
haciendo una importación a este espacio de nombres nos permitirá usarlo sin necesidad de instanciarlo.
Este objeto ExpertisApp posee el método de ExecuteTask con el que podremos llamar y configurar la tarea que
deseamos llamar. Especificando los parámetros de entrada, salida y dirección de la función.
Vemos en el siguiente ejemplo la llamada a una tarea con un parámetro de entrada y llamándolo desde presentación.
Private Sub CICurso_RecordUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.RecordUpdated
Dim DtArticulo As DataTable
DtArticulo = ExpertisApp.ExecuteTask(Of String, DataTable)(AddressOf ObtenerDatosArticulo,
Me.CurrentRow("IDArticulo"))
End Sub
NOTA: a diferencia de la llamada de tareas en negocios, el parámetro de tipo ServiceProvider se omite en la llamada desde
presentación puesto que dicho tipo de objeto no está disponible en la capa de Presentación.
Volver al Índice
Tipos de Formularios de Expertis
1.
Formas de Creación de Formularios
Podemos crear los diferentes formularios de expertis de la manera que más cómoda nos resulte y que pasaremos a
explicar a continuación:
Creación Manual
Para crear un formulario de forma manual, en el proyecto existente de capa de presentación vamos al menú:
Proyecto -> Agregar Nuevo Elemento.
84/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Después en el siguiente asistente seleccionaríamos: Elementos Comunes -> Windows Forms -> Windows
Forms. Y establecemos un nombre para el nuevo formulario que vamos a crear y aceptamos.
Una vez agregado el nuevo formulario lo buscamos en el explorador de soluciones del proyecto. Pulsamos el
botón de mostrar todos los archivos. Una vez viendo todos los archivos expandimos el nivel de nuestro
nuevo formulario y abrimos con doble click el fichero con nombre: Formulario.Designer.vb
Teniendo abierto este fichero nos fijaremos en el principio del mismo y en la herencia que tiene: Inherits, y le
cambiaríamos lo que tiene establecido por lo mostrado en la imagen.
85/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Dentro de ese nivel de Solmicro.Expertis.Engine.UI tendremos ahí disponibles y pondremos el modelo de
formulario buscado:
-
CIMnto
CIMntoBase
SimpleMnto
GridMnto
FormBase
Creación con Herencia
Para crear un formulario que hereda de otro, desde el explorador de soluciones, botón derecho en el
proyecto y seleccionar Agregar -> Agregar Nuevo Elemento.
Después Seleccionar en Categorías: Windows Forms, y como plantilla Formulario Heredado. Establecer
también el nombre del formulario nuevo y pulsar Agregar.
86/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el formulario de Selector de herencia pulsar Examinar:
El formulario de dialogo nos permite seleccionar el componente donde está la clase de la cual se quiere
heredar. En este ejemplo vamos a heredar de la clase GridMnto que está en el componente
Expertis.Engine.UI.CommonClasses. La referencia debe apuntar al directorio de desarrollo, en este caso,
C:\ExpertisNet50\Bin.
87/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El siguiente formulario muestra todas las clases disponibles para crear un formulario heredado. Seleccionar
(por ejemplo) GridMnto y aceptar.
NOTA: cuando se crea el proyecto y se añade el primer formulario que hereda de alguna clase de mantenimiento de
Expertis, se añaden automáticamente una serie de referencias a otros componentes del Engine de Expertis, a
componentes Janus, y a componentes de Crystal Reports. En particular las referencias a Crystal Reports no son
necesarias y se pueden eliminar.
Creación con Template
El formulario de dialogo nos permite seleccionar el componente donde está la clase de la cual se quiere
Para crear un formulario que hereda de otro, desde el explorador de soluciones, botón derecho en el
proyecto y seleccionar Agregar -> Agregar Nuevo Elemento.
Después en el siguiente asistente seleccionaríamos: Elementos Comunes. Después en la sección central en
la parte de abajo en Mis Plantillas tendríamos que ver la plantilla personalizada correspondiente de cada tipo
formulario que tenemos en expertis. Seleccionaríamos el que necesitemos y le establecemos un nombre y
pulsamos aceptar.
88/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
2.
Formulario Tipo Tabla
Formulario de tipo tabla cuyo control principal sería un grid para el mostrado de datos en forma de tabla.
Dispondremos asimismo de una barra de herramientas para opciones de búsqueda de registros, impresión,
exportación, grabado de datos y acciones personalizadas.
El uso general de este tipo de formulario es para representar en forma de listado el contenido de una tabla o
vista. El uso más generalizado en expertis es para administrar tabla sencillas con pocos datos y pocas
columnas.
Tendremos que configurar el diseño de las columnas del grid o bien a través del Diseñador de Expertis o
bien manualmente.
Herencia de formulario de: Solmicro.Expertis.Engine.UI.GridMnto
Tipo Template: GridMntoExpertis.
El aspecto que tendría el formulario creado sería el siguiente:
89/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Propiedades Formulario
Las propiedades principales y más importantes del formulario en tiempo de diseño tendríamos:
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en el formulario. Debe coincidir con un nombre de entidad
válido de Expertis.
NavigationFields
Propiedad para definir el campo del origen de datos del formulario por el que navegaremos a la hora de realizar la
búsqueda de un registro por la búsqueda avanzada del Formulario.
ViewName
Propiedad para definir el origen de datos que se cargará en el formulario. Si se deja vacío se cargará la información de la
tabla de la entidad asociada al formulario
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
RecordsState
Propiedad que nos permite saber en qué estado se encuentra el formulario dependiendo de la acción que haya hecho el
usuario. De esta manera podemos saber si el formulario está en modo de nuevo registro, registro modificado, salvado,…
CurrentData
Datatable con toda la información que contiene el formulario y que visualizamos en el grid.
Ok
Botón de validar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Cancel
Botón de cancelar datos del formulario al que podemos simular e invocaar su pulsación a través del método:
InvokeOnClick
Requery
Botón de refrescar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Params
Colección de parámetros/valores que posee el formulario y que se ha podido pasar en la apertura del formulario desde
otro sitio de expertis. Esto nos permite enviar a un formulario información extra que necesitemos cuando abramos un
formulario en cualquier punto de Expertis.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not Me.Params Is Nothing Then
Dim HtParam As Hashtable = Me.Params
If HtParam.ContainsKey("Valor_Insertado") AndAlso Length(HtParam("Valor_Insertado")) > 0
Then
Me.AdvParam.Value = HtParam("ValorInsertado")
End If
End If
End Sub
FomActions
Colección de acciones que queramos tener en el formulario. Se agregan todas en orden en el que queramos que
aparezcan. Para agregar un separador entre acciones poseemos el método del formulario AddSeparator para agregar en
ese nivel de acciones un separador.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
90/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Me.FormActions.Add("Accion_Primera", AddressOf AccionPrimera,
ExpertisApp.GetIcon("MyIcon.ico"))
Me.AddSeparator()
Me.FormActions.Add("Accion_Segunda", AddressOf AccionSegunda,
ExpertisApp.GetIcon("MyIcon2.ico"))
End Sub
Métodos principales
BusinessCalling
Método que se invoca antes de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
BusinessCalled
Método que se invoca después de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
Navigating
Evento que se ejecuta antes de que lleva a cabo el comando de navegación y al que podremos controlar qué acción se ha
dado y poder cancelar el evento.
Navigated
Evento que se ejecuta después de que se lleve a cabo el comando de navegación dicho por el usuario.
RecordStateChanged
Evento que se ejecutará siempre que cambie el valor de la propiedad de la ventana: RecordsState. Esto nos permite poder
llevar a cabo mecanismos de control cada vez que el estado del formulario cambie por alguna acción del usuario.
RecordAdding,
RecordAdded,
RecordUpdating,
RecordCanceling, RecordCanceled
RecordUpdated,
RecordDeleting,
RecordDeleted,
Métodos relacionado con la inserción, modificación, borrado y cancelación de registros en el formulario. Con mecanismos
para los eventos de antes de llevar a cabo estas acciones con la variable e de poder cancelarlos con el Cancel.
SetReportDataSource, SetReportDesignObjects, SetReportExportOptions, SetReportSelectionCriteria
Eventos de informes en el formulario. Ver sección de Informes para el detalle de los eventos.
Volver al Índice
3.
Formulario Tipo Ficha
Formulario de tipo ficha del cual es el que heredan todo el resto de formularios de expertis. No tiene
controles presentes de base y serían para moldear por completo por nosotros.
El uso general de este tipo de formulario es para representar formularios modales sencillos o complejos en
expertis.
Podemos usar este tipo de formularios con manejo de datos llevado a cabo por nosotros o bien seguir
usando las propiedades estándar de entidad y vista que contiene el formulario.
Herencia de formulario de: Solmicro.Expertis.Engine.UI.FormBase
Tipo Template: FormBaseExpertis.
El aspecto que tendría el formulario creado sería el siguiente:
91/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Propiedades Formulario
Las propiedades principales y más importantes del formulario en tiempo de diseño tendríamos:
92/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en el formulario. Debe coincidir con un nombre de entidad
válido de Expertis.
NavigationFields
Propiedad para definir el campo del origen de datos del formulario por el que navegaremos a la hora de realizar la
búsqueda de un registro por la búsqueda avanzada del Formulario.
ViewName
Propiedad para definir el origen de datos que se cargará en el formulario. Si se deja vacío se cargará la información de la
tabla de la entidad asociada al formulario
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
RecordsState
Propiedad que nos permite saber en qué estado se encuentra el formulario dependiendo de la acción que haya hecho el
usuario. De esta manera podemos saber si el formulario está en modo de nuevo registro, registro modificado, salvado,…
CurrentData
Datatable con toda la información que contiene el formulario y que visualizamos en el grid.
Ok
Botón de validar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Cancel
Botón de cancelar datos del formulario al que podemos simular e invocaar su pulsación a través del método:
InvokeOnClick
Requery
Botón de refrescar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Params
Colección de parámetros/valores que posee el formulario y que se ha podido pasar en la apertura del formulario desde
otro sitio de expertis. Esto nos permite enviar a un formulario información extra que necesitemos cuando abramos un
formulario en cualquier punto de Expertis.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not Me.Params Is Nothing Then
Dim HtParam As Hashtable = Me.Params
If HtParam.ContainsKey("Valor_Insertado") AndAlso Length(HtParam("Valor_Insertado")) > 0
Then
Me.AdvParam.Value = HtParam("ValorInsertado")
End If
End If
End Sub
FomActions
Colección de acciones que queramos tener en el formulario. Se agregan todas en orden en el que queramos que
aparezcan. Para agregar un separador entre acciones poseemos el método del formulario AddSeparator para agregar en
ese nivel de acciones un separador.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormActions.Add("Accion_Primera", AddressOf AccionPrimera,
ExpertisApp.GetIcon("MyIcon.ico"))
Me.AddSeparator()
Me.FormActions.Add("Accion_Segunda", AddressOf AccionSegunda,
ExpertisApp.GetIcon("MyIcon2.ico"))
93/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
Métodos principales
UpdateData
Método para provocar que se actualicen los datos del formulario asociado y actualizarlos en la base de datos llamando a
los procesos de actualización de la entidad asociada en el formulario.l
BusinessCalling
Método que se invoca antes de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
BusinessCalled
Método que se invoca después de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
Navigating
Evento que se ejecuta antes de que lleva a cabo el comando de navegación y al que podremos controlar qué acción se ha
dado y poder cancelar el evento.
Navigated
Evento que se ejecuta después de que se lleve a cabo el comando de navegación dicho por el usuario.
RecordStateChanged
Evento que se ejecutará siempre que cambie el valor de la propiedad de la ventana: RecordsState. Esto nos permite poder
llevar a cabo mecanismos de control cada vez que el estado del formulario cambie por alguna acción del usuario.
RecordAdding,
RecordAdded,
RecordUpdating,
RecordCanceling, RecordCanceled
RecordUpdated,
RecordDeleting,
RecordDeleted,
Métodos relacionado con la inserción, modificación, borrado y cancelación de registros en el formulario. Con mecanismos
para los eventos de antes de llevar a cabo estas acciones con la variable e de poder cancelarlos con el Cancel.
SetReportDataSource, SetReportDesignObjects, SetReportExportOptions, SetReportSelectionCriteria
Eventos de informes en el formulario. Ver sección de Informes para el detalle de los eventos.
Volver al Índice
4.
Formulario Tipo Mantenimiento Simple
Formulario de tipo Simple cuyo objetivo es la visualización de registro a registro de un origen de datos,
pudiéndonos mover entre registros con la barra de herramientas de desplazamiento.
El uso general de este tipo de formulario es para representar formularios con datos de una tabla padre con
datos de tablas hijas. Representando en una cabecera los datos del padre y los datos de los hijos en
datagrid hijos del padre.
Hay que tener en cuenta que este formulario nos crea directamente una barra de herramientas personalizada
con botones de desplazamiento de registros, búsqueda avanzada y botones de validación, cancelación,
exportación, acciones personalizadas, impresora,…
Herencia de formulario de: Solmicro.Expertis.Engine.UI.SimpleMnto
Tipo Template: SimpleMntoExpertis.
El aspecto que tendría el formulario creado sería el siguiente:
94/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Propiedades Formulario
Las propiedades principales y más importantes del formulario en tiempo de diseño tendríamos:
95/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
AllowDeleteCommand
Propiedad para habilitar o no el botón de borrado de registro del formulario.
AllowNewCommand
Propiedad para habilitar o no el botón de nuevo registro del formulario.
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en el formulario. Debe coincidir con un nombre de entidad
válido de Expertis.
LastUsedDescFields
Especificación de qué campo del origen de datos queremos que se muestre y almcene en el listado de últimos usados de la
búsqueda avanzada del formulario.
NavigationFields
Propiedad para definir el campo del origen de datos del formulario por el que navegaremos a la hora de realizar la
búsqueda de un registro por la búsqueda avanzada del Formulario y movernos por los registros.
ViewName
Propiedad para definir el origen de datos que se cargará en el formulario. Si se deja vacío se cargará la información de la
tabla de la entidad asociada al formulario
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
RecordsState
Propiedad que nos permite saber en qué estado se encuentra el formulario dependiendo de la acción que haya hecho el
usuario. De esta manera podemos saber si el formulario está en modo de nuevo registro, registro modificado, salvado,…
CurrentData
Datatable con toda la información que contiene el formulario y que visualizamos en el grid.
CurrentRow
Datarow con el registro actual en el que se encuentra posicionado el formulario.
Ok
Botón de validar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Cancel
Botón de cancelar datos del formulario al que podemos simular e invocaar su pulsación a través del método:
InvokeOnClick
Requery
Botón de refrescar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Params
Colección de parámetros/valores que posee el formulario y que se ha podido pasar en la apertura del formulario desde
otro sitio de expertis. Esto nos permite enviar a un formulario información extra que necesitemos cuando abramos un
formulario en cualquier punto de Expertis.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not Me.Params Is Nothing Then
Dim HtParam As Hashtable = Me.Params
If HtParam.ContainsKey("Valor_Insertado") AndAlso Length(HtParam("Valor_Insertado")) > 0
Then
Me.AdvParam.Value = HtParam("ValorInsertado")
End If
End If
End Sub
FomActions
Colección de acciones que queramos tener en el formulario. Se agregan todas en orden en el que queramos que
aparezcan. Para agregar un separador entre acciones poseemos el método del formulario AddSeparator para agregar en
ese nivel de acciones un separador.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormActions.Add("Accion_Primera", AddressOf AccionPrimera,
ExpertisApp.GetIcon("MyIcon.ico"))
96/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Me.AddSeparator()
Me.FormActions.Add("Accion_Segunda", AddressOf AccionSegunda,
ExpertisApp.GetIcon("MyIcon2.ico"))
End Sub
Métodos principales
UpdateData
Método para provocar que se actualicen los datos del formulario asociado y actualizarlos en la base de datos llamando a
los procesos de actualización de la entidad asociada en el formulario.
BusinessCalling
Método que se invoca antes de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
BusinessCalled
Método que se invoca después de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
Navigating
Evento que se ejecuta antes de que lleva a cabo el comando de navegación y al que podremos controlar qué acción se ha
dado y poder cancelar el evento.
Navigated
Evento que se ejecuta después de que se lleve a cabo el comando de navegación dicho por el usuario.
RecordStateChanged
Evento que se ejecutará siempre que cambie el valor de la propiedad de la ventana: RecordsState. Esto nos permite poder
llevar a cabo mecanismos de control cada vez que el estado del formulario cambie por alguna acción del usuario.
RecordAdding,
RecordAdded,
RecordUpdating,
RecordCanceling, RecordCanceled
RecordUpdated,
RecordDeleting,
RecordDeleted,
Métodos relacionado con la inserción, modificación, borrado y cancelación de registros en el formulario. Con mecanismos
para los eventos de antes de llevar a cabo estas acciones con la variable e de poder cancelarlos con el Cancel.
SetReportDataSource, SetReportDesignObjects, SetReportExportOptions, SetReportSelectionCriteria
Eventos de informes en el formulario. Ver sección de Informes para el detalle de los eventos.
Configuración de datos por Entidad / Vista o por Ejecución
Para el mostrado de datos en una consulta interactiva podemos llevarlo a cabo de dos manera: uno siendo por entidad /
Vista y otro asignando nosotros el origen de datos en ejecución.
Para la configuración por entidad / vista no tendríamos mas que configurar un nombre de entidad y vista en el formulario
para que nos cargue automáticamente datos de esta entidad / Vista. Si dejásemos solo el nombre de entidad y no
poniendo vista, nos mostrará datos de la tabla que está configurada la entidad del formulario. Si no pusiésemos nombre
de entidad y pusiésemos nombre de vista se mostrarían los datos de la vista configurada.
Para la carga de datos a través de un proceso nuestro, lo que necesitaríamos es confirmar que el formulario no tiene
establecido ni nombre de entidad ni nombre de vista, ambas propiedades en vacio.
Luego prograríamos en el evento QueryExecuting del formulario el conformar el filtro que necesitamos y traer los datos de
nuestro proceso.
Private Sub CI_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles Me.QueryExecuting
e.Filter.Add("IDCliente", FilterOperator.Equal, "00")
e.Filter.Add("IDArticulo", FilterOperator.Equal, "ART001")
Dim DtGrid As System.Data.DataTable = New BE.DataEngine().Filter("tbAuxDatos",
e.Filter.InnerFilter)
Me.Grid.Datasource = DtGrid
Me.BindEditEvents(DtGrid)
97/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
Como se observa en el código de ejemplo, necesitamos establecer los datos que hemos procesado al origen de datos del
Grid del formulario de consulta interactiva y además ejecutar el comando de Me.BindEditEvents. Este comando sirve para
indicar al formulario que el origen de datos del formulario es nuestro datatable procesado y así se entere la barra de
herramientas para que funcione con nuestro datatable.
Si no ejecutásemos este comando veríamos que la barra de herramientas no se activarían los botones.
Además si en el formulario usamos el tema de marcas y activamos con la marca de UseCheck del formulario,
necesitaremos el comando a continuación para que nos funcionase correctamente el tema de marcas con nuestro
datatable cargado en ejecución. Sería un comando del DataGrid al que le pasamos nuestro DataTable para que lo procese
y agregue las columnas de checks y esté enlazado con el datasource del Grid de la consulta interactiva.
Private Sub CI_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles Me.QueryExecuting
e.Filter.Add("IDCliente", FilterOperator.Equal, "00")
e.Filter.Add("IDArticulo", FilterOperator.Equal, "ART001")
Dim DtGrid As System.Data.DataTable = New BE.DataEngine().Filter("tbAuxDatos",
e.Filter.InnerFilter)
Me.Grid.DataSource = DtGrid
Me.Grid.AddCheckColumnToDataSource(DtGrid, Nothing)
Me.BindEditEvents(DtGrid)
End Sub
Volver al Índice
5.
Formulario Tipo Consulta Interactiva
Formulario de tipo Consulta Interactiva cuyo objetivo es la visualización de datos con la posibilidad de
configuración de filtros para una obtención de resultados concreta.
El uso general de este tipo de formulario es para representar información ya preparada en vistas de la base
de datos con posibilidad de filtrar estos datos con los filtros que configuremos en la ventana o bien con el
filtro dinámico.
Herencia de formulario de: Solmicro.Expertis.Engine.UI.CIMnto
Tipo Template: CIMntoExpertis.
El aspecto que tendría el formulario creado sería el siguiente:
98/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Propiedades Formulario
Las propiedades principales y más importantes del formulario en tiempo de diseño tendríamos:
AllowDynamicFilter
Propiedad para habilitar o no el filtrado dinámico en la consulta interactiva.
AllowUpdate
Propiedad para habilitar o no la posibilidad de actualización de datos en la consulta interactiva. Con esto nos mostrará u
ocultará los botones de validación y cancelación de datos de la consulta.
CheckFields
Colección de columnas de guardado de datos junto con la propiedad de usar chequeos en la consulta interactiva.
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en el formulario. Debe coincidir con un nombre de entidad
válido de Expertis.
FilterPanelVisible
Propiedad para mostrar o no por defecto el panel de filtros de la consulta interactiva.
KeyField
Propiedad para definir el campo del origen de datos del formulario por el que navegaremos a la hora de realizar la
ViewName
Propiedad para definir el origen de datos que se cargará en el formulario. Si se deja vacío se cargará la información de la
tabla de la entidad asociada al formulario
UseCheck
Propiedad para activar o desactivar el uso de chequeos en la consulta interactiva. Con esta opción nos mostrará / ocultará
los correspondiente botones y columna relacionado con los chequeos.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Ok
Botón de validar datos del formulario al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Cancel
Botón de cancelar datos del formulario al que podemos simular e invocaar su pulsación a través del método:
InvokeOnClick
Params
Colección de parámetros/valores que posee el formulario y que se ha podido pasar en la apertura del formulario desde
otro sitio de expertis. Esto nos permite enviar a un formulario información extra que necesitemos cuando abramos un
formulario en cualquier punto de Expertis.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not Me.Params Is Nothing Then
Dim HtParam As Hashtable = Me.Params
If HtParam.ContainsKey("Valor_Insertado") AndAlso Length(HtParam("Valor_Insertado")) > 0
Then
Me.AdvParam.Value = HtParam("ValorInsertado")
End If
End If
99/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
FomActions
Colección de acciones que queramos tener en el formulario. Se agregan todas en orden en el que queramos que
aparezcan. Para agregar un separador entre acciones poseemos el método del formulario AddSeparator para agregar en
ese nivel de acciones un separador.
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormActions.Add("Accion_Primera", AddressOf AccionPrimera,
ExpertisApp.GetIcon("MyIcon.ico"))
Me.AddSeparator()
Me.FormActions.Add("Accion_Segunda", AddressOf AccionSegunda,
ExpertisApp.GetIcon("MyIcon2.ico"))
End Sub
ExecuteRequery
Botón de ejecución de la consulta interactiva al que podemos simular e invocar su pulsación a través del método:
InvokeOnClick.
Métodos principales
Execute
Método para provocar la ejecución de la consulta interactiva simulando la pulsación del botón de prismáticos.
BindEditEvents
Método del formulario que nos permite agregar el origen de datos que estemos trabajando en el formulario. De esta
manera el formulario activa la barra de herramientas y los botones reaccionan al origen de datos que le hemos pasado.
Esto es para casos en el que el origen de datos es dinámico y por una ejecución de un proceso nuestro, no nos vale cargar
información en el formulario a través de nombre de entidad y vista.
Private Sub Grid_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles MyBase.QueryExecuting
Dim FilDatos As New Filter
Dim DtGrid As DataTable = New BE.DataEngine().Filter("VistaDatos", FilDatos)
Me.BindEditEvents(DtGrid)
Me.Grid.DataSource = DtGrid
End Sub
BusinessCalling
Método que se invoca antes de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
BusinessCalled
Método que se invoca después de que se llamen a las reglas de negocio de cualquier entidad del formulario. Con lo cual
siempre hace falta llevar a cabo un control de qué entidad llama a este evento del formulario para concretar las opciones
para cada entidad. En este evento podremos trabajar con la información del current y context que manejan las reglas de
negocio de Expertis.
RecordStateChanged
Evento que se ejecutará siempre que cambie el valor de la propiedad de la ventana: RecordsState. Esto nos permite poder
llevar a cabo mecanismos de control cada vez que el estado del formulario cambie por alguna acción del usuario.
CheckingRecord
Método para controlar cuando se esté chequeando o deschequeando un registro, usando con el sistema de chequeos del
Grid. Para ello podremos controlar el estado del check a través de la propiedad e.CheckState, teniendo en cuenta que el
evento es de la acción que se va a llevar a cabo, no de la acción ya hecha. Con lo cual tendremos que analizar el valor de
esta propiedad negándola.
Tengamos en cuenta que este evento se llamará tanto en la acción de chequear como deschequear un registro y antes de
que lleve esta acción a su valor final.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckState: nos da la información de la situación actual de la columna check del registro que ha
-
E.Row: todo el registro del Grid que se está llevando la acción de chequeo o deschequeo
-
E.Cancel: propiedad para cancelar por completo el evento de check/uncheck del registro.
invocado este evento y con lo cual sabremos qué acción futura se va a hacer.
Private Sub CIMntoExpertis1_CheckingRecord(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckingEventArgs) Handles CIMntoExpertis1.CheckingRecord
100/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
If e.CheckState = CheckStates.UnChecked Then
If e.Row.Cells("Estado").Value = 1 Then
e.Cancel = True
End If
End If
End Sub
RecordChecked
Método que se invocará después de que se haya chequeado o deschequeado un registro.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckState: nos da la información de la opción de chequeo / deschequeo que se ha llevado a cabo en el
-
E.Row: todo el registro del Grid que se está llevando la acción de chequeo o deschequeo
registro actual.
Private Sub CIMntoExpertis1_RecordChecked(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckedEventArgs) Handles CIMntoExpertis1.RecordChecked
If e.CheckState = CheckStates.Checked Then
If e.Row.Cells("Estado").Value = 1 Then
ExpertisApp.GenerateMessage("Se ha seleccionado un registro con Estado 1",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
End If
End If
End Sub
CheckingAllRecord
Evento para cuando hayamos hecho un chequear o deschequear todos los registros del Grid. Esta acción será para las
dos opciones realizadas y antes de que pueda llevar a cabo la acción, con lo cual nos posibilita poder cancelar el evento
dependiendo de las circunstancias que necesitemos.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckAction: nos da la información de la acción de chequeo o deschequeo llevada a cabo.
-
E.Cancel: propiedad para cancelar por completo el evento de checkall/uncheckall del registro.
Private Sub CIMntoExpertis1_CheckingAllRecord(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckingAllEventArgs) Handles CIMntoExpertis1.CheckingAllRecord
If e.CheckAction = UI.CheckAction.Check Then
If Me.txtEstado.Text = 1 Then
ExpertisApp.GenerateMessage("No se pueden seleccionar todos los registros",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
e.Cancel = True
End If
End If
End Sub
AllRecordChecked
Evento para cuando haya completado la acción de chequear o deschequear todos los registros del Grid.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckAction: nos da la información de la acción de chequeo o deschequeo llevada a cabo.
Private Sub CIMntoExpertis1_AllRecordChecked(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.AllCheckedEventArgs) Handles CIMntoExpertis1.AllRecordChecked
If e.CheckAction = UI.CheckAction.Check Then
ExpertisApp.GenerateMessage("Se han seleccionado todos los registros.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
End If
End Sub
QueryExecuting
Evento para configurar los filtros que se van a aplicar a la consulta del origen de datos establecido en la consulta
interactiva. Para ello disponemos en la variable e la propiedad Filter para agregar todos los filtros que deseemos. Sobre
todo tendremos que configurar y añadir en este punto aquellos filtros configurados en el panel de criterios de selección
para recoger los datos configurados por el usuario.
Private Sub CIMntoExpertis1_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles Me.QueryExecuting
e.Filter.Add("IDClave", FilterOperator.Equal, Me.AdvClave.Value)
e.Filter.Add("DescClave", FilterOperator.Equal, Me.txtDescClave.value)
e.Filter.Add("FechaAlta", FilterOperator.GreaterThanOrEqual, Me.ClbFechaDesde.Value)
e.Filter.Add("FechaAlta", FilterOperator.LessThanOrEqual, Me.ClbFechaHasta.Value)
101/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
QueryExecuted
Evento para cuando se haya completado la ejecución de la consulta interactiva y por si deseamos ejecutar procesos.
Generalmente solemos dar uso a este evento para el tema de cálculo de totales del grid que mostramos en la consulta
interactiva para el usuario.
FilterClearing
Evento para capturar cuando se ha dado al botón de limpiar los controles del panel de criterios de selección y antes de que
lleve a cabo esta limpieza.
FilterCleared
Evento para cuando se haya completado la ejecución de la acción de limpieza de los controles del panel de criterios de
selección.
RecordAdding,
RecordAdded,
RecordUpdating,
RecordCanceling, RecordCanceled
RecordUpdated,
RecordDeleting,
RecordDeleted,
Métodos relacionado con la inserción, modificación, borrado y cancelación de registros en el formulario. Con mecanismos
para los eventos de antes de llevar a cabo estas acciones con la variable e de poder cancelarlos con el Cancel.
SetReportDataSource, SetReportDesignObjects, SetReportExportOptions, SetReportSelectionCriteria
Eventos de informes en el formulario. Ver sección de Informes para el detalle de los eventos.
Volver al Índice
6.
Formulario Tipo Consulta Interactiva Padre
Formulario de tipo Consulta Interactiva Padre cuyo objetivo es el mismo que una consulta interactiva normal
pero en este caso no nos da un grid principal en el diseño ni una sección del filtros en la ventana. Esto es
para que podamos diseñar a nuestras necesidades el formulario.
El uso general de este tipo de formulario es para representar formularios con datos de varias vistas en
diferentes grids. Siendo luego el grid que mostremos el principal de la ventana y por el que funcionaría la
barra de herramientas del formulario.
Herencia de formulario de: Solmicro.Expertis.Engine.UI.CIMntoBase
Tipo Template: CIMntoBaseExpertis.
El aspecto que tendría el formulario creado sería el siguiente:
102/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Como propiedades y eventos generales de esta poseerá los mismos que el formulario de tipo Consulta
Interactiva, puesto que como ya hemos comentado este formulario es el padre de la Consulta Interactiva.
Lo que tenemos que tener en cuenta principalmente con este tipo de formulario, es el crear como
necesitemos el formulario y que a la hora de la ejecución de la consulta en el método QueryExecuting,
hagamos un análisis de si la propiedad CIPrimaryObject del formulario no esté vacía y asignarle el DataGrid
que se está visualizando en ese momento en el formulario.
Private Sub CIMntoBaseExpertis1_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles Me.QueryExecuting
If Me.CIPrimaryObject Is Nothing Then Me.CIPrimaryObject = Me.Grid1
Select Case Me.TabGrids.SelectedTab.Key
Case "Principal"
Me.CIPrimaryObject = Me.Grid1
Case "Secundario"
Me.CIPrimaryObject = Me.Grid2
End Select
End Sub
Esto es para poder decir al formulario cuál es el objeto principal en la pantalla y con el que funcionará los
botones de las barras de herramientas y los eventos.
Hemos de tener en cuenta también que cada vez que hagamos la asignación de la propiedad
CIPrimaryObject automáticamente el motor llama al evento QueryExecuting del formulario.
Otra forma para establecer cuál el es el DataGrid principal de una Consulta Interactiva Padre sería a través
del método siguiente:
Private Sub CIMntoBaseExpertis1_QueryExecuting(ByVal sender As Object, ByRef e As
Solmicro.Expertis.Engine.UI.QueryExecutingEventArgs) Handles Me.QueryExecuting
If Me.CIPrimaryObject Is Nothing Then Me.CIPrimaryObject = Me.Grid1
Select Case Me.TabGrids.SelectedTab.Key
Case "Principal"
Me.SetCIPrimaryObject(Me.Grid1, False)
Case "Secundario"
Me.SetCIPrimaryObject(Me.Grid2, False)
End Select
End Sub
Con este comando conseguimos el mismo efecto, pero en vez de ejecutar el evento QueryExecuting de la
consulta de manera automática, lo hará dependiendo del valor del 2º parámetro, pudiendo especificar False
para que no lleve a cabo la ejecución automática de la consulta
Volver al Índice
Controles de Expertis en Presentación
1.
Agregar los Controles de Expertis al Cuadro de Herramientas
Crear una ficha nueva al cuadro de herramientas del entorno de desarrollo de Visual Studio, para ello, botón
derecho sobre el cuadro de herramientas, Agregar nueva ficha, y asignar un nombre a la ficha, por ejemplo,
Expertis.
103/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Para agregar los controles a la nueva ficha, botón derecho, Agregar o quitar elementos…
A continuación conviene ordenar los elementos por el espacio de nombres al que pertenecen. Los controles
de Expertis pertenecen al espacio de nombres Solmicro.Expertis.Engine.UI.
Marcar los siguientes elementos:
AdvSearch
Button
CalendarBox
CheckBox
ComboBox
CounterTextBox
Frame
Grid
GridBase
Label
ListBox
NumericTextBox
Panel
RadioButton
Tab
TextBox
UnderLineLabel
Y aceptar.
NOTA: Es importante usar siempre los controles de expertis. Si el que necesita para su desarrollo existe del tipo de
Expertis, use ese primero sino acuda a otros controles del framework / thirdparties. Es esencial usar el tipo de expertis de
cara para la herramienta de traducciones ya que para procesar lo que se tiene que traducir se coge solo de controles de
tipo Expertis.
Volver al Índice
104/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
2.
AdvancedSearch
Control de búsqueda avanzada de expertis. Control que nos permite acceder a datos de entidades con sistema de filtrados
para localizar un valor concreto. Podremos configurar búsquedas avanzadas sueltas en cualquier formulario que
necesitemos y además embeberlas en datagrid configurando ciertas columnas para que sean de tipo AdvSearch.
No permite la carga de tablas externas o vistas, solo a través de la configuración de nombre de entidad y vista en el
control.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
ASSelectedFields
Listado de relación de controles con campos donde queremos descargar información relacionada con la entidad de la
búsqueda avanzada. Este listado nos permite definir en qué controles del formulario que campos queremos mostrar
de esta entidad cuando seleccionemos un valor en la búsqueda avanzada.
DisplayField
Campo del origen de datos de la entidad de la búsqueda avanzada que queremos que se muestre en la caja de
texto. Si se omite este campo el campo mostrado en la búsqueda avanzada será el descrito en
SecondaryDataFields.
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en la búsqueda avanzada. Debe coincidir con un
nombre de entidad válido de Expertis.
PrimaryDataFields
Campo del formulario padre en el que se encuentra situada la búsqueda avanzada para la relación del control con el
formulario contenedor. Este campo sería el coincidente con uno perteneciente al origen de datos del formulario o
control padre.
Esta propiedad deberá permanecer en vacío si es un control de búsqueda avanzada que usamos en una consulta
interactiva, o bien en cualquier formulario que no tenga una conexión con un formulario padre.
SecondaryDataFields
Campo de la búsqueda avanzada para la relación de la búsqueda avanzada con el formulario padre contenedor. Este
campo sería el coincidente con uno de la entidad de la búsqueda avanzada. Esta propiedad siempre ha de estar
rellenada y correctamente configurada con el campo correcto para el correcto funcionamiento de la búsqueda
avanzada.
ViewName
Nombre de la tabla – vista de la que tomará los datos la búsqueda avanzada. Generalmente podrá ir en vacío, al
dejarlo vacío funcionará como origen de tabla la tabla de la entidad puesta en la propiedad EntityName. Si
especificamos otro origen funcionará con este otro origen.
DataBindings - Value
Conexión de bindeo del control con un campo del formulario padre en el que se encuentre. Aconsejamos para los
controles de tipo búsqueda avanzada el realizarlo a la propiedad value, más que a la propiedad text.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Value
Propiedad por la que obtendremos el campo de valor asociado a la propiedad SecondaryDataFields del control de
búsqueda avanzada.
105/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Text
Propiedad por la que obtendremos el campo de texto asociado a la propiedad SecondaryDataFields o si estuviera
configurado el campo de DisplayField el correspondiente a este.
SelectedRow
Propiedad por la que podremos obtener todo el datarow asociado al valor que tenga el control de búsqueda
avanzada.
Métodos principales
NotInList
Método que se invoca cuando se detecta que se ha insertado un valor en la caja de texto de la búsqueda avanzada,
que no existe en la tabla de la entidad configurada. Por defecto el motor siempre sacará un mensaje de error de
registro no existente y no nos permitirá aceptar este valor para la búsqueda avanzada. Con lo cual si lo que
queremos es no mostrar este mensaje genérico o mostrar otro más personalizado, escribiremos un código parecido
marcado a continuación.
Private Sub AdvSearch1_NotInList(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.NotInListEventArgs) Handles AdvSearch1.NotInList
e.Handled = True
ExpertisApp.GenerateMessage("No existe el Valor introducido.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
e.Cancel = True
End Sub
OpenningAdvSearch
Método que se llama en cuanto pulsamos al botón de la búsqueda avanzada para mostrar la pantalla de
configuración de filtros y resultados. Se dispone de este método para poder cancelar esa apertura por si se desea.
Private Sub AdvSearch1_OpenningAdvSearch(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles AdvSearch1.OpenningAdvSearch
If Me.TextBox1.Text = "00" Then
e.Cancel = True
End If
End Sub
SetPredefinedFilter
Método para establecer filtros a la búsqueda avanzada. Este método será invocado cada vez que entremos a escribir
en la caja de texto de la búsqueda avanzada, o bien abramos la pantalla de configuración de filtros y resultados.
Para ello en este método agregamos filtros como de un objeto filter de expertis se tratara
Private Sub AdvSearch1_SetPredefinedFilter(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.AdvSearchFilterEventArgs) Handles AdvSearch1.SetPredefinedFilter
e.Filter.Add("IDClave", FilterOperator.Equal, "00")
End Sub
SelectionChanged
Método que se ejecuta cuando seleccionamos un registro de la pantalla de configuración de filtros y resultados y
también se ejecuta cuando validamos un valor introducido en la caja de texto de la búsqueda avanzada. Esto nos
permite acceder a todo el registro seleccionado coincidente con el valor introducido para lo que necesitemos.
Private Sub AdvSearch1_SelectionChanged(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.AdvSearchSelectionChangedEventArgs) Handles
AdvSearch1.SelectionChanged
If e.Selected.Rows(0)("Tipo_Clave") = "01" Then
ExpertisApp.GenerateMessage("No se puede seleccionar del tipo 01.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
End If
End Sub
Configuración en Formularios de una búsqueda avanzada.
La propiedad EntityName es el nombre de la clase del componente de negocio que se va a encargar de
realizar las búsquedas.
La propiedad PrimaryDataFields es el nombre del campo del proveedor de datos del control, con el cual
se relacionan los datos sobre los que actúa el propio control.
106/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
La propiedad SecondaryDataFields es el nombre del campo del esquema de datos relacionado con
EntityName, con el que se relaciona con el valor de PrimaryDataFields.
La propiedad DisplayField es el nombre del campo del esquema de datos relacionado con EntityName,
cuyo valor se muestra en la caja de texto de la búsqueda. Por defecto es el valor de
SecondaryDataFields.
La propiedad ViewName es el nombre del origen de datos sobre el que se realizan las búsquedas. Si
no tiene valor, es igual a la tabla relacionada con EntityName.
La configuración básica de la búsqueda avanzada difiere según la clase de mantenimiento.
En una clase SimpleMnto en la que el control esta enlazado con el origen de datos del formulario es
necesario establecer EntityName, PrimaryDataFields y SecondaryDataFields.
En una clase CIMnto la búsqueda no está enlazada al origen de datos de la clase de mantenimiento
con lo que al menos hay que dar valores a EntityName y SecondaryDataFields.
NOTA: La configuración de una búsqueda avanzada consta de dos partes. Una parte corresponde al diseño del
control y la otra parte se realiza en tiempo de ejecución. La configuración en diseño es común para todos los
usuarios; la configuración en tiempo de ejecución es particular para cada usuario.
Para poder realizar la configuración en tiempo de ejecución es necesario actualizar los metadatos de la base de
datos de sistema con la estructura de las tablas involucradas.
Configuración en DataGrids de una búsqueda avanzada.
El control Grid de Expertis mantiene su propia colección de controles AdvSearch. Para asociar una
búsqueda avanzada a una de las columnas de Grid, desde la sección Grids del diseñador de Expertis,
botón derecho sobre la columna en cuestión, seleccionar la opción Set Adv. Search
En la solapa Adv.Search se puede configurar las búsquedas definidas en el Grid. La propiedad
EntityName es el nombre de la clase de negocio asociada a la tabla sobre la que se van a realizar las
búsquedas. La propiedad SelectedField es el nombre del campo cuyo valor se va a volcar sobre la
celda del Grid. ViewName permite establecer un origen de datos personalizado (por defecto el origen
de datos es la tabla asociada a EntityName).
107/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El panel inferior dentro de esta solapa permite configurar el volcado de los valores del registro
seleccionado en la búsqueda avanzada sobre otras columnas del Grid. En la imagen anterior se
muestra un ejemplo: el valor del campo DescArticulo se volcara sobre la columna Descripción.
Volver al Índice
3.
CounterTextBox
Control de contadores de expertis para mostrar el listado de contadores disponibles de la entidad del formulario donde
esté alojado el control.
Este control no dispone de propiedades ni de métodos específicos para su configuración, ya que toda la administración de
esta información la hace de manera automática el motor.
Propiedades Control
DataBindings - Text
La única propiedad que tenemos que tener bien configurada para este control sería el databinding en text.
Tendremos que configurar aquí el campo final que descargaría los contadores y el valor que deseamos ver ya
compuesto.
Para toda esta configuración necesitaríamos tener en nuestra tabla un campo que fuese clave principal de tipo
numérico o autonumérico. Luego otro campo de tipo NContador donde almacenaríamos el valor de contador final. Y
por último un campo llamado IDContador donde se guardará la información de qué IDContador del maestro de
contadores usamos.
Para el uso y configuración final de contadores lo explicaremos más adelante en otro apartado.
Volver al Índice
108/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
4.
Combobox
Control de Listado de datos. Nos permite cargar la información de tabla o vista relacionada con la entidad de expertis que
configuremos en sus propiedades en diseño o bien suministrándole el datatable de datos que queramos y de cualquier
origen de tabla o vista.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en la búsqueda avanzada. Debe coincidir con un
nombre de entidad válido de Expertis.
PrimaryDataFields
Campo del formulario padre en el que se encuentra situada la búsqueda avanzada para la relación del control con el
formulario contenedor. Este campo sería el coincidente con uno perteneciente al origen de datos del formulario o
control padre.
Esta propiedad deberá permanecer en vacío si es un control de búsqueda avanzada que usamos en una consulta
interactiva, o bien en cualquier formulario que no tenga una conexión con un formulario padre.
SecondaryDataFields
Campo de la búsqueda avanzada para la relación de la búsqueda avanzada con el formulario padre contenedor. Este
campo sería el coincidente con uno de la entidad de la búsqueda avanzada. Esta propiedad siempre ha de estar
rellenada y correctamente configurada con el campo correcto para el correcto funcionamiento de la búsqueda
avanzada.
RelationMode
Modo de relación del control con el formulario padre en el que se encuentre alojado.
Para esta propiedad tendremos 3 opciones posibles:
-
NoRelation: el control no tiene relación de ningún tipo con el formulario padre y para su carga de datos
es administrada completamente por nosotros. Aunque tuviera los datos de relación y configuración no
funcionaría correctamente el control
-
ChildMode: modo de relación con el formulario padre. De esta manera la carga de datos la administrará
el motor de expertis.
-
ComplementaryMode: modo complementaria con el formulario padre. De esta manera el motor de
expertis si nos cargaría de manera automática el control su origen de datos pero sin relación. Sería todo
el contenido de la tabla – vista configurada en el control.
ViewName
Nombre de la tabla – vista de la que tomará los datos la búsqueda avanzada. Generalmente podrá ir en vacío, al
dejarlo vacío funcionará como origen de tabla la tabla de la entidad puesta en la propiedad EntityName. Si
especificamos otro origen funcionará con este otro origen.
ComboStyle
Opción de modo de manejo del control combobox, cambiando la manera en la que nos permite editar el control
combobox.
Para esta propiedad tendremos 2 opciones posibles:
-
Combo: el control combobox muestra el listado de datos que tiene a través del botón despegable y
cargando en la caja de texto del control el campo establecido en DisplayMember. Pero con esta opción
nos permite editar el contenido de esta caja de texto del control
109/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
-
DropDownList: el control combobox muestra el listado de datos que tiene a través del botón despegable
y cargando en la caja de texto del control el campo establecido en DisplayMember. Pero no nos permite
modificar el contenido de la caja de texto.
ColumnAutoresize
Accesible este propiedad desde el diseñador de combo (DropDown Designer).
Nos permite indicar que todas las columnas mostradas en el control tendrán un ancho automático hasta ocupar el
máximo tamaño que tiene el control combobox
DisplayMember
Propiedad en la que establecemos que campo del origen de datos se utiliza para el mostrado en la caja de texto del
control y el campo que accederemos a través de la propiedad Text.
ValueMember
Propiedad en la que establecemos que campo del origen de datos se utiliza para valor que se almacena en el control
y es el campo que accederemos a través de la propiedad Value.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor o establecerlo.
Value
Valor del control que tiene seleccionado para el valor text. Podremos obtener este valor o establecerlo.
DataSource
Origen de datos del control combobox. Generalmente será un Datatable, pero se puede establecer tanto un
datatable como un dataview. Es una propiedad tanto de escritura como de lectura. Es a la que acudiremos para
poder obtener todo ese datatable que tiene como origen de datos el control o bien establecerle uno en los casos de
configuración manual y que no se administran por nombre de entidad – vista.
Métodos principales
ValueChanged
Método que se activará cada vez que cambie el contenido de la propiedad Value del control.
TextChanged
Método que se activará cada vez que cambie el contenido de la propiedad Text del control.
Diseñador de Combobox
Para el control Combobox disponemos de una herramienta de diseño visual para una mayor configuración y
personalización del control.
Para acceder a este diseñador bastará con que demos botón derecho del ratón encima del control combobox ->
DropDown Designer.
110/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Después de pinchar a esta opción tendremos disponible el diseñador del Combobox y todas las posibilidades que nos
ofrece:
Aquí tendremos disponibles más opciones generales de configuración de todo el control combobox en sí y otras
como: configurar la colección de columnas, diseños de columnas, condiciones de formato, colección de columnas de
ordenamiento, grupos, etc…
Para conocer más de este configurador y opciones acudir al manual de Combobox de los controles Janus.
Configuración en Diseño de un control ComboBox.
La propiedad EntityName es el nombre de la clase del componente de negocio asociado al origen de
datos del control.
La propiedad PrimaryDataFields es el nombre del campo del proveedor de datos del control, con el cual
se relacionan los datos sobre los que actua el propio control.
La propiedad SecondaryDataFields es el nombre del campo del esquema de datos relacionado con
EntityName, con el que se relaciona con el valor de PrimaryDataFields.
La propiedad ViewName es el nombre del origen de datos sobre el que se realizan las búsquedas. Si
no tiene valor, es igual a la tabla relacionada con EntityName.
La propiedad ValueMember establece el valor que se guarda internamente. Este valor es el que se
utiliza para vincular internamente los elementos con el valor del combo.
NOTA: Si no se configura, la propiedad ValueMember es el nombre de la primera columna del origen de datos del
ComboBox.
La propiedad RelationMode es un valor de tipo Solmicro.Expertis.Engine.RelationMode que establece
el tipo de relación del control con su proveedor de datos (generalmente un formulario de Expertis).
Si RelationMode es NoRelation (este es el valor por defecto) los datos que se solicitan al componente
del Engine de la capa de negocio, Expertis.Engine.BE.BusinessEngine, no están ligados con el
formulario (se obtienen todos los registros de la entidad correspondiente a la propiedad EntityName).
Los datos se obtienen la primera vez que son solicitados por parte del formulario, y en las posteriores
solicitudes del formulario ya no se recuperan datos para dicho ComboBox. Trabajando de esta manera
no se deben establecer las propiedades PrimaryDataFields y SecondaryDataFields. Se deberá
configurar la propiedad ValueMember para indicar el campo del origen de datos que se enlazará con el
control.
Si RelationMode es ComplementaryMode los datos del ComboBox si están ligados con el formulario.
Para el enlace se utilizan las propiedades PrimaryDatafields y SecondaryDataFields. El ComboBox
111/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
recibe datos en cada movimiento de navegación del formulario. Se deberá configurar la propiedad
ValueMember para indicar el campo del origen de datos que se enlazará con el ComboBox.
NOTA: En cualquiera de los dos comportamientos existe la posibilidad de aplicar un filtro a los datos del ComboBox
utilizando la propiedad Filter.
El control ComboBox, por defecto, muestra todos los campos de la tabla o vista que se ha establecido
en la propiedad ViewName. Sin embargo, es probable que el origen de datos tenga más información de
la que en realidad conviene mostrar en el combo.
Por esta razón, habitualmente es necesario configurar las columnas que se van a mostrar. Hay dos
opciones
Equivalentes. La primera consiste en abrir el configurador del Combo, haciendo botón derecho sobre el
control, Configure MultiColumnCombo
Esta opción abre un asistente con el que se pueden configurar las columnas del control. En el primer
paso seleccionar la opción DataSource is not available at design time
En el segundo paso es posible añadir, modificar y eliminar las columnas del combo
112/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el último paso es posible establecer las propiedades ValueMember con el nombre del campo cuyo
valor se guarda internamente, y DisplayMember, con el nombre del campo cuyo valor se va a mostrar.
La segunda opción consiste en abrir el diseñador del control, haciendo botón derecho sobre el control,
seleccionar DropDown Designer
NOTA: Esta opción es la que se suele utilizar cuando se quiere modificar el diseño del combo una vez que se ha
creado un primer layout para el control.
En la sección Columns del diseñador es posible definir las columnas de la lista
113/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Asignar un origen de datos por código y con Datatable
La propiedad DataSource permite asignar un origen de datos personalizado. También es posible
configurar las propiedades ValueMember y DisplayMember por código, como se muestra en este
código de ejemplo
Dim dt As DataTable
dt = New Moneda().Filter()
If dt.Rows.Count > 0 Then
cmbIDMoneda.DataSource = dt
End If
cmbIDMoneda.ValueMember = "IDMoneda"
cmbIDMoneda.DisplayMember = "IDMoneda"
Asignar un origen de datos por código y con Enumerados
El control ComboBox puede mostrar también una lista de valores correspondientes a un enumerado de
Expertis. Para asignar el enumerado como origen de datos del ComboBox se utiliza la clase EnumData.
El siguiente ejemplo asigna el enumerado CursoEstadoContabilizacion a un control ComboBox llamado
cmbEstado
cmbEstado.DataSource = New EnumData("CursoEstadoContabilizacion")
NOTA: Si el ComboBox muestra una lista de enumerado conviene establecer la propiedad ComboStyle igual a
DropDownList. De esta forma no es posible editar directamente en el control, y el usuario está obligado a seleccionar
un elemento existente en la lista.
Volver al Índice
114/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
5.
CalendarBox
Control de mostrado de calendarios y fechas. Se aconseja para cualquier campo de base de datos de tipo fecha el
asociarlo a un control de este tipo.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
DateFormat
Propiedad para definir el formato del campo fecha de cómo será mostrado y manejado en el control.
Para esta propiedad tenemos las siguientes opciones:
-
Short: formato corto de fecha.
-
Long: formato largo de fecha.
-
Time: mostrado sólo de la parte de hora de una fecha.
-
DateTime: mostrado de la fecha en formato conjunto de fecha con hora.
-
Custom: configuración personalizada del formato de la fecha, esta propiedad funciona
conjuntamente con la propiedad CustomFormat.
CustomFormat
Podemos definir una máscara en esta propiedad para establecer un formato personalizado de la fecha que queremos
mostrar. Esta propiedad solo funcionará cuando la propiedad DateFormat esté a Custom.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor o establecerlo.
Value
Valor del control que tiene seleccionado para el valor text. Podremos obtener este valor o establecerlo.
Métodos principales
TextChanged
Método que se activará cada vez que cambie el contenido de la propiedad Text del control.
ValueChanged
Método que se activará cada vez que cambie el contenido de la propiedad Value del control.
Volver al Índice
115/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
6.
NumericTextBox
Control de búsqueda avanzada de expertis. Control que nos permite acceder a datos de entidades con sistema de filtrados
para localizar un valor concreto. Podremos configurar búsquedas avanzadas sueltas en cualquier formulario que
necesitemos y además embeberlas en datagrid configurando ciertas columnas para que sean de tipo AdvSearch.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
Decimal Digits
Número de posiciones decimales que se permiten y se formatean en el control. Por defecto tendremos un valor de -1
que indicamos al control que queremos usar el número de decimales que esté configurada en la configuración
regional de la máquina. Para manejar el control con números enteros podremos establecer el valor a 0.
FormatMask
Tipo de máscara del control para diversos tipos de datos:
-
General: formato general de texto, se permite introducción de datos no numéricos.
-
Currency: formato para datos numéricos de monedas. Nos agregará el símbolo de la moneda a la
derecha del control. Este símbolo se cogerá de la configuración regional de la máquina en ejecución.
-
Number: formato para datos numéricos normales.
-
Percent: formato para datos numéricos de porcentajes. Nos agregará el símbolo de porcentaje a la
derecha del control.
FormatString
Cadena personalizada de máscara de entrada para establecer un formato de entrada personalizado a lo que
necesitemos.
NullBehavior
Propiedad para controlar la introducción y manejo de nulos en el control.
Tendremos 3 opciones posibles:
-
NoNulls: no permite nunca introducción de valores nulos. Si no se introduce nada se tomará como
valor por defecto el 0.
-
AllowNull: se permite la introducción de nulos, siendo este nulo el tipo de nulo estándar.
-
AllowDBNull: se permite la introducción de nulos, siendo este nul el tipo de nulo proveniente de base
de datos.
ValueType
Propiedad para establecer el tipo de valor numérico que manejará el control. Siendo posible definir en esta
propiedad todos los tipos de datos numéricos de bases de datos: enteros, decimales, enteros 16, enteros 64 etc…
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor o establecerlo.
Value
Valor del control que tiene seleccionado para el valor text. Podremos obtener este valor o establecerlo.
Métodos principales
TextChanged
Método que se activará cada vez que cambie el contenido de la propiedad Text del control.
ValueChanged
Método que se activará cada vez que cambie el contenido de la propiedad Value del control.
Volver al Índice
116/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
7.
TextBox
Control de caja de texto. Control para poder mostrar campos de contenido texto para su visualización o edición.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
PasswordChar
Propiedad para definir el carácter que se mostrará ocultando los valores que el usuario va introduciendo. De esta
manera podemos definir un control textbox en un control de tipo contraseña.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor o establecerlo.
Métodos principales
TextChanged
Método que se activará cada vez que cambie el contenido de la propiedad Text del control.
Volver al Índice
117/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
8.
Grid
Control DataGrid de Expertis para el mostrado horizontal de datos.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
AdvSearchColumns
Colección de columnas del grid que están configuradas como búsquedas avanzadas.
CheckFields
Colección de columnas del grid que están configuradas como columnas de almacenaje de datos junto con las marcas
de chequeados.
EntityName
Nombre de la entidad de expertis de la cargaremos los datos en el Grid. Debe coincidir con un nombre de entidad
válido de Expertis.
KeyField
Nombre del Campo Clave de la entidad configurada del Grid, es obligatorio rellenar este campo cuando se usa
conjuntamente con la opción de UseCheck = True (Usar columna de Marcas).
PrimaryDataFields
Campo del formulario padre en el que se encuentra situado el grid para la relación del control con el formulario
contenedor. Este campo sería el coincidente con uno perteneciente al origen de datos del formulario o control padre.
Esta propiedad deberá permanecer en vacío si es un control de grid que está en cualquier formulario que no tenga
una conexión con un formulario padre.
SecondaryDataFields
Campo del grid para la relación del grid con el formulario padre contenedor. Este campo sería el coincidente con uno
de la entidad del grid. Si no existiera conexión con un formulario padre puede permanecer en vacío esta propiedad.
118/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
RelationMode
Modo de relación del control con el formulario padre en el que se encuentre alojado.
Para esta propiedad tendremos 3 opciones posibles:
-
NoRelation: el control no tiene relación de ningún tipo con el formulario padre y para su carga de datos
es administrada completamente por nosotros. Aunque tuviera los datos de relación y configuración no
funcionaría correctamente el control
-
ChildMode: modo de relación con el formulario padre. De esta manera la carga de datos la administrará
el motor de expertis.
-
ComplementaryMode: modo complementaria con el formulario padre. De esta manera el motor de
expertis si nos cargaría de manera automática el control su origen de datos pero sin relación. Sería todo
el contenido de la tabla – vista configurada en el control.
ViewName
Nombre de la tabla – vista de la que tomará los datos el grid Generalmente podrá ir en vacío, al dejarlo vacío
funcionará como origen la tabla de la entidad puesta en la propiedad EntityName. Si especificamos otro origen
funcionará con este otro origen.
UseCheck
Opción del Grid para especificar que se desea usar la columna de Check de Expertis en el Grid. Habilitándose para
ello una serie de opciones en el Grid y de Métodos relacionados con los marcajes.
RequeryManually
Opción para especificar en el grid que los datos se solicitarán a la base de datos cuando nosotros lo requerimos
(True) o bien lo haga automáticamente el motor (False).
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
DataSource
Origen de datos del DataGrid, siendo el tipo de datos más general y común en expertis el DataTable o DataView. Es
una propiedad que podremos tanto establecer valor como recoger el contenido del mismo.
RowCount
Propiedad que nos permite obtener el número total de registros que posee el origen de datos del Grid.
Col
Forma de obtener el índice de columna que está posicionado la celda actual seleccionada.
Row
Forma de obtener el índice del registro que está posicionada la celda actual seleccionada.
Actions
Colección de acciones locales personalizadas configuradas en el Grid y donde podemos ir agregando las diferentes
acciones que necesitemos.
NewTopRowPosition
Propiedad que nos da la información del índice de registro en el que está posicionada la fila de nuevo registro. Este
dato lo usaremos generalmente en el evento EditingCell del Grid para saber cuándo aplicar bloqueos de columnas
de registros en el grid.
CheckedRecords
Datatable de los registros que se hayan seleccionado en el datagrid. Esta propiedad sería funcional junto con las
propiedades y sistema de chequeo dentro del Grid. El datagrid nos proporcionará un datatable de aquellos registros
que se hayan seleccionado y con los datos que tuvieran en el momento del chequeo. Hay que tener en cuenta este
detalle porque seleccionando un registro y si posteriormente modificamos alguno de esos datos, éstos cambios no se
reflejarán posteriormente en el CheckedRecords.
CheckedRecordsCount
Propiedad que nos dirá el total de registros chequeados en el grid y que coincidirá con el recuento total de registros
presentes en el CheckedRecords. Esta propiedad será funcional con el sistema de chequeos del Grid.
Filter
Opción para establecer un filtrado al origen de datos cargado en el datagrid. De esta manera podremos asociarle un
objeto Filter de Expertis.
119/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Métodos principales invocables en código
AddSeparator
Nos permitirá agregar un separador a la colección de acciones locales personalizadas del DataGrid y agregándola a la
siguiente posición de la colección.
Requery
Método que nos permite volver a solicitar la carga de datos del origen de datos establecido en el DataGrid. Este
evento funcionaría conjuntamente con la propiedad RequeryManually establecida a True. De esta manera un
datagrid no solicitaría los datos hasta que ejecutásemos este método Requery. Como parámetro opcional de este
comando, nos permite especificar directamente en la llamada un objeto Filter de expertis para que dentro de la
solicitud que se hace en ese momento de los datos sea con un filtro.
Dim FilRequery As New Filter
FilRequery.Add("IDClave", FilterOperator.Equal, "00")
Me.Grid1.ReQuery(FilRequery)
120/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
GetValue
Forma de obtener el valor de la columna que indiquemos en el registro que esté posicionado en ese momento en el
datagrid.
Dim StrDesc As String = Me.Grid1.GetValue("DescClave")
SetValue
Forma de establecer valor a la columna que indiquemos en el registro que esté posicionado en ese momento en el
datagrid.
Me.Grid1.SetValue("DescClave", "Descripción Nueva")
InvokebusinessRules
Alternativamente con el comando anterior descrito puede que necesitemos después de establecer el valor en un
columna de esta manera, el que se invoquen las reglas de negocio de la entidad del DataGrid (proceso
GetBusinessRules de Entidad de Negocio). Esto es que al ser un establecimiento del valor de una columna por
código el datagrid no se entera que igual tenga que llamar a las reglas de negocio. Para ello disponemos de este
método.
De esta manera especificaremos el nombre de columna que queremos invocar las reglas de negocio, el valor original
del campo y el valor nuevo que queremos establecer.
Me.Grid1.InvokeBusinessRules("IDClave", "NuevoValor", "ValorOriginal")
De esta manera conseguiremos garantizar que se ejecuten las reglas de negocio siempre y en todo momento y
siempre que veamos que sea necesario.
CheckRecord
Método que funcionará de forma conjunta con el sistema de chequeos del Grid. Nos permite chequear el registro en
el que esté posicionado en ese momento en el Grid.
UnCheckRecord
Método que funcionará de forma conjunta con el sistema de chequeos del Grid. Nos permite deschequear el registro
en el que esté posicionado en ese momento en el Grid.
CheckAllRecords
Método que funcionará de forma conjunta con el sistema de chequeos del Grid. Nos permite ejecutar el chequeo de
todos los registros del origen de datos del Grid.
UnCheckAllRecords
Método que funcionará de forma conjunta con el sistema de chequeos del Grid. Nos permite ejecutar el deschequeo
de todos los registros del origen de datos del Grid.
Métodos principales
AdvSearchNotInList
Método que se invocará en el código cuando en una columna que sea de tipo búsqueda avanzada, el registro
insertado no exista en el origen de datos.
El motor de expertis saca directamente un mensaje de error advirtiendo que no existe el dato introducido en la base
de datos y no permitiendo el salvar este dato introducido.
Para ello tenemos este método disponible para poder cancelar esa acción o bien mostrar un mensaje más
personalizado o bien llevar a cabo la ejecución de lo que necesitemos.
Para toda la información para llevar a cabo esto acudiremos a la variable e de entrada del evento:
-
E.Value: valor incorrecto introducido por el usuario. Generalmente en este evento se utiliza para mostrar el
-
E.Handled: estableciéndolo a True haremos que el motor cancele su control y mensaje de error. Esto
-
E.Cancel: estableciéndolo a True cancelaremos todo el evento del NotInList y haremos que no se permita
-
E.Key: nos da la información de la clave de la columna de búsqueda avanzada que ha invocado al método.
valor en el mensaje personalizado de error.
puede ser porque queremos que en la búsqueda avanzada que se ejecuta no salga ningún mensaje de
error por parte del motor y permitir el valor no existente.
el aceptar el valor incorrecto introducido por el usuario en la búsqueda avanzada.
Private Sub Grid1_AdvSearchNotInList(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.AdvSearchNotInListEventArgs) Handles Grid1.AdvSearchNotInList
Select Case e.Key
Case "IDClave"
e.Handled = True
ExpertisApp.GenerateMessage("La Clave | no existe en la base de datos",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation, e.Value)
e.Cancel = True
121/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Select
End Sub
AdvSearchSelectionChanged
Cada vez que se busque un dato introducido en la búsqueda avanzada se invocará este método en el cual podemos
obtener todo el registro seleccionado de la entidad de la búsqueda avanzada.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.Key: nos da la información de la clave de la columna de búsqueda avanzada que ha invocado al método.
-
E.Selected: DataTable con un solo row con el contenido de todo el registro que hemos seleccionado en la
búsqueda avanzada.
Private Sub Grid1_AdvSearchSelectionChanged(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.GridAdvSearchSelectionChangedEventArgs) Handles
Grid1.AdvSearchSelectionChanged
Select Case e.Key
Case "IDClave"
Me.TxtDescClave.Text = e.Selected.Rows(0)("DescClave")
End Select
End Sub
AdvSearchSetPredefinedFilter
Evento para establecer filtros predeterminados a las búsquedas avanzadas, de esta manera cuando se ejecuten
aplicarán siempre y en todo momento los filtros configurados en este evento.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.Key: nos da la información de la clave de la columna de búsqueda avanzada que ha invocado al método.
-
E.Filter: Filtro de expertis a configurar para establecer un filtro predeterminado para la búsqueda
-
E.ForcePredefinedFilter: variable booleana con la que podemos forzar a la columna de búsqueda avanzada
avanzada.
invocada el que vuelva a obtener los datos de la búsqueda con el filtro configurado en este evento.
Private Sub Grid1_AdvSearchSetPredefinedFilter(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.GridAdvSearchFilterEventArgs) Handles
Grid1.AdvSearchSetPredefinedFilter
Select Case e.Key
Case "IDClave"
e.Filter.Add("Estado", FilterOperator.Equal, 1)
End Select
End Sub
UpdatingCell
Método que se invoca antes de actualizar por completo y aceptar el valor introducido en una celda del grid.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.Column: nos da la información de la de la columna que ha invocado al método.
-
E.InitialValue: valor inicial de la celda de la columna que tenía antes de la actualización.
-
E.Value: valor actual introducido en la celda de la columna.
-
E.Cancel: propiedad para cancelar por completo el evento previo de actualización de la celda.
Private Sub Grid1_UpdatingCell(ByVal sender As Object, ByVal e As
Janus.Windows.GridEX.UpdatingCellEventArgs) Handles Grid1.UpdatingCell
Select Case e.Column.Key
Case "IDClave"
If e.InitialValue = 0 AndAlso e.Value = 1 Then
ExpertisApp.GenerateMessage("No se puede cambiar el estado de 0 a 1.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
e.Cancel = True
End If
End Select
End Sub
CellUpdated
Método que se invoca después de actualizar el valor introducido en una celda del grid.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.Column: nos da la información de la de la columna que ha invocado al método.
Private Sub Grid1_CellUpdated(ByVal sender As Object, ByVal e As
Janus.Windows.GridEX.ColumnActionEventArgs) Handles Grid1.CellUpdated
Select Case e.Column.Key
Case "IDClave"
122/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
ExpertisApp.GenerateMessage("Valor Actulizado",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
End Select
End Sub
EditingCell
Método que se invocará en cuanto nos posicionemos en una celda para la edición de su valor. Generalmente en este
evento lo que solemos programar es un control para ver si el usuario puede modificar o no a nivel de celda esta
columna dependiendo de valores dinámicos.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.Column: nos da la información de la de la columna que ha invocado al método.
-
E.Value: valor actual de la celda de la columna.
-
E.Cancel: propiedad para cancelar por completo el evento de edición de la celda.
Private Sub Grid1_EditingCell(ByVal sender As Object, ByVal e As
Janus.Windows.GridEX.EditingCellEventArgs) Handles Grid1.EditingCell
Select Case e.Column.Key
Case "IDClave"
If e.Value > 0 Then
e.Cancel = True
End If
End Select
End Sub
CheckingRecord
Método para controlar cuando se esté chequeando o deschequeando un registro, usando con el sistema de
chequeos del Grid. Para ello podremos controlar el estado del check a través de la propiedad e.CheckState, teniendo
en cuenta que el evento es de la acción que se va a llevar a cabo, no de la acción ya hecha. Con lo cual tendremos
que analizar el valor de esta propiedad negándola.
Tengamos en cuenta que este evento se llamará tanto en la acción de chequear como deschequear un registro y
antes de que lleve esta acción a su valor final.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckState: nos da la información de la situación actual de la columna check del registro que ha
-
E.Row: todo el registro del Grid que se está llevando la acción de chequeo o deschequeo
-
E.Cancel: propiedad para cancelar por completo el evento de check/uncheck del registro.
invocado este evento y con lo cual sabremos qué acción futura se va a hacer.
Private Sub Grid1_CheckingRecord(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckingEventArgs) Handles Grid1.CheckingRecord
If e.CheckState = CheckStates.UnChecked Then
If e.Row.Cells("Estado").Value = 1 Then
e.Cancel = True
End If
End If
End Sub
RecordChecked
Método que se invocará después de que se haya chequeado o deschequeado un registro.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckState: nos da la información de la opción de chequeo / deschequeo que se ha llevado a cabo en el
-
E.Row: todo el registro del Grid que se está llevando la acción de chequeo o deschequeo
registro actual.
Private Sub Grid1_RecordChecked(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckedEventArgs) Handles Grid1.RecordChecked
If e.CheckState = CheckStates.Checked Then
If e.Row.Cells("Estado").Value = 1 Then
ExpertisApp.GenerateMessage("Se ha seleccionado un registro con Estado 1",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
End If
End If
123/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
CheckingAllRecord
Evento para cuando hayamos hecho un chequear o deschequear todos los registros del Grid. Esta acción será para
las dos opciones realizadas y antes de que pueda llevar a cabo la acción, con lo cual nos posibilita poder cancelar el
evento dependiendo de las circunstancias que necesitemos.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckAction: nos da la información de la acción de chequeo o deschequeo llevada a cabo.
-
E.Cancel: propiedad para cancelar por completo el evento de checkall/uncheckall del registro.
Private Sub Grid1_CheckingAllRecord(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.CheckingAllEventArgs) Handles Grid1.CheckingAllRecord
If e.CheckAction = UI.CheckAction.Check Then
If Me.txtEstado.Text = 1 Then
ExpertisApp.GenerateMessage("No se pueden seleccionar todos los registros",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
e.Cancel = True
End If
End If
End Sub
AllRecordChecked
Evento para cuando haya completado la acción de chequear o deschequear todos los registros del Grid.
Para ello tendremos en la variable e de entrada toda la información necesaria:
-
E.CheckAction: nos da la información de la acción de chequeo o deschequeo llevada a cabo.
Private Sub Grid1_AllRecordChecked(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.AllCheckedEventArgs) Handles Grid1.AllRecordChecked
If e.CheckAction = UI.CheckAction.Check Then
ExpertisApp.GenerateMessage("Se han seleccionado todos los registros.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
End If
End Sub
RecordAdded, RecordUpdated, AddingRecord, RecordAdded, DeletingRecord, RecordsDeleted
Eventos generales relacionados con la inserción, modificación y borrado de registros dentro del grid. Tendremos
disponibles tanto los eventos anteriores a llevar a cabo la acción correspondiente como después de haber llevado a
cabo la acción.
En los eventos anteriores a las acciones disponemos dentro de la variable e su propiedad Cancel para poder cancelar
el evento anterior.
FormattingRow
Evento que ejecutará el grid ante cambios fromateo y de orígenes de datos en el cual podremos aplicar estilos
personalizados por columna y celda. Nos permitirá analizar la información por celda que se está procesando y su
valor y poder cambiar sus propiedades de diseño visual.
-
E.Row: todo el registro del Grid que se está llevando la acción de formateo
Private Sub Grid1_FormattingRow(ByVal sender As Object, ByVal e As
Janus.Windows.GridEX.RowLoadEventArgs) Handles Grid1.FormattingRow
If Me.TxtEstado.text = 1 Then
e.Row.Cells("DescClave").FormatStyle.ForeColor = Drawing.Color.Aqua
End If
124/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
End Sub
Diseñador de Grid
Para el control Grid disponemos de una herramienta de diseño visual para una mayor configuración y personalización
del control.
Para acceder a este diseñador bastará con que demos botón derecho del ratón encima del control Grid -> GridEX
Designer.
Esta opción nos abrirá el diseñador específico del DataGrid y todo su conjunto de propiedades y funcionalidades
especiales que nos proporciona el Grid de Expertis.
Dentro de las opciones del Datagrid tendremos disponibles de todo tipo y para mayor información sobre todo lo que
contiene este grid acudir a la ayuda del GridEx de los controles de Janus System.
Volver al Índice
125/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
9.
UnderLineLabel
Control para el mostrado de contenido e campos pero sin permitir edición y con una barra de subrayada fija para todo el
control.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
DataBindings - Text
Propiedad de bindeo del control con la propiedad text del control.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor.
Métodos principales
TextChanged
Método que se activará cada vez que cambie el contenido de la propiedad Text del control.
Volver al Índice
10. Label
Control para establecer etiquetas por el formulario y para definir para controles.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
Text
Valor de la caja de texto que posee el control al que podemos obtener este valor
Volver al Índice
126/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
11. RadioButton
Control para mostrar estado de verdadero o falso dentro de un grupo de este tipo de controles para escoger solo una
opción. Este control viene acompañado con un label por defecto para el nombre de la opción accesible a través de la
propiedad Text.
Propiedades Control
Las propiedades principales y más importantes del control en tiempo de diseño tenemos:
CheckAlign
Propiedad para definir dónde se alinea la parte visual del control: derecha, izquierda, centro, ……
Checked
Propiedad para establecer u obtener el estado verdadero o falso de este control.
Text
Propiedad del texto que se visualizará conjunto con el control
DataBindings - BindableValue
Propiedad de Bindeo del control. Aconsejamos utilizar esta propiedad para el bindeo y no aconsejamos usar la
propiedad Checked en este bindeo.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Checked
Propiedad para establecer u obtener el estado verdadero o falso de este control.
Métodos principales
CheckedChanged
Método que se invocará cada vez que cambie el valor de checked del control.
Volver al Índice
127/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
12. CheckBox
Control para mostrar estado de verdadero, falso o nulo dentro de un grupo de este tipo de controles para escoger una o
varias opciones. Este control viene acompañado con un label por defecto para el nombre de la opción accesible a través de
la propiedad Text.
Propiedades Control
CheckAlign
Propiedad para definir dónde se alinea la parte visual del control: derecha, izquierda, centro, ……
Checked
Propiedad para establecer u obtener el estado verdadero o falso de este control.
Text
Propiedad del texto que se visualizará conjunto con el control
ThreeState
Opción para configurar si se desea utilizar el tercer estado de Nulo o no se admite valores nulos en este control.
DataBindings - BindableValue
Propiedad de Bindeo del control. Aconsejamos utilizar esta propiedad para el bindeo y no aconsejamos usar la
propiedad Checked en este bindeo.
Las propiedades principales y más importantes del control en tiempo de ejecución tenemos:
Checked
Propiedad para establecer u obtener el estado verdadero o falso de este control.
Métodos principales
CheckedChanged
Método que se invocará cada vez que cambie el valor de checked del control.
Volver al Índice
128/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
13. Otros Controles
Panel
Control aglutinador de controles en el que no se visualiza nada en tiempo de ejecución de dicho control. Nos sirve
para mantener agrupados controles sin que se note en la ejecución final por parte del usuario
Frame
Control aglutinador de controles que se visualiza con un marco y un título de control. Nos sirve para mantener
agrupados controles visualizándonos con el marco y un título descriptivo para el usuario final.
Tab
Control de pestañas para organizar la información y controles del usuario.
Para este control disponemos con el botón derecho del ratón encima del control las opciones de Add Tab y Remove
Tab, para añadir y eliminar rápidamente más pestañas a este control.
129/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Asimismo disponemos de un diseñador de todas las pestañas de este control. Dicho diseñador disponemos de él en
la ventana de propiedades -> Propiedad TabPages.
Volver al Índice
130/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Acciones Locales
Formularios
Las Acciones Locales de Expertis es una funcionalidad que nos permite generar acciones personalizadas localmente
en el formulario en las que programemos. De esta manera podemos desarrollar funcional adicional a un formulario
para el usuario final que no se engrose dentro del diseño y formato del propio formulario.
Para esta funcionalidad tenemos disponibles en todos los formularios de Expertis (a excepción del FormBase) una
colección de acciones locales donde podremos ir agregando las acciones que creamos oportunas. Esta colección
sería: Me.FormActions.
En esta colección iremos agregando todas las acciones locales que deseemos y necesitemos, teniendo en cuenta que
en el orden en que las programemos será en el orden de visualización que veremos en el resultado final. . También
hemos de tener en cuenta de programar el alta de estas acciones solo una vez en la pantalla puesto que si lo hacemos
más dinámico podemos estar haciendo que se dupliquen, tripliquen,… las acciones del formulario.
Private Sub SimpleMntoExpertis1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.FormActions.Add("Cargar Factura", AddressOf CargarFactura, ExpertisApp.GetIcon("xico.ico"))
End Sub
Private Sub CargarFactura()
'Proceso de Cargar una Factura
End Sub
La parte del código de agregado de una acción especificaremos la descripción visual que veremos en el listado de
acciones, el proceso que se ejecutará cuando se seleccione la acción y optativamente la especificación de un icono
visual para su mostrado.
Junto con todo esto podemos hacer más visual y ordenadas las acciones locales especificando líneas de separación
entra las acciones (AddSeparator). Para ello bastaría con el comando siguiente entre las acciones que deseemos que
aparezca un separador. Recordemos que hemos comentado antes que en el orden en el que estén programados las
acciones así se agregarían en ese orden en la colección y en su mostrado en pantalla y lo mismo sería para los
separadores. Este comando hay que fijarse que lo tenemos disponible dentro de los métodos y propiedades del
formulario.
Private Sub SimpleMntoExpertis1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.FormActions.Add("Cargar Factura", AddressOf CargarFactura, ExpertisApp.GetIcon("xIco.ico"))
Me.AddSeparator()
Me.FormActions.Add("Nueva Factura", AddressOf NuevaFactura, ExpertisApp.GetIcon("xIco.ico"))
End Sub
Private Sub CargarFactura()
'Proceso de Cargar una Factura
End Sub
Private Sub NuevaFactura()
'Proceso de Nueva Factura
End Sub
DataGrids
131/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Con el desarrollo ya explicado para las acciones locales de formularios tendremos lo mismo posible por cada Datagrid
que tengamos en Expertis. De esta manera nos permite mostrar un menú contextual personalizado con acciones que
necesitemos por cada registro que seleccionemos con botón derecho en el Grid.
Para esta colección de acciones personalizadas por DataGrid la tendríamos en: Grid.Actions.
En esta colección iremos agregando las diferentes acciones que deseemos mostrar en el Grid. Recordemos que se
mostrarán el mismo orden en el que las agreguemos en el código fuente. También hemos de tener en cuenta de
programar el alta de estas acciones solo una vez en la pantalla puesto que si lo hacemos más dinámico podemos
estar haciendo que se dupliquen, tripliquen,… las acciones del grid.
Private Sub SimpleMntoExpertis1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Grid1.Actions.Add("Cargar Factura", AddressOf CargarFactura, ExpertisApp.GetIcon("xIco.ico"))
End Sub
Private Sub CargarFactura()
'Proceso de Cargar una Factura
End Sub
La parte del código de agregado de una acción especificaremos la descripción visual que veremos en el listado de
acciones, el proceso que se ejecutará cuando se seleccione la acción y optativamente la especificación de un icono
visual para su mostrado.
Junto con todo esto podemos hacer más visual y ordenadas las acciones locales especificando líneas de separación
entra las acciones (AddSeparator). Para ello bastaría con el comando siguiente entre las acciones que deseemos que
aparezca un separador. Recordemos que hemos comentado antes que en el orden en el que estén programados las
acciones así se agregarían en ese orden en la colección y en su mostrado en pantalla y lo mismo sería para los
separadores. Este comando hay que fijarse que lo tenemos disponible dentro de los métodos y propiedades del
DataGrid.
Private Sub SimpleMntoExpertis1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Grid1.Actions.Add("Cargar Factura", AddressOf CargarFactura, ExpertisApp.GetIcon("xIco.ico"))
Me.Grid1.AddSeparator()
Me.Grid1.Actions.Add("Nueva Factura", AddressOf NuevaFactura, ExpertisApp.GetIcon("xIco.ico"))
End Sub
Private Sub CargarFactura()
'Proceso de Cargar una Factura
End Sub
Private Sub NuevaFactura()
'Proceso de Nueva Factura
End Sub
Volver al Índice
Acciones Globales
Las Acciones Globales de Expertis es una funcionalidad que nos permite crear genéricamente en un sitio de nuestro
código una funcionalidad que podremos disponer en cualquier programa que dispongamos. Asimismo es una utilidad
para tener contraladas acciones de expertis con el tema de permisos de usuario de Expertis. De esta manera
podremos hacer que acciones de Expertis sean visibles o no dependiendo del rol del usuario.
Para ello el sitio común donde se alojan las acciones globales de Expertis son en:
Expertis.Application.ERP.GlobalActions.dll. Para cada acción hace falta crear un fichero de tipo clase y que tenga la
implementación que marcamos en el código a continuación: Implements Expertis.Engine.IAction.
132/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El único método que nos brinda este IAction es el Execute el cual se corresponderá como respuesta al evento de
pulsar a esa correspondiente acción de Expertis. Éste método nos da los siguientes parámetros de entrada e
información:
entityname
Nombre de la entidad de la ventana que lo ha invocado, de esta manera podremos saber y diferenciar si han sido
facturas o albaranes, etc…
programID
El Guid del programa que ha invocado esta acción, de esta manera podemos controlar y programar funciones
específicas para una misma acción, dependiendo de si lo ha llamado un programa u otro.
record
Datatable con la información del registro de la ventana que ha invocado la acción global. Siempre será un datatable,
de manera que si lo ha invocado una consulta interactiva vendrán tantos registros como hayamos seleccionado en el
grid si es de marcas o bien si no es de marcas todo el datasource del grid que veamos en ese momento en pantalla.
Para mantenimientos de tipo simple nos vendrá un datatable con un datarow del registro actual en el que estemos
posicionados.
Para mantenimientos de tipo grid nos vendrá todo el datasource del datagrid de ese formulario.
Para mantenimientos de tpo consulta interactiva nos vendrá todo el datasource del datagrid de ese formulario,
independientemente del uso o no de marcas en el grid.
Para el registro de estas acciones globales se lleva a cabo en el manager de Expertis, para inventariar dicha acción y
darle permisos y asociarlas a lso formulario de expertis que deseamos.
Para ello acudimos al Manager de Expertis y vamos a la sección de: Objetos -> Acciones.
Aquí veremos ya las acciones globales ya existentes de Expertis, tanto como dar de alta nuevas, modificar las
existentes o borrarlas.
Si Deseamos agregar una nueva acción global, aconsejamos hacerlo a través del método automático del menú de:
Programas -> Añadir Acciones
133/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Con esto conseguimos agregar de manera automática y rápida las acciones de la dll de Expertis donde las
hubiésemos agregado.
Como datos que podemos ver dentro de una acción tendríamos lo siguiente:
Descripción
Descripción de la Acción global, que será el texto que veremos colgado dentro de las acciones del/los formularios que
estará colgada dicha acción global.
Imagen
Icono visual que aparecerá al lado de la descripción de la Acción Global en los formularios.
Ensamblado
Ensamblado donde se encuentra dicha Acción Global.
134/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Asociar A
Opción a seleccionar para configurar en qué formularios de Expertis queremos que aparezca la Acción Global en la
que nos hemos posicionado.
Para esto tenemos los siguientes valores:
-
AllPrograms: sería para asociarlas a todos los formularios de expertis.
CIMntoPrograms: sería para asociarla a todos los formularios de Tipo CIMnto de Expertis.
GridMntoPrograms: sería para asociarla a todos los formularios de Tipo GridMnto de Expertis.
SimpleMntoPrograms: sería para asociarla a todos los formularios de tipo SimpleMnto de
Expertis.
SpecifiedPrograms: con esta opción solo se asociaría dicha acción al listado de programas
especificados en la pestaña de programas.
Clase
Clase dentro del ensamblado que sería la acción global de expertis.
Índice para Agrupar
Número de índice único entre todos las acciones globales, para que se agrupen y de esta manera crear grupos de
Acciones Globales.
Orden en el Grupo
Número de Orden que ocuparía la acción global dentro del índice del Grupo que hemos marcado anteriormente.
En la sección e Grupos es donde podremos establecer para la acción global en la que estamos, los diferentes grupos
de expertis a los que queremos dar permisos para visualizar y ejecutar dicha Acción.
Volver al Índice
135/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Parámetros Formularios
Los parámetros de los formularios nos permiten manejar cierta información extra en la ventana de manera que en el
momento de la carga de la ventana desempeñemos ciertas acciones. Éste es el uso general que suele darse en
expertis, siendo en formularios simples la idea de añadir mas información en la ventana y dependiendo de esta
información llevar a cabo una acción en el formulario. O bien en formularios de consultas interactivas nos sirve para
que un formulario aparezca filtrado por una serie de filtros cuando carguemos la ventana.
Para ello disponemos en los formularios de expertis de la propiedad Me.Params.
Es un objeto declarado como tipo object para que podamos manejarlo con el tipo de objeto qué queramos usar. El
tipo de objeto mas común usado en Expertis sería de tipo HashTable.
Para esto lo primero que hacemos es preparar los parámetros que queremos enviar al abrir un formulario y
enviándoselos en la apertura:
Dim HashParams As New Hashtable
HashParams.Add("IDArticulo", "001")
HashParams.Add("IDCliente", "00")
ExpertisApp.OpenForm("CPV", , HashParams)
Después en el formulario de destino hacemos las comprobaciones de si existen parámetros en la apertura de la
ventana y de si existiendo parámetros coinciden los tipos y valores esperados. Con ello ya pasamos a ejecutar lo que
necesitamos:
Private Sub CIMntoBase_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Me.Params Is Nothing Then
If TypeOf Me.Params Is Hashtable Then
Dim HashParams As Hashtable = Me.Params
If HashParams.ContainsKey("IDArticulo") Then Me.AdvArticulo.Value =
HashParams("IDArticulo")
If HashParams.ContainsKey("IDCliente") Then Me.AdvCliente.Value =
HashParams("IDCliente")
End If
End If
End Sub
Volver al Índice
Componentes de Motor Capa Presentación
1.
Componente BE.DataEngine
Componente de comunicación del motor entre la capa de presentación y la capa de negocio.
De este componente sobre todo usaremos el método Filter que nos permitirá traernos datos de la base de
datos de la siguiente manera:
Dim FilArt As New Filter
FilArt.Add("IDArticulo", FilterOperator.Equal, "Tuerca")
Dim ClsBE As New BE.DataEngine
Dim DtArt As DataTable
DtArt = ClsBE.Filter("tbCursoArticulo", FilArt)
Volver al Índice
2.
Componente ExpertisApp
Componente del Engine de Expertis exclusivo para la capa de presentación de Expertis. Nos brindará
diversos métodos y propiedades muy útiles para la capa de presentación de Expertis. Pasamos a enumerar
los métodos y propiedades más importantes.
ExpertisApp.GenerateMessage:
Método para generar mensajes en pantalla desde presentación. Podemos usarla para mostrar cualquier tipo
de mensaje. Pudiendo escribir el mensaje en sí, los tipos de botones a mostrar, el tipo de icono del mensaje
y parámetros para la composición de mensajes personalizados.
136/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
ExpertisApp.GenerateMessage("El Artículo | se ha dado de Alta correctamente.",
Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information, "Tuerca")
ExpertisApp.OpenForm:
Método para abrir formularios de expertis desde presentación. Especificando el Alias del programa de
Expertis (que podemos verlo en la consola de administración de expertis, pudiendo filtrar la ventana de
manera predeterminada, y pasando además parámetros a la propia ventana que abrimos.
ExpertisApp.OpenForm("ARTCURSO", New FilterItem("IDArticulo", FilterOperator.Equal, "Tuerca",
FilterType.String), )
ExpertisApp.CloseForm:
Método para cerrar formularios de expertis desde presentación.
ExpertisApp.CloseForm("ARTCURSO")
ExpertisApp.OpenReport:
Método para abrir objetos reports definidos en la capa de presentación.
Dim RptArt As New Report("RPTART")
ExpertisApp.OpenReport(RptArt)
ExpertisApp.ExecuteTask:
Método para ejecutar tareas de Negocio en la capa de Presentación.
Dim DtArt As DataTable
DtArt = ExpertisApp.ExecuteTask(Of String, DataTable)(AddressOf GetInfoArticulo, "Tuerca")
ExpertisApp.GetIcon:
Método para obtener un objeto de tipo drawing.icon, especificando el nombre del icono que existirá en el
directorio por defecto configurado en Expertis como directorio de recursos de imágenes.
Me.FormActions.Add("Abrir
Articulo",
ExpertisApp.GetIcon("xArticulos.ico"))
AddressOf
AccionAbrirArticulo,
Volver al Índice
Configuración del Manager para procesar Capa Presentación
Debemos recordar en todo momento que después de generar nuestros nuevos programas de presentación de
Expertis, debemos de registrarlas en el manager de expertis para que consten inventariadas en su sistema, para un
correcto funcionamiento de la aplicación y disponibilidad de uso.
Para ello acudiremos al manager de expertis e iremos a la sección: Objetos -> Programas. En el menú superior de
Procesos tendremos un proceso automático de agregado de Programas indicándole en qué dll tenemos alojada el/los
programa/s que queremos pasar. Si no siempre tendremos la opción manual de inserción de un nuevo programa.
Para mayor información sobre las propiedades de un programa acudir al manual de la Consola de Administración de
Expertis 5.0.
137/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Para ello acudiremos al manager de expertis e iremos a la sección: Objetos -> Acciones. En el menú superior de
Procesos tendremos un proceso automático de agregado de acciones indicándole en qué dll tenemos alojada la/s
clase/s que queremos pasar. Si no siempre tendremos la opción manual de inserción de una nueva entidad.
Como último punto tenemos que tener en cuenta que si para nuestros proyectos la parte de presentación vamos a
llevar a cabo el uso de la herencia. Hemos de introducir los formularios padres en la sección de Negocios para que
éstos se actualicen automáticamente cuando demandemos la nueva ventana heredada.
Para ello acudimos a la sección de negocios de Expertis:
138/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
139/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
4. PROGRAMACIÓN GENERAL
Enumerados
Los enumerados de expertis serían lista de valores con descripción que usan para mostrar en la aplicación. Teniendo
disponibles los enumerados en cualquier parte de la aplicación y con sistema de traducciones.
Como veremos a continuación los enumerados a pesar de lo sencillo de su definición requiere algo de desarrollo y
control en expertis, para poder así tener disponible un sistema de traducciones para estos valores que se ven en los
formularios de los usuarios finales.
Alta de Enumerados
Todos
los
enumerados
de
Expertis
se
encuentran
disponibles
en
el
Proyecto:
Expertis.Business.BusinessEnum.BusinessEnum. Con lo cual daremos de alta los enumerados en este proyecto, no
habría problema de cara para la extensibilidad.
También se pueden generar los enumerados propios en el proyecto que consideremos conveniente, no hay porqué
crearlos obligatoriamente solo en este estándar.
Una vez generados los enumerados en la correspondiente DLL, los daremos de alta en el sistema de expertis.
Abrir la consola de administración de Expertis. Desde el menú Procesos -> Agregar Enumerados
El cuadro de dialogo permite seleccionar la DLL que contiene las definiciones de los enumerados. En el caso del
Estándar de Expertis, estos se encuentran en Expertis.Business.BusinessEnum.
140/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez agregados los Enumerados podemos establecer las descripciones y traducciones de los enumerados en la
pestaña de Traducciones de cada Enumerado.
Propiedad Enums
La propiedad Enums de la clase Solmicro.Expertis.Engine.UI.ExpertisApp define un DataTable que contiene toda la
información de los enumerados de Expertis. De esta forma el programador tiene disponibles todos los enumerados
que contiene la tabla xEnumerate de la base de datos de sistema. Las columnas de este DataTable son
Name
MemberName
Value
Language
Text
Nombre del enumerado
Nombre de cada uno de los miembros
Valor numérico del miembro
ID del idioma del usuario
La descripción traducida
Clase EnumData
La clase EnumData, que se encuentra en el componente Solmicro.Expertis.Engine.UI.WinControls, se ha creado
expresamente para la gestión de los enumerados de Expertis. En el fondo define un DataTable que contiene los
valores correspondientes al enumerado especificado (a diferencia de la propiedad Enums de ExpertisApp, que
contiene todos los enumerados).
141/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Esta clase es especialmente útil a la hora de asignar listas de enumerados como origen de datos para controles de
Expertis, como un ComboBox, o un lista de valores en un columna de un grid.
Por ejemplo, esta línea de código asigna el enumerado CursoEstadoContabilizacion al control ComboBox cmbEstado
cmbEstado.DataSource = New EnumData("CursoEstadoContabilizacion")
Para asignar una lista de valores a una columna del Grid se utiliza el método shared PopulateValueList de la clase
EnumData. En el siguiente ejemplo se asignar una lista de valores del mismo enumerado que en el ejemplo anterior a
una columna de un Grid con nombre Estado
EnumData.PopulateValueList("CursoEstadoContabilizacion", Grid.Columns("Estado"))
O de forma alternativa
EnumData.PopulateValueList(GetType(CursoEstadoContabilizacion), Grid.Columns("Estado"))
NOTA: Cuando la columna de un Grid tiene asociada una lista de valores la propiedad EditType de la columna puede ser igual a
EditType.Combo, o bien EditType.DropDownList. La diferencia entre las dos es que DropDownList no nos permitirá editar en la celda
del Grid, lo que obliga a seleccionar un elemento de la lista. Si el valor es EditType.Combo y se introduce un valor que no está
dentro de la lista de valores posibles, la celda no perderá el foco y se mantendrá en modo de edición (de hecho no pierde el foco
hasta introducir un valor valido o cancelar la edición en curso). En este caso el control Grid de Janus dispone de un evento llamado
NotInList por si se quiere validar los valores introducidos.
Clase EnumData.EnumView
Dentro de la clase enumdata tendremos un método especial llamado: EnumView. Con este método lo que nos
permite es que el motor de expertis nos devuelva a un datatable todo el conjunto de datos del enumerado que
hayamos solicitado, pero no nos modificaría nada a nivel de diseño de objetos.
Esto lo que nos permite es poder configurar el diseño del ComboBox u objeto donde lo carguemos como queramos.
Para ello tendremos que tener en cuenta sobre todo que en este datatable tendremos dos columnas que serían las
más importantes:
-
Text: la columna con la descripción del enumerado y que sería la columna que estableceríamos para
visualizar como dato al usuario final.
-
Value: la columna con el valor del enumerado y que sería la columna que estableceríamos como origen
de datos principal y el que guardaríamos en base de datos.
Volver al Índice
Objeto Filter
En Expertis disponemos dentro de la DLL del Engine de Expertis: Expertis.Engine.Global.Dll, el objeto Filter. Objeto
que nos permite componer condiciones de filtrado de una manera más fácil y manejable que escribir las sentencias
Where de SQL. Es un objeto que usaremos en los métodos que nos brindan los objetos del Engine de Expertis para
llevar a cabo filtrados en vistas, en tablas, en entidades,…
El objeto Filter se puede componer de manera principal con tipo AND u OR de la siguiente manera:
Dim FilAND As New Filter
Para definir de tipo OR accedemos a la sobrecarga de la definición NEW del objeto.
Dim FilOR As New Filter(FilterUnionOperator.Or)
Para ya introducir campos de condición dentro del objeto Filter lo haríamos de la siguiente manera:
Dim FilAND As New Filter
FilAND.Add("IDArticulo", FilterOperator.Equal, "Tuerca", FilterType.String)
Dim DtArt As DataTable = New CursoArticulo().Filter(FilAND)
Vemos que el comando Add del objeto Filter se compone de varias partes y sobrecargas. La más completa sería la
descrita anteriormente. Se compondría primero del Nombre del Campo a filtrar. Siguiente sería el tipo de condición
que queremos evaluar. Siguiente valor sería el valor en sí para evaluar. Y como último parámetro el tipo del campo a
evaluar.
Luego vemos que este objeto Filter lo aplicamos a la entidad CursoArtículo y el método Filter de la entidad. De esta
manera obtendremos de la entidad CursoArtículo (Tabla tbCursoArtículo) los datos cuyo IDArtículo sea igual a Tuerca.
Como valores posibles en el tipo de condición tendríamos:
142/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
-
FilterOperator.Equal: condición =
FilterOperator.GreaterThan: condición >
FilterOperator.GreaterThanOrEqual: condición >=
FilterOperator.LessThan: condición <
FilterOperator.LessThanOrEqual: condición <=
FilterOperator.NotEqual: condición <>
Como valores posibles en el tipo de campo tendríamos:
-
FilterType.Boolean: tipo de campo Boolean o Bit de la base de datos.
FilterType.Guid: tipo de campo UniqueIdentifier de la base de datos.
FilterType.DateTime: tipo de campo Date o DateTime de la base de datos.
FilterType.String: tipo de campo char, varchar, nvarchar de la base de datos.
FilterType.Numeric: condición <=
Otro método disponible que tendremos en el objeto Filter sería el Compose. Esto lo que nos haría sería traducirnos en
una cadena string todo el objeto Filter que hayamos compuesto. Como parámetro para especificar en el método
Compose sería el tipo de lenguaje en que queramos que nos componga la cadena.
Dim StrFil As String = FilAND.Compose(New AdoFilterComposer)
"IDArticulo = 'Tuerca'"
En este caso hemos usado el tipo AdoFilterComposer. Nos compondría la cadena en formato de ADO .Net. Éste sería
un tipo que tendríamos disponible tanto en la capa de Presentación como en la capa de Negocio de Expertis.
Para componer en otras sintaxis lo haríamos en la capa de Negocio de Expertis Utilizando el objeto AdminData y con
el método ComposeFilter:
Dim StrFil As String = AdminData.ComposeFilter(FilAND)
"IDArticulo = 'Tuerca'"
Además de todo esto poseemos objetos de tipo FilterItem para poder especificar condiciones especiales para los
objetos Filter:
StringFilterItem
Objeto ítem para campos de tipo Char, Varchar, nVarchar, ….
Dim FilAND As New Filter
FilAND.Add(New StringFilterItem("IDArticulo", "Tuerca"))
DateFilterItem
Objeto ítem para campos de tipo Date o Date Time
Dim FilAND As New Filter
FilAND.Add(New DateFilterItem("FechaArticulo", Today.Date))
NumberFilterItem
Objeto ítem para campos de tipo Integer, Decimal, ….
Dim FilAND As New Filter
FilAND.Add(New NumberFilterItem("CantidadArticulo", 15))
BooleanFilterItem
Objeto ítem para campos de tipo Boolean o Bit.
Dim FilAND As New Filter
FilAND.Add(New BooleanFilterItem("ArticuloActivo", True))
GuidFilterItem
Objeto ítem para campos de tipo UniqueIdentifier.
Dim FilAND As New Filter
FilAND.Add(New GuidFilterItem("IDArticulo", New Guid()))
LikeFilterItem
Objeto ítem para componer una cláusula de condición de tipo LIKE de SQL.
Dim FilAND As New Filter
FilAND.Add(New LikeFilterItem("IDArticulo", "Tuerca"))
143/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
IsNullFilterItem
Objeto ítem para componer una cláusula de condición de tipo IS NULL de SQL.
Dim FilAND As New Filter
FilAND.Add(New IsNullFilterItem("IDArticulo", False))
BetweenFilterItem
Objeto ítem para componer una cláusula de condición de tipo Between de SQL.
Dim FilAND As New Filter
FilAND.Add(New BetweenFilterItem("FechaAlta", New Date(2010, 1, 1), Today.Date, FilterType.DateTime))
NoRowsFilterItem
Objeto ítem para componer una cláusula de condición de 1 = 2. Esto lo hacemos así para obtener de una tabla o vista
sólo la estructura de los datos y no traer de la base de datos ningún registro.
Dim FilAND As New Filter
FilAND.Add(New NoRowsFilterItem)
InListFilterItem
Objeto ítem para componer una cláusula de condición de Tipo InList de SQL.
Dim FilAND As New Filter
Dim StrIDS(1) As String
StrIDS(0) = "Tuerca"
StrIDS(1) = "Llave"
FilAND.Add(New InListFilterItem("IDArticulo", StrIDS, FilterType.String))
Volver al Índice
Contadores
Los contadores de expertis nos permiten definir un sistema para generación automática de códigos de clave primaria
para entidades. Por ejemplo, nos permite así definir un contador clave para las facturas tanto de ventas como de
compras, siguiendo un formato que deseemos y una numeración que también la que queramos. Siendo el uso
general te de estos contadores en temas de logística y pudiendo reiniciar su enumeración con cada nuevo año fiscal.
Como primero paso acudiremos a la ventana de administración de contadores para dar de alta un contador, el que
deseemos. Generalmente esta ventana estará colgada dentro del punto de menú de: Configuración -> Empresa ->
Empresa -> Contadores -> Contadores
En la parte de programación tendremos que realizar los siguientes pasos para que funcione nuestro contador para la
entidad que deseemos.
144/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis




Primero hemos de crear en la base de datos en la tabla de la entidad que deseamos usar un contador, un
campo NContador que contendrá el número de contador final que formemos. Generalmente este campo
suele ser de tipo nvarchar(25).
Crearemos también en la tabla de la entidad en cuestión un campo IDContador para contener el IDContador
con el que fue formado el NContador. Generalmente este campo suele ser de tipo nvarchar(10).
En el diseño de la ventana que mostraremos este campo NContador lo que tenemos que hacer es alojar un
objeto de tipo CounterTextBox de Expertis y la única propiedad que tenemos que configurar correctamente
sería su DataBinding –Text con el campo de NContador como enlace. Ponemos como ejemplo la pantalla de
Factura de Venta.
En la parte de código fuente tendremos que crear en la parte de nuevo registro de nuestra entidad una tarea
para asignar ya el valor provisional siguiente del contador en la serie para que el usuario lo vea en pantalla.
Tendremos que programar el proceso de RegisterAddNewTaks (AddNewForm antiguamente) para reflejar
correctamente el valor del contador en la propuesta de un nuevo registro de nuestra entidad. Para ello habría
que hacer algo parecido a como ponemos a continuación y con código como ejemplo de Facturas de Venta:
Public Overrides Function AddNewForm() As DataTable
Dim dt As DataTable = MyBase.AddNewForm
ProcessServer.ExecuteTask(Of DataRow)(AddressOf FillDefaultValues, dt.Rows(0), New
ServiceProvider)
Return dt
End Function
<Task()> Public Shared Sub FillDefaultValues(ByVal data As DataRow, ByVal services As ServiceProvider)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf ProcesoComunes.AsignarIdentificadorFactura,
data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf NegocioGeneral.AsignarCentroGestion, data,
services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarContador, data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarNumeroFacturaProvisional, data,
services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarDatosDeclaraciones, data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf ProcesoComunes.AsignarFechaFactura, data,
services)
ProcessServer.ExecuteTask(Of IPropertyAccessor)(AddressOf
ProcesoComunes.AsignarEjercicioContableFactura, New DataRowPropertyAccessor(data), services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf ProcesoComunes.AsignarFechaParaDeclaracion,
data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarTipoFactura, data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarEstadoFactura, data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf AsignarArqueoCaja, data, services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf NegocioGeneral.AsignarMarcaIVAManual, data,
services)
ProcessServer.ExecuteTask(Of DataRow)(AddressOf NegocioGeneral.AsignarMarcaVtosManuales, data,
services)
End Sub
<Task()> Public Shared Sub AsignarContador(ByVal data As DataRow, ByVal services As ServiceProvider)
Dim CE As CentroEntidad
CE.CentroGestion = data("IDCentroGestion") & String.Empty
CE.ContadorEntidad = CentroGestion.ContadorEntidad.FacturaVenta
data("IDContador") = ProcessServer.ExecuteTask(Of CentroEntidad, String)(AddressOf
CentroGestion.GetContadorPredeterminado, CE, services)
End Sub
145/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Public Shared Sub AsignarNumeroFacturaProvisional(ByVal data As DataRow, ByVal services As
ServiceProvider)
If Length(data("IDContador")) > 0 Then
Dim dtContadores As DataTable = ProcessServer.ExecuteTask(Of String, DataTable)(AddressOf
Contador.CounterDt, GetType(FacturaVentaCabecera).Name, services)
Dim adr As DataRow() = dtContadores.Select("IDContador = " & Quoted(data("IDContador")))
If Not IsNothing(adr) AndAlso adr.Length > 0 Then
data("NFactura") = adr(0)("ValorProvisional")
Else
'Si no está bien configurado el Contador de Facturas de Venta en el Centro de Gestión,
'cogemos el Contador por defecto de la entidad Factura Venta Cabecera.
Dim dtContadorPred As DataTable = ProcessServer.ExecuteTask(Of String,
DataTable)(AddressOf Contador.CounterDefault, GetType(FacturaVentaCabecera).Name, services)
If Not dtContadorPred Is Nothing AndAlso dtContadorPred.Rows.Count > 0 Then
data("IDContador") = dtContadorPred.Rows(0)("IDContador")
adr = dtContadores.Select("IDContador = " & Quoted(data("IDContador")))
If Not IsNothing(adr) AndAlso adr.Length > 0 Then
data("NFactura") = adr(0)("ValorProvisional")
End If
End If
End If
End If
End Sub

Una vez programada la parte de propuesta de un nuevo registro. Tendríamos que programar la parte de
actualización de inserción del registro. De manera que a la hora de grabar el registro en la base de datos de
nuestra entidad comprobemos y verifiquemos que el NContador que tenemos que insertar es correcto. Esto
es porque trabajando diversos usuarios a la vez en la plataforma es posible que el NContador que tenemos
en la propuesta de la ventana haya sido ya recogido por otro usuario, con lo cual no sería correcto grabar el
mismo NContador y tendríamos que seguir con el siguiente número disponible en la serie. Para ello
escribiríamos una tarea en el proceso de RegisterUpdateTasks de nuestra entidad para llevar a cabo este
control y manejo. Ponemos a continuación código de ejemplo de la entidad FacturaVenta:
Protected Overrides Sub RegisterUpdateTasks(ByVal updateProcess As Engine.BE.BusinessProcesses.Process)
MyBase.RegisterUpdateTasks(updateProcess)
updateProcess.AddTask(Of UpdatePackage, DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CrearDocumento)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.AsignarNumeroFactura)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.AsignarDatosFiscales)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf ProcesoComunes.AsignarCentroGestion)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoComunes.ActualizarCambiosMoneda)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.TratarPromocionesLineas)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularImporteLineasFacturas)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularRepresentantes)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularAnalitica)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularBasesImponibles)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularTotales)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularPuntoVerde)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.CalcularVencimientos)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.AsignarClaveOperacion)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
Business.General.Comunes.BeginTransaction)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.ActualizarAlbaran)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
Business.General.Comunes.UpdateDocument)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
Business.General.Comunes.MarcarComoActualizado)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionObras.ActualizarObras)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.ActualizarOTs)
updateProcess.AddTask(Of DocumentoFacturaVenta)(AddressOf
ProcesoFacturacionVenta.ActualizarQLineasPromociones)
End Sub
<Task()> Public Shared Sub AsignarNumeroFactura(ByVal fra As DocumentoFacturaVenta, ByVal services As
ServiceProvider)
If fra.HeaderRow.RowState = DataRowState.Added Then
If Not IsDBNull(fra.HeaderRow("IDContador")) Then
Dim StDatos As New Contador.DatosCounterValue
StDatos.IDCounter = fra.HeaderRow("IDContador")
StDatos.TargetClass = New FacturaVentaCabecera
146/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
StDatos.TargetField = "NFactura"
StDatos.DateField = "FechaFactura"
StDatos.DateValue = fra.HeaderRow("FechaFactura")
StDatos.IDEjercicio = fra.HeaderRow("IDEjercicio") & String.Empty
fra.HeaderRow("NFactura") = ProcessServer.ExecuteTask(Of Contador.DatosCounterValue,
String)(AddressOf Contador.CounterValue, StDatos, services)
End If
End If
End Sub

Para llevar a cabo los controles y actualizaciones relacionados con contadores disponemos de clase
Contador en el proyecto: Expertis.Business.General.Contador, dentro de la cual tenemos disponibles
diversos métodos y propiedades para el manejo de contadores, dependiendo de la situación y
necesidad que tengamos en el momento.
Volver al Índice
Parámetros
Los parámetros de Expertis nos permiten almacenar cierta información de configuración y valores permanentes que
necesitemos en toda la aplicación.
Expertis ya tiene de base una serie de parámetros para diversas funcionalidades dentro de la aplicación y para que la
aplicación actúe de ciertas formas.
Nosotros podremos dar de alta nuevos parámetros de Expertis según la necesidad que tengamos.
Como primer paso tendríamos que acudir a la ventana de Expertis de Parámetros para definir un parámetro con las
características que necesitemos. Generalmente esta ventana estará colgada dentro del punto de menú de:
Configuración -> Empresa -> Parametrización -> Parámetros -> Parámetros.
147/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
A nivel de programación tendremos en el proyecto de: Expertis.Business.General.Parametro todos los parámetros
generales de Expertis aquí definidos.
Lo que básicamente programamos en esta parte es una lectura de ese parámetro de la tabla de parámetros de
expertis para acudir a estos métodos siempre que necesitemos y no estar programando siempre un acceso a la tabla
de parámetros y recordando el valor del ID del Parámetro.
Public Function SituacionActividadCRM() As String
Dim Dt As DataTable = SelOnPrimaryKey("CRMSITACT")
If Not Dt Is Nothing AndAlso Dt.Rows.Count > 0 Then
Return Dt.Rows(0)("Valor")
Else : Return String.Empty
End If
End Function
Public Function ValidarCambioFechaFacturas() As Boolean
Dim Dt As DataTable = SelOnPrimaryKey("VALCAMF")
If Not Dt Is Nothing AndAlso Dt.Rows.Count > 0 Then
Return CBool(Dt.Rows(0)("Valor"))
Else : Return False
End If
End Function
Para nuestros desarrollos podemos programarlo en otra entidad nueva para todos los parámetros específicos que
necesitemos y así seguir manteniendo la extensibilidad de Expertis.
Una vez programados solo acudimos a nuestra dll desarrollada y llamar al método del parámetro que hayamos
creado.
Volver al Índice
Agrupaciones
Concepto de Agrupación
A la hora de hacer agrupaciones de elementos para crear uno nuevo (por ejemplo, agrupar albaranes de venta
para crear una factura de venta), básicamente lo que se hace en las tareas de agrupación es que dado un
148/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
DataTable (creado dentro de la tarea), a través de unas clases que veremos a continuación obtendremos un
array de elementos “Cabecera-lineas” a partir de los cuales podremos formar un Documento.
Los elementos “cabecera-lineas” en Expertis 4.1 son 2 datatables que contenían uno todas las cabeceras y otro
todas las líneas. En Expertis 5.0, son varios objetos que cada uno de ellos formará una Factura, en el caso del
ejemplo que veremos. Es decir, la agrupación nos devolverá un array de elementos en el que cada uno de ellos
contiene la información mínima del origen para montar una cabecera de factura y las líneas de la misma. (Array
de elementos FraCabAlbaran, que contiene otro array de FraLinAlbaran)
Esto se puede hacer de una manera “automática”, gracias a varias clases (IGroupUser, GroupHelper) y
métodos. De manera, que definiendo las columnas que deben abrir factura nueva y las clases que van a montar
los elementos del array a devolver, recorriendo los registros a agrupar se monta el array.
-
-
-
En la tarea GetGroupColumns, indicaremos las columnas que abren factura. Como vemos, el caso del
IDAlbaran será opcional.
En la clase GroupUserAlbaranes (que implementa la interfaz IGroupUser), definiremos qué tipos se van a
montar para retornar. En este caso, FraCabAlbaran y FraLinAlbaran, y le indicaremos que incluya los
elementos de tipo FraLinaAlbaran en un array en FraCabAlbaran.
Con el array de columnas que retorna la tarea GetGroupColumns y el objeto de tipo GroupUserAlbaranes,
creamos una clase de tipo GroupHelper (en el caso de las facturas se crean 2 dependiendo de si la
agrupación es por cliente o por albarán)
A partir de las rows del DataTable origen, y con las tareas y tipos que acabamos de definir, el método Group
de la clase GroupHelper, es capaz de hacer las agrupaciones correspondientes .
Ejemplo de Creación y Manejo de Agrupaciones
<Task()> Public Shared Function AgruparAlbaranes(ByVal data As DataPrcFacturacionGeneral,
ByVal services As ServiceProvider) As FraCabAlbaran()
Dim dtLineas As DataTable
'se seleccionan todas las lineas de albaran no facturadas
Dim strViewName As String = "vNegComercialCrearFactura"
If data.IDAlbaranes.Length > 0 Then
Dim values(data.IDAlbaranes.Length - 1) As Object
data.IDAlbaranes.CopyTo(values, 0)
Dim oFltr As New Filter
oFltr.Add(New InListFilterItem("IDAlbaran", values, FilterType.Numeric))
oFltr.Add(New NumberFilterItem("EstadoFactura", FilterOperator.NotEqual,
enumavlEstadoFactura.avlFacturado))
dtLineas = New BE.DataEngine().Filter(strViewName, oFltr)
End If
If Not dtLineas Is Nothing AndAlso dtLineas.Rows.Count > 0 Then
Dim p As New Parametro
Dim fvcFecha As enumfvcFechaAlbaran = p.FacturacionFechaAlbaran()
Dim oGrprUser As New GroupUserAlbaranes(data.DteFechaFactura, fvcFecha)
Dim strCondicionPago As String = p.CondicionPago
Dim grpAlb As DataColumn() = ProcessServer.ExecuteTask(Of DataGetGroupColumns,
DataColumn())(AddressOf GetGroupColumns, New DataGetGroupColumns(dtLineas,
enummcAgrupFactura.mcAlbaran), services)
Dim grpClte As DataColumn() = ProcessServer.ExecuteTask(Of DataGetGroupColumns,
DataColumn())(AddressOf GetGroupColumns, New DataGetGroupColumns(dtLineas,
enummcAgrupFactura.mcCliente), services)
Dim groupers(1) As GroupHelper
groupers(enummcAgrupFactura.mcAlbaran) = New GroupHelper(grpAlb, oGrprUser)
groupers(enummcAgrupFactura.mcCliente) = New GroupHelper(grpClte, oGrprUser)
For Each rwLin As DataRow In dtLineas.Rows
groupers(rwLin("AgrupFactura")).Group(rwLin)
Next
Return oGrprUser.Fras
Else
ApplicationService.GenerateError("No hay datos a Facturar. Revise sus
Albaranes.")
End If
End Function
149/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
<Task()> Public Shared Function GetGroupColumns(ByVal data As DataGetGroupColumns, ByVal
services As ServiceProvider) As DataColumn()
Dim columns(8) As DataColumn
columns(0) = data.Table.Columns("IDCliente")
columns(1) = data.Table.Columns("IDFormaPago")
columns(2) = data.Table.Columns("IDCondicionPago")
columns(3) = data.Table.Columns("IDBancoPropio")
columns(4) = data.Table.Columns("IdMoneda")
columns(5) = data.Table.Columns("EDI")
columns(6) = data.Table.Columns("IDDireccion")
columns(7) = data.Table.Columns("IDDireccionFra")
columns(8) = data.Table.Columns("IDClienteBanco")
If data.Agrupacion = enummcAgrupFactura.mcAlbaran Then
ReDim Preserve columns(9)
columns(9) = data.Table.Columns("IDAlbaran")
End If
Return columns
End Function
Volver al Índice
ProviderNeededData
El objeto ProviderNeededData es elobjeto de Expertis que es un proveedor de Datos y nos permite de esta manera
poder llevar a cabo la carga de información extra en un formulario de Expertis, cuando no queremos mostrar los datos
en un Grid de Expertis o bien en algún objeto proveedor de Datos.
El uso más general dado en Expertis para este objeto sería para mostrar datos de una entidad en un formulario pero
en cajas de textos y labels en una pestaña. Para lograr esto hacemos uso de este tipo de objetos que puede
cargarnos la información que necesitamos en los objetos que indiquemos, siendo información no contenido en la
entidad principal del formulario ni en la vista u origen de datos del formulario principal.
Para ello instanciamos en el formulario donde deseamos utilizar este objeto una instancia del mismo:
Private NdData As ProviderNeededData
En la carga del formulario llevaríamos a cargo la configuración del objeto ProviderNeededData:
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not Me.DesignMode Then
LoadNedeedData()
End If
End Sub
Private Sub LoadNedeedData()
NdData = New ProviderNeededData
NdData.Name = "Data"
NdData.EntityName = "Entidad_Data"
Dim s(0) As String
s(0) = "IDClavePrimaria"
NdData.PrimaryDataFields = s
NdData.SecondaryDataFields = s
NdData.RelationMode = RelationMode.ChildMode
NdData.ViewName = "vFrmData"
NdData.UpdateOrder = -1
Me.AddDataItem(NdData)
End Sub
Entre las propiedades principales que posee y que tenemos que configurar estarían:
Name
Nombre interno
EntityName
Nombre de entidad de la que deseamos manejar los datos.
PrimaryDataFields / SecondaryDataFields
Nombre de los campos de relación entre el objeto ProviderNeededData y el formulario actual.
RelationMode
150/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Modo de relación del objeto ProviderNeededData con el formulario principal.
ViewName
Nombre de la vista / table de Origen de datos del Objeto ProviderNeededData.
UpdateOrder
Orden en la actualización y manejo de datos del ProviderNeededData con respecto a otros objetos
ProviderNeededData que hubieran en el formulario. Por defecto: -1.
Fijemonos que la última línea es para agregar nuestro ProviderNeededData al origen de datos del formulario. De esta
manera en la solicitud de movimiento de registros en el formulario se encargará el motor de llevar a cabo la carga
automática de los datos que queremos del ProviderNeededData. Esto se hace con el Me.AddDataItem.
Una vez configurado el objeto pasaríamos a establecer los bindeos entre los controles del formulario y el control
providerneededdata.
Para esto necesitamos una variable local para controlar este bindeo se lleve a cabo solamente una vez en el
formulario. De manera que sea solo la primera vez en la solicitud de moverse a un registro en el formulario.
Private MakeBinding As Boolean
Una vez declarada la variable pasamos a establecer el código de Bindeo en el movimiento de registro del formulario.
Private Sub MntoObras_Navigated(ByVal sender As Object, ByVal e As
Solmicro.Expertis.Engine.UI.NavigatedEventArgs) Handles MyBase.Navigated
BindingData()
End Sub
Private Sub BindingData()
If Not MakeBinding Then
Me.AddBinding(Me.AdvClave, "Value", "IDClavePrimaria")
Me.AddBinding(Me.TxtDescClave, "Text", "DescClavePrimaria")
Me.AddBinding(Me.UlblDescEstado, "Text", "IDEstado")
MakeBinding = True
End If
End Sub
Private Sub AddBinding(ByVal control As Control, ByVal propertyName As String, ByVal dataMember As
String)
If (dataMember = "codtrabajo") Or (dataMember = "Desctrabajo") Then
control.Enabled = False
Else : control.Enabled = True
End If
control.DataBindings.Add(propertyName, Me.ndTrabajos, dataMember)
End Sub
Se puede observer que establecemos la unión entre un control, especificando el nombre de la propiedad a la que
queremos bindear, el campo que establecemos en el tercer parámetro.
Volver al Índice
Login en Expertis para Ejecutables Externos
Se puede llevar a cabo en el desarrollo de un ejecutable propio el llevar a cabo el logeo en expertis y mantener viva
una sesión contra expertis. De esta manera podemos realizar ejecutables propios usando los datos de Expertis.
Para esto tenemos a través de dos maneras: una sencilla de abrir simplemente la sesión sin configurar nada más y
otra que nos permite especificar más parámetros.
Para la primera manera sencilla lo que necesitamos sobre todo es tener configurado un fichero .config con el mismo
nombre y extensión de nuestro ejecutable, a modo de como tiene el ejecutable de Expertis:
Expertis.Engine.UI.Shell.exe.Config. Y la configuración de este fichero sería la misma que la de expertis, conteniendo
todo el tema de la configuración de remoting. Con esto correctamente configurado y existente bastaría con que
hiciéramos el siguiente comando en la carga del formulario:
Private Sub Me_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ExpertisApp.Open()
End Sub
Una vez abierta la sesión también lo único que tendríamos que tener en cuenta sería en cerrar esta sesión una vez
que se cierre el programa. Para ello programaríamos lo siguiente:
151/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Private Sub Me_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
ExpertisApp.CloseSession()
End Sub
Para una mayor especificación y control de este logeo en expertis podríamos hacerlo a través de otra manera con el
siguiente código:
Private Sub Login()
Dim Aut As New AuthenticationInfo
Aut.Authentication = AuthenticationMode.ExpertisAuthentication
Aut.UserName = "PARAMETRO_VUESTRO_USER"
Aut.Pwd = "PARAMETRO_VUESTRO_PASSWORD"
Dim ClsApp As New ApplicationService
Dim Tok As TokenInfo = ClsApp.Login(Aut, "Nombre_Máquina")
ExpertisApp.GetSessionDescriptor(SessionInfo.All)
ExpertisApp.CheckBusinessVersion()
System.Runtime.Remoting.Messaging.CallContext.SetData(SessionInformation.SessionSlot, New
SessionInformation(Tok.Token))
End Sub
Se explica el contenido de cada línea y lo necesario para llevar a cabo todo el sistema. Fijarse en todo este código
que establecemos un Login para cuando se hace la apertura de nuestro ejecutable y tendremos un LogOut cuando se
cierre la aplicación para el cierre de sesión y el liberar el Token.
Volver al Índice
Cambio de Base de Datos en MultiEmpresa
En Expertis es posible cambiar la conexión actual de la base de datos para posicionarnos en otra base de datos y
poder trabajar con ella. Este concepto es para poder llevar a cabo conceptos de MultiEmpresa que manejamos en
Expertis.
Para ello bastará que el proceso que queremos que se ejecute con otra base de datos de Expertis, se programe en
una tarea de Negocio de Expertis. En dicha tarea tiene que tener obligatoriamente como primera línea de código la
descrita en el código fuente a continuación. Con ello establecemos la conexión a otra base de datos que tiene que
estar inventariada en el sistema de expertis en Bases de Datos.
Hay que tener en cuenta que antes de cambiar la conexión lo que tenemos es que tratar de cerrar todas las
transacciones pendientes anteriores de la conexión actual que tenemos. Para ello llevamos a cabo el comando
AdminData.CommitTx() para realizar esto. Este comando lo tenemos detallado mas adelante en este apartado.
<Task()> Public Shared Sub ChangeDataBase(ByVal data As DataTable, ByVal services As
ServiceProvider)
'Obligatorio como primera instrucción de Negocio que llamemos sea la siguiente
AdminData.CommitTx()
AdminData.SetSessionConnection("Nombre_Base_Datos_Destino")
'Tu proceso en esa otra Base de Datos.
For Each Dr As DataRow In data.Select
'.......
Next
'Al finalizar la tarea de negocio y irse de esta tarea el motor restablecerá la conexión
de expertis con la anterior, sino podemos establecer la conexión de nuevo por la base de datos de
origen
AdminData.CommitTx()
AdminData.SetSessionConnection("Nombre_Base_Datos_Origen")
End Sub
Una vez que acabe todo la tarea y se acabe la ejecución de la misma, el motor se encargará de volver a establecer la
conexión originaria de expertis.
Con este sistema asi podemos generar datos en otras bases de datos y cuando manejamos el concepto de
MultiEmpresa.
Volver al Índice
Transacciones
152/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Tenemos diversas maneras en Expertis para llevar a cabo un control de los procesos que hagamos sean
transaccionales o no, y en donde lo necesitemos.
En primera instancia, si deseamos que cualquier comunicación desde un formulario de expertis, todo sea ya
transaccional en las llamadas de este formulario con el negocio de la entidad asociada, sólo tenemos que activar la
propiedad CreateTransaction del formulario.
Con esto y como comentamos, cualquier comunicación desde el formulario con la entidad de expertis, se hará de
forma transaccional.
Otra manera que tenemos para llevar a cabo transacciones a nivel de listado de tareas, bien sea por listado de tareas
de un Update o Delete de una entidad, o bien del listado de tareas de un proceso de expertis, disponemos de unas
tareas específicas para llevar esto a cabo que serían las siguientes:
ProcessServer.ExecuteTask(Of Object)(AddressOf Business.General.Comunes.BeginTransaction, Nothing,
services)
Con esta tarea abriríamos transacción donde quisiéramos y con dicha tarea la podemos agregar en cualquier listado
de tareas de un Update o Delete o en listado de tareas de un proceso de expertis.
ProcessServer.ExecuteTask(Of Boolean)(AddressOf Business.General.Comunes.CommitTransaction, False,
services)
Con esta tarea cerraríamos la última transacción abierta. De esta manera si abrimos por ejemplo 3 transacciones nos
cerraría la 3º transacción última abierta. Esta tarea se puede usar en listado de procesos de expertis pero no
podemos agregarla en listado de tareas de Update o de Delete.
ProcessServer.ExecuteTask(Of Boolean)(AddressOf Business.General.Comunes.RollbackTransaction,
False, services)
Con esta tarea haríamos un deshacer la última transacción abierta. De esta manera si abrimos por ejemplo 3
transacciones nos desharían la 3º transacción última abierta. Esta tarea se puede usar en listado de procesos de
expertis, pero no podemos agregarla en listado de tareas de Update o de Delete.
NOTA: Hay que tener en cuenta que abriendo las transacciones en la capa de negocio, Éstas se cerrarán siempre 100% en cuanto
abandonásemos la capa de negocio de Expertis. Esto es porque el Engine de expertis se encarga siempre que cuando se acabe la
ejecución de expertis en capa de negocio y volver a presentación, se cierren las transacciones pendientes.
Volver al Índice
Filtrado Horizontal
Descripción de Componente de Filtrado Horizontal
Utilidad para disponer de funcionalidad de perfiles a un filtrado horizontal personalizable sobre los mantenimientos.
Cuando hablamos de personalizable nos referimos a que se pueda definir/implementar el filtrado horizontal a aplicar sobre los mantenimientos en
función de la entidad y programa.
Creación de la Interfaz y descripción de los Componentes
Para ello se ha definido el siguiente interfaz:
Interface Profile
Implements Solmicro.Expertis.Engine.IProfile
Public Function GetProfileType(ByVal Entity As String) As ProfileType Implements GetProfileType
Se define el tipo de filtro para cada entidad
153/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Public Function GetProfileFilter(ByVal Entity As String, ByVal IdUsuario As System.Guid) As
ProfileFilter Implements GetProfileFilter
Esta es la función donde hay que programar el filtrado para cada entidad. Los parámetros que recibe esta función son entidad y usuario
ProfileType
Enumerado que puede tomar los valores:

SimpleProfile: tipo simple.

ComplexProfile: tipo complejo.

NoProfile: sin perfil.
ProfileFilter
Clase que representará el filtro del perfil asociado a la entidad y que se aplicará sobre registros asociados a la entidad. Se compone de los
siguientes componentes:

FilterType As ProfileType: es el tipo del filtro del perfil asociado a la entidad (Simple o complejo)

SimpleFilter As IFilter: será el filtro del perfil asociado a la entidad en caso de que el tipo sea simple.

ComplexFilter As ComplexFilter: será el filtro del perfil asociado a la entidad en caso de que el tipo sea complejo.
ComplexFilter
Filtro de perfil que podemos asociar cuando deseemos que sea de tipo complejo. Se compone de los siguientes componentes:

Source As String: Vista que definirá el conjunto de registros asociados a la entidad que podrán ser visualizados. Dicha vista se cruzará
con en los datos asociados a la entidad.

LinkFields As Links: Campos del origen de datos asociado a la entidad y de la vista por los cuales se hará el cruce.

WhereClause As IFilter: es donde realmente vamos a filtrar esa vista. Aquí le tendremos que establecer un objeto de tipo filtro.
Structure Links
Estructura con la cual se establece una relación entre los campos de la pantalla (indicados en el punto anterior) y los que devuelve
la vista de filtrado..

FormFileds() As String: es donde se establece el campo o los campos del formulario que identifican de forma única al
registro de la entidad.

ProfileFields() As String: donde se identifica el campo o los campos que identifican de forma única el registro de la vista
Ejemplo de Clase de Filtrado Horizontal: ProfileManager.
Ejemplo de filtrado horizontal para el módulo de Recursos Humanos.
En él se está generando para las entidades de RHOperario, Operario y RHOperarioContrato un tipo de filtrado complejo y para el resto de
entidades no se hace control de filtrado horizontal. Para ello se usa el tipo NoProfile en la función de GetProfileType.
Después en la función de GetProfileFilter se configura para las entidades de Operario y RHOperario, el usar la vista ProfileOperario unida con
la tabla del entidad a través de los campos de IDOperario, filtrando por el IDUsuario actual. De esta manera en el acceso a estas entidades el
usuario de expertis solo ve sus datos correspondientes. Para la siguiente entidad de RHOperarioContrato se hace lo mismo pero usando otra
vista: ProfileOperarioContrato y definiendo como campos de unión los suyos necesarios: IDOpContrato.
Configuración del Manager de Expertis para Filtrado Horizontal
Hay que Completar y definir los siguientes parámetros en el manager de Expertis para el funcionamiento del Filtrado Horizontal.
Para ello acudir a: Aplicación -> Configuración de Aplicación -> Descripción del Componente del Filtrado Horizontal
154/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el ensamblado figuraría el nombre de la dll donde va incluida la clase Profilemanager y en Clase iría el nombre completo de la clase (dentro
del proyecto de negocio en el que se haya incluido).
Volver al Índice
Extensibilidad en Mensajería y Alertas de Expertis
Introducción
Utilidad para disponer de funcionalidad de perfiles a un filtrado horizontal personalizable sobre los mantenimientos.
La idea es heredar de AlertExtensionBase y sobrescribir los métodos que te hagan falta (aquellos en los que no puedas hacer algo mediante el
interfaz de diseño).
Los métodos son:
public function Recipients(ByVal args As AlertExtensionArgs) As datatable
Añade destinatarios a la alerta (predeterminado null)
public function MatchesCondition(ByVal args As AlertExtensionArgs) As boolean
Comprueba si la alerta (insert, update, delete) cumple las condiciones (predeterminado true)
public function TimedMatches(ByVal args As AlertExtensionArgs) As DataTable
Devuelve los registros que cumplen la alerta temporal
public function Message(ByVal args As AlertExtensionArgs) As string
Compone el mensaje a enviar (pred. null). Si null, toma el mensaje del diseñador.
public sub ExecuteAction(ByVal args As AlertExtensionArgs)
Los parámetros que se reciben son ()
Public Class AlertExtensionArgs
Public Alert As AlertBusiness
Public Match As DataRowView
Public RecordKey As String
Public Trigger As AlertTrigger
Public Schema As DataTable
End Class
'
'
'
'
'
El objeto alerta que se está comprobando
El registro de datos que se está tratando
Campos clave (no recuerdo bien)
Detonante de la alerta (insert, update, delete, temporal…)
Esto creo que no se usa mucho, esquema de BBDD del registro
Esta clase hay que programarla en un Business
155/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Ejemplo
Programación de una Alerta que salta cuando el precio de factura compra de un artículo es mayor que el precio estándar.
Imports Solmicro.Expertis.Engine.BE.Alerts
Public Class ExtensibilidadAlerta
Inherits AlertExtensionBase
Public Overrides Function MatchesCondition(ByVal args As Engine.BE.Alerts.AlertExtensionArgs)
As Boolean
Dim drv As DataRowView = args.Match
If Length(drv.Row("IDArticulo")) > 0 Then
Dim IDArticulo As String = drv.Row("IDArticulo")
Dim dtArticulo As DataTable = New BE.DataEngine().Filter("tbMaestroArticulo", New
StringFilterItem("IDArticulo", drv.Row("IDArticulo")), "")
If dtArticulo.Rows.Count > 0 Then
Return drv.Row("PrecioA") > dtArticulo.Rows(0)("PrecioEstandarA")
End If
End If
Return False
End Function
Public Overrides Function Message(ByVal args As Engine.BE.Alerts.AlertExtensionArgs) As String
Dim drv As DataRowView = args.Match
Return ParseFormatString("El precio de última compra del Artículo {0} es mayor que el
precio estándar", Quoted(drv.Row("IDArticulo")))
End Function
End Class
5. PROYECTOS EXPERTIS
Proyectos de Presentación
Expertis.Application.ERP.ActualizacionAlbaranCompra
156/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación que contiene los datos de Presentación de actualizaciones de Albaranes de Compra del
Modulo de Compras
Expertis.Application.ERP.ActualizacionAlbaranVenta
Proyecto de Presentación que contiene los datos de Presentación de actualizaciones de Albaranes de Venta del
Modulo de Ventas.
Expertis.Application.ERP.Agrupaciones
Proyecto de Presentación que contiene los datos de Presentación del Módulo de Agrupaciones.
Expertis.Application.ERP.AlbaranCompra
Proyecto de Presentación que contiene todo lo relacionado con los Albaranes de Compra.
Expertis.Application.ERP.AlbaranVenta
Proyecto de Presentación que contiene todo lo relacionado con los Albaranes de Venta.
Expertis.Application.ERP.Almacenes
Proyecto de Presentación que contiene todo lo relacionado con los Almacenes de Expertis.
Expertis.Application.ERP.Alquiler
Proyecto de Presentación que contiene todo lo relacionado con el módulo de Alquileres.
Expertis.Application.ERP.AnalisisFoss
Proyecto de Presentación de ventana de Analisis Foss de Módulo de Bodegas.
Expertis.Application.ERP.AnalisisRiesgo
Proyecto de Presentación de formularios de Analisis de Riesgo de Clientes para las ventas.
Expertis.Application.ERP.Articulos
Proyecto de Presentación de Formulario de Artículos y formularios relacionados como Tipos de Artículos.
Expertis.Application.ERP.Aseguradora
Proyecto de Presentación de Formulario de Aseguradoras.
Expertis.Application.ERP.BancosPropios
Proyecto de Presentación de Formulario principal de Expertis de Bancos Propios.
Expertis.Application.ERP.Bodega
Proyecto de Presentación de todos los formularios del Módulo de Bodegas.
Expertis.Application.ERP.BodegaAnalisisFinca
Proyecto de Presentación de formularios de Análisis de Fincas de Bodegas.
Expertis.Application.ERP.Calendar
Proyecto de Presentación de Herramienta de Calendarios de Expertis.
Expertis.Application.ERP.Calibraciones
Proyecto de Presentación de Formularios de Calibraciones de Maquinaria.
Expertis.Application.ERP.Calidad
157/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de todos los formularios relacionados con el módulo de Calidad.
Expertis.Application.ERP.Cargo
Proyecto de Presentación de Formulario de Cargos de Clientes, Proveedores y Cuentas de CRM.
Expertis.Application.ERP.Categoria
Proyecto de Presentación de Formulario de Categorías.
Expertis.Application.ERP.CausaRechazo
Proyecto de Presentación de Formulario de Causas y Rechazos de Producción.
Expertis.Application.ERP.CentroCoste
Proyecto de Presentación de Formulario de Centros de Coste de Expertis.
Expertis.Application.ERP.CentroGestion
Proyecto de Presentación principal de Formulario de Centros de Gestión de Expertis.
Expertis.Application.ERP.Centros
Proyecto de Presentación de Formulario de Centros de Trabajo de Expertis.
Expertis.Application.ERP.CFDisplay
Proyecto de Presentación de Herramienta de visualización de datos que se compone con ERP.Visor.
Expertis.Application.ERP.CIDisplay
Proyecto de Presentación de Herramienta de visualización de recursos de Producción.
Expertis.Application.ERP.CierreInventario
Proyecto de Presentación de Formulario de Cierres de Inventario de Stocks de Expertis.
Expertis.Application.ERP.CierreIVA
Proyecto de Presentación de Formulario de Cierre de IVA de Expertis.
Expertis.Application.ERP.Clientes
Proyecto de Presentación de Mantenimiento de Clientes y formularios relacionados con Clientes.
Expertis.Application.ERP.CobroCont
Proyecto de Presentación de Cobros de Tesorería.
Expertis.Application.ERP.CobroSinAg
Proyecto de Presentación de formulario de Seguimiento y consulta de cobros.
Expertis.Application.ERP.CommonClasses
Proyecto de Presentación que aglutina la funcionalidad de muchos formularios y funcionalidad diversa de todo
expertis.
Expertis.Application.ERP.CompClteProv
Proyecto de Presentación de Compensación de Cobros y Pagos.
Expertis.Application.ERP.Concepto
158/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación del mantenimiento de Conceptos de Facturas de Venta.
Expertis.Application.ERP.CondicionEnvio
Proyecto de Presentación de Maestro de Condiciones de Envio de Ventas.
Expertis.Application.ERP.CondicionPago
Proyecto de Presentación de Maestro de Condiciones de pago deFinanciero.
Expertis.Application.ERP.Configurador
Proyecto de Presentación del módulo de Configurador de producto de Expertis.
Expertis.Application.ERP.ConsRiesgoClte
Proyecto de Presentación de formulario de Consulta de Riesgo de Cliente en Ventas.
Expertis.Application.ERP.ConsultaPC
Proyecto de Presentación de consultas interactivas de Pedidos de Compra.
Expertis.Application.ERP.ConsultaProyectos
Proyecto de Presentación de consultas interactivas de Proyectos / Obras.
Expertis.Application.ERP.ConsultaPV
Proyecto de Presentación de consultas interactivas de Pedidos de Venta.
Expertis.Application.ERP.Contador
Proyecto de Presentación del Maestro de Contadores de Expertis.
Expertis.Application.ERP.Contrato
Proyecto de Presentación del Maestro de Contratos.
Expertis.Application.ERP.ControlCaja
Proyecto de Presentación del Módulo de TPV.
Expertis.Application.ERP.ControlPrd
Proyecto de Presentación de Herramienta Táctil de introducición de partes de trabajo de Producción.
Expertis.Application.ERP.ControlPresencia
Proyecto de Presentación de los diferentes Formularios para hacer entradas y salidas de Control de Presencia
Expertis.Application.ERP.ConversionGenerica
Proyecto de Presentación de Formularios de Conversiones Genéricas.
Expertis.Application.ERP.CosteStd
Proyecto de Presentación de formularios relacionado con el cálculo de Coste Estándar de Artículos.
Expertis.Application.ERP.DatosEmpresa
Proyecto de Presentación de los Datos Principales de la Empresa, tales como datos registrales, logos, etc…
Expertis.Application.ERP.Departamento
159/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de mantenimiento de Departamentos relacionados con el Operario.
Expertis.Application.ERP.DesajusteStock
Proyecto de Presentación de mantenimientos de muestra de Desajustes de Stocks.
Expertis.Application.ERP.DiaPago
Proyecto de Presentación del Formulario de Días de Pago de condiciones económicas.
Expertis.Application.ERP.DiarioContable
Proyecto de Presentación que contiene todos los formularios relacionados con el módulo Financiero
Expertis.Application.ERP.Disponibilidad
Proyecto de Presentación con los diversos formularios de disponibilidades de artículos, materiales, …
Expertis.Application.ERP.Empresa
Proyecto de Presentación que contiene todos los formularios relacionados con el módulo de CRM
Expertis.Application.ERP.Encuestas
Proyecto de Presentación de Formulario de Encuestas de Marketing
Expertis.Application.ERP.EntregasACuenta
Proyecto de Presentación de formularios de Entregas a Cuenta de Clientes y Proveedores.
Expertis.Application.ERP.EstadisticaCompras
Proyecto de Presentación principal de formularios de Consulta Interactiva de Estadisticas de Compras
Expertis.Application.ERP.EstadisticaRetencion
Proyecto de Presentación de formularios de Consulta Interactiva de Estadisticas de Retenciones
Expertis.Application.ERP.EstadisticaRetraso
Proyecto de Presentación de formularios de Consulta Interactiva de Estadisticas de Retrasos
Expertis.Application.ERP.EstadisticaVentas
Proyecto de Presentación de formularios de Consulta Interactiva de Estadisticas de Ventas
Expertis.Application.ERP.EstadoTarifa
Proyecto de Presentación de mantenimiento de Estados de Tarifas
Expertis.Application.ERP.EstrucGraf
Proyecto de Presentación de Formulario de Representación gráfica de Estructura de Artículos.
Expertis.Application.ERP.EtiRecepcion
Proyecto de Presentación de mantenimiento de Etiquetas de Recepción de Pedidos.
Expertis.Application.ERP.Expediciones
Proyecto de Presentación de Expediciones de Ventas.
Expertis.Application.ERP.FactElecCorreo
160/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación que contiene toda la funcionalidad de Correo Electrónica y Facturación Electrónica
Expertis.Application.ERP.FacturacionCompra
Proyecto de Presentación del Proceso de Generación de Facturas de Compra.
Expertis.Application.ERP.FacturacionVenta
Proyecto de Presentación del Proceso de Generación de Facturas de Venta.
Expertis.Application.ERP.FacturaCompra
Proyecto de Presentación de Mantenimiento de Facturas de Compra.
Expertis.Application.ERP.FacturaVenta
Proyecto de Presentación de Mantenimiento de Facturas de Venta.
Expertis.Application.ERP.FicheroDAA
Proyecto de Presentación de Generación de Ficheros DAA de Módulo de Bodegas.
Expertis.Application.ERP.FormaEnvio
Proyecto de Presentación de Mantenimiento de Formas de Envío de Expertis.
Expertis.Application.ERP.FormaPago
Proyecto de Presentación de Mantenimiento de Formas de Pago de Expertis.
Expertis.Application.ERP.Gasto
Proyecto de Presentación de Mantenimiento de Gastos.
Expertis.Application.ERP.GDProgramas
Proyecto de Presentación de Módulo de Gestión Documental de Expertis.
Expertis.Application.ERP.GeneracionFicheros
Proyecto de Presentación de Módulo de Generación de Ficheros de la AEAT, XML, Facturae, …
Expertis.Application.ERP.GestionContactos
Proyecto de Presentación de Mantenimiento de Gestión de Contactos de Expertis.
Expertis.Application.ERP.GestionEDI
Proyecto de Presentación de Módulo de Generación de Ficheros EDI de Expertis.
Expertis.Application.ERP.GlobalActions
Proyecto de Presentación que contiene todas las Acciones Globales definidas en Expertis.
Expertis.Application.ERP.GlobalActionsOffice
Proyecto de Presentación que contiene todas las Acciones Globales de Office Definidas en Expertis.
Expertis.Application.ERP.Graphics
Proyecto de Presentación que contiene todo lo relacionado con Gráficos de Expertis y Cuadros de Mando.
Expertis.Application.ERP.Help
161/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación que contiene la ayuda de Expertis que se agrega a la barra de herramientas
Expertis.Application.ERP.Hora
Proyecto de Presentación de Mantenimiento de Horas de Expertis.
Expertis.Application.ERP.Idioma
Proyecto de Presentación de Mantenimiento de Idiomas de Expertis.
Expertis.Application.ERP.ImportacionDatos
Proyecto de Presentación de Módulo de Importación de Datos de Expertis.
Expertis.Application.ERP.ImpresionAlbaranVenta
Proyecto de Presentación de formularios relacionados con las Impresiones de Albaranes de Venta.
Expertis.Application.ERP.ImpresionFacturasVenta
Proyecto de Presentación de formularios relacionados con las impresiones de Facturas de Venta.
Expertis.Application.ERP.ImpresionPedidoCompra
Proyecto de Presentación de formularios relacionados con las Impresiones de Pedidos de Compras.
Expertis.Application.ERP.Incidencia
Proyecto de Presentación de Incidencias de Calidad de Expertis.
Expertis.Application.ERP.IncidenciaAlquiler
Proyecto de Presentación de Incidencias relacionadas con el Módulo de Alquiler.
Expertis.Application.ERP.InformeTesoreria
Proyecto de Presentación de Informes relacionados con el Módulo de Tesorería.
Expertis.Application.ERP.Inmovilizado
Proyecto de Presentación de Módulo de Inmovilizado de Expertis de Elementos amortizables, amortizaciones, etc…
Expertis.Application.ERP.Intrastat
Proyecto de Presentación de formularios de Intrastat de Ventas y Compras.
Expertis.Application.ERP.IvaCompra
Proyecto de Presentación de formularios relacionados con la Declaración de IVA de Compra.
Expertis.Application.ERP.IvaVenta
Proyecto de Presentación de formularios relacionados con la Declaración de IVA de Venta.
Expertis.Application.ERP.LecturaContAlquiler
Proyecto de Presentación de mantenimiento de Lectura de Contadores de Maquinaria de Alquiler.
Expertis.Application.ERP.LiquidacionRepresentante
Proyecto de Presentación de formularios de Liquidaciones de Ventas de Representantes.
Expertis.Application.ERP.Mailing
162/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de formularios de Generación de Etiquetas de clientes y proveedores.
Expertis.Application.ERP.Mercado
Proyecto de Presentación de Mantenimiento de Mercados usado en clientes y proveedores
Expertis.Application.ERP.MmtoStocks
Proyecto de Presentación de formularios relacionados con la Administración y Consulta de Stocks de Expertis.
Expertis.Application.ERP.MntoActivo
Proyecto de Presentación de formularios de Activos de Módulo de Alquileres – Maquinarias.
Expertis.Application.ERP.MntoMaestro
Proyecto de Presentación de mantenimiento Correctivo – Preventivo GMAO de Expertis.
Expertis.Application.ERP.ModosTransporte
Proyecto de Presentación de formularios de Modos de Transporte de Envíos de Venta.
Expertis.Application.ERP.Moneda
Proyecto de Presentación de mantenimiento principal de Monedas de Expertis.
Expertis.Application.ERP.ObraPresup
Proyecto de Presentación de formularios de Módulo de Presupuestos de Proyectos / Obras.
Expertis.Application.ERP.ObraPromo
Proyecto de Presentación de formularios de Módulo de Obras Promotoras.
Expertis.Application.ERP.Obras
Proyecto de Presentación de formularios de Módulo de Proyectos / Obras.
Expertis.Application.ERP.Observacion
Proyecto de Presentación de formulario de Mantenimiento de Observaciones de Expertis.
Expertis.Application.ERP.OfertaComercial
Proyecto de Presentación de formularios de Módulo Comercial de Expertis.
Expertis.Application.ERP.OfertaCompra
Proyecto de Presentación de formularios de Ofertas de Módulo de Compras.
Expertis.Application.ERP.Oficio
Proyecto de Presentación de mantenimiento de Oficios de Personal de Expertis.
Expertis.Application.ERP.Operaciones
Proyecto de Presentación de Operaciones de Módulo de Producción.
Expertis.Application.ERP.Operario
Proyecto de Presentación de formulario principal de Mantenimiento de Operarios de Expertis.
Expertis.Application.ERP.OrdenFabricacion
163/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de formularios de Moódulo de Producción de Expertis.
Expertis.Application.ERP.PagoCont
Proyecto de Presentación de formularios relacionados con Pagos del Módulo Financiero
Expertis.Application.ERP.Pais
Proyecto de Presentación de formulario Principal de Mantenimiento de Paises de Expertis.
Expertis.Application.ERP.Parametro
Proyecto de Presentación de formularios de Mantenimientos de Parámetros de Expertis.
Expertis.Application.ERP.PartidaEstadistica
Proyecto de Presentación de formularios usados para las Declaraciones de iva intrastat.
Expertis.Application.ERP.PedidoCompra
Proyecto de Presentación de Mantenimiento de Pedidos de Compra de Expertis.
Expertis.Application.ERP.PedidoVenta
Proyecto de Presentación de Mantenimiento de Pedidos de Venta de Expertis.
Expertis.Application.ERP.PlanifCompra
Proyecto de Presentación de formularios de Módulo de Planificación de Compras.
Expertis.Application.ERP.PlanificadorRecursos
Proyecto de Presentación de formularios de Planificador de Recursos de Producción / Obras / …
Expertis.Application.ERP.PlanifProduccion
Proyecto de Presentación de formularios de Módulo de Planificación de Producción.
Expertis.Application.ERP.PrepararExp
Proyecto de Presentación de formularios de Preparación de Expediciones de Ventas.
Expertis.Application.ERP.Presupuesto
Proyecto de Presentación de Módulo de Presupuestos Comerciales de Expertis.
Expertis.Application.ERP.Prevision
Proyecto de Presentación de Módulo de Previsiones de Ventas de Expertis.
Expertis.Application.ERP.Programa
Proyecto de Presentación de Módulo de Programas de Venta de Expertis.
Expertis.Application.ERP.ProgramaCompra
Proyecto de Presentación de Módulo de Programas de Compra de Expertis.
Expertis.Application.ERP.Promocion
Proyecto de Presentación de formularios de Mantenimiento de Promociones de Ventas.
Expertis.Application.ERP.PromocionCurso
164/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de formularios de Mantenimiento de Promociones de Ventas en Curso.
Expertis.Application.ERP.Proveedores
Proyecto de Presentación principal del Mantenimiento de Proveedores de Expertis.
Expertis.Application.ERP.PuntoVerde
Proyecto de Presentación principal de Mantenimiento de Punto Verde de reciclajes.
Expertis.Application.ERP.RecepcionPedidos
Proyecto de Presentación principal de Recepción de Pedidos de Compras.
Expertis.Application.ERP.Representante
Proyecto de Presentación principal de Mantenimiento de Representantes de clientes de ventas.
Expertis.Application.ERP.RH
Proyecto de Presentación que contiene todos los formularios del móulo de Recursos Humanos.
Expertis.Application.ERP.Secciones
Proyecto de Presentación principal de Mantenimiento de Secciones de Expertis.
Expertis.Application.ERP.SimulacionTesoreria
Proyecto de Presentación de formularios de Situación de Cartera de bancos a futuro.
Expertis.Application.ERP.SituacionBancos
Proyecto de Presentación de Formularios de Situación de nuestros bancos y saldos.
Expertis.Application.ERP.SolicitudCompra
Proyecto de Presentación principal de Mantenimiento de Solicitudes de Compras.
Expertis.Application.ERP.Subcontratacion
Proyecto de Presentación de formularios relacionados con la subcontratación de compras.
Expertis.Application.ERP.Tarifa
Proyecto de Presentación principal de Tarifas de Expertis.
Expertis.Application.ERP.TarifaCurso
Proyecto de Presentación principal de Tarifas en Curso de Expertis.
Expertis.Application.ERP.Tasa
Proyecto de Presentación principal del Mantenimiento de Tasas.
Expertis.Application.ERP.TesoreriaContabilidad
Proyecto de Presentación de Formularios de Contabilidad del Módulo Financiero - Tesorería
Expertis.Application.ERP.TesoreriaPorBanco
Proyecto de Presentación de Formulario de Estado de Bancos Propios en Periodos.
Expertis.Application.ERP.Tipos
165/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Proyecto de Presentación de formularios de mantenimientos de Tipos de Expertis.
Expertis.Application.ERP.TrazabilidadFactura
Proyecto de Presentación de formularios relacionados con la Trazabilidad de Facturas Compras / Ventas
Expertis.Application.ERP.UDMedida
Proyecto de Presentación de Mantenimiento principal de Unidades de Medidas de Expertis.
Expertis.Application.ERP.UsoMaquinaria
Proyecto de Presentación de Mantenimiento principal de Usos de Maquinaria de Expertis.
Expertis.Application.ERP.Varios
Proyecto de Presentación de Mantenimiento principal de Formulario de Varios de Expertis.
Expertis.Application.ERP.Vendedor
Proyecto de Presentación de Mantenimiento principal de Formulario de Vendedores de Expertis.
Expertis.Application.ERP.VisorInmuebles
Proyecto de Presentación de formularios relacionados con el Visor de Inmuebles.
Expertis.Application.ERP.VisorOFs
Proyecto de Presentación de formularios relacionados con el Visor de Ordenes de Fabricación.
Expertis.Application.ERP.Zona
Proyecto de Presentación de Mantenimiento principal de Zonas de Expertis.
Volver al Índice
Proyectos de Negocio
Expertis.Business.BC3
Proyecto de Negocio sobre el fichero BC3 en Presupuestos del Módulo de Proyectos.
Expertis.Business.Bodega
Proyecto de Negocio que contiene todo lo relacionado con el módulo de Bodegas de Expertis.
Expertis.Business.BusinessEnum
Proyecto de Negocio que contiene todos los enumerados de Expertis.
Expertis.Business.Calidad
Proyecto de Negocio que contiene todo lo relacionado con el módulo de Calidad de Expertis.
Expertis.Business.Comercial
Proyecto de Negocio que contiene todo lo relacionado con las Ofertas Comerciales de Expertis.
Expertis.Business.Compra
Proyecto de Negocio que contiene todo lo relacionado con las Ofertas, Solicitudes y Contratos de Compra de
Expertis.
Expertis.Business.Configurador
Proyecto de Negocio que contiene todo lo relacionado con el Configurador de Producto de Expertis.
166/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Expertis.Business.ControlPresencia
Proyecto de negocio que contiene todo lo relacionado con la Herramienta de Control de Presencia de Expertis.
Expertis.Business.CRM
Proyecto de Negocio que contiene todo lo relacionado con el módulo de CRM – Empresa de Expertis.
Expertis.Business.EDI
Proyecto de Negocio que contiene todo lo relacionado con el Módulo de Ficheros de EDICOM de Expertis.
Expertis.Business.Ficheros
Proyecto de Negocio que contiene todo lo relacionado con la generación de ficheros planos de hacienda, fichero
Facturae, ficheros XML de Bodegas, etc….
Expertis.Business.Financiero
Proyecto de Negocio que contiene todo lo relacionado con el módulo Financiero de Expertis: Contabilizaciones,
plantillas, diario contable, etc…
Expertis.Business.GD
Proyecto de Negocio que contiene todo el sistema de Gestión Documental de Expertis.
Expertis.Business.General
Proyecto de Negocio que contiene toda una serie de clases generales de uso en todos los módulos de negocio de
Expertis y funcionalidades generales de Expertis.
Expertis.Business.Help
Proyecto de Negocio que contiene todo lo relacionado con la Ayuda de Expertis del menú principal.
Expertis.Business.ImportacionDatos
Proyecto de Negocio que contiene todo lo del módulo de Importación de Datos del CRM.
Expertis.Business.Mnto
Proyecto de Negocio que contiene todo lo relacionado con el módulo de Correctivo / Preventivo GMAO de Expertis.
Expertis.Business.Negocio
Proyecto de Negocio general que contiene la gran mayoría de entidades y funcionalidades de Expertis. Sobre todo se
encuentran los procesos de facturaciones, albaranar, etc… de los módulos de ventas y compras de expertis, entre
otros…
Expertis.Business.Obra
Proyecto de Negocio que contiene todo lo relacionado con el Módulo de Proyectos de Expertis, de Presupuestos de
Expertis y de Promotoras.
Expertis.Business.Planificacion
Proyecto de Negocio que contiene todo lo relacionado con la planificación MRP de Compras y la Planificación MRP
de Producción.
Expertis.Business.PlanificadorRecursos
Proyecto de Negocio para la herramienta del Planificador general de recursos usado en varios puntos de Expertis.
Expertis.Business.Produccion
Proyecto de Negocio que contiene todo lo relacionado con el módulo de Producción / Fabricación.
167/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Expertis.Business.Promo
Proyecto de Negocio que contiene todo lo relacionado con las promotoras de Expertis.
Expertis.Business.RH
Proyecto de Negocio que contiene todo lo relacionado con el Módulo de Recursos Humanos de Expertis.
Expertis.Business.TPV
Proyecto de Negocio que contiene todo lo relacionado con el Módulo de TPV de Expertis.
Expertis.Business.Visor
Proyecto de Negocio que contiene todo lo relacionado con el visor de recursos, fincas, etc… de Expertis.
Volver al Índice
Proyectos de Motor
Expertis.Engine.BE.BusinessEngine
Contiene los elementos básicos para la ejecución de aplicaciones construidas con (EE)
Expertis.Engine.DAL
Contiene los elementos de acceso a datos independientes del origen de datos. El componente principal de este
ensamblado es Solmicro.Expertis.Engine.DAL.AdminData, que encapsula toda la lógica de lectura y actualización de
datos.
Expertis.Engine.Global
Es un ensamblado que contiene utilidades y elementos comunes tanto para la capa de presentación como para la
capa de negocio.
Expertis.Engine.License
Proyecto de motor que se encarga de la licencia del Expertis que se ejecuta.
Expertis.Engine.SqlDAL / Expertis.Engine.ODPNetDAL
Son las implementaciones de los proveedores de datos específicos para Sql Server y Oracle respectivamente.
Básicamente contienen una clase que implementa la interfaz Solmicro.Expertis.Engine.DAL.IAdminData, que define
los métodos necesarios que debiera implementar un proveedor de datos para (EE)
Expertis.Engine.UI.CommonClasses
Contiene las plantillas de formularios para aplicaciones construidas sobre (EE)
Expertis.Engine.UI.Design
Proyecto de motor necesaria solo en el Bin de Expertis de un desarrollador. No es necesario en un Bin de Cliente
final. Funciona conjuntamente con el Expertis.Designer.
Expertis.Engine.UI.Resources
Contiene exclusivamente iconos y texto propios de (EE).
Expertis.Engine.UI.WinControls
Contiene todos los controles gráficos empleados por (EE), sobre los cuales se ha implementado las características
necesarias para su correcta integración con el resto de componentes de (EE), así como un conjunto de reglas
estéticas unificadas. Contiene también la clase Solmicro.Expertis.Engine.UI.ExpertisApp que proporciona métodos
para configurar y lanzar el entorno de ejecución de cualquier aplicación construida con (EE), así como métodos de
interacción con la capa de negocio útiles para los desarrolladores. Entre las tareas importantes que realiza esta clase,
168/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
está la configuración de la aplicación para que funcione correctamente de forma distribuida, esto es, la configuración
de Remoting
Volver al Índice
169/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
6. VARIOS
Objeto DataTable
Para el objeto DataTable en su uso en Expertis, tendremos que tener claro y muy presente siempre los estados en los
que vayan los Rows que componen el DataTable de cara a cómo funcionen luego con los procesos de una entidad.
Para ello los DataRows poseen una propiedad llamada: RowState que describe el estado en el que se encuentra una
DataRow.
También tenemos el método GetChanges de un DataTable y pudiendo especificar qué tipo de estados para obtener
un DataTable con los cambios exactos del tipo que queramos y comprobar también de esta manera si un DataTable
posee cambios del tipo que le digamos.
Para añadir nuevos DataRows a un DataTable existente tenemos varias formas:
-
Método Normal
Por el procedimiento normal lo que haríamos sería generar un DataRow con la estructura del DataTable al que va
a ser agregado y añadirlo dentro de la colección de Rows del DataTable.
Dim DtNew As New DataTable
Dim DrNew As DataRow = DtNew.NewRow
DrNew("IDClave") = "00"
DrNew("DescClave") = "Prueba"
DtNew.Rows.Add(DrNew)
-
Método Normal con ItemArray
Por el procedimiento normal con ItemArray podríamos agregar un DataRow perteneciente a otro DataTable y
agregarlo como nuevo al Datatable nuestro de destino. Los dos DataTables tienen que coincidir en estructura de
datos, tanto en número de columnas como en el propio orden de las columnas.
Dim DtOrigen As New DataTable
Dim DtDestino As New DataTable
DtDestino.Rows.Add(DtOrigen.Rows(0).ItemArray)
-
Método ImportRow
Método de un DataTable el cual nos permite importar por completo un DataRow existente en un DataTable,
respetándonos de ese DataTable tanto la estructura como los datos y sobre todo el RowState de ese DataRow
en concreto.
Dim DtOrigen As New DataTable
Dim DtDestino As New DataTable
DtDestino.ImportRow(DtOrigen.Rows(0))
-
Método LoadDataRow
Método de un DataTable el cual nos permite actualizar la información de un DataRow en un DataTable existente
y que contenga ya ese DataRow para llevar a cabo la actualización. Si dicho DataRow no existiese lo agregaría
como nuevo en nuestro DataTable.
Dim DtOrigen As New DataTable
Dim DtDestino As New DataTable
DtDestino.LoadDataRow(DtOrigen.Rows(0).ItemArray, True)
Volver al Índice
Modificadores a Métodos
Para ver una enumeración de los diferentes atributos que posee un proceso o función ver la ayuda de msdn de
Microsoft.
http://msdn.microsoft.com/es-es/library/sect4ck6(v=VS.90).aspx
Volver al Índice
170/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Atributo Shared
Para el atributo Shared y especificaciones de este tipo de atributo ver la ayuda de msdn de Microsoft.
http://msdn.microsoft.com/es-es/library/zc2b427x(v=VS.90).aspx
Nosotros en Expertis usamos este atributo para todas las tareas de Expertis, ya sean tareas que pertenecen a
procesos o bien tareas que son públicas.
Es obligatorio el uso de este atributo para las tareas de Expertis. Todo aquello que no sea una tarea y sea de tipo
público en una clase de negocio no puede llevar el atributo Shared o bien tendremos errores en remoting.
Volver al Índice
Genéricos
Los genéricos permiten personalizar un método, clase o interfaz para el tipo de datos preciso sobre el que actúa. Un
sitio en el que se utiliza es en las clases para el cacheo en el ServiceProvider.
La clase EntityInfoCache(en Expertis.Busines.General) está preparada para trabajar con genéricos, lo cual nos
permite decir el tipo de datos que va a contener.
Dim Clientes As EntityInfoCache(Of ClienteInfo) = services.GetService(Of EntityInfoCache(Of
ClienteInfo))()
Si no tuviéramos los genéricos, tendríamos que haber creado un clase que herede de EntityInfoCache por cada clase
que quisiéramos cachear (ClienteInfoCache, ProveedoreInfoCache,……)
http://msdn.microsoft.com/es-es/library/w256ka79.aspx
Volver al Índice
? Atributo Nulo en Variables
Para que las variables que definimos en expertis (sean del tipo que sean) se puede establecer el atributo final con ?
para remarcar que se desea que esa variable se instancie de base como nothing en contenido. Esto es visible y
utlizado sobre todo cuando queremos que variables de tipo numérico no cojan como valor por defecto en su definición
el 0.Por circunstancias del desarrollo y control del desarrollo vemos que no queremos que las variables vengan con
un 0 por defecto y mejor con un valor a nothing.
Private mAplicarAnalitica As Boolean?
Uno de los tipos de variables que no admiten este uso del atributo nulo sería el String con este tipo de variables nos
daría error.
Volver al Índice
Componente BackgroundWorker
Elemento de Visual Studio 2008 del Framework 2.0 en adelante. Nos permite a través de la configuración de un
objeto más visual, la posibilidad de ejecutar procesos en otros hilos.
De esta manera podremos seguir teniendo la ejecución principal del programa y ejecutar otro proceso en otro hilo.
Esto surge por necesidades de ir ejecutando actualizaciones en alguna ventana de estado, o log o barra de progreso.
Para agregar este control, lo tenemos en el Cuadro de Herramientas del Visual Studio, sección de Componentes:
171/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El Resultado que veríamos de agregar este control a nuestro formulario lo veríamos en la sección de objetos de
formulario de la parte de abajo dentro del Visual Studio.
Propiedades / Eventos /Métodos

Propiedades principales:
o
Tiempo de Diseño:

WorkerReportsProgress: propiedad para indicar si el control irá reportando el
progreso del avance del proceso que se está ejecutando en este hilo. Esta propiedad
sobre todo lo que provocaría es que haría caso del método ReportProgress y de lo
que programemos en el evento ProgressChanged.

WorkerSupportsCancellation: propiedad en la que especificamos si el control permite
cancelación por parte del usuario. Esto sería que haría caso del método CancelAsync
que podemos usar en el control.
172/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
o
Tiempo de Ejecución:

IsBusy: propiedad que nos indica si está realmente en ejecución el proceso
asíncrono que hemos mandado o bien está parado.
If BgWork.IsBusy Then
'Ejecución de Proceso
End If

CancellationPending: propiedad que nos indica si se ha llevado a cabo cancelación
por parte del usuario y está pendiente de llevarla a cabo. Para esto sería si hemos
ejecutado el método CancelAsync
If BgWork.CancellationPending Then
'Ejecución de Proceso
End If

Eventos principales:
o
DoWork: evento en el que programaremos la ejecución del proceso que deseamos en ese
otro hilo de ejecución. Este evento responderá a la llamada del método RunWorkerAsync
donde lo hagamos en nuestro código.
'2º.- Validar si hay Facturas sin Vencimientos
If DescuadreVencimientos(e.Argument) Then BlnError = True
BgWork.ReportProgress(20)
System.Threading.Thread.Sleep(500)
Podemos observer en este código de ejemplo como en el evento DoWork usamos de la variable
e.Argument para recoger el argumento que enviamos en el método RunWorkerAsync (en este caso un
DataTable).
o
ProgressChanged: evento que podemos ya reportar esos status, pasos, log, barra de
progreso que tengamos para representar la ejecución de nuestro proceso en otro hilo. Este
evento responderá a la llamada en el código que hagamos al método ReportProgress.
Select Case e.ProgressPercentage
Case 10
MFrmProgress.LblInfo.Text = "Verificando Vencimientos..."
MFrmProgress.UIPrgProgreso.Value = 10
End Select
Como se puede ver en el código de ejemplo controlamos el valor del porcentaje reportado a través de la
variable e.ProgressPercentage que habríamos enviado y con lo cual hacer las respectivas
actualizaciones que necesitemos.
o
RunWorkerCompleted: evento que se llamará una vez se haya completado todo el proceso
del backgroundworker, en el que podremos observar si la ejecución fue correcta, o se canceló
o bien ocurrió algún error.
If e.Cancelled Then
'Se canceló el proceso
ElseIf Not e.Error Is Nothing Then
'Se devolvió un error
173/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Else
Dim BlnCorrecto As Boolean = e.Result
End If
Dentro de la variable e de este evento dispondremos de 3 propiedades para controlar los estados
anteriormente comentados siendo: Cancelled (Si se canceló la ejecución), Error (se terminó la
ejecución por causa de un error) y Result (Resultado final correcto devuelto por nuestro proceso y el
DoWork).

Métodos principales:
o
CancelAsync: método por el que podemos cancelar la ejecución del proceso del
backgroundworker. Esto provocaría que se ejecute el evento RunWorkerCompleted.
BgWork.CancelAsync()
o
RunWorkerAsync: método para comenzar la ejecución programada para el backgroundworker
en el evento DoWork. Podremos pasar un parámetro de entrada al método para cierta
información que deseemos enviar al evento DoWork.
BgWork.RunWorkerAsync(DtGrid)
Se puede observar que en la llamada pasamos un DataTable ya que es lo que necesitamos luego en el
evento DoWork para manejar.
o
ReportProgress: método por el cual podemos ir reportando el porcentaje en entero del
progreso total de nuestro proceso. Este método provocaría que s ejecute el evento
ProgressChanged.
BgWork.ReportProgress(40)
Información de MSDN de BackgroundWorker:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.90).aspx
Volver al Índice
LINQ To SQL
La tecnología de Linq To SQL es una tecnología que aparece tímidamente por Expertis en esta versión actual. De
momento se han implementado en ciertos apartados de Expertis, pero su uso todavía no es generalizado.
Pero como en algunos casos podemos encontrarnos este tipo de metodología convendría saber algo acerca de este
Linq.
Os ponemos a vuestra disposición la información que nos aporta Microsoft sobre esto:
http://msdn.microsoft.com/en-us/library/bb308959
Volver al Índice
174/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
7. REMOTING
Consideraciones
La comunicación remota en Expertis se hace a través del modelo SingleCall. Esto significa que puedo tener todas las
instancias que quiera en el servidor (similar a COM+), ya que es el servidor el que controla la vida del objeto. Los
objetos del servidor sólo viven durante la ejecución de un proceso.
CLIENTE
Dim A as new MiClase
A.M1
A.M2
SERVIDOR
objeto A
Los métodos M1 y M2, puede que sean servidor por 2 instancias distintas en el servidor.
Todo objeto que sea invocable remotamente debe heredar de MarshallByRef (En Expertis, deben heredar de
ContextBoundObject que a su vez hereda de MarshallByref, que junto con el atributo Transactional aseguran en
control de transacciones de Expertis).
Las conexiones a la BBDD duran como mucho lo que dura la ejecución de un método. La DAL cuando requiere una
conexión, la crea y se la asocia a la sesión (en su caché). El Transactional lo que hace es “poner una barrera” que
hace que cuando termine el proceso mire si se ha hecho o no el Commit o Rollback.
Si no lo ponemos, podemos dejar sesiones abiertas en la caché de sesiones de la DAL o que cerremos antes de
tiempo la conexión.
Tipos de Clases:
Tradicionales.
Remotas (modelo Single Call). Sin estado, salvo excepciones.
Viajeras (serializables). Con estado. No pueden tener código de acceso a datos, porque van a acceder a la
DAL desde presentación.
-
Hay que tener en cuenta, que si se hace referencia desde presentación a un objeto remoto, se ejecutará el código en
el cliente.
¿Por qué tiene que estar la dll de Negocio en el puesto cliente? Por qué en tiempo de ejecución el cliente debe poder
saber cuál es el interfaz de la clase remota, ya que realmente no tendremos un objeto, sino un proxy.
No se puede parametrizar un tipo de objeto de entrada de una tarea de negocio que no sea Serializable.
El viaje entre la capa de negocio y la de presentación no está permitido para muchos tipos de objetos y esto es
marcado por Microsoft.
Enviar como tipo de objeto desde presentación a negocio un DataRow no está permitido ya que esto nos provocaría
error de serialización en remoting, ya que el DataRow no es un objeto serializable.
Marcar como Serializable las clases que enviamos como objetos de entrada de una tarea pública de negocio.
No se puede enviar DataRow en un objeto Clase, aun estando marcado el objeto clase como Serializable.
Las entidades dadas de alta en el manager tienen que tener la marca de Publicar para que se publiquen
efectivamente en remoting.
Al usar el sistema de tareas de Expertis no hace falta si tenemos una Clase de Negocio que no es entidad y que
alberga tareas públicas el definirla con la Herencia con ContextBoundObject. Esto solo haría falta si tuviésemos una
clase de Negocio de Expertis con Procesos o Funciones públicas pero sin ser tareas. Para ello necesitaríamos de
establecer la herencia con ContextBoundObject y con el atributo Transactional.
Volver al Índice
Errores Comunes
Errores más comunes y frecuentes que nos mostrará en Expertis si hemos hecho una programación inadecuada para
Remoting:
-
El objeto XX no está marcado como Serializable.
Errores derivados haciendo referencia a algo de la serialización.
No se encuentra el fichero System.Config de Expertis.
Volver al Índice
175/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Configuración de Remoting de puesto Cliente y Servidor
Para llevar a cabo la configuración del Remoting en nuestro ámbito tendríamos que tener en cuenta las siguientes
consideraciones:
Parte Servidor
-
Debemos instalar el programa Expertis.Host de la versión 5.0 en el equipo servidor de nuestra red interna.
Cuando instalamos este Expertis.Host debemos elegir un directorio en donde hayamos alojado previamente
el Bin de Expertis con el que trabajará el servidor.
Este Bin de la parte Servidor es el que tenemos que tener presente el fichero System.Config, que es el que
se usará para conectarse a la Base de Datos de Sistema de Expertis dónde coger toda la información
relacionada con Expertis:
-
En este fichero podemos observar las propiedades de la conexión contra la base de datos de sistema. Para
ello especificaremos:
o Data Source = Nombre del servidor donde se encuentra la BD de Sistema.
o Initial Catalog = Nombre de la BD de Sistema.
o User / Pass = Datos del usuario para llevar a cabo la conexión contra la BD.
-
En el servidor el fichero de Expertis.Engine.UI.Shell.Exe.Config no tendría uso y no lo usaría la parte
servidor.
Parte Cliente
-
En el cliente dispondremos del mismo bin de Expertis que hubiésemos alojado en la parte Servidor pero sin
que esté presente el fichero System.config. Este fichero se ha de quitar en el Bin de la parte de cliente.
En el fichero Expertis.Engine.UI.Shell.Exe.Config es donde especificaremos los datos de conexión del cliente
con el servidor de Remoting:
176/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
o
o
o
o
o
o
Remoting Mode = parámetro con diversas opciones, que sobre todo nos interesa para
poder activar /desactivar (Automatic / Disabled) que el cliente se conecta por Remoting y
no en modo local.
Remoting Channel = parámetro que nos permite especificar el tipo de canal usado del
Remoting. Generalmente si usamos el servicio de Expertis.Host será canal tcp. Y si
usamos como Remoting el IIS usaremos el canal http o https. (Por defecto en blanco será
TCP).
Remoting Host = Nombre el servidor donde se encuentra nuestro servidor de Remoting.
Remoting Port = Número de puerto por el que hemos configurado que se comuniquen
nuestro cliente con el servidor.
RemotingCompression = Opción para habilitar / deshabilitar que los paquetes de
comunicación entre el servidor y el cliente vayan comprimidos y con ello para aumentar la
velocidad de transmisión de los paquetes.
ExceptionDetails opción para habilitar / deshabilitar que en caso de error no controlado
en expertis, nos aparezca un error con un mayor nivel de detalle. Esta opción la damos
por defecto a False para que en una primera instancia de error no salga un error con
tanto detalle que asuste al usuario final y no entiendo nada. Cuando en nuestro desarrollo
ocurra algo y el error que nos comentan son sin esta opción de detalle, y efectivamente la
información es escasa, Podemos activar esta opción para ver en ese caso un mayor nivel
de detalle y así visualizar más rápidamente el error dado.
Volver al Índice
177/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
8. INFORMES
Introducción a Informes en Expertis
El desarrollo que se hace con un informe viene condicionado en principio por la forma en que se va a abrir. Existen
dos formas de abrir un informe, una, automatizada, que consiste en vincular el informe a un programa y abrirlo desde
el comando de impresión de la barra de comandos de un mantenimiento, y dos, personalizada, utilizando la clase
Report de Expertis.
Desde el punto de vista de programación las diferencias fundamentales que hay entre las dos formas son:
- La forma de interactuar y de intercambiar información con el informe.
Si el informe se abre por vínculo con un programa la manera de pasar información al informe se basa en programar
ciertos eventos de las clases de mantenimiento. Si el informe se abre por código no se lanza ningún evento, en su
lugar se dispone de la clase Report de Expertis para programar.
- La automatización de ciertas propiedades y el tipo de informe.
Si el informe se abre por vínculo con un programa, el tipo de informe juega un papel importante, ya que permite al
motor de Expertis establecer de forma automática una serie de propiedades, por ejemplo los criterios de selección o
el origen de datos. Si el informe se abre por código el tipo del informe no tiene relevancia y todas las propiedades las
debe establecer el programador.
En cualquier caso el informe tiene que ser reconocido por Expertis, y para ello es necesario introducir cierta
información en algunas tablas de la base de datos de sistema.
En lo referente a los proyectos de presentación no hay que incluir ninguna referencia de Crystal Reports.
En los puestos cliente finales es necesario instalar el runtime de Crystal. Dentro del paquete de distribución de
Expertis se incluye un instalador (CrystalReportsXI.msi) que realiza esta función.
Volver al Índice
Tipos de Informes
1.
Registro Actual
El motor de informes construye un filtro con el valor de la o las claves primarias del registro actual, para la
entidad asociada a la clase de mantenimiento. El criterio de selección resultante se aplica sobre el origen de
datos del informe.
Es válido abrir este tipo de informes desde un mantenimiento simple (de hecho este tipo de informes está
creado especialmente para este tipo de mantenimientos). En un mantenimiento en Grid también funcionaria
para la línea del Grid que estuviera seleccionada en ese momento.
Este tipo de informes no se abren desde las consultas interactivas.
Crear un informe con una conexión OLE DB (ADO) tal y como se indica en el apartado E.2 del apéndice.
Seleccionar como origen de datos la tabla tbCursoMaestroCliente
178/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Realizar un diseño sencillo del informe seleccionando algunos campos de la tabla.
Guardar el informe como CursoCliente.rpt y desde la consola de administración dar de alta un informe de tipo
Registro Actual y alias CURCLI.
Desde la consola de administración de la aplicación dar los permisos necesarios al informe y vincular el
informe al mantenimiento de clientes creado en el apartado 4.2.
179/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
2.
Criterio Selección
Este tipo está creado para utilizarlo en las consultas interactivas. El motor construye un filtro en base a los
criterios de selección de la consulta interactiva. El filtro se aplica al origen de datos del informe, ya sea el que
tiene diseñado o bien el que se le establezca por código.
Aunque está pensado para las consultas interactivas, también es posible lanzar este tipo de informes desde
los otros tipos de mantenimientos, sin ningún tipo de restricción, el motor se limita a lanzar los eventos para
que podamos interactuar con el informe.
Crear una vista con el nombre vrptCursoConsultaFactura con el siguiente diseño
Crear un informe con una conexión OLE DB (ADO) tal y como se indica en el apartado E.2 del apéndice,
seleccionando la vista anterior como origen de datos del informe.
180/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Realizar un diseño sencillo del informe seleccionando algunos campos de la tabla.
Guardar el informe como CursoConsultaFactura.rpt y utilizando la consola de administración dar de alta un
informe de tipo criterio de selección, y alias CURCIFV.
Desde la consola de administración de la aplicación dar los permisos necesarios al informe y vincular el
informe a la consulta de facturas creada en el apartado 4.4.
Comprobar en depuración como se ejecuta el evento QueryExecuting de la clase de mantenimiento.
Volver al Índice
3.
Tabla Auxiliar
Este tipo de informes se utiliza para imprimir de forma masiva, o cuando se quieren distinguir varias copias
de un mismo informe, y se pueden lanzar desde los mantenimientos simples o desde consultas interactivas
que utilicen marcas.
Este tipo de informes no se abren desde los mantenimientos tipo Grid.
Ver también propiedad LinkField de la clase Report, y en el apartado Algunos temas de diseño, Diseño de
informes de tipo Impresión de tabla auxiliar.
Diseño de informes nuevos.
Un diseño correcto del origen de datos es lo más importante en este tipo de informes. Cuando se diseña la
vista que sirve como origen de datos debemos hacer obligatoriamente lo siguiente:
1.
Incluir la tabla xPrintingAuxiliarTable de la base de datos de usuario.
2.
Establecer un vínculo entre la tabla principal de la vista y la tabla xPrintingAuxiliarTable.
El campo de la tabla principal que se vincula debe tener valores únicos, por ejemplo, un campo
primary key de tipo auto numérico.
El vínculo debe hacerse con el campo NumericLink o TextLink en función del tipo de dato que
contiene el campo de la tabla principal que se vincula.
3.
Incluir los campos IdProcess y NumberOfCopies de la tabla xPrintingAuxiliarTable.
Ejemplo:
Cuando se lanza un informe de este tipo, el motor de informes se encarga, primero, de crear un identificador
de proceso y guardar en la tabla xPrintingAuxiliarTable los registros con ese identificador, y segundo, se
encarga de aplicar un criterio de selección de registros en base a dicho identificador.
Cuando el informe se abre, recupera el conjunto de registros de la vista filtrados por el identificador de
proceso, y la relación establecida entre las tablas xPrintingAuxiliarTable y la tabla principal hace el resto.
Por defecto, el motor de Expertis se encarga de saber cuál es el campo NumericLink o TextLink, de tal forma
que si es un mantenimiento simple (o en Grid), considerara como campo de enlace la clave primaria de la
entidad asociada a la clase de mantenimiento (propiedad EntityName de FormBase).
Cuando los registros de la tabla xPrintingAuxiliarTable no son necesarios se eliminan para el identificador de
proceso en cuestión. Si solo se ha mostrado la vista previa del informe, esto ocurre justo cuando se cierra el
181/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
formulario de la vista previa, bien sea directamente o bien porque se cierra Expertis. En el caso de que se
haya realizado alguna acción de exportación los registros se eliminan justo después de ejecutar la orden de
exportación.
Si en el tiempo que dura el pre visualización, o la exportación, la aplicación se cierra anormalmente, los
registros no se eliminaran de xPrintingAuxiliarTable. Por esta razón, y aunque no es crítico ni será lo
habitual, puede ser conveniente realizar comprobaciones periódicas del contenido de esta tabla, por parte de
los administradores de la aplicación, con objeto de que no crezca demasiado.
Los registros que queden sin borrar no afectan en modo alguno al funcionamiento de otros informes.
En algunos casos es necesario cambiar el comportamiento por defecto y se hace necesario escoger otro
campo de enlace diferente. En ese caso es posible establecer el campo de enlace en la configuración del
informe o alternativamente por código. Este nombre se almacena en el campo LinkField de la tabla xReport
de la base de datos de sistema y se establece desde la consola de administración. Si queremos modificar
esta propiedad por código, deberemos utilizar la propiedad LinkField que posee la clase Report, o que posee
también la clase ReportDataSourceEventArgs que aparece como argumento de evento en el evento
SetReportDataSource de la clase de mantenimiento.
Por ejemplo, siguiendo el ejemplo anterior, el valor de LinkField seria IDAlbaran, aunque en este caso no
sería necesario configurarlo en xReport, ya que este informe se lanza desde el mantenimiento de Albaranes,
y el motor de informes se encarga de determinar que la clave principal asociada al mantenimiento es
IDAlbaran.
Volver al Índice
4.
RecordSet
Se toma como origen de datos un conjunto de registros al cual tiene acceso la clase de mantenimiento.
Es válido abrir este tipo de informes desde un mantenimiento en Grid o desde una consulta interactiva. En
ambos casos, por defecto, se utiliza el origen de datos del Grid para pasar los datos al informe. También se
puede hacer una selección múltiple de filas en el Grid para que solo aparezca esa selección en el informe.
Este tipo de informes no se abren desde los mantenimientos simples.
Volver al Índice
5.
Sin Filtro
El informe toma como origen de datos el que tiene asignado en diseño, o el que se le proporciona por código,
con la peculiaridad de que no utilizara ningún criterio de selección.
Este tipo de informes se puede lanzar desde cualquier tipo de mantenimiento.
Volver al Índice
6.
Personalizado
Este tipo de informes se puede utilizar en todos los tipos de mantenimiento, sin ninguna restricción, y es el
tipo por defecto cuando se da de alta un informe en Expertis.
El informe toma como origen de datos el que tenga diseñado o el que se le proporcione por código.
Volver al Índice
Configuración del Manager de Datos de Informes
Para ello acudiremos al manager de expertis e iremos a la sección: Objetos -> Informes. Para el agregado de
infromes se hace de forma manual a través del botón Añadir. Luego en él cumplimentaremos la información necesaria
acerca del informe, tales como alias, una descripción, nombre de archivo y tipo de informe. Asimismo no olvidemos
fijo el tema de permisos del informe y de asociarlo al programa en concreto
182/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
Servicio de Informes
La utilización de este servicio permite que los informes estén disponibles en una única ubicación para todos los
puestos cliente, con lo que no es necesario mantenerlos en cada uno de ellos.
El servicio de informes también permite que los informes de Expertis se resuelvan y se conecten en el servidor, en
lugar de que esto suceda en el equipo cliente. Esta opción puede resultar útil cuando, por razones generalmente de
seguridad, no es posible una conexión cliente-servidor de datos y solo sea el servidor host el que puede acceder al
gestor de datos.
Cuando se utiliza el servicio de informes lo que viaja al puesto cliente es una copia del informe ya resuelto, con los
datos incluidos, se almacena de forma temporal y se elimina cuando ya no es necesaria.
La configuración del servicio de informes se realiza desde la consola de administración, desde la sección Aplicación y
en Configuración de Aplicación.
183/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
El campo Usar Servicio de Informes tiene tres valores: Si, no y por defecto. El valor por defecto equivale a no.
En este cuadro se resumen las opciones disponibles, junto con la posibilidad de estar en un entorno de remoting.
Remoting
NO
UseReportService
NO
ReportPath
Vacio
<dir>
\\Recurso_Compartido
NO
SI
Vacio
<dir>
\\Recurso_Compartido
SI
NO
Vacio
<dir>
\\Recurso_Compartido
SI
SI
Vacio
<dir>
\\Recurso_Compartido
Especificación
Directorio especificado por <dir>, recurso
compartido o vacio que equivale al directorio por
defecto \Bin\Informes.
Ubicación de los informes Siempre relativa al
cliente.
Conexión: Cliente
Directorio especificado por <dir>, recurso
compartido o vacio que equivale al directorio por
defecto \Bin\Informes
Ubicación de los Informes siempre relativa al
Cliente
Conexión: Cliente.
Directorio especificado por <dir>, recurso
compartido o vacio que equivale al directorio por
defecto \Bin\Informes.
Ubicación de los informes siempre relativa al
Cliente.
Conexión: Cliente.
Direcotrio especificado por <dir>, recurso
compartido o vacio que equivale al directorio por
Defecto \Bin\Informes.
Ubicación de los Informes siempre relativa al
Servidor (Host).
Conexión: Servidor (Host)
En la opción de Modo de Ejecución tendremos 3 valores posibles:
-
Default: Modo por Defecto que equivaldría al modo Normal.
Normal: Modo Normal de trabajo con informes. Se devuelve de equipo servidor a los clientes un objeto de
tipo report.
LightClient: Modo Cliente Light de trabajo con Informes. Se devuelve de equipo servidor a los clientes un
objeto de tipo PDF.
184/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
NOTA: Desde la consola de administración el servicio de informes se puede establecer a nivel global para toda la aplicación
(internamente la tabla que mantiene estos datos es xApplication), pero también se puede establecer una configuración particular
para cada máquina desde la sección Maquinas de la consola de administración (en este caso la tabla es xMachine). Esto puede ser
particularmente útil, por ejemplo, cuando una misma base de datos de sistema es compartida por puestos cliente en producción y
puestos de desarrollo. Por lo general en los puestos de desarrollo se modifican y se prueban los informes de forma local y no utilizan
el servicio de informes.
Volver al Índice
Tipos de Conexión
Todos los informes que se utilizan en Expertis y se generan con Crystal Reports se diseñan con el mismo tipo de
conexión.
Para crear un informe nuevo, seleccionar Nuevo Informe en blanco desde Crystal Reports y crear una nueva conexión
OLE DB (ADO)
Seleccionar el proveedor de datos Microsoft OLE DB Provider for SQL Server
y establecer las propiedades de conexión para la base de datos de desarrollo que se esté utilizando
185/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Cuando se diseñan nuevos informes con Crystal Reports 11 el tipo de conexión va a ser OLE DB (ADO), proveedor
SQLOLEDB. Este tipo de conexión es válido tanto si el informe toma directamente el origen de la base de datos o
bien si va a ser proporcionado por código.
NOTA: En la mayoría de los informes diseñados para versiones anteriores de Expertis el tipo de conexión ya viene de Crystal
Reports 10 y 9 como OLE DB (ADO), de forma que, en principio, no hay que actualizarlos.
Esto se puede comprobar desde el diseñador de Crystal Reports en el Menú Base de Datos --> Establecer Ubicación.
Es posible que haya informes de versiones anteriores con el proveedor MSDASQL en lugar de SQLOLEDB.
Este tipo de proveedor no da problemas y lo podemos dejar así.
Volver al Índice
Eventos Informes
Las clases de mantenimiento SimpleMnto, GridMnto, CIMntoBase (y por herencia CIMnto) disponen de los eventos
que se lanzan cuando se abren informes desde el comando de impresión de la barra de comandos.
La clase FormBase no dispone de estos eventos, entre otras cosas, porque no tiene una barra de comandos y no se
ha diseñado ninguna acción específica que se pueda vincular a la apertura de un informe. Para abrir un informe desde
un FormBase (un formulario modal por ejemplo), necesitaríamos un evento o acción, como el evento Click de un
control Button, para poder programar la clase Report de Expertis y utilizar el método OpenReport de dicha clase.
El orden de ejecución de los eventos es el siguiente (1)
SetReportDesignObjects
SetReportSelectionCriteria
SetReportOptions
186/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
SetReportDataSource
ReportExported (2)
Cada evento salta para el informe principal (1), y para cada uno de los subinformes que pueda tener.
Todos los eventos, excepto ReportExported, disponen de una propiedad que permite cancelar la ejecución de todo el
proceso.
(1)Para algunos tipos de informe, no se ejecutan todos los eventos, pero el orden siempre se mantiene.
(2)Solo se lanza para el informe principal
ReportExported
Ocurre después de exportar un informe. Acciones de exportación se consideran:
guardar el informe en disco
enviar el informe adjunto por mail
imprimir el informe por impresora
Recibe un argumento del tipo ReportExportedEventArgs que contiene los datos del evento. Esta clase proporciona la
propiedad Status, de tipo ReportExportStatus, que indica si la exportación se ha ejecutado, y un valor de tipo
ReportExportDestinationType que indica el tipo de exportación
NOTA: Hay que tener en cuenta que el proceso de exportación se compone de dos acciones, primero, la ejecución de la orden de
exportación, y segundo, enviar el informe al contexto particular de exportación. La propiedad Status indica únicamente si se ha
podido ejecutar la orden de exportación. La ejecución con éxito del segundo paso depende de otros factores que la aplicación no
puede controlar, como pueden ser por ejemplo, que el informe se queda atascado en la impresora o que el informe que va adjunto
en un mail quede encolado en el servidor de correo.
SetReportDataSource
Ocurre antes de abrir un informe asociado a la lista de informes del comando de impresión.
Recibe un argumento del tipo ReportDataSourceEventArgs que contiene los datos relacionados con este evento. Este
evento permite asignar al informe un origen de datos personalizado por medio de la propiedad DataSource del
ReportDataSourceEventArgs.
Este evento también permite configurar las opciones de impresión de los informes de tipo Tabla Auxiliar (número de
copias, origen de las copias, etc).
SetReportDesignObjects
Ocurre antes de abrir un informe asociado a la lista de informes del comando de impresión.
Recibe un argumento del tipo ReportDesingObjectsEventArgs que contiene los datos relacionados con este evento.
Este evento permite asignar y modificar valores de todos los objetos contenidos en el diseño del
(formulas, parámetros, campos de ordenación y subinformes) por medio de las
ReportDesignObjectsEventArgs.
informe
propiedades
de
SetReportOptions
Ocurre antes de abrir un informe asociado a la lista de informes del comando de impresión.
Recibe un argumento del tipo ReportOptionsEventArgs que contiene los datos relacionados con este evento.
Este evento permite configurar por medio de las propiedades del ReportOptionsEventArgs, varias
opciones como
por ejemplo, opciones de impresión, el canal de exportación (mail, disco duro,
impresora),
el
formato
de
exportación (excel, word, ...), etc.
También permite controlar el estado del formulario de vista previa y la posibilidad de mostrar formularios de decisión
para el usuario.
SetReportSelectionCriteria
Ocurre antes de abrir un informe asociado a la lista de informes del comando de impresión.
Recibe un argumento del tipo ReportSelectionCriteriaEventArgs que contiene los datos relacionados con este evento.
Permite personalizar el criterio de selección que se aplicara sobre el origen de datos del informe, por medio de las
propiedades Filter o RecordSelecionFormula del ReportSelectionCriteriaEventArgs.
Volver al Índice
187/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
9. HERRAMIENTAS DE EXPERTIS
Consola de Administración
Para conocer a fondo la consola de administración de Expertis acudir al manual concreto de ayuda y manejo que se
dispone en la ayuda de expertis o bien en la web de documentos de ayuda de Expertis.
Pasaremos a marcar algunos puntos rápidos y de mayor conocimiento para un desarrollador de Expertis.
1.
Autenticación en Expertis [Cambio de Usuario]
Existen dos tipos de autenticación:


Autenticación de Windows. Se iniciará la sesión con el usuario con el que se ha iniciado la máquina.
Autenticación de Expertis. Al iniciar la sesión pedirá la introducción de un usuario de Expertis y su
contraseña.
En las bases de datos de sistema que se proporcionan siempre existe el usuario ‘Expertis’. Este usuario
permite realizar las primeras configuraciones de la aplicación a nivel general, por ejemplo, cambiar el tipo de
autenticación del sistema, gestionar nuevos usuarios, bases de datos de usuario, etc.
Para realizar el desarrollo y las pruebas con mayor comodidad y rapidez es conveniente dar de alta un
usuario nuevo con autenticación de Windows y cambiar el tipo de autenticación.
Para ello, ejecutar la consola de administración de Expertis y autenticarse con Expertis
Acudiríamos a la sección de Seguridad en la barra lateral de Opciones, y después en la opción de Usuarios:
188/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Daríamos al botón de Nuevo en la barra de herramientas y nos dejaría la pantalla de la siguiente manera:
Veríamos que nos agrega una nueva línea en el Grid de Usuarios y nos marca los siguientes campos a
rellenar en la sección de abajo. Rellenamos los datos como especificamos a continuación:
-
Pestaña Editar Usuario:
1. Usuario: Solmicro-Curso\Sol-Curso
2. Autenticación: WindowsAutentication
3. Idioma: Castellano
4. Grupo: Solmicro Admins
5. Base de Datos: xExpertisCurso
6. Menú: Curso 5.0
7. Empresa: Solmicro
8. Ver menú Contextual en Grids: V
9. Bloqueado: Vacío.
Y damos al botón Guardar de la barra de herramientas. Nos aseguramos de que ha sido correctamente
guardado el nuevo usuario y en la pestaña de Bases de Datos esté dado de alta la base de datos de
xExpertisCurso.
Como siguiente paso pasamos a cambiar el modo de autenticación de Expertis en
189/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Seleccionamos en Modo de Autenticación a WindowsAutentication
Guardar los cambios pendientes y comprobamos que se puede ejecutar la aplicación.
2.
Actualización / Inserción de Entidades
NOTA: Para ejecutar esta acción es necesario tener la DLL del proyecto de negocio compilada y actualizada.
Abrir la consola de administración de Expertis. Desde el menú Procesos -> Agregar Entidades
El cuadro de dialogo permite seleccionar la DLL que contiene las clases de negocio
190/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
3.
Actualización / Inserción de Programas
Para dar de alta un programa, abrir la consola de administración de Expertis. Desde la barra de
herramientas, Nuevo, Programa
Establecer las siguientes propiedades:

Título: Es el texto que aparece en los grupos de menú. El siguiente texto es opcional y es el
texto del formulario en sí

Alias (Opcional): Es un identificador del programa. Se utiliza cuando el programa se abre desde
otro programa utilizando el método OpenForm de la clase ExpertisApplication

Título en Pantalla: y es el texto del formulario en sí

Ensamblado: El nombre del archivo DLL.

Clase: Es el nombre completo de la clase dentro del espacio de nombres que define la raíz del
espacio de nombres del proyecto

Tipo: El valor por defecto es Windows.Forms. No modificar este valor por defecto

Imagen: Nombre de un recurso de la carpeta de recursos del directorio de instalación
191/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Para que el programa sea accesible para el usuario es necesario incluir dicho programa en el conjunto de
programas de un rol de Expertis. Para ello en el programa pinchar en la pestaña de Grupos, dar al botón de
Añadir de la barra de herramientas y nos aparecerá para seleccionar un rol del grupo de roles definidos en
Expertis.
El siguiente paso es habilitar un acceso al programa desde un elemento de menú. Para ello, ir a la sección
Menú, seleccionar el Menú 5.0.
192/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Agregamos en algún punto del menú el programa pinchando en la Opción Añadir de la sección de Lista de
Programas. Seleccionamos el programa. Aceptamos y damos a Guardar en la barra de herramientas.
193/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
4.
Actualización / Inserción de Informes
Para dar de alta un informe, abrir la consola de administración de Expertis. En la sección de Objetos nos
posicionamos en Informes.
Pulsamos el botón Añadir de la barra de herramientas del Manager y pasaremos a introducir los datos del
Nuevo Informe.
194/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Establecer las siguientes propiedades

Alias (opcional): Sirve para identificar el informe. Si el informe se vincula a un programa no se
utiliza, ya que la clase de mantenimiento que abre el informe sabe de antemano cual es el
informe que tiene que abrir, sin embargo, el alias es imprescindible si se va a utilizar la clase
Report para abrir el informe por código.
NOTA: no confundir este alias con el alias que se asigna al informe en diseño. El alias de diseño lo utiliza
internamente Crystal para construir el criterio de selección, para la formulación de parámetros, formulas, etc. El
alias de la base de datos solo será necesario en la creación de la instancia de la clase Report.



Descripción: Es el texto que aparece en la lista de informes del comando de impresión de la
clase de mantenimiento, y que también aparece como título en el formulario de la vista previa.
Fichero: Es el nombre del archivo diseñado con Crystal Reports, con extensión .rpt incluida. No
es necesario incluir la ruta completa.
Tipo (opcional): Es uno de los siguientes valores:
Numero
1
2
3
4
5
6
Tipo
CurrentRecord
RecordSet
SelectionCriteria
AssistantTable
FilterLess
Custom
Descripción
Registro Actual
ADO.NET – XML
Criterio de Selección
Tabla de Impresión Auxiliar
Sin Filtro
Personalizado
El tipo por defecto es el personalizado.



Impresora (Opcional): Nombre de la impresora que se utilizara por defecto para la impresión del
informe. Si no se especifica ninguna se utilizara la impresora predeterminada.
Enlace (Opcional): El nombre del campo que actúa como campo de enlace entre la tabla
principal del origen de datos del informe y la tabla xPrintingAuxiliarTable. Ver en Tipos de
informes, informes de tipo Impresión de tabla auxiliar.
Entidad (Opcional): Entidad que se utilizará en el filtrado horizontal.
Tanto si el informe se abre desde un programa como si se abre por código, este debe tener los permisos
necesarios para su ejecución. Los pasos a seguir para vincular un informe a un rol son exactamente los
mismos que los seguidos con los programas.
Finalmente, si el informe se va a abrir desde el comando de impresión de la barra de comandos de un
mantenimiento será necesario vincularlo a un programa. Si el informe se va a abrir únicamente por código no
es necesario. Si un informe ya está vinculado a un programa, también se puede utilizar de forma
personalizada y abrirlo por código.
5.
Actualización / Inserción de Enumerados
195/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
NOTA: Para ejecutar esta acción es necesario tener el compilado actualizado del proyecto de negocio donde están
definidos los enumerados.
Abrir la consola de administración de Expertis. Desde el menú Procesos -> Agregar Enumerados
El cuadro de dialogo permite seleccionar la DLL que contiene las definiciones de los enumerados. En el caso
del Estándar de Expertis, estos se encuentran en Expertis.Business.BusinessEnum.
Una vez agregados los Enumerados podemos establecer las descripciones y traducciones de los
enumerados en la pestaña de Traducciones de cada Enumerado.
196/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
6.
Actualización / Inserción de Procesos y Tareas
Abrir la consola de administración de Expertis. Desde el menú Programas -> Agregar Procesos y Tareas
El cuadro de dialogo permite seleccionar la DLL que queramos procesar sus procesos y tareas y con lo cual
siendo una dll de parte de negocio.
Una vez procesada la DLL tendremos disponibles sus procesos y tareas y podríamos ya llevar a cabo el
reemplazo de tareas, tarea antes y después, etc…
197/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
DataBase Comparer
Herramienta para desarrolladores para la comparación de estructuras de datos entre bases de datos.
Nos permitirá ver todas las diferencias a nivel estructural entre dos bases de datos a niveles, campo, tabla, vista,
función, procedimiento almacenado, índices, etc…
Asimismo de las diferencias detectadas nos permitirá generar scripts de dichas diferencias. Bien sea de manera global
o bien de manera particular por cada cambio.
Para ello, tendremos que establecer qué base de datos de origen y qué base de datos de destino vamos a comparar.
Lo tendremos en el menú conectar para establecer las dos bases de datos.
198/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En la ventana de conexión estableceremos todos los datos necesarios para llevar a cabo la conexión tanto con la B.D.
de Origen como con la B.D. de Destino.
199/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Una vez establecidas las conexiones daremos al botón de comparar e iremos viendo los pasos que va haciendo en la
comparación y esperaremos a que termine el proceso.
Terminado ya el proceso de comparación podremos ir viendo por secciones qué cambios nos ha detectado. Pudiendo
ver el script personalizado de cada cambio con el botón Ver Detalle. Asimismo podremos generar un script con todos
los cambios pulsando en Generar Fichero.
200/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
Expertis.Tools.Translator
Para la traducción de los textos, mensajes, etc.. contenidos dentro de expertis, se dispone de una herramienta muy
sencilla llamada: Expertis.Tools.Traslator. Con ello solo bastará con pasarle las dlls o carpeta para que nos coja el
contenido de dichas dlls para procesar todos los textos, mensajes, etc.. contenidos en esa dll. El proceso lo que hará
será volcar toda esa información en la base de datos de sistema a la que estamos conectados. Es por ello que con el
programa viene un fichero de configuración en el que editaremos y posicionaremos contra nuestra base de datos de
sistema.
Una vez procesado todo acudiremos en el manager a la sección de: Objetos -> Textos.
201/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
O bien: Objetos -> Mensajes.
Ahí procederemos a buscar los textos o mensajes correspondientes que sabemos de la aplicación que queremos
traducir y pasaríamos a insertar las traducciones en los idiomas que necesitemos.
Volver al Índice
Expertis.Tools.CRConnectionUpdater
Herramienta para actualizar la cadena de conexión de los informes de Crystal Reports.
Para entender la carga de proceso en la ejecución de un informe, veamos los pasos que sigue Crystal Reports en la
ejecución de un informe:
1.
2.
3.
Carga del propio motor de Crystal Reports.
Trabajo de reconexión del informe.
Trabajo dentro del propio informe que consiste en el procesamiento de los datos, ejecución de fórmulas,
agrupamiento, etc.
Si el origen de datos del informe es calculado, hay que tener en cuenta además la programación que proporciona los
datos al informe.
202/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Respecto al punto 2, cuando un informe de Crystal se ejecuta contra un servidor diferente al servidor contra el que fue
diseñado, el trabajo de reconexión que hace Crystal puede retardar la apertura del informe.
Esta herramienta permite actualizar los informes del cliente con una conexión válida para ese cliente en cuestión.
1.
Propiedades de conexión
Antes de lanzar el proceso es obligatorio especificar los parámetros de conexión.
La herramienta comprueba si es una conexión valida en el cliente, ya que el proceso de actualización obliga
a los informes a que se conecten con la nueva conexión, de lo contrario no es posible guardarlos con la
nueva configuración.
2.
Carpetas
Carpeta Origen donde están ubicados los informes que se quieren actualizar.
Carpeta de destino donde se dejaran los informes ya actualizados. Los informes originales no se modifican.
203/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Al elegir la carpeta de origen se nos cargará en la sección de informes todos los informes detectados en
dicho directorio y pudiendo elegir qué informes deseamos actualizar y cuáles no.
NOTA: Cuidado, porque si el directorio de origen coincide con el destino los informes se sobrescribirán.
3.
Actualizar
Lanza el proceso.
Dado que los informes deben volver a conectarse para ser guardados con la conexión nueva, el proceso
puede tardar, de manera que hay que pensar en el número de informes a actualizar, y el momento de lanzar
el proceso, tener en cuenta que se está haciendo un trabajo contra el servidor de SQL, y además, aunque no
consume mucha CPU de la máquina que lanza el proceso, existen momentos puntuales en los que sí.
Durante el proceso es posible que algunos informes den un error de conexión (no existe el origen de datos,
la vista no está actualizada, etc.). Estos casos hay que tratarlos de forma manual.
Después de terminar, la herramienta deja un fichero, CRConnectionUpdater.log, con un resumen del
proceso. Este fichero se abre con cualquier editor de texto.
204/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
Volver al Índice
FederatedSearch & SmartTags
Información de Búsqueda Federada
La Información de la conexión de la Búsqueda Federada se guarda en el fichero de Configuración del
Expertis.Host.
Nombre del Fichero: Expertis.Host.Exe.Config
Hay que comprobar la Línea:
<value>http://devsaas:8000/FederatedSearch/</value>
Nota: Importante Nombre de Servidor y Puerto.
El nombre que va antes del puerto es del servidor donde está instalado el servicio de Expertis.Host.
La composición normal del Fichero Expertis.Host.Config sería:
<?xml version="1.0"?>
<configuration>
<!-- configSections: applicationSettings, Expertis.Host.My.MySettings -->
<configSections>
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<section name="Expertis.Host.My.MySettings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false"/>
</sectionGroup>
</configSections>
<!-- Diagnostic: -->
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource"
switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
205/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch"
value="Information"/>
</switches>
<sharedListeners>
<add name="FileLog"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
initializeData="FileLogWriter"/>
<!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application
Event Log -->
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
<!-- Startup: -->
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
<!-- applicationSettings: Namespace: httpBaseNS -->
<applicationSettings>
<Expertis.Host.My.MySettings>
<setting name="httpBaseNS" serializeAs="String">
<value>http://devsaas:8000/FederatedSearch/</value>
</setting>
<setting name="ServiceName" serializeAs="String">
<value>ExpertisHost50</value>
</setting>
<setting name="DisplayName" serializeAs="String">
<value>Expertis Host 5.0</value>
</setting>
</Expertis.Host.My.MySettings>
</applicationSettings>
<!-- Servicios de web: -->
<system.serviceModel>
<!-- Bindings: WebHttpBinding -->
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<!-- Services -->
<services>
<!-- Service: ExpertisSearchFeed -->
<service behaviorConfiguration="ServiceBehavior"
name="Solmicro.Expertis.Host.SyndicationService.FederatedSearch.ExpertisSearchFeed">
<!-- Endpoint: webHttpBinding -->
<endpoint address="ExpertisFeed"
behaviorConfiguration="ExpertisFeedBehavior"
binding="webHttpBinding"
bindingConfiguration="WebHttpBinding"
contract="Solmicro.Expertis.Host.SyndicationService.FederatedSearch.ISearchFeed" />
</service>
<!-- Service: ExpertisSearchItem -->
<service behaviorConfiguration="ServiceBehavior"
name="Solmicro.Expertis.Host.SyndicationService.FederatedSearch.ExpertisSearchItem">
<!-- Endpoint: webHttpBinding -->
<endpoint address=""
behaviorConfiguration="ExpertisFeedBehavior"
binding="webHttpBinding"
contract="Solmicro.Expertis.Host.SyndicationService.FederatedSearch.ISearchItem" />
206/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
</service>
</services>
<!-- Behaviors -->
<behaviors>
<!-- ServiceBehaviors: ServiceBehavior -->
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="True"
policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<!-- EndpointBehaviors: ExpertisFeedBehavior -->
<endpointBehaviors>
<behavior name="ExpertisFeedBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Configuración de los Elementos a Buscar
Desde el Manager de Expertis, en la opción de menú: Objetos -> Entidades buscamos la entidad que deseemos.
En la entidad posicionada activamos la casilla de Búsqueda Federada. Junto con esta opción debemos configurar el
Campo correspondiente a Descripción. Éste campo sería sobre el que se hacen las búsquedas.
Autenticación de Expertis
Es Obligatorio el uso de Autenticación de Windows en Expertis cuando usemos el servicio de Búsqueda Federada. .
Fichero xslTemplate.xslt
En la Carpeta bin del Servidor (donde esté alojada el Expertis.Host) tendremos que tener alojado el fichero:
xslTemplate.xslt (Fichero Suministrado por Solmicro).
Servicio de Búsqueda de Windows 7
En Windows 7 podemos registrar servicios de Búsqueda. Esto se hace a través de unos ficheros con extensión .osdx.
Solmicro suministra un fichero osdx para instalar en el equipo deseado búsquedas para expertis.
Para ello solo hace falta hacer doble click sobre el fichero .osdx suministrado.
SMART TAGS
Con esta utilidad podemos obtener información de la base de datos de Expertis para ayudarnos, por ejemplo, a
redactar una carta. Imaginemos que estamos escribiendo un texto y necesitamos información de un cliente.
Instalamos el paquete de Smart Tag y luego lo activamos (si no se ha hecho automáticamente)
Volver al Índice
Doble Expertis Host en Servidor
Se necesita mínimo de FrameWork 2.0 instalado en la máquina
El Expertis.Host y su fichero Config que se adjuntan son de versión Expertis 5.0, pudiendo instalar anteriormente un
Expertis host 4.1 con su instalable o bien otro Host de Expertis 5.0 con su instalable.
El fichero Expertis.Host.Exe y su config los colocaremos donde esté el bin de expertis que queremos que sea de
remoting y que va a dar servicio.
207/208
Versión 1.4 / Mayo 2014
Manual Programación Expertis
En el fichero Config editaremos los siguientes datos dentro de la sección de ApplicationSettings y dando los nombres
que queramos y diferentes a los nombres de otros Expertis.Host que puedan estar instalados en el listado de
servicios del Windows donde estamos ejecutando.
<setting name="ServiceName" serializeAs="String">
<value>ExpertisHost50</value>
</setting>
<setting name="DisplayName" serializeAs="String">
<value>Expertis Host 5.0</value>
</setting>
Dando al ServiceName otro diferente al de por defecto y al DisplayName otro diferente al de por defecto.
Acudir al directorio de la máquina: C:\Windows\Microsoft.NET\Framework\v2.0.50727 y verificar que existe el
programa InstallUtil
Una vez confirmado arrancar el ms-dos de Windows y lo arrancamos, si fuera un sistema Windows con control UAC
ejecutamos con botón derecho encima -> Ejecutar como administrador, sino nos dará error en la instalación por
temas de permisos
En el ms-dos nos movemos al directorio anteriormente marcado:
C:\Windows\Microsoft.NET\Framework\v2.0.50727
y ejecutaríamos el siguiente comando:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil UBICACION_DEL_EJECUTABLE_DE_EXPERTIS.HOST.EXE.
Por ejemplo:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil C:\Expertis50\Bin\Expertis.Host.Exe
Debe estar localizado el Expertis.Host.Exe del paquete que distribuimos con el fichero config que también damos y
posicionar estos ficheros en el directorio Bin de Expertis que va a ser el remoting de la red.
Si deseáramos en algún momento desinstalar este Expertis.Host instalado de una manera especial bastaría con
volver a arrancar ms-dos y acudir a la utilidad de InstallUtil, como los pasos anteriormente marcados y ejecutar el
siguiente comando:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil /u UBICACION_DEL_EJECUTABLE_DE_EXPERTIS.HOST.EXE.
Por ejemplo:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil /u C:\Expertis50\Bin\Expertis.Host.Exe
Volver al Índice
208/208
Versión 1.4 / Mayo 2014

Documentos relacionados