Showing posts with label Map. Show all posts
Showing posts with label Map. Show all posts

Definition of List, Set, Container, and Map

 

Difference between List, Set, Container, and Map


Containers:

Containers are dynamic and have no limits. They can contain elements of
almost all data types: boolean, integer, real, date, string, container,
arrays, tables, and extended data types. However, objects may not be stored
in containers.

Containers in AX are used very often. It’s easy to work with them. But…
data in containers are stored sequentially and thus retrieved sequentially.
This means that containers provide slower data access if you are working with
_large numbers_ of records. In case of large numbers of records use temporary
tables.

List:

Lists are structures that may contain any number of elements that are
accessed sequentially. Lists may contain values of any X++ type. All the
values in the list must be of __the same__(this is the main difference
between lists and containers) type, given in the creation of the list. The
implementation of lists is such that the traversal of the list elements is __very
fast.

Take a look for example at the class Dialog addControl() method.
Their controls are stored in ctrls List.

Map:

A map is a data type that associates one (key) value with another value [An
analog – a small table in memory with two fields: Keys, Values]. Both the key
and value values may be of any valid X++ type, including objects. The types
of the key and the value are given in the declaration of the map. The
implementation of maps is such that access to the values is _very fast_.

Don’t confuse map X++ types with Map objects in AOT, which are used for
mapping tables with similar structures of fields

Set:

The functionality of Sets is similar to the list.  A Set is just an unordered list of items, while a list of items held by a Map
are indexed via a key.
Take look at
\Classes\sysLabel\LabelModuleId().

Map Enumerator VS Map Iterator D365FO



Map Enumerator VS Map Iterator



Map Enumerator

Map enumerators are automatically created on the same tier as the map when you call the Map.getEnumerator method.

Using the MapEnumerator class avoids a potential problem in code marked as Called from, where the iterator and map can end up on separate tiers
Map enumerators require less code than map iterators, they perform slightly better.

Map Iterator

Map Iterator should be used when you want to delete items from a list by using the MapIterator.delete method.

Email SSRS Report As Attachment D365FO


SSRS Report Email Attachment Dynamics 365FO



In one of my projects, We have a requirement to send the SSRS report as an attachment to an Email.

As everyone knows that this task is too simple in AX 2012, Where we save the file in client or server file systems and then send it as an Email attachment.

But the things are a bit more complicated when it comes to D365 in the cloud. You are no longer able to save the file locally as storage.

Following is the code to convert the SSRS report in Binaries 




public class ConvertReportPDF
{

    public static void main(Args _args)
    {
       
  
        Filename                        fileName = "P000173_AbcTest.pdf";
        SrsReportRunController    controller = new SrsReportRunController();
        SLD_TaxProfileContract   contract = new SLD_TaxProfileContract();
        SRSPrintDestinationSettings     settings;
        Array                           arrayFiles;
        System.Byte[]                   reportBytes = new System.Byte[0]();
        SRSProxy                        srsProxy;
        SRSReportRunService             srsReportRunService = new SrsReportRunService();
        Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;
        Map reportParametersMap;
        SRSReportExecutionInfo executionInfo = new SRSReportExecutionInfo();
        ;

  
        contract.parmAccountNum('K-VDR-000001');
        contract.parmAccountType(SLD_AccountType::Vendor);
        // Provide details to controller and add contract
        controller.parmArgs(_args);
        controller.parmReportName(ssrsReportStr(SLD_TaxProfile, Report));
        controller.parmShowDialog(false);
        controller.parmLoadFromSysLastValue(false);
        controller.parmReportContract().parmRdpContract(contract);
        // Provide printer settings
        settings = controller.parmReportContract().parmPrintSettings();
        settings.printMediumType(SRSPrintMediumType::File);
        settings.fileName(fileName);
        settings.fileFormat(SRSReportFileFormat::PDF);

        // Below is a part of code responsible for rendering the report
        controller.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
        controller.parmReportContract().parmReportExecutionInfo(executionInfo);

        srsReportRunService.getReportDataContract(controller.parmreportcontract().parmReportName());
        srsReportRunService.preRunReport(controller.parmreportcontract());
        reportParametersMap = srsReportRunService.createParamMapFromContract(controller.parmReportContract());
        parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);

        srsProxy = SRSProxy::constructWithConfiguration(controller.parmReportContract().parmReportServerConfig());
        // Actual rendering to byte array
        reportBytes = srsproxy.renderReportToByteArray(controller.parmreportcontract().parmreportpath(),
                                              parameterValueArray,
                                              settings.fileFormat(),
                                              settings.deviceinfo());
    



        // You can also convert the report Bytes into an xpp BinData object if needed
        container binData;
        Binary binaryData;
        System.IO.MemoryStream mstream = new System.IO.MemoryStream(reportBytes);
        binaryData = Binary::constructFromMemoryStream(mstream);
       // System.IO.File::WriteAllBytes("C:\\backup\\"+fileName,reportBytes); // You can save the file on your local instance for verification
       

        if(binaryData)
        {
            binData = binaryData.getContainer();
        }
        Map map=new Map (Types::String,Types::String);
        map.insert("message","Its working fine for me");
        SLD_EmailAttachment::sendPDFEamilAttachment("EmailRecpt","en-us","ShaikhSohailHussain@gmail.com",map,binData,"P000173_AbcTest");
    }

}


USE following code to send as Email Attachment 



class SLD_EmailAttachment

{


  

    public static void sendPDFEamilAttachment( SysEmailId      _emailId,
        LanguageId      _language,
        SysEmailAddress             _emailAddr,
        Map             _mappings,container _binData,str _fileName)
    {
        SysEmailItemId                   nextEmailItemId;
        SysEmailTable                    sysEmailTable;
        SysEmailMessageTable             sysEmailMessageTable;
        SysEmailContents                 sysEmailContents;
        SysOutgoingEmailTable            outgoingEmailTable;
        SysOutgoingEmailData             outgoingEmailData;
        Filename filename, FileExtension;
      
        FileExtension=".pdf";
       
        select sysEmailTable
               join    sysEmailMessageTable
                where sysEmailMessageTable.EmailId==sysEmailTable.EmailId
                    && sysEmailMessageTable.EmailId== _emailId
                    && sysEmailMessageTable.LanguageId==_language;
       
        if(sysEmailTable.RecId>0)
        {
            sysEmailContents=SysEmailMessage::stringExpand(sysEmailMessageTable.Mail, _mappings);
            nextEmailItemId = EventInbox::nextEventId();
      
            filename =strFmt("%1_%2.pdf",nextEmailItemId,_fileName);
    
    
            outgoingEmailTable.clear();
            outgoingEmailTable.Origin=sysEmailTable.Description;
            outgoingEmailTable.EmailItemId = nextEmailItemId;
            outgoingEmailTable.IsSystemEmail = NoYes::Yes;
            outgoingEmailTable.Sender = sysEmailTable.SenderAddr;
            outgoingEmailTable.SenderName = sysEmailTable.SenderName;
            outgoingEmailTable.Recipient = _emailAddr;
            outgoingEmailTable.Subject = SysEmailMessage::stringExpand(sysEmailMessageTable.Subject, _mappings);
            outgoingEmailTable.Priority = eMailPriority::High;
            outgoingEmailTable.WithRetries = NoYes::NO;
            outgoingEmailTable.RetryNum = 0;
            outgoingEmailTable.UserId = curUserId();
            outgoingEmailTable.Status = SysEmailStatus::Unsent;
            outgoingEmailTable.Message =  sysEmailContents;
            outgoingEmailTable.LatestStatusChangeDateTime = DateTimeUtil::getSystemDateTime();
            outgoingEmailTable.TemplateId= _emailId;
            outgoingEmailTable.insert();


            if(conLen(_binData)>0)
            {
                outgoingEmailData.clear();

                outgoingEmailData.EmailItemId = nextEmailItemId;
                outgoingEmailData.DataId = 1;
                outgoingEmailData.EmailDataType = SysEmailDataType::Attachment;
                outgoingEmailData.Data = _binData;
                outgoingEmailData.FileName = filename;
                outgoingEmailData.FileExtension =FileExtension;

                outgoingEmailData.insert();
            }
        }
    }

}



Virtual Fields Vs Computed Fields

  Virtual Field: A virtual field in D365FO is a field that doesn't have a direct representation in the database. It's a field that y...