Showing posts with label AX2009. Show all posts
Showing posts with label AX2009. Show all posts

2021-07-16

[AX2009] Update SalesLine Qty by Code

 Update sales line Qty manually. This code also update remain qty in SalesLine tabale and qty in InventTrans table.

static void UpdateSalesLineQty(Args _args)
{
    SalesLine       salesLine;
    ;
    ttsbegin;
    salesLine = SalesLine::findInventTransId('14723621_068', true);
    salesLine.SalesQty = 3;//example
    salesLine.modifiedField(fieldnum(SalesLine, SalesQty));
    InventMovement::bufferSetRemainQty(salesLine);
    salesLine.update();
    ttscommit;
    info("Done");
}

2019-07-26

[AX 2009] Access Form Control by Code

This is a sample to change formstringcontrol label by code without autodeclaration. Control::GroupPayment_M_paymentDescription is a control id. The control id is formed from Control::+"Control Name".

public void run()
{
    FormStringControl   paymentDesc;

    ;

    paymentDesc = element.control(Control::GroupPayment_M_paymentDescription);
    paymentDesc.label("Payment description");
}


//AX2012
element.control(element.controlId(formControlStr(CustInvoice, GroupPayment_M_paymentDescription))).label("Payment description"); 

Form control type
Class
ActiveX
FormActiveXControl
Animate
FormAnimateControl
Button
FormButtonControl
ButtonGroup
FormButtonGroupControl
CheckBox
FormCheckBoxControl
ComboBox
FormComboBoxControl
CommandButton
FormCommandButtonControl
DateEdit
FormDateControl
Grid
FormGridControl
Group
FormGroupControl
GuidEdit
FormGuidControl
HTML
FormHTMLControl
Int64Edit
FormInt64Control
IntEdit
FormIntControl
ListBox
FormListBoxControl
ListView
FormListControl
MenuItemButton
FormFunctionButtonControl
MenuButton
FormMenuButtonControl
Progress
FormProgressControl
RadioButton
FormRadioControl
RealEdit
FormRealControl
StaticText
FormStaticTextControl
StringEdit
FormStringControl
Tab
FormTabControl
TabPage
FormTabPageControl
Table
FormTableControl
TimeEdit
FormTimeControl
Tree
FormTreeControl
Window
FormWindowControl

2018-04-25

[AX2009] AX COM Business Connector

This is how to create a connection from C# to Dynamics AX 2009.
Install AxCom.dll
  1. Run  D:\Setup.exe HideUI=1 AcceptLicenseTerms=1 InstallComBusinessConnector=1 if it is failed, find AxCom.dll from installation and copy the file into C:\Program Files (x86)\Microsoft Dynamics AX\50\Client\Bin.
  2. Register AxCom.dll by regSvr32 in command prompt.
Create a Class in AX
  1. Create axCom class.
  2. Create method getName.
Name getName(Name _name)
{
    ;
    return strfmt("-- %1 --",_name);
}
Create a C# Console program (Just a sample) 
  1. Add reference to AxCom.dll, in tab COM, select Axapta Com Connector 1.2 Type Library.
  2. C# code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AxaptaCOMConnector;//AX Business Connector

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Axapta3             ax = new Axapta3();
            IAxaptaObject       axObj;
            string              axName;
            AxaptaParameterList list = new AxaptaParameterList();
            String              name;

            name = "Default Name";
            //axCOM.Logon("CEU", "", "", "");
            ax.LogonAs("axService", "DAX", "axProxy", "DAX", "Password");//log on as AxService user in DAX domain over on proxy user. Add parameters as needed.
            axObj = ax.CreateObject("axCom", null, null, null, null, null, null);//create object from axCom class in AX

            name = System.Console.ReadLine();//get name from console
          
            //create parameter
            list.Size=1;
            list.set_Element(1, name);
          
            axName = (string)axObj.CallEx("getName", list);//execute method in axCom class
          
            System.Console.WriteLine(axName);//show modified name in console
            System.Console.ReadKey();//wait until hit a key
          
            ax.Logoff();//log out
        }
    }
}


2018-04-16

[AX2009] Run Workflow Batch Job

Find SysWorkflowMessageQueueManager and WorkflowWorkItemDueDateJob in AOT. Run them by right click.

2016-11-02

[AX2009] Merge Query Range from Two Different Queries

In my case, I want to merge query ranges from Query object to Form Data source. The data source will join to CustTable. The CustTable will be filtered by Query Object TIDCustTable.

public class FormRun extends ObjectRun
{
    QueryBuildDatasource    qbds3;
    Query                   q3;
    QueryRun                qRunCustTable;
}
 public void init()
{
    QueryBuildDatasource    qbds1, qbds4;
    ;
    qRunCustTable = new QueryRun(QueryStr(TIDCustTable));
    super();
    qbds1 = TIDIRTable_ds.query().dataSourceTable(tablenum(TIDIRTable));
    qbds4 = SalesTableDS_ds.query().dataSourceTable(tablenum(SalesTable));
    qbds4.addLink(fieldnum(TIDIRTable, SalesId), fieldnum(SalesTable, SalesId));

    qbds3 = qbds1.addDataSource(tablenum(CustTable));
    qbds3.addLink(fieldnum(TIDIRTable, InvoiceAccount), fieldnum(CustTable, AccountNum));

}

When click Select button:
void btnSelect()
{
    ;
    if(qRunCustTable.prompt())
    {
        q3  = new Query(qRunCustTable.query());
    }
}
Process button:
public void btnProcess()
{
    QueryBuildDatasource    qbds1 = TIDIRTable_ds.query().dataSourceTable(tablenum(TIDIRTable));
    QueryBuildDatasource    qbds4 = SalesTableDS_ds.query().dataSourceTable(tablenum(SalesTable));
    ;

    if(element.validateProcess())
    {
        qbds3.clearRanges();
        if(qRunCustTable.query().dataSourceTable(tablenum(CustTable)).rangeCount() >0)
            element.mergeRanges(TIDIRTable_ds.query(), qRunCustTable.query(), 4);//4 is table number of CustTable in TIDIRTable query


        SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, InvoiceDate)).value(SysQuery::range(dtFromDate.dateValue(), dtToDate.dateValue()));
        if(txBranch.valueStr())
        {
            SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, CountryRegionId)).value(SysQuery::value(txCountryRegionId.valueStr()));
            SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, Branch)).value(SysQuery::value(txBranch.valueStr()));
        }
        else
        {
            if(qbds1.findRange(fieldnum(TIDIRTable, CountryRegionId)))
                qbds1.clearRange(fieldnum(TIDIRTable, CountryRegionId));

            if(qbds1.findRange(fieldnum(TIDIRTable, Branch)))
                qbds1.clearRange(fieldnum(TIDIRTable, Branch));
        }

        if(cbSalesStatus.selection() == SalesStatus::None)
        {
            qbds4.joinMode(JoinMode::OuterJoin);
            if(qbds4.findRange(fieldnum(SalesTable, SalesStatus)))
            {
                qbds4.clearRange(fieldnum(SalesTable, SalesStatus));
            }
        }
        else
        {
            qbds4.joinMode(JoinMode::InnerJoin);
            SysQuery::findOrCreateRange(qbds4, fieldnum(SalesTable, SalesStatus)).value(SysQuery::value(cbSalesStatus.selection()));
        }
        TIDIRTable_ds.executeQuery();
    }
}

Merge method:
public void mergeRanges(Query       q,
                               Query       initQ,
                               int         dsNo,
                               int         initQdsNo = 1,
                               boolean     alwaysAddDatasource     = false,
                               boolean     addSameFieldRange       = true)
{
    QueryBuildRange     fromQbr;
    QueryBuildRange     toQbr;
    QueryBuildDynalink  dyna;
    Counter             fromI = 1;
    //int                 qdsNo = initQdsNo;
    int                 qdsNo = dsNo;
    Counter             toI;
    tableId             tableId;
    DictField           dictField;
    int                 dictIndex;
    int                 originalId;

    void add()
    {
        q.addDataSource(initQ.dataSourceNo(initQdsNo).file());
        qdsNo = q.dataSourceCount();
    }

    void findToQbr(fieldId id)
    {
        originalId  = id;
        id          = fieldExt2Id(id);
        toQbr       = null;

        // get table id & dictField
        tableId = q.dataSourceNo(qdsNo).table();
        dictField = new DictField(tableId,id);
        dictIndex = originalId >> 16;

        // If this is a dimension field, get range using the array index, otherwise get range with id
        if ( ((dictField.arraySize() > 1) && q.dataSourceNo(qdsNo).findRange(fieldId2Ext(id, dictIndex))) ||
            ((dictField.arraySize() <= 1) && q.dataSourceNo(qdsNo).findRange(id)) )
        {
            // If same range is found, then next range
            if (! addSameFieldRange)
                continue;

            toI = 1;
            while (toI)
            {
                // is this a Dimension field?
                if (dictField.arraySize() > 1)
                    toQbr  = q.dataSourceNo(qdsNo).findRange(fieldId2Ext(id, dictIndex),toI);
                else
                    toQbr  = q.dataSourceNo(qdsNo).findRange(id,toI);

                if (! toQbr)
                    break;

                // If To value is empty, use it later
                if (! toQbr.value())
                    break;

                // If To and From values are equal then add new range later
                if (toQbr.value() == fromQbr.value())
                    break;

                toI++;
            }
        }
        if (! toQbr             ||
            (addSameFieldRange  &&
             toQbr              &&
             toQbr.value()      &&
             fromQbr.value()    &&
             toQbr.value()      != fromQbr.value()
            )
           )
        {

            if (dictField.arraySize() > 1)
            {
                // yes, working with Dimension
                toQbr  = q.dataSourceNo(qdsNo).addRange(fieldId2Ext(id, dictIndex));
            }
            else
            {
                toQbr  = q.dataSourceNo(qdsNo).addRange(id);
            }
        }
    }


    // Start

    if (! initQ)
        throw error(strfmt("@SYS23669",funcname()));

    if (! initQ.dataSourceNo(initQdsNo))
        throw error(strfmt("@SYS23667",funcname()));

    if (! q)
        throw error(strfmt("@SYS23669",funcname()));
/*
    if (q.dataSourceCount() >= initQdsNo)
    {
        if (q.dataSourceNo(initQdsNo).file() != initQ.dataSourceNo(initQdsNo).file())
        {
            if (alwaysAddDatasource)
                add();
            else
               throw error(strfmt("@SYS23668",funcname()));
        }
    }
    else
        add();
*/
    if (! initQ)
        return;

    for (fromI=1;fromI<=initQ.dataSourceNo(initQdsNo).rangeCount();fromI++)
    {
        fromQbr = initQ.dataSourceNo(initQdsNo).range(fromI);

        findToQbr(fromQbr.field());

        if (toQbr)
        {
            // Only set if From has a value
            if (fromQbr.value())
                toQbr.value(fromQbr.value());

            switch (fromQbr.status())
            {
                case RangeStatus::Locked:
                    if (toQbr.status() == RangeStatus::Open)
                        toQbr.status(RangeStatus::Locked);
                    break;
                case RangeStatus::Hidden:
                    switch (toQbr.status())
                    {
                        case RangeStatus::Open,RangeStatus::Locked:
                            toQbr.status(RangeStatus::Hidden);
                            break;
                    }
                    break;
            }
        }

    }

    fromI = 1;
    while (fromI <= initQ.dataSourceNo(initQdsNo).dynalinkCount())
    {
        dyna =  initQ.dataSourceNo(initQdsNo).dynalink(fromI);

        findToQbr(dyna.field());

        if (toQbr)
            toQbr.value(queryValue(dyna.cursor().(dyna.dynamicField())));

        fromI++;
    }
}