Archive

Archive for the ‘Axapta’ Category

El estamento select de X++ comparado con el estamento select del ANSI SQL

Simple Select sobre una Tabla

static void OrderByWhereJob(Args _args)
{
  CustTable axCustTable;
  ;
  while
    select * from axCustTable
      order by axCustTable.AccountNum desc  
      where (!(axCustTable.Name like ‘*ant*’) 
            && axCustTable.Name like ‘T?e*’)
  {
     info(axCustTable.AccountNum + ”
          axCustTable.Name);
  }
}

  • En la clausula FROM se usa la variable Buffer de la tabla, no la tabla.
  • La clausula ORDER BY precede a la clausula SELECT.
  • Usamos ! para la negación lógica, no NOT.
  • & y || son los operadores lógicos, no AND y OR.
  • * y ? para comodines en la clausula LIKE, no % y _.

Clausula Join

static void OrderByWhereoinJob(Args _args)
{
  CustTable  axCustTable;
  SalesPool  axSalesPool;
  ;
  while
    select AccountName, Name  
      from axCustTable
        order by axCustTable.AccountNum desc  
        where (axCustTable.Name like ‘*ant*’) 
      join axSalesPool
        where axCustTable.salesPoolId ==
              axSalesPool.SalesPoolId
  {
     info(axCustTable.AccountNum + ”
          axCustTable.Name);
  }
}

  • Solo se pueden seleccionar columnas de la primera tabla nombrada en la clausula FROM (las columnas no deben de llevar cualificadores)
  • No usamos en el JOIN la palabra clave ON, simplemente lo hacemos con un WHERE.
  • El JOIN será por defecto INNER JOIN. El OUTER JOIN está también disponible.
  • La dirección del JOIN es LEFT. Se puede usar el RIGHT.
  • Un doble igual == es usado como comparador, y no un simple igual =.

Campos Calculados

static void SumJob(Args _args)
{
  PurchLine axPurchLine;
  ;
  while
    select sum(QtyOrdered)
      from axPurchLine
  {
    info(“Cantidad: ” +
          num2str(axPurchLine.QtyOrdered, 3,2,1,3);
  }

}

  • Debemos referirnos al campo calculado con el nombre de su columna, ya que este no puede llevar un Alias.

Otras diferencias

  • El estamento WHILE SELECT del SQL de X++, nos proporciona un cursor automático para las filas devueltas.
  • No disponemos de la palabra clave HAVING, que en ANSI SQL permite indicar un filtro a las filas devueltas con una clausula GROUP BY.
  • Los valores nulos (Null) no serán devueltos. Si un valor es nulo, la fila es ignorada( tanto por WHILE como por NEXT).
  • La clausula FROM es opcional cuando no indiquemos columnas (usemos *), o solo una tabla participa en en SELECT. En X++ es lo mismo decir estas dos sentencias:

    select * from Custtable;

    select CustTable

Categorías:Axapta

La potencia de los MenuItems en Axapta

Flores1 Los MunuItems constituyen una de las áreas principales del control de los permisos de usuarios de AXAPTA. Las propiedades ConfigurationKey y SecurityKey permiten determinar cuando un usuario o un grupo de usuarios podrán acceder a un ítem de un menú. Si un usuario no tiene los privilegios para ejecutar un MenuItem, este no será visible para el usuario. Su potencia radica en que solo los MenuItems accesibles al usuario serán los visibles. Con esto se consigue que cada usuario solo vea las partes de la aplicación que son relevantes para su trabajo.

Otra de las áreas principales del control de permisos de usuarios son las tablas, pero eso ya lo discutiremos en próximas entradas.

Un MenuItem puede ser usado para instanciar un objeto desde un menú, desde un formulario que llame a otro objeto o desde el propio código. Lo objetos que formen parte de la interfaz de un usuario deberían ser siempre llamados usando un MenuItem.

Podríamos llamar a los formularios y los informes desde el código sin usar un MenuItem, pero si utilizamos un MenuItem podemos estar seguros que los permisos de usuario serán verificados.

static void GenEjecutaMenuItem(Args _args)
{
  ;
  new menuFunction(menuItemDisplayStr  (MiFormMenuItem).MenuItemType::Dysplay).run();
}

En el ejemplo, el formulario MiForm es llamado usando el display MenuItem MiFormMenuItem. El formulario solo será cargado si el usuario tiene asignados privilegios suficientes para ello. El método run() ejecuta el MenuItem y pasa la clase Args como parámetro. Por ejemplo podríamos filtrar los datos en MiForm usando los valores de Args.

Otra manera de pasar parámetros desde el el MenuItem es usando sus propiedades EnumTypeParameter y EnumParameter.

Configurando un parámetro enumerado en un MenuItem es fácil reutilizar un objeto, tal como un formulario, para realizar distintos propósitos sin tener que crear formularios similares.

Categorías:Axapta, Programación

La clase Args()

En AXAPTA la System Class Args se usa para gestionar parámetros.

En toda clase que se piense ejecutar debe de existir un método main que recibe Args como argumento. El propósito de Args es transferir parámetros entre distintos objetos.

La clase Args define la comunicación entre los distintos objetos de la aplicación que se están ejecutando. El objeto invocante (caller) es el que inicializa la información del objeto Args, el cual es pasado como argumento al objeto que es invocado (called).

03-08-2008 15-51-32

static void main(Args _args)
{
  CustTable custTable;
  ;

  if (_args.dataset() == TableNum(CustTable))
  {
     custTable = _args.record();
     info(strfmt("Cliente seleccionado: %1",
    
custTable.name);
  }
}

Si creásemos una nueva clase con ese método main y un MenuItem que llame a dicha clase, podriamos arrastra desde el AOT ese MenuItem al nodo diseño de un formulario que se nutra de CustTable para crear un botón que al pulsarse mostraría el nombre del cliente seleccionado.

Categorías:Axapta, Programación

El particular estamento While Select de Axapta

whileX++ usa el estamento Select para obtener registros desde la base de datos.

El estamento Select se escribe desde código como cualquier otro estamento X++. Antes de usar un estamento select debemos declarar primero las variables para las tablas de la base de datos a las cuales hará referencia.

En X++ una variante del estamento while, while select, nos permite crear una iteración que nos vaya obteniendo todos los registros que cumplan un determinado criterio. El criterio de selección se define usando expresiones basadas en operadores y variables.

Hay que tener en cuenta que el tipo base str no puede usarse en las expresiones dado que su longitud es indefinida. Para los strings debemos usar los tipos de datos extendidos.

 
static void SelectStament(Args _args) {
 CustTable custTable;
 CustTrans custTrans;
 TransDate fromYear = SystemDateGet();
 ;
 while select custTable join custTrans
     where custTrans.accountNum == CustTable.accountNum &&
           custTrans.transDate  >= fromYear
     {
          info(strfrm("%1 %2",
               custTable.accountNum,
               custTrans.transDate);
     }
 }

Vemos en el ejemplo como usar el estamento select en X++. Las tablas CustTable y TransTable están relacionadas, los registros de CustTrans que tengan una fecha de transacción mayor o igual a la fecha del sistema que obtenemos con la llamada a la función SystemDateGet() serán devueltos.

Destacamos que se declara la variable que contendrá el valor que nos devuelve SystemDateGet(). Con ello conseguimos no utilizar directamente SystemDateGet() en el select, lo cual relentizaría el proceso pues la llamada a SytemDateGet() se ejecutaría en cada iteración.

El estamento select de X++ no es precisamente lo mismo que el estamento select del SQL Standard. Además X++ no implementa todas las palabras claves del SQL Standard. Si estamos acostumbrados a escribir estamentos SQL, debemos de familiarizarnos con el estamento select de X++.

En próximas entradas iremos publicando todas las palabras claves disponibles en X++ para el estamento select.

Categorías:Axapta

¡Hola Mundo!

Como no podía ser de otra forma os saludamos con el típico Job con el que los programadores ejecutamos cuando nos enfrentamos a un nuevo entorno.

static void HolaMundo(Args _args)
{
   ;
   Box::info("¡Hola Mundo!", "Bienvenidos a AxaptaMente");
}

Si lo ejecutamos obtendremos la típica ventana de bienvenida:

HolaMundo

Categorías:Axapta