miércoles, 1 de septiembre de 2010

Mantener Personalizaciones de Usuarios al Cambiar Dominio

Hola, en ocasiones se debe copiar o restaurar Dynamics Ax en otro dominio y tenemos problemas cuando existe una lista grande de usuarios y se debe volver a importar esta, perdiendo la personalizacion de cada usuario.
Para evitar esto, se debe cambiar los campos NETWORKDOMAIN y SID en la tabla USERINFO de la BD de Dynamics AX, para saber el nuevo SID de la lista de usuarios podemos usar lo sgte:

1.- Abrimos un block de notas
2.- Copiamos este codigo:

Option Explicit
Dim objExcel, i, strCompu, objWMIUserAccount , colUserAccount , objUserAccount
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.Workbooks.Add
i = 1
strCompu = "."
Set objWMIUserAccount = GetObject _
("winmgmts:\\" & strCompu & "\root\cimv2")
Set colUserAccount = objWMIUserAccount.ExecQuery _
("Select * From Win32_UserAccount")
For Each objUserAccount in colUserAccount
objExcel.Cells(i, 1) = objUserAccount.Name
objExcel.Cells(i, 2) = objUserAccount.SID
i = i + 1
Next

3.- Guardamos el archivo como *.vbs (ej. miSID.vbs)
4.- Damos doble click al archivo creado y nos muestra la información en un archivo excel.

//------------------------------------------------------------------------------\\

Otra forma sería creando el sgte. job dentro del AX:

static void TestSID(Args _args)
{
sid userSid;
Microsoft.Dynamics.IntegrationFramework.Util util;
userinfo userinfo;
str usuarioX;
str dominioX;
;
dominioX = "dominio";
while select userinfo
{
usuarioX = userinfo.networkAlias; // Usuario
util = new Microsoft.Dynamics.IntegrationFramework.Util();
userSid = util.GetUserSid(dominioX, usuarioX);
CodeAccessPermission::revertAssert();

info(usuarioX);
info(userSid);
}
}

Saludos.

lunes, 16 de agosto de 2010

Ventanas dentro del Workspace

A partir de la version 2009 las ventanas se abren fuera del workspace, para algunos usuarios esto les parece molestoso. Con este codigo podremos volver al estilo de las anteriores versiones:
* Agregar el siguiente codigo en el método Init de la clase SysSetupFormRun

public void init()
{
//CODIGO AGREGADO
if(this.form().design().windowType()==FormWindowType::Standard)
this.form().design().windowType(FormWindowType::Workspace);
//CODIGO AGREGADO

super();
SysSecurityFormSetup::loadSecurity(this);
this.dimensionFieldCtrls();
this.inventStorageDimFieldCtrls();

if (this.isWorkflowEnabled())
{
workflowControls = SysWorkflowFormControls::construct(this);
workflowControls.initControls();
}
}

Saludos.

viernes, 13 de agosto de 2010

Utilizar campo create/modifiedDateTime de las tablas

Hola, mediante este código podremos utilizar los campos create/modifiedDateTime de las tablas.

static void CapturaCreatedDateTime(Args _args)
{
PurchTable ptable;
purchid id;
;
id = "000007";
Select ptable Where ptable.PurchId == id;

print DateTimeUtil::date(purchtable::find(ptable.PurchId).createdDateTime);
pause;
}

Saludos.

martes, 10 de agosto de 2010

Ejecutar directamente sentencias T-SQL desde Dynamics AX

Hola, bueno no es muy recomendable hacer esto, pero es un camino más que nos podria servir para resolver algún problema:

Vamos a crear un metodo en la clase Global:
server static void DAXExecuteSQL(str _sql)
{
str ddl = '';
SqlStatementExecutePermission ssep;
Statement statement;
Connection connection;
;

ddl = _sql;

connection = new Connection();
connection.ttsbegin();

ssep = new SqlStatementExecutePermission(ddl);
ssep.assert();
statement = connection.createStatement(ResultSetType::Dynamic, ResultSetConcurrency::Updatable);

// BP deviation documented
statement.executeUpdate(ddl);
connection.ttscommit();
}

Luego para utilizar este metodo, tenemos que poner esto:
DAXExecuteSQL('Cualquier Consulta T-SQL');

Saludos.

Ocultar mensaje de ajuste de reporte

Hola, me imagino que se han topado con esta clase de mensaje: "Informe se ha definido en xx por ciento para ajustarlo a la página". Bueno esto es normal cuando el reporte contiene mucha informacion y se tiene que ajustar al reporte.
Si queremos evitar este mensaje simplemente tendremos que poner este codigo en el init del reporte.
element.printJobSettings().SuppressScalingMessage(true);

Saludos.

lunes, 9 de agosto de 2010

Envío de varios parámetros a la vez mediante args

Hola con este pequeño desarrollo, se podrá enviar varios parámetros de distintos tipos a un reporte ó formulario, mediante args y parmobject, para esta demostración enviaré dos parámetros a un reporte para que haga un filtro.

Paso1: creamos la clase “ParametrosReporte”, que recibirá todos los parámetros que necesitamos.
class ParametrosReporte
{
str para1;
str para2;
}
public str parm1( str _para1 = para1 )
{
;
if (!prmisdefault( _para1 ))
{
para1 = _para1;
}
return para1;
}
public str parm2( str _para2 = para2 )
{
;
if (!prmisdefault( _para2 ))
{
para2 = _para2;
}
return para2;
}

Paso 2: la mayoría de veces se tendrá que poner este código en un botón, pero por motivo de explicación lo he realizado en un job.
static void ParametrosVarios(Args _args)
{
Args args = new Args();
ReportRun reportRun;
ParametrosReporte parametrosReporte = new ParametrosReporte();
;
parametrosReporte.parm1( "1101" ); //código de cliente
parametrosReporte.parm2( "1102" ); //código de cliente
args.parmObject( parametrosReporte );
args.name(reportstr(Parametros));
reportRun = classFactory.reportRunClass(args);
reportRun.init();
reportrun.run();
}

Paso 3: creamos el reporte “Parametros”, con el datasource custtable y agregamos algunos campos al diseño del formulario. Luego en el método init() ponemos:
public void init()
{
ParametrosReporte parametrosReporte;
;
super();
if( element.args().parmObject() )
{
parametrosReporte = element.args().parmObject(); //recuperamos parametros
}
element.query().dataSourceName('CustTable').addRange(fieldnum(Custtable, accountNum)).value(parametrosReporte.parm1() + ".." +parametrosReporte.parm2());
this.query().userUpdate(false);
}

Saludos.

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.

Unir palabra con salto de linea

Hola, este metodito sirve para unir palabras en una sola línea cuando hay saltos de línea (dando ENTER después de cada palabra).
Esto nos podría servir en los formularios o reportes para presentar un valor guardado en la base de datos con varios saltos de línea en una sola línea (Como el dato Dirección de Proveedores o Clientes que permite dar un enter en el campo).
 
static void UnirPalabraConEspacios(Args _args)


{

    str palabraVertical;
    int TotalLetras;
    int contaposicion;
    str letra;
    ;

    palabraVertical = "Palabra\n";
    palabraVertical += "Unida\n";
    palabraVertical += "Con\n";
    palabraVertical += "Saltos de Línea";

    TotalLetras = strlen(palabraVertical); //Lee la cantidad de caracteres de una palabra

    for (contaposicion = 1; contaposicion <= TotalLetras; contaposicion++) //Se hace un for con el tamaño    
                                                                                                                 // total de las letras en la palabra
                                                                                                                 // con ENTER
   {

       letra += substr(palabraVertical,contaposicion,1); //Va armando nuevamente "POR LETRA" toda la
                                                                                 //palabra
   }

   print letra; //Imprime la palabra completa en una sola línea
   pause;

}

sábado, 30 de enero de 2010

Seleccionar Data de Varias Compañias mediante queries

Hola, tambien se puede seleccionar data de varias compañias mediante queries. Les dejo un ejemplo x++:

static void Acceso_CrossCompany_Query(Args _args)
{

    Query query = new Query();

    QueryBuildDataSource qbds = query.addDataSource(tableNum(InventTable));

    QueryRun queryRun;

    InventTable inventTable;
;

    qbds.addRange(fieldNum(InventTable, ItemId)).value(queryValue("1000001"));

    query.allowCrossCompany(true);//permitir cruce

    query.addCompanyRange("dm0");//compañia

   query.addCompanyRange("dm1");//compañia

   queryRun = new QueryRun(query);

   while (queryRun.next())

  {

      inventTable = queryRun.get(tableNum(InventTable));

     print inventTable.ItemId, " / ", inventTable.dataAreaId;

  }

   pause;

}
Saludos

Seleccionar Data de Varias Compañias

Hola, aca un fragmento de codigo que es util si es que desean seleccionar data de varias compañias a la vez.
static void getTotalLineAmount(Args _args)

{

        SalesLine salesLine;

       container companies = ['dmo', 'dm2', 'dm3']; // compañias
       ;

       select crossCompany : companies sum(LineAmount) from salesLine;
       info (num2str(salesLine.LineAmount,0,2,1,2));

}

Dynamics AX y .Net

Hola, aqui les paso un ejemplo de como llenar un grid de un formulario, trayendo data desde Dynamics AX mediante Business Conector .Net con lenguaje C - Sharp (C#)

1.- Lo primero es iniciar Visual Studio 2005/2008 y crear un nuevo

proyecto(WindowsFormsApplication).

2.- Nos vamos al explorador de soluciones y damos click derecho al

proyecto creado y seleccionamos agregar referencia(add reference),

luego aparece una ventana y nos vamos a la pestaña "Browser" y

buscamos la direccion del BusinnesConector .Net (por default la

direccion es: C:\Archivos de programa\Microsoft Dynamics AX\50

\Client\Bin)

3.- Al formulario arrastramos un datagridview, un boton y un label.

4.- Al boton le damos doble click y ponemos el siguiente codigo:

___4.1 Antes de empezar damos una referencia:

using Microsoft.Dynamics.BusinessConnectorNet;
private void btnAxDataAccess_Click(object sender, EventArgs e)

{

/*Objetos Business Conector .Net*/

Axapta ax;

AxaptaRecord axRecord;



/*Nombre de la tabla de la consulta*/

string strTable = "VendTable";



/*Campos de la tabla VendTable que va a llamar AxRecord.get_Field*/

string strVendAccountNumField = "AccountNum";

string strVendNameField = "Name";

string strVendPhoneField = "Phone";



/*Variables de salida para las llamadas de AxRecord.get_Field */

object vendAccNum, vendName, vendPhone;



/*Consulta a la tabla*/

string strQuery = "select * from %1";



try

{

/*Se inicia acceso a Microsoft Dynamics*/

ax = new Axapta();

/*cot es nombre de la empresa con la cual se va trabajar*/

ax.Logon("cot", null, null, null);



/*Se crea un objeto AxaptaRecord para la tabla VentTable*/

axRecord = ax.CreateAxaptaRecord(strTable);



/*Ejecutamos la consulta de la tabla*/

axRecord.ExecuteStmt(strQuery);



/*Se crea un DataTable*/

/*el metodo CreateVendorDataTable() se explica en el punto

5*/

DataTable dt = CreateVendorDataTable();

DataRow row;



/*Comenzamos un bucle de los registros*/

while (axRecord.Found)

{

/*Recuperando el registro de los datos de los campos especificados*/

vendName = axRecord.get_Field(strVendNameField);

vendAccNum = axRecord.get_Field(strVendAccountNumField);

vendPhone = axRecord.get_Field(strVendPhoneField);



/*llenamos filas del datatable*/

row = dt.NewRow();

row["Name"] = vendName.ToString();

row["AccNum"] = vendAccNum.ToString();

row["Phone"]=vendPhone.ToString();

dt.Rows.Add(row);



/*Avanza al siguiente registro*/

axRecord.Next();

}

/*Desechamos el objeto axRecord*/

axRecord.Dispose();



/*Termina acceso de Microsoft Dynamics*/

ax.Logoff();



/*Llenamos al dataGridView con el dataTable*/

dataGridView1.DataSource = dt;

lblResultado.Text = "Hay " + (dataGridView1.RowCount - 1) + " Registros";

}

catch (Exception ex)

{

lblResultado.Text = "Error encontrado {0}: " + ex.Message;

}

}
5.- Creamos el metodo CreateVendorDataTable(), que sirve para crear

las columnas del dataTable :
public DataTable CreateVendorDataTable()

{

DataTable dt = new DataTable();



dt = new DataTable();



DataColumn vendorNameColumn;

vendorNameColumn = new DataColumn("Name");

vendorNameColumn.DataType = Type.GetType("System.String");

dt.Columns.Add(vendorNameColumn);



DataColumn vendorAccNumColumn;

vendorAccNumColumn = new DataColumn("AccNum");

vendorAccNumColumn.DataType = Type.GetType("System.String");

dt.Columns.Add(vendorAccNumColumn);



DataColumn vendorPhoneColumn;

vendorPhoneColumn = new DataColumn("Phone");

vendorPhoneColumn.DataType = Type.GetType("System.String");

dt.Columns.Add(vendorPhoneColumn);
return dt;

}
6.- Presionamos F5 para ver los resultados.
Saludos