jueves, 23 de junio de 2016

Crear documentos de MS Word desde AX 2012 R3

Buenas tardes a todos, hace tiempo que no publico nada en el blog por motivos de falta de tiempo, los que hayan realizado una migración de algún ERP me entenderán....

Nuestro objetivo de hoy es crear documentos de Word directamente desde AX 2012. Para ello utilizaremos una plantilla de Word previamente diseñada, que después utilizaremos en nuestro código x++.

Crearemos nuestra plantilla, para ello insertaremos los marcadores de posición en el lugar deseado, según veis en la imagen:



Después ejecutaremos el siguiente job para enviar los datos a los marcadores, así como también rellenar la tabla que contendrá la lineas del pedido.
    
// ------------------------------------------------(c) 2016 Last
// System: Microsoft Dynamics AX 2013 R3 CU9
// Description:     JOB de ejemplo para crear documentos de MS Word
// Pre-conditions:  Imprimir a Word el Pedido nº 001461
// Creator:         Juan Ruiz Romero
// Creation date:   23.06.16
// -----------------------------------------------------------------
// -----------------------------------------------------------------

static void JR_CreateWordDocument(Args _args)
{
    COM word, documents, document, bookmarks, bookmark, tables, table, rows, row, cells, cell, range;
    SalesTable  _salesTable;
    SalesLine   _salesLine;    
    int i;

    // Funcion Auxiliar para procesar los marcadores
    void processBookmark(str _name, anytype _value) {
        if (!bookmarks.exists(_name)) {
            info("El marcador no existe");
            return;
        }
        bookmark = bookmarks.item(_name);
        range = bookmark.range();
        switch (typeOf(_value)) {
            case Types::Real:
                range.insertAfter( num2str(_value, 4, 2, 2, 1) );
                break;
            case Types::Date:
                range.insertAfter(date2str(_value, 123, dateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4));
                break;
            case Types::String:
                range.insertAfter(_value); 
                break;
            default:
                range.insertAfter(_value); 
                break;
        }
    } //  End Funcion Auxiliar

    #define.WordApp('Word.Application')
    #define.template(@'C:\template.dotx')
    
    try {
        word = new COM(#WordApp);
    } catch (Exception::Internal) {
        if (word == null)
            throw error('Microsoft Word is not installed');
    }
    
    documents = word.documents(); document = documents.add(#template); bookmarks = document.bookmarks();    
    _salesTable = SalesTable::find('001461'); // Pedido de ejemplo
    
    // Enviar los marcadores de la cabecera del pedido
    processBookmark('SalesId', _salesTable.SalesId);
    processBookmark('CustName', _salesTable.customerName()); processBookmark('Address', _salesTable.deliveryAddressing());     
    processBookmark('CustAccount', _salesTable.CustAccount); processBookmark('DeliveryDate', _salesTable.DeliveryDate);
    processBookmark('PurchOrderFormNum', _salesTable.PurchOrderFormNum); processBookmark('CustomerRef', _salesTable.CustomerRef);

    // Rellenamos la tabla que contiene las lineas del pedido
    tables = document.tables(); table = tables.item(2); rows = table.rows();  i = 1; // Nos posicionamos en la tabla nº2 de Word
    while select _salesLine index hint SalesLineIdx where _salesLine.SalesId == _salesTable.SalesId {
        i++;
        row = rows.item(i); // Posicion de fila
        cells = row.cells();
        cell = cells.item(1); range = cell.range(); range.insertAfter(_salesLine.ItemId);
        cell = cells.item(2); range = cell.range(); range.insertAfter(_salesLine.Name);
        cell = cells.item(3); range = cell.range(); range.insertAfter(_salesLine.SalesUnit);
        cell = cells.item(4); range = cell.range(); range.insertAfter(num2str(_salesLine.SalesQty ,4, 2, 2, 1));
        cell = cells.item(5); range = cell.range(); range.insertAfter(num2str(_salesLine.SalesPrice ,4, 2, 2, 1));
        cell = cells.item(6); range = cell.range(); range.insertAfter(num2str(_salesLine.LineAmount ,4, 2, 2, 1));
        row = rows.add();
    }
    if (i > 1)
        row.delete();    

    word.visible(true);    
}

El resultado lo podéis ver en la siguiente imagen:


Espero que os sirva de ayuda. La plantilla utilizada la podéis descargar en el siguiente enlace: Plantilla.

1 comentario: