Monday, November 29, 2021

Create a New custom service in D365FO

 Hi guys, Today we see how to create a custom service in D365FO using X++.


In custom service, we have Inbound and Outbound services.

Inbound service: Get the data from 3rd party application and do some operations in D365Fo.

Outbound service: Send the data from D365Fo to 3rd party application.

components required:

  • Service class
  • Business logic class (Instead of writing the logic in the service class I created a new class)
  • Contract class
  • Service object
  • Service group object
Link : Url/api/services/serviceGpName/serviceName/OpertaionName.

  • OpertaionName(method name) is exposed to the outside systems.
  • HTTP web request. (Java client/Postman/dot net-based application)
  • We can call this API from any App.
  • 3rd party application will send data to D365FO and D365FO will store the data and send a response "Success" or "failed" based on business operation.
  • I took a simple example. I send the customer data to D365FO If the customer exists it will update the customer name otherwise it will insert the data in D365FO. I have used a custom table.


1. Create a contract class and parm methods.

[DataContractAttribute]
class TestCustomServiceDataContract
{
    str customer, name;

    public TestCustomServiceDataContract construct()
    {
        return new TestCustomServiceDataContract();
    }

    [DataMemberAttribute('Customer account')]
    public str parmCustomer(str _customer = customer)
    {
        customer = _customer;

        return customer;
    }

    [DataMemberAttribute('Customer name')]
    public str parmName(str _name = name)
    {
        name = _name;

        return name;
    }

}

2. Create service class and method is in public.

class TestCustomServiceDataService
{
    public str customers(TestCustomServiceDataContract     _contract)
    {
        return TestCustomServiceBussinessLogic::getCustomer(_contract);
    }
} 

3. Bussiness logic class.

class TestCustomServiceBussinessLogic
{
    public static str getCustomer(TestCustomServiceDataContract     _contract)
    {        
        TestCustomers       customer = TestCustomers::find(_contract.parmCustomer(), true);

        if (customer)
        {
            ttsbegin;
            customer.Name = _contract.parmName();
            customer.update();
            ttscommit;

            return 'Success';
        }
        else
        {
            customer.clear();
            customer.Customer   = _contract.parmCustomer();
            customer.Name       = _contract.parmCustomer() + ' ' + _contract.parmName();
            customer.insert();

            return 'Success';
        }

        return 'Failed';
    }

}

4. Create Service.
        




5. Create a Service Group.



Link : Url/api/services/serviceGpName/serviceName/OpertaionName

Url/api/services/TestCustomServiceGroup/TestCustomService/customers

Use the above link in postman.


Remove custom service default parameter: id in D365FO:


Write the below line on top of the contract to remove that "Id".
[DataContractAttribute, Newtonsoft.Json.JsonObjectAttribute(IsReference = false)]

Multiple records:

{ "record": [ { "ID": "140127-000003", "EffectiveDate": "2022-06-05", "IsTrue": "Yes", "DueDate": "2022-06-05T13:49:51.141Z" } ] }

We need to build a method like the below in the service class:

[AifCollectionType('record', Types::Class, classStr(TestDataContract))] [AifCollectionType('return', Types::Class, classStr(Test2DataContract))] public List updateStockOnHand(List record) { }

For the above example code is written in the below link. Please check.



Keep daxing!!


Generate QR code using x++ in SSRS report

 Hi guys, Today we see how to Generate QR codes using x++ in D365FO SSRS reports. We can generate QR codes in two ways. Please check below.


Steps :

            1. Need to create container filed in Temp table.


            2. Add Way1/Way2 code in DP class and calling that method while inserting data into temp table. Like below.

                    headerTmp.Image = this.QRCode('TEST');// Your method.

                     headerTmp.insert();

            3.click restore on report

            4. Add image field in design                          


            5. Image Properties :

      • Select the image source : Database
      • Use this field : Field from Table
      • Use this MIME type : image/bmp               



Way 1:

using QRCoder;
public class GetQRCode
{
public static container QRCode(JournalTable  _jour)
{
    Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder   qrCode;
    str                                 QrCodeBase64String;
    System.String                       netString;
    str                                 tempFileName;
    System.Drawing.Bitmap               netBitmap;
    Bitmap                              imageQR;
    FileIOPermission                    perm;
    BinData                             binData;
    container                           imageContainer;
    Str1260                             qrString;
    real                                taxWithoutVat;
    QRCodeGenerator.ECCLevel            eccLevel;
    QRCodeGenerator                     qrGenerator = new QRCodeGenerator();
    ;

    qrCode          = new Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder();
    //qrString        = strFmt("https://www.google.com/");
    qrString        = strFmt("Supplier name: %1", CompanyInfo::findDataArea(_jour.DataAreaId).Name);
    qrString        += strFmt("\nInvoice number: %1", _jour.InvoiceId);
    qrString        += strFmt("\nInvoice Date: %1", _jour.InvoiceDate);
    qrString        += strFmt("\nTotal amount with VAT: %1", _jour.InvoiceAmount);

    netBitmap       = qrCode.Encode(qrString);

    binData         = new binData();

    QrCodeBase64String  = qrString;
    tempFileName        = qrCode.GetTempFile(QrCodeBase64String);

    perm  = new FileIOPermission(tempFileName,'RW');

    perm.assert();
    binData.loadFile(tempFileName);
    imageContainer          = binData.getData();

    // header.QRValue = imageContainer;
    return imageContainer;
}
}

==============================================================================

Way 2:

using QRCoder;
public class GetQRCode
{
    public static container QRCode(SalesId _salesId)
    {
        Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder  
            qrCode = new Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder();
        System.Drawing.Bitmap       bitmap;
        container                   imageContainer;
        str                         url= strFmt("%1'%2'", Parameters::find().QRCodeUrl, _salesId);
        ;        

        System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

        bitmap = qrCode.Encode(url);

        bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat::get_Png());
        //bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat::Png);

        imageContainer = Binary::constructFromMemoryStream(memoryStream).getContainer();

        return imageContainer;
    }
}
-------------------oR------------------------------------
    private container QRCode(str _value) { Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder qrCode = new Microsoft.Dynamics.ApplicationSuite.QRCode.Encoder(); System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); System.Drawing.Bitmap bitmap; bitmap = qrCode.Encode(_value); bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat::Png); return Binary::constructFromMemoryStream(memoryStream).getContainer();; }


Keep daxing!!

Tuesday, November 23, 2021

How to get attachments of notes in d365FO.

 Hi guys, today we see how to get notes attachments in d365FO. The below method is to return the notes based on the sender table.


        private Notes getAttachments(Common _common) { DocuRef docuRef; DocuType docuType; ; select firstOnly Notes from docuRef order by docuRef.createddatetime desc where docuRef.RefTableId == _common.TableId && docuRef.RefRecId == _common.RecId && docuRef.RefCompanyId == _common.DataAreaId exists join DocuType where DocuType.TypeId == docuRef.TypeId && DocuType.TypeGroup == DocuTypeGroup::Note; return docuRef.Notes; }


Keep Daxing!!

How to convert a Amount into Words in d365FO

 Hi guys, today we see how to convert a Amount in Words in d365FO.


We can get it by using standard class Global::numeralsToTxt(). By this method we are not getting the correct words for lakhs. If you print Indian rupees just follow method 2. I have created display method and I added code in that method. 


Method 1:


    display Tempstr numberToWords() { Amount amount = this.Amount; Notes amount2Str; if (amount > 0) { amount = real2int(round(amount , 1)); } else { amount = real2int(round(-(amount) , 1)); } amount2Str = Global::numeralsToTxt(amount); amount2Str = subStr(amount2Str,5,strLen(amount2Str)-4); amount2Str = subStr(amount2Str,strLen(amount2Str)-10,- strLen(amount2Str)); amount2Str = '(Amount:' +' '+ str2Capital(amount2Str) + ' only)'; return amount2Str; }


Method 2:

    display Tempstr numberToWords() { int numOfpaise = frac(this.Amount)*100 mod 100; int test = real2int(round(this.Amount,0)); int paise; int numOfTenths; str 20 ones[19], tenths[9], hundreds, thousands, lakhs, crores, millions, billions; str 40 textpaise; int tmpnumOfpaise; int temp; str 200 returntxt; ; int checkPower(int _test, int _power) { int numOfPower; if (_test >= _power) { numOfPower = _test DIV _power; if (numOfPower >= 100) { temp = numOfPower DIV 100; returntxt = returntxt + ' ' + ones[temp] + ' ' + hundreds; numOfPower = numOfPower MOD 100; } if (numOfPower >= 20) { temp = numOfPower DIV 10; returntxt = returntxt + ' ' + tenths[temp]; numOfPower = numOfPower MOD 10; } if (numOfPower >= 1) { returntxt = returntxt + ' ' + ones[numOfPower]; numOfPower = numOfPower MOD 10; } switch(_power) { case 1000000000 : { returntxt = returntxt + ' ' + billions; _test = _test MOD 1000000000; break; } case 10000000 : { returntxt = returntxt + ' ' + crores; _test = _test MOD 10000000; break; } case 100000 : { returntxt = returntxt + ' ' + lakhs; _test = _test MOD 100000; break; } case 1000 : { returntxt = returntxt + ' ' + thousands; _test = _test MOD 1000; break; } case 100 : { returntxt = returntxt + ' ' + hundreds; _test = _test MOD 100; break; } } } return _test; } ones[1] = "@SYS26620"; ones[2] = "@SYS26621"; ones[3] = "@SYS26622"; ones[4] = "@SYS26626"; ones[5] = "@SYS26627"; ones[6] = "@SYS26628"; ones[7] = "@SYS26629"; ones[8] = "@SYS26630"; ones[9] = "@SYS26631"; ones[10] = "@SYS26632"; ones[11] = "@SYS26633"; ones[12] = "@SYS26634"; ones[13] = "@SYS26635"; ones[14] = "@SYS26636"; ones[15] = "@SYS26637"; ones[16] = "@SYS26638"; ones[17] = "@SYS26639"; ones[18] = "@SYS26640"; ones[19] = "@SYS26641"; tenths[1] = 'Not used'; tenths[2] = "@SYS26643"; tenths[3] = "@SYS26644"; tenths[4] = "@SYS26645"; tenths[5] = "@SYS26646"; tenths[6] = "@SYS26647"; tenths[7] = "@SYS26648"; tenths[8] = "@SYS26649"; tenths[9] = "@SYS26650"; hundreds = "@SYS26651"; thousands = "@SYS26652"; lakhs = "Lakh"; crores = "Crore"; millions = "@SYS26653"; billions = "@SYS26654"; test = checkPower(test, 1000000000); test = checkPower(test, 10000000); test = checkPower(test, 100000); test = checkPower(test, 1000); test = checkPower(test, 100); if (test >= 20) { numOfTenths = test DIV 10; returntxt = returntxt + ' ' + tenths[numofTenths]; numOfTenths = numOfTenths MOD 10; test = test MOD 10; } if (test >= 1) { numOfTenths = test; returntxt = returntxt + ' ' + ones[numOfTenths]; } if (numOfpaise) { returntxt = returntxt + ' ' + "@SYS5534" + "\n\n"; } paise = numOfpaise; if (paise) { if (paise >=20) { numofTenths = paise DIV 10; returntxt = returntxt + ' rupees '+ tenths[numofTenths]; numofTenths = numofTenths MOD 10; paise = paise MOD 10; } if (paise >=1) { numOfTenths = paise; returntxt = returntxt + ' ' + ones[numOfTenths]; } return returntxt + " Paise Only"; } return returntxt + " rupees Only"; }

This above method I followed from below reference.

https://www.theaxapta.com/search?q=how+to+convert+amount+in+words


Result:



Keep Daxing!!


Tuesday, November 16, 2021

Add symbol icons to the Grid in Dynamics 365FO

 

    We see how to add symbol icons to the grid in Dynamics 365FO. I have to add icons to the records based on qty. 


For this, 

1. I have created a display method on my table    

    [SysClientCacheDataMethod(true)]
    public display container logo()
    {
        ImageReference          imageReference;
        container               image;
        
        
        //imageReference = ImageReference::constructForSymbol(
				this.QtyAvailable mod 2 ? 'GreenCheck' : 'RedX');
				
        str name = this.QtyAvailable mod 2 ? 'GreenCheck' : (
				this.QtyAvailable mod 3 ? 'YellowTriangle': 'RedX');
        imageReference = ImageReference::constructForSymbol(name);

        if (imageReference)
        {
            image = imageReference.pack();
        }

        return image;
    }

2. Created new Form image control in the form grid and set up the properties for that control.





Symbols:
  • GreenCheck
  • YellowTriangle
  • RedX
  • GreenCircle
  • RedDiamond
  • BlueSquare
  • RedSquare
  • GreenSquare
  • OrangeSquare
  • GreenSquare
  • YellowSquare
  • TemporaryUser
  • EditEvent
  • YellowExclamationPoint
We can use the above symbols as per our requirements.

Reference: https://www.avantiico.com/adding-symbol-font-icons-to-a-grid-in-dynamics-365-for-finance-and-operations-enterprise-edition/

Keep Daxing!!

Monday, November 15, 2021

Add custom dialog form to standard new button in form in d365fo using x++

 Hi guys, I got a requirement like I have to add my custom dialog to the standard New button. I have to change the standard new button operation and I have to add a custom one. Please refer below for the solution.




My custom form


Way 1:

  • In the form design 'Show new button' property I have set it as no. I add a new menu item button in the form and I have called my custom form in that button properties.


Way 2:

  • Override the Create method in the form data source and write the below logic. (Main form). From here we can call our custom form by using args class. Here we have to comment super() otherwise the standard code will run. 
        public void create(boolean _append = false)
        {
            //super(_append); we need to comment super.

            Args            args = new Args();

            args.name(formStr(MyForm));
            args.caller(this);
            args.record(MyTable);

            FormRun myCreateOrder = classfactory.formRunClass(args);

            myCreateOrder.init();
            myCreateOrder.run();

            if  (!myCreateOrder.closed())
            {
                myCreateOrder.wait();
            }

            if  (myCreateOrder.closedOk())
            {
                Info('Clicked ok');
                //MyTable_ds.research(true);
            }
            else
            {
                Info('Clicked cancle');
            }
        }


  • Write the below code in the clicked method of custom form OKCommandButton.

                Mytable      mytable;

        ;

        super();

        if  (MyID.valueStr())
        {
            ttsbegin;
            mytable.clear();
            mytable.MyID = MyID.valueStr();
            mytable.Qty = 1;
            mytable.String = 'Test';
            mytable.InventLocationId = '11';
            mytable.insert();
            ttscommit;

            element.args().record().dataSource().research(true);
        }

  • When I click the new button my custom dialog will open. After entering the my Id and I clicked on the ok button it will insert data in my table and refresh the caller form. 
Keep Daxing!!

How to refresh caller datasource in D365fo

 Today we discuss how to refresh the caller form from another form using x++. I have to refresh the caller form after inserting data in the caller table. For this, we have multiple ways. follow any one of the below-mentioned ways.


1. I have used FormDataUtil calss.

    Mytable = element.args().record(); FormDataSource formdataSource = FormDataUtil::getFormDataSource(Mytable); formdataSource.research(true); // FormDataUtil::getFormDataSource(Mytable).research(true);we can use directly like this


2. Get the form data source from args. (This is a simple one)

    FormDataSource formdataSource = element.args().record().dataSource(); //formdataSource.research(); formdataSource.refresh(); formdataSource.executeQuery(); //element.args().record().dataSource().research(true); we can use directly like this

3. Get the caller and refresh the data source. We can use only form is calling another form menu item button instead of Args class.

    FormRun formRun; ; formRun = element.args().caller(); formRun.dataSource().refresh(); formRun.dataSource().research(true);


4. We can use the task method in formrun. We can use only form is calling another form menu item button instead of Args class.                

    #Task FormRun formRun; // Get an instance of the calling form. formRun = element.args().caller(); // If the caller is a form, refresh that form. if (formRun) { formRun.task(#taskF5); }

Reference: https://docs.microsoft.com/en-us/dynamicsax-2012/developer/how-to-refresh-the-calling-form

Keep Daxing!!

Add an image to a button in d365fo.


Today we see how to add image to custom button in d365fo. I got a requirement like I have to add standard button images to my custom buttons.

For this I have set up one property. Just check below.

Image location as symbol.

Normal Image as new(required symbol name).


Result.


Refer below link for button image names.

https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/user-interface/action-controls#button-images


Keep Daxing!!


Friday, November 12, 2021

create number sequence in d365 x++

 Topic : Create number sequence in d365 using x++.

In this post I created a new number sequence for my existing module. Just follow the below steps.

1. Create a new extension class for NumberSeqModuleMyModule. written the below code in loadModule method.  

         [ExtensionOf(classStr(NumberSeqModuleMyModule))]
    final class NumberSeqModuleMyModule_Extension
    {
        protected void loadModule()
        {
            NumberSeqDatatype datatype = NumberSeqDatatype::construct();

            next loadModule();

            datatype.parmDatatypeId(extendedTypeNum(MyId));
            datatype.parmReferenceHelp(literalStr('My Id'));
            datatype.parmWizardIsContinuous(false);
            datatype.parmWizardIsManual(NoYes::No);
            //datatype.parmWizardFetchAheadQty(10);
            datatype.parmWizardIsChangeDownAllowed(NoYes::No);
            datatype.parmWizardIsChangeUpAllowed(NoYes::No);
            datatype.parmWizardHighest(999999999);
            datatype.parmSortField(1);
            datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
            this.create(datatype);
        }

    }

2. Create a new extension class for parameter table(MyParmeters) and a new method.

    [ExtensionOf(tableStr(MyParameters))] final class MyParameters_Extension { public static NumberSequenceReference myId() { return NumberSeqReference::findReference(extendedTypeNum(MyId)); } }

3. To run the NumberSeq class just create a job(runnable class).

        class RunnableClass

{ public static void main(Args _args) { NumberSeqModuleMyModule loadModule = new NumberSeqModuleMyModule(); ; loadModule.load(); } }

4. run the runnable class and then go to Organization administration –> Number sequences –> Number sequences –> Generate Button (Run the wizard).

5. To test that number seq follow the below code.

    class RunnableClass { public static void main(Args _args) { NumberSeq numberSeq; str num; ; numberSeq = NumberSeq::newGetNum(MyParameter::MyID()); num = numberSeq.num(); info(num); } }

Keep daxing!!

SysOperation without using controller class in d365fo.

 We can run the batch using sys operation frame work. we can use sys operation without using controller class.


I created a service class and I wrote the logic. After I created an action menu item and I mentioned below properties.


TestSysOperationServiceClass is my service class and process is my service class method.

Keep Daxing!!

SysOperation in D365fo

 Topic : SysOperation /Batch Processing in D365fo.

Instead of the RunBase framework, we can use the SysOperation framework. It contains 4 classes. Based on requirements we can use the required classes.

Controller class: 

    This class is the main class. Here we are calling service class and we can call contract also.

    public class TestSysOperationController extends SysOperationServiceController { public void new() { //super(classStr(TestSysOperationService), methodStr(TestSysOperationService, process), SysOperationExecutionMode::Synchronous); super(); this.parmClassName(classStr(TestSysOperationService)); this.parmMethodName(methodStr(TestSysOperationService, process)); this.parmDialogCaption("Dialog Title"); } public ClassDescription caption() { return "Task Description"; } public static void main(Args args) { TestSysOperationController controller; controller = new TestSysOperationController(); //controller = TestSysOperationController::construct();

            //controller.parmShowDialog(false);//Hide the batch dialog

            //controller.initFromCaller()//Get contract class

            //controller.refreshCallerRecord()//Refresh caller data source

            //controller.captionIsSet = false;

       // controller.parmDialogCaption(isExcelUp ? "ExcelUpload" :"Manual");

controller.startOperation();    

            //controller.getDataContractObject()//// for sys operation     //controller.parmReportContract().parmRdpContract() } public static TestSysOperationController construct(SysOperationExecutionMode _executionMode = SysOperationExecutionMode::Synchronous) { TestSysOperationController controller; controller = new TestSysOperationController(); controller.parmExecutionMode(_executionMode); return controller;

        /*ClassName className; MethodName methodName; switch (_args.menuItemName()) { // It will trigger change whs process in site locations case menuItemActionStr('Action menu item name') : className = classStr(Service); methodName = methodStr(Service, process); break; default: break; } return new TestSysOperationController(className, methodName);*/ }

        private void initFromCaller()     {     HelperContract contract;     #define.dataContractKey('_contract')     contract = this.getDataContractObject(#dataContractKey)     contract.initialize();     contract.parmCallerTableId(this.parmCallerRecord().TableId);     }

        protected void refreshCallerRecord()     {

            FormDataSource    callerDataSource; 

          callerDataSource = FormDataUtil::getFormDataSource(this.parmCallerRecord());

    if (this.parmCallerRecord() && callerDataSource)     {     callerDataSource.reread();     callerDataSource.research(true);     callerDataSource.refresh();     }     }

}

--------------------------------------------------------------------------

Service Class :

Our business logic is written here and this class is called from the controller class.

public class TestSysOperationServiceClass extends SysOperationServiceBase { public void process(TestContractClass _contract) { info(‘Running’); List list = _contract.parmVendorList(); }

}

------------------------------------------------------------------------

Contract Class :

This class is used to create the parm methods If any parameters are required in the dialog.

[ DataContractAttribute, SysOperationContractProcessingAttribute(classstr(TestUIBuilderClass)) ] class TestContractClass { List vendAccountList; [ DataMemberAttribute("Vendor"), AifCollectionTypeAttribute("Vendor", Types::String), SysOperationLabelAttribute(literalstr("Vend account")), SysOperationHelpTextAttribute(literalstr("Vend account.")), //SysOperationGroupMemberAttribute('Group'), SysOperationDisplayOrderAttribute('1')

//SysOperationControlVisibilityAttribute(false)// Hide control ] public List parmVendorList(List _vendAccountList = vendAccountList) { vendAccountList = _vendAccountList; return vendAccountList; }

}

-------------------------------------------------------------------------------------------------------------

UI Builder Class:

This class is used to lookup, jumpref, modified, validate methods for dialog controls. we can add groups in that dialog. This is mainly for dialog design changes.

    class TestUIBuilderClass extends SysOperationAutomaticUIBuilder//SrsReportDataContractUIBuilder { TestContractClass myContractClass; DialogField dialogField; container con; public void build() { // super(); // Add group to dialog //Dialog dialogObject = this.dialog(); // dialogObject.addGroup('Group'); myContractClass = this.dataContractObject() as TestContractClass; dialogField = this.addDialogField(methodStr(TestContractClass,                                       parmVendorList), TestContractClass);

} public void postBuild() //or postRun() we can use any method. { super(); myContractClass = this.dataContractObject() as TestContractClass; dialogField = this.bindInfo().getDialogField(TestContractClass,                                                 methodStr(TestContractClass, parmVendorList));

dialogField.registerOverrideMethod(methodStr(FormStringControl, lookup),                             methodStr(TestUIBuilderClass, VendorLookup), this);

//dialogField.registerOverrideMethod(methodStr(FormStringControl, modified),                       methodStr(TestUIBuilderClass, Vendormodified), this); // modified method.

//dialogField.registerOverrideMethod(methodStr(FormStringControl, validate),                     methodStr(TestUIBuilderClass, vendorValidate), this); // validate method.

//if (dialogField) //{ // dialogField.lookupButton(2); //} } public boolean vendorValidate(FormStringControl _control) { if(!VendTable::Exist(_control.Value())) { error("Selected Vendor is not exists"); return false; } return true; } public void VendorLookup(FormStringControl _control) { Query query = new Query(); QueryBuildDataSource vendQBD; // QueryBuildFieldList fieldList; vendQBD = query.addDataSource(tableNum(VendTable)); //qbds1 = qbds.addDataSource(tableNum(DirPartyTable)); //qbds1.relations(True); //qbds1.fields().clearFieldList(); //fieldList = qbds.fields(); //fieldList.addField(fieldNum(DirPartyTable, Name)); //fieldList.dynamic(QueryFieldListDynamic::No); vendQBD.addSelectionField(fieldNum(VendTable, AccountNum)); SysLookupMultiSelectGrid::lookup(query, _control, _control, _control, con); } }


Keep Daxing!!