web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Create batch job through X++ code

(0) ShareShare
ReportReport
Posted on by 384

Dear Gentlemen,

i am creating a new batch job using x++ code, using the below code:

class IS_BatchClassTEst extends RunBaseBatch

{

  boolean canGoBatchJournal()
    {
        return true;
    }

    public container pack()
    {
        return conNull();
    }

    //Returns the stored object for the batch to use
    public boolean unpack(container packedClass)
    {
        return true;
    }

    //Determines whether to run on server or client
//True - Server; False - Client
    public boolean runsImpersonated()
    {
        return true;
    }

    public void Run()
    {
      //  info("Batch WOrking");
    }

}

I was able to retrieve the class in Microsoft dynamics 365 but the code isn't executing.

When the status is ended, i don't get the results ( let's say an info message saying Batch Working).

can you please advise if i am missing something ? And if i can  use main(Args _args) instead of run () ?

Regards,

I have the same question (0)
  • Suggested answer
    Sukrut Parab Profile Picture
    71,699 Moderator on at
    RE: Create batch job through X++ code

    You can create batch in two ways by extending RunbaseBatch or using Sysoperation framework. You are doing using RunbaseBatch. You can refer standard doc and figure out  what you are doing wrong 

    https://docs.microsoft.com/en-us/dynamicsax-2012/developer/walkthrough-extending-runbasebatch-class-to-create-and-run-a-batch

    If  you want to learn about how to create batch using Sysoperation framework refer below links.

    https://community.dynamics.com/365/financeandoperations/b/dynamicsaxinsightbyanas/posts/ax-2012-create-a-simple-batch-job

    daxmusings.codecrib.com/.../from-runbase-to-sysoperation-business.html

  • Suggested answer
    nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Create batch job through X++ code

    How did you set the batch to run? I don't see any main method in your class. Normally there would be a main method in RunBaseBatch based batches. That's executed when you launch the class from menu (menu item), and it contains the logic for showing the batch setup dialog (calling prompt method) and running the actual logic (run method).

    Check Tutorial_RunbaseBatch class in AOT.

  • Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    RE: Create batch job through X++ code

    main() and run() do completely different things; you can't use one instead of the other.

    • run() is what will execute when the batch is actually triggered.
    • main() is called when you have a menu item for the class. All it typically does it creating an instance, calling prompt() (to display a dialog) and run().

    Your run() method won't do anything, because it doesn't contain any runnable code. The call of info() is commented out.

    Also, it's not clear whether you know how to see the result. You would find Infolog messages in batch history ("Log" button).

  • sylvesterPowerBi Profile Picture
    384 on at
    RE: Create batch job through X++ code

    Dear Nikolaos,

    This code is just an example, the below code is the one im trying to generate:

    public class IS_RetailStatementJournalShortage extends RunBaseBatch

    {        

               /// <summary>

       /// Runs the class with the specified arguments.

       /// </summary>

       /// <param name = "_args">The specified arguments.</param>

       public static void main(Args _args)

       {  

    //my code

       }

       boolean canGoBatchJournal()

       {

           return true;

       }

       public container pack()

       {

           return conNull();

       }

       //Returns the stored object for the batch to use

       public boolean unpack(container packedClass)

       {

           return true;

       }

       //Determines whether to run on server or client

    //True - Server; False - Client

       public boolean runsImpersonated()

       {

           return true;

       }

    }

    What i want to know is, is there any missing method that keeping my code not running ?

    Regards,

  • nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Create batch job through X++ code

    I'm sorry but we can't troubleshoot your code if you don't share it and instead share some "just an example" that doesn't contain all the details.

    Please share your full class. For example, we still can't see what's in your main method so it's just not possible for us to see what could be wrong.

  • sylvesterPowerBi Profile Picture
    384 on at
    RE: Create batch job through X++ code

    Below is my full class:

    public class IS_RetailStatementJournalShortage extends RunBaseBatch
    {        
               /// 
       /// Runs the class with the specified arguments.
       /// 
       /// The specified arguments.
       public static void main(Args _args)
       {  
           RetailPosBatchTable     retailPosBatchTable;
           RetailTransactionTable  retailTransactionTable;
           RetailParameters        retailParameters;
           int counter = 0;
           NoYes posted = NoYes::No;
           LedgerJournalTable journalTable;
           LedgerJournalTrans journalTrans;
           LedgerJournalName   journalName;
           container                           _acctPattern;
           container                           _offSetAcctPattern;
           NumberSeq                           numberSeq;
           Voucher                             voucher;
           ledgerJournalCheckPost               ledgerJournalCheckPost;
           // Create journal
           ttsbegin;
           retailParameters = RetailParameters::find();
           journalName = LedgerJournalName::find(retailParameters.IS_LedgerJournalNameID);
           journalTable.clear();
           journalTable.initValue();
           JournalTable.initFromLedgerJournalName(journalName.JournalName);
           journalTable.Name = journalName.Name;
           journalTable.JournalName = journalName.JournalName;
           journalTable.insert();
           while select forupdate retailPosBatchTable where retailPosBatchTable.IS_Shortage == NoYes::No /*&& retailPosBatchTable.CloseDate >= str2DateDMY("01/08/2019")*/
           {
               posted = NoYes::No;
               if(retailPosBatchTable.Posted == NoYes::Yes && retailPosBatchTable.StatementId != "")
               {
                   posted = NoYes::Yes;
               }
               else if(retailPosBatchTable.Posted == NoYes::No)
               {
                   while select retailTransactionTable where retailTransactionTable.BatchID == retailPosBatchTable.BatchID && retailTransactionTable.store == retailPosBatchTable.StoreId && retailTransactionTable.BatchTerminalId == retailPosBatchTable.TerminalId
                   {
                       if(retailTransactionTable.entryStatus == RetailEntryStatus::Posted)
                       {
                           posted = NoYes::Yes;
                           break;
                       }
                   }
               }
               if(posted == NoYes::Yes)
               {
                   if(retailPosBatchTable.overAmountTotal() == 0)
                       continue;
                   else if(retailPosBatchTable.overAmountTotal() > 0)
                   {
                       var s = new IS_RetailStatementJournalShortage();
                       JournalTrans.LedgerDimension = s.getDimension(retailParameters.IS_ExcessAccount, retailPosBatchTable.StaffId);
                       JournalTrans.OffsetLedgerDimension = s.getDimension(retailParameters.IS_ExcessOffsetAccount, retailPosBatchTable.StaffId);
                       JournalTrans.AmountCurDebit = abs(retailPosBatchTable.overAmountTotal());
                       JournalTrans.AmountCurCredit = 0;
                   }
                   else
                   {
                       var s = new IS_RetailStatementJournalShortage();
                       JournalTrans.LedgerDimension = s.getDimension(retailParameters.IS_ShortageAccount, retailPosBatchTable.StaffId);
                       JournalTrans.OffsetLedgerDimension = s.getDimension(retailParameters.IS_OffsetShortageAccount, retailPosBatchTable.StaffId);
                       JournalTrans.AmountCurDebit = 0;
                       JournalTrans.AmountCurCredit = abs(retailPosBatchTable.overAmountTotal());
                   }
                   journalTrans.journalNum = JournalTable.JournalNum;
                   journalTrans.Txt = strFmt("%1 - %2",retailPosBatchTable.terminalID,retailPosBatchTable.batchid);
                   JournalTrans.AccountType            = LedgerJournalACType::Ledger;
                   JournalTrans.OffsetAccountType            = LedgerJournalACType::Ledger;
                   JournalTrans.TransDate              = retailPosBatchTable.CloseDate;
                   numberSeq = NumberSeq::newGetVoucherFromId(JournalTable.NumberSequenceTable, false);
                   voucher   = numberSeq.voucher();
                   JournalTrans.Voucher      = voucher;
                   JournalTrans.LineNum      = LedgerJournalTrans::lastLineNum(JournalTable.JournalNum)   1;
                   JournalTrans.CurrencyCode = Ledger::accountingCurrency(CompanyInfo::current());
                   JournalTrans.ExchRate = 100;
                   journalTrans.insert();
                   counter  ;
                   retailPosBatchTable.IS_Shortage = NoYes::Yes;
                   retailPosBatchTable.update();
               }// end if shift is posted
           }// end while shifts
           if(counter == 0)
           {
               ttsabort;
               Info("No shifts shortage/excess transactions were created.");
           }
           else
           {
               //ledgerJournalCheckPost = ledgerJournalCheckPost::newLedgerJournalTable(journalTable,NoYes::Yes);
               //ledgerJournalCheckPost.run();
               ttscommit;
               Info(strFmt("%1 Shifts shortage/excess transactions have been created.",counter));
           }    
       }
    public RecId getDimension(str _ledgerAccount, str _worker)
    {
       DimensionServiceProvider      DimensionServiceProvider = new DimensionServiceProvider();
       LedgerAccountContract        LedgerAccountContract = new LedgerAccountContract();
       DimensionAttributeValueContract   ValueContract;
       List                ListValueContract = new List(Types::Class);
       dimensionAttributeValueCombination dimensionAttributeValueCombination;
       DimensionStorage          dimStorage;
       if (_worker)
       {
           ValueContract = new DimensionAttributeValueContract();
           ValueContract.parmName('Worker') ;
           ValueContract.parmValue(_worker);
           ListValueContract.addEnd(ValueContract);
       }
       LedgerAccountContract.parmMainAccount(_ledgerAccount);
       LedgerAccountContract.parmValues(ListValueContract);
       dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);
       dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());
       return dimensionAttributeValueCombination.RecId;
    }
       boolean canGoBatchJournal()
       {
           return true;
       }
       public container pack()
       {
           return conNull();
       }
       //Returns the stored object for the batch to use
       public boolean unpack(container packedClass)
       {
           return true;
       }
       //Determines whether to run on server or client
    //True - Server; False - Client
       public boolean runsImpersonated()
       {
           return true;
       }
    }

  • Verified answer
    nmaenpaa Profile Picture
    101,160 Moderator on at
    RE: Create batch job through X++ code

    One more thing, please use the code formatting when you share your code, so that it's easier to read.

    You can reach it by "Use rich text formatting -> Insert -> Insert Code

    This time I did it for you.

    Looking at your code, it seems that you ignored our earlier comments. Please read our earlier posts again.

    Here's a summary of them:

    In main method, you must call prompt() which shows the batch dialog.

    Then you must call run to run the actual batch logic.

    Please check class Tutorial_RunBaseBatch in AOT.

  • sylvesterPowerBi Profile Picture
    384 on at
    RE: Create batch job through X++ code

    Thank You Sir.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Abhilash Warrier – Community Spotlight

We are honored to recognize Abhilash Warrier as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 1,841

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 783 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 490 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans