Actualizar InventSum desde InventTrans

1 Estrella2 Estrella3 Estrella4 Estrella5 Estrella (Sin calificar)
Cargando…
Escrito por René Roca el . Posteado en X++

En algunas ocasiones, necesitamos volver a calcular los valores de la inventsum, a partir de los datos existentes en la inventtrans, para ello tenemos una forma muy sencilla para realizarlo sobre un artículo, utilizando la clase InventSumReCalcItem

InventSumReCalcItem InventSumReCalcItem;
;
InventSumReCalcItem = new InventSumReCalcItem("Código de artículo");
InventSumReCalcItem.updateNow();

Agrupaciones en Query

1 Estrella2 Estrella3 Estrella4 Estrella5 Estrella (Sin calificar)
Cargando…
Escrito por René Roca el . Posteado en X++

En algunas ocasiones nos encontramos que necesitamos utilizar el objeto Query, para realizar una consulta SQL con agrupaciones, a continuación os pongo un ejemplo de como utilizar este objeto.

Imaginemos que queremos realizar la siguiente consulta medita un objeto Query:

SELECT custaccount,itemid, SUM(lineamount)AS lineamount
FROM salesline
GROUP BY custaccount, itemid
HAVING SUM(lineamount) > 0
ORDER BY lineamount DESC

Para ello utilizaremos la siguiente sintaxis:

Queryrun 	queryRun;
Query 		query = new Query();
SalesLine 	salesLine;
;
 
query.addDataSource(tablenum(SalesLine));
query.dataSourceTable(tablenum(SalesLine)).orderMode(OrderMode::GroupBy);       			//Indicamos que vamos a utilizar la opción de agrupación
query.dataSourceTable(tablenum(SalesLine)).fields().clearFieldList();                       //Borramos los campos de inicialización del select
 
query.dataSourceTable(tablenum(SalesLine)).fields().addField(fieldnum(SalesLine, LineAmount), SelectionField::Sum);                //Indicamos que el campo LineAmount se tiene que sumar
 
query.dataSourceTable(tablenum(SalesLine)).fields().addField(fieldnum(SalesLine, CustAccount), SelectionField::Database);
 
query.dataSourceTable(tablenum(SalesLine)).fields().addField(fieldnum(SalesLine, ItemId), SelectionField::Database);
query.dataSourceTable(tablenum(SalesLine)).sortClear();                                     //Borramos los criterios de ordenación
 
query.dataSourceTable(tablenum(SalesLine)).addSortField(fieldnum(SalesLine,LineAmount), SortOrder::Descending);
 
query.dataSourceTable(tablenum(SalesLine)).addSortField(fieldnum(SalesLine,CustAccount), SortOrder::Descending);
 
query.dataSourceTable(tablenum(SalesLine)).addSortField(fieldnum(SalesLine,ItemId), SortOrder::Ascending);
query.dataSourceTable(tablenum(SalesLine)).addRange(fieldnum(SalesLine,LineAmount)).value('> 0');
 
queryRun = new QueryRun(query);

Depurar Report (SSRS) Dynamics AX con Visual Studio 2008

1 Estrella2 Estrella3 Estrella4 Estrella5 Estrella (Sin calificar)
Cargando…
Escrito por René Roca el . Posteado en X++

En Dynamics AX  los informes de Reporting Services, permiten insertar una Lógica de Negocios. Esta lógica del negocio puede ser llamadas a código X + +  del AOT o a código C # directamente en el informe de SSRS.

En el caso que nos interese poder depurar el código C # cuando sea necesario. Podemos utilizar el depurador de Visual Studio 2008 integrado sin embargo es necesario seguir ciertos pasos:

Necesitamos una máquina, donde estén instalados los siguientes componentes:

  • Microsoft Dynamics AX 2009 Cliente
  • Microsoft Dynamics AX 2009 Reporting Tools
  • Microsoft SQL Server 2005 o 2008 Reporting Services
  • Microsoft Dynamics AX 2009 Extensiones de informes
  • Microsoft Visual Studio 2008

Nota:
En el ejemplo que proponemos, utilizaremos un informe que se base en Microsoft SQL Server Analysis Services (SSAS), para extraer losdatos. Por lo tanto, necesitamos tener los cubos defecto por defecto de Dynamics AX

A continuación detallamos los pasos que tenemos que seguir para depurar el siguiente informe Cust.CashInflowvsCashOutflow:

Nota: Es importante para implementar la solución en Visual Studio, incluso si los informes de SSRS ya se habían implementado y nohan sido modificados!)

  1. Inicie el cliente de Dynamics AX, abra la ventana de AOT e ir al AOT \ bibliotecas de informes
  2. Haga clic con el botón derecho del ratón en la biblioteca informe de Clientes (CUST) y seleccione Editar en Visual Studio en el menú contextual
  3. Espere hasta que el IDE de Visual Studio arranque totalmente.
  4. Asegúrese de que la configuración activa de la solución está en depuración (para comprobar la configuración de Activa, vamosr a Build – Configuration Manager…)
  5. Volvemos a generar la solución completa mediante la selección Build – Build Solution
  6. Implementar la solución de Microsoft SQL Server Reporting Services, seleccionamos Build – Deploy Solution

Nota: Es importante implementar la solución en Visual Studio, incluso si los informes de SSRS ya se habían implementado y no han sido modificados!)

  • Abrimos el informe CashInflowvsCashOutflow desde la ventana del Explorador de soluciones de Visual Studio
  • En la ventana del Explorador de Informe desplegamos los métodos del nodo de datos y hacemos doble click en GetDefaultCompany
  • Colocamos un punto de interrupción en cualquier línea de código
  • Iniciamos Internet Explorer y vamos a la pagina del Administrador de informes de Reporting Services
  • Hacemos clic en la carpeta Dynamics
  • Volvemos a Visual Studio y seleccionamos Tools – Attach to Process desde el menú
  • Nos aseguraremos que las opciones how processes from all users y Show processes in all sessions están activadas
  • El siguiente paso es diferente según la versión de Microsoft SQL Server Reporting Services:
    • Si estamos utilizando Microsoft SQL Server 2008 Reporting Services:
      En la lista de los procesos seleccionaremos reportingservicesservice.exe
    • Si estamos utilizando Microsoft SQL Server 2005 Reporting Services:
      En la lista de procesos seleccionaremos w3wp.exe
  • Volvemos a la página del Administrador de informes de Reporting Services, en el navegador Web y ejecutamos el informe Cust.CashInflowvsCashOutflow.FullPage
  • Acto seguido, veremos como el proceso se detiene en el punto de interrupción que hemos puesto en Visual Studio.

 

Nota:
En Windows Vista y Windows Server 2008 no tenemos que asegurar que ejecutamos Visual Studio con privilegios de Administrador

Agregar funcionalidad Ir a la tabla principal

1 Estrella2 Estrella3 Estrella4 Estrella5 Estrella (Sin calificar)
Cargando…
Escrito por René Roca el . Posteado en X++

En Axapta, existe la funcionalidad Ir a la tabla principal, cuando nos situamos encima de un registro el cual es el código de otra tabla, como por ejemplo el campo código de cliente, este registro nos identifica en la tabla de Clientes, a un cliente.

En ocasiones, la funcionalidad de ir a la tabla principal no está activa si por ejemplo estamos usando un campo que no está vinculado con una tabla, como podría ser al crear un desplegable de filtro en un formulario, que nos muestre los códigos de cliente.

Si queremos habilitar la funcionalidad de Ir a la tabla principal en estos casos, tendremos que sobre escribir el método JumpRef() del desplegable o campo que estemos utilizando.

A continuación os pongo un ejemplo de cómo quedaría el método modificado para acceder a la tabla de clientes:

public void jumpRef()
{
	EmplTable 		emplTable;
	Args 			args;
	MenuFunction 	menuFunction;
	;
 
	emplTable = EmplTable::find(this.text());
 
	if (emplTable)
	{
		args = new Args();
		args.caller(element);
		args.record(emplTable);
 
		//Llamamos al formulario de clientes
		menuFunction = new MenuFunction(menuitemdisplaystr(EmplTable), MenuItemType::Display);
		menuFunction.run(args);
	}
}

Acceso Axapta una instancia por usuario

1 Estrella2 Estrella3 Estrella4 Estrella5 Estrella (Sin calificar)
Cargando…
Escrito por René Roca el . Posteado en X++

Si deseamos controlar en acceso por usuario en Dynamics Ax y que un usuario solo tenga abierta una sesión y una licencia, impidiendo que un usuario tenga dos instancias de Dynamics AX abiertas a la vez, podemos realizar la siguiente modificación en la clase Info, método StartupPost

void startupPost()
{
	int 				cuentaSesionActiva = 0;
	UserId 				IdUsuario;
	SysClientSessions 	_SysClientSessions;
	;
	 
	IdUsuario = curuserid(); 	// Capturamos el id del usuario
 
	while select RecId from _SysClientSessions order by login_time desc
		  where _SysClientSessions.userId == curuserid() && _SysClientSessions.Status == 1
	{
		if (_SysClientSessions.RecId)
			cuentaSesionActiva = cuentaSesionActiva + 1; //Acumula el número de logins activos del usuario en el sistema
		else
			cuentaSesionActiva = 0;
	}
	 
	if (cuentaSesionActiva > 1)
	{
		infolog.shutDown(false);
	} 
}