miércoles, 21 de julio de 2010

Leer registros de un archivo excel desde MS Dynamics AX

Hola, bueno para que este codigo funcione, es necesario tener una clase llamada ExcelImportADO, la cual MS Dynamics AX no la tiene :S, pero les dejo el link donde la puedan bajar:
http://www.axaptapedia.com/Image:ExcelImportADO.zip
----------------------------------------------------------------------------
Counter cnTotal = 0;
ItemId itemId;
ItemName itemName;
AmountCur price;
Filename strFilename;
container conSheets;
ExcelImportADO xlImport;
;
strFilename = @"c:\import.xls"; // nombre del archivo
xlImport = new ExcelImportADO(strFilename);
try
{
// abre la primera hoja por default
if(!xlImport.openFile())
throw error(strfmt("Error opening Excel file «%1»", strFilename));
if(xlImport.getFieldsCount() < 3)
throw error(strfmt("Too few columns in the recordset:" +
" found %1, expected at least %2",
xlImport.getFieldsCount(), 3));
while(!xlImport.eof())
{
itemId = xlImport.getFieldValue(1);
itemName = xlImport.getFieldValue('ItemName');
price = xlImport.getFieldValue('ItemPrice', false);
// process data...
cnTotal++;
xlImport.moveNext();
}
xlImport.finalize();
Box::info(strfmt("%1 registros leidos", cnTotal));
}
catch(Exception::Error)
{
xlImport.finalize();
}
---------------------------------------------------------------------------
Este codigo me pareció muy interesante porque me ayudo a leer un excel donde se guardaban varios registros contables y luego con las clases respectivas registrarlas y contabilizarlas.
Saludos.

viernes, 18 de junio de 2010

Llamar un stored procedure mediante Dynamics AX

static void llamaStoredProcedure(Args _args)
{
LogInProperty Lp = new LogInProperty();
OdbcConnection myConnection;
Statement myStatement;
ResultSet myResult;
;

LP.setServer("NombreSrv");
LP.setDatabase("NombreBD");

try
{
myConnection = new OdbcConnection(LP);
}
catch
{
info("Check usuario/password.");
return;
}

myStatement = myConnection.createStatement();
//stored procedure
myResult = myStatement.executeQuery('EXEC [custtablesp]');
custtablesp --- contiene la sentencia --- select * from custtable
while (myResult.next())
{
print myResult.getString(1);
}
pause;
}

Saludos

lunes, 17 de mayo de 2010

Nuevo Editor X++

Hola, navegando por la web me encontre algunos pantallazos de como se verá el nuevo editor de X++ de MS Dynamics 6 (2011).
Vincent's Blog - Dynamics AX6 – The new X++ editor
Algunas nuevas características:
* Numeración de líneas y marcado
* Soporta multiples tipos de letras y estilos (los comentarios son en el tipo de
letra italic)
* Coloración de operadores(=,&&)

Saludos.

martes, 30 de marzo de 2010

Presentación Dynamics AX 2009

Hola, navegando por internet me encontre con esta presentación que me pareció realmente interesante, les dejo el link para que lo vean

http://www.microsoft.com/global/dynamics/en/us/RichMedia/demoHTML/demo-ax-capabilities.html

Saludos.

miércoles, 24 de marzo de 2010

Restringir empresas a usuarios

Hola, con este parrafo de codigo se puede restringir empresas a usuarios específicos, ya que como sabemos AX soporta multiempresas.
Para esto debemos ir al formulario SysDataAreaSelect y reprogramar el query en el metodo Run().

x++:

void run()
{
Query query;
queryBuildDatasource qbs;

qbs = dataArea_ds.query().datasourceTable(tableNum(dataArea));

if ( (CurUserID() == 'USU1') ) //check usuarios
{
/* Con esta sentencia añadimos a la query el siguiente rango */
/* El formulario solo mostrara para USU1 las empresas cuyo id sea igual a
EMP1 o EMP2*/
qbs.addRange(FieldNum(dataArea,id)).value('EMP1,EMP2');
}

super();
}
saludos.

martes, 9 de marzo de 2010

Modificando el menu contextual de un objeto

Hola, aqui muestro como como agregar un item en los menus que salen al hacer clic derecho en un objeto.
Un menu de este tipo aparece al llamar el metodo showContextMenu y su codigo default es:

public int showContextMenu(int MenuHandle)
{
int ret;

ret = super(MenuHandle);

return ret;
}

Bueno es cuestión de cambiar este código:

public int showContextMenu(int MenuHandle)
{
int ret;
PopupMenu menu;
int menuItem;
;

// Crea un nuevo menú utilizando el manejador recibido por parámetros
menu = PopupMenu::create(MenuHandle, this.hWnd());

// Añade un nuevo Menu Item al menú recién creado
menuItem = menu.insertItem("Mi nuevo menú");

// Abre el menú
ret = menu.draw();

// Comprueba el Menu Item que se ha pulsado
if (ret == menuItem)
{
// Aquí es donde se pone cualquier codigo
Box::info('Pon código aquí!');

return 0;
}

// Si ha pulsado alguno que no es el mío, se lo devuelvo al estándar
return ret;
}

Saludos.

jueves, 11 de febrero de 2010

¿Cómo importar clientes y proveedores en Microsoft Dynamics AX 2009?

Este artículo describe como importar data de clientes en Microsoft Dynamics AX 2009 desde una hoja de Excel, siendo los mismos pasos para importar a proveedores.


1. En el panel de navegación, clic en Administración – Periódico – Importación/Exportación de Datos – Hojas ayuda de estilo Excel – Asistente para planillas.

2. Clic Siguiente en el asistente para plantillas.

3. En el campo Nombre de archivo, ingrese el nombre del archivo que se va a usar y clic Siguiente.

4. En la parte de selección de tablas, agregar la tabla CustTable y presionar Siguiente.

    Nota: para proveedores agregar la tabla VendTable.

5. En la parte Generar lista de campo, clic Siguiente.

6. En la parte seleccionar campos, expandir Cliente, y clic seleccionar los campos que quieres importar. Los campos requeridos para una importación de la tabla CustTable son:

  • Cuenta del Cliente
  • Grupo del Cliente
  • Moneda
  • Lenguaje
  • Tipo de Libreta de Direcciones
  • Id de Libreta de direcciones
  • Dirección
  • Condiciones de pago
  • País/Region
  • ZIP/Codigo Postal
  • Estado
  • Pais
  • Busqueda de Nombre
  • Ciudad
  • Calle
  • País/Region
  • Estado
  • Compañía
7. Clic Siguiente

8. Seguir los pasos del asistente para completar la importación.

9. En el panel de navegación, clic Base-Configuración-Libreta de direcciones global-Parámetros.

10. Clic en el tab Secuencias Numéricas, y luego verificar que el número de secuencia es seleccionado para el libro de direcciones ID.

11. Buscar el archivo que se creó en el paso 3. La hoja de cálculo de Excel que contiene los datos que desea importar debe tener data.

12. Dejar vacio el campo de ID libreta de direcciones. Este campo es llenado cuando se importe la hoja Excel usando el numero de secuencia que se ha puesto en el paso 10.

13. En el panel de navegación, clic Administración-Periodico-Importacion/Exportacion de data-Definición de grupos.

14. Seleccionar el grupo de definición que se creó usando el asistente de Excel y clic en Configuración de tablas.

15. Hacer clic en el tab Conversión y agregar el siguiente código para importar la tabla Custtable.

      Str dirId;
      ;

     //Ver que la tabla Custtable no está asociada a una entrada
     If(!custTable.PartyId // custTable.PartyId == "")
      {
            //crear una entrada de las partes para el cliente
           dirId = DirParty:: createPartyFromCommon(custTable).PartyId;
          custTable.PartyId = dirId;
     }
     else
    {
          DirParty::updatePartyFromCommonInsert(custTable.PartyId,custTable);
    }

Para importar proveedores:
    
      Str dirId;
      ;
     //Ver que la tabla Vendtable no está asociada a una entrada
     if (!vendTable.PartyId // vendTable.PartyId == "")
    {
           //crear una entrada de las partes para el cliente
          dirId = DirParty::createPartyFromCommon(vendTable).PartyId;
          vendTable.PartyId = dirId;
   }
   else
  {
         DirParty::updatePartyFromCommonInsert(vendTable.PartyId,vendTable);
  }

16. Clic en Ejecutar Conversión y clic en el botón Compilar.

17. Clic en el tab Vista Preliminar, y ver que los campos sean los correctos seleccionados en la hoja de Excel, cerrar Configuración de tablas.

18. En Importacion/Exportacion de datos, seleccionar el grupo de definición creado y clic en Import.

19. En Importación de Excel, seleccionar la hoja que se creo en el paso 3 y clic Aceptar.

20. Verificar que los clientes han sido importados a la tabla Custtable y que han sido creados los registros correspondientes en la tabla DirPartyTable.

Saludos.

martes, 2 de febrero de 2010

Importar y exportar data en formato XML usando clases Axd

Hola, en este artículo se explicará cómo utilizar AXD-clases con el fin de importar los archivos XML en Dynamics AX y Data Dynamics AX a la exportación en archivos XML. Este metodo está orientado más a los desarrolladores debido por la forma de ejecución.
Otra cosa importante es que funciona tanto en dynamics AX 4.0 como en el 2009.

Partes de configuración
Para importar o exportar data desde dynamics AX en formato XML, es necesario que existan los siguientes objetos:
a) Tabla: donde se encuentre la data que será importada o exportada.
b) Clase AxBC: que es un contenedor para la tabla y es utilizado por AXD-Framework por la data por 
    defecto en los campos de la tabla y actualizar las tablas relacionadas.
c) Query: es usado por Axd-framework para la selección de data de la tabla o del archive XML.
d) Clase Axd: representa el documento XML y es usado por Axd-framework para importar o exportar data
    desde ó hacia Dynamics AX.

Todos los objetos mencionados excepto la tabla ó el query pueden ser generados automáticamente usando el asistente Axd.

En si lo que vamos hacder es crear una tabla MiTabla, insertamos algunos registros dentro de la tabla y generamos todos los objetos mencionados arriba usando el asistente Axd. Después, en la parte de ejecución, se exportará los registros de la tabla creada (MiTabla) dentro de un archivo XML e importaremos la data de un archivo XML dentro de la tabla creada (MiTabla).
1) Crear una nueva tabla (MiTabla)
Fig.1: Nueva tabla MiTabla
2) Usando el buscador de tablas, inserter 2 registros en la table MiTabla. Después estos registros serán exportados al archivo XML.

Fig. 2: Ruta de acceso al elemento de menú del navegador de la tabla
Fig. 3: Insertando 2 nuevos registros a la tabla creada
3) Creamos un nuevo query que sera usado para exportar la data de MiTabla al archivo XML e importar la data del archivo XML a la tabla MiTabla. El nombre del query debe empezar con Axd en orden de facilitar la distinción entre los queries estandars y los queries Axd.
Fig. 4: Nuevo query AxdMiTabla
4) Ir a herramientas – Herramientas de desarrollo - Asistente – y seleccionar Axd Asistente.
Fig. 5: Ruta de acceso al elemento de menú Asistente Axd.

5) El asistente de Axd empezará. En la página de bienvenida, hacer clic en el botón siguiente.

Fig. 6: Ventana de bienvenida del asistente Axd.


6) Seleccionar el query AxdMiTabla creado en el paso 3 y dar clic en el boton continuar.

Fig. 7: Ventana de selección del query

7) Seleccionamos todas las acciones para poder importar y exportar varios registros del documento.Especifique una descripción del documento en el campo de etiqueta y haga clic en el botón Siguiente.

Fig. 8: Selección de etiqueta y métodos

8) Clic en generar clases AxBC en la parte Generación AxBC.
Fig. 9: Ventana para generar los cúdigos Axd.

9) Después de haber realizado todos los pasos anteriores, darclic en Generar.

Fig. 10: Ventana de resumen de los objetos que se van a generar


Fig. 11: Ventana final del Asistente

10) Si nos fijamos en la ventana de salida del compilador, muy probablemente encontrará varios errores en
       la clase AxMiTabla.

Fig. 12: Ventana del compilador después de que el asistente Axd se ha completado.

11) Para arreglar los errors que ha botado el compilador necesitamos ir al proyecto creado
      AxdMiTabla, borrar los 2 metodos cacheObject y cacheRecordRecord de la clase AxdMitabla y
      compilar el proyecto entero.
Fig. 13: Proyecto AxdMitabla generado por el asistente Axd.

Fig. 14: Borrando los métodos fallidos cacheObject y cacheRecordRecord.

Fig. 15: Compilando el proyecto entero
 
Ahora todos los objetos necesarios han sido creados por axd Asistente y estamos listos para exportar e importar los datos en formato XML.


Parte de ejecución:

1) Exportar data desde la table MiTabla al archive XML usando la clase AxdMiTabla
    El job exporta los registros de la tabla MiTabla en XML archivo C: \ Temp \ AxdMiTabla_Salida.xml.
    Por favor, asegúrese de que el directorio C: \ Temp existe antes de ejecutar este job.


    static void exportarAxdMiTabla(Args _args)
   {
        MiTabla miTabla;
        AxdMiTabla axdMiTabla = AxdBase::newClassId(classnum(AxdMiTabla));
        AifEntityKeyList aifEntiryKeyList = new AifEntityKeyList();
        AifDocumentXml aifDocumentXml;
        XmlDocument xmlDocument;

        // convertir un registro a la clave de entidad
        AifEntityKey getEntityKey(Common _record)
        {
              AifEntityKey aifEntityKey = AifEntityKey::construct();
              List keyFields = SysDictTable::getUniqueIndexFields(_record.TableId);
              Map keyMap = SysDictTable::mapFieldIds2Values(keyFields,_record);
              ;

              aifEntityKey.parmKeyDataMap(keyMap);
              aifEntityKey.parmTableId(_record.TableId);
              aifEntityKey.parmRecId(_record.RecId);
              return aifEntityKey;
         }
         ;
         // añadir los registros destinados a la exportación en la entidad lista de claves
         while select miTabla
         {
              aifEntiryKeyList.addEntityKey(getEntityKey(miTabla));
         }

         // creando el documento XML conteniendo los registros
         aifDocumentXml = axdMiTabla.readList(aifEntiryKeyList, null, new AifEndpointActionPolicyInfo(),
                                                                        new AifConstraintListCollection(), connull());
         xmlDocument = XMLDocument::newXML(aifDocumentXML);

         // guardando el documento XML en el disco
         xmlDocument.save('C:\\Temp\\AxdMiTabla_salida.xml');
   }
   
    Y el resultado de correr este método sería:

2) Importar data de un archivo XML a la tabla MiTabla usando la lcase AxdMiTabla.

    Para probar este metodo puedes usar el archivo XML generado AxdMitabla_Salida.xml y renombrarlo 
    como axdMitabla_Entrada.xml.

    static void importarAxdMiTabla(Args _args)
    {
         AxdMiTabla axdMiTabla;
         AifDocumentXml xml;
         XmlDocument xmlDocument;
         ;

         // crear un documento XML de un archivo
         xmlDocument = XmlDocument::newFile("C:\\Temp\\axdMiTabla_Entrada.xml");
         xml = xmlDocument.xml();
         axdMiTabla = AxdBase::newClassId(classnum(AxdMiTabla));

         // insertar datos desde el docuemnto XML dentro de Dynamics AX
         axdMiTabla.createList(xml, new AifEndpointActionPolicyInfo(), new AifConstraintListCollection());
}

Saludos.

lunes, 1 de febrero de 2010

Abrir pagina web desde desde AX

Hola, este sencillo codigo nos permite abrir cualquier pagina web desde AX.

infoLog.urlLookup('http://www.blogger.com');

Saludos.

Acceso a AX para ocupar solamente una licencia

Hola, con estas lineas de codigo se puede controlar el acceso a AX para ocupar solo una licencia por usuario y no permitirle conectarse más de una vez.


Hay que buscar en la clase "Info" el método "startupPost" y asignarle el código siguiente:
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);
   }

}

Bueno este codigo ya lo he probado con ax 4 y ax 2009 y funciona bien.
Este código como verán es muy simple, pero dejo a imaginación del lector todo lo que se puede hacer, por ejemplo yo hecho que el ax diferencie usuarios por empresas y cada empresa tenga un numero limitado de licencias.

Saludos.