1. Put break point where you required in code.
2. Click symbols settings
Here is the tip/ resolution for debugging in VS 2015 when you faced issue with symbols are not loaded. Why symbols are loaded? After analyzing found that trying to debug the code which is out of your customized code which means other suite/ model code (standard Form from other model/ non extension form). So try to load symbols for the module and start debugging as shown below. 1. Put break point where you required in code. 2. Attach to Process. Debug->Attach to Process. After Attach to process (w3wp.exe) you will face that Symbols are not loaded issue. 3. Go to Module as shown. 4. In Modules select Ledger.dll -> right click -> 1. Click Always load automatically 2. Click symbols settings 5. Now Click on Load all symbols button. Make sure that select properties as shown below. 6. Now system will load all symbols related to Ledger Module for you. Click OK after finish. 7. Open AX and click form, now break point will hit for debugging......:-)
4 Comments
In AX2012 or AX 2009 we directly write code on existing number sequence class but in AX (7) new version need to create new class and required extend to NumberSeqApplicationModule and required delegate method for mapping. 1. Create EDT ChangeId. 2. Add EDT to Table ChangeLog. 3. Create new Table method numRefChangeId(). public class ChangeLog extends common { static NumberSequenceReference numRefChangeId() { return NumberSeqReference::findReference(extendedTypeNum(ChangeId)); } } 4. Create New Class NumberSeqModuleRisk and extend NumberSeqApplicationModule and a delegate method. lass NumberSeqModuleRisk extends NumberSeqApplicationModule { public void initializeReference(NumberSequenceReference _reference, NumberSeqDatatype _datatype, NumberSeqScope _scope) { #ISOCountryRegionCodes super(_reference, _datatype, _scope); switch (_datatype.parmDatatypeId()) { case extendedTypeNum(ChangeId): if("USA") { _reference.AllowSameAs = true; } /*if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoIT])) { _reference.AllowSameAs = true; }*/ } } protected void loadModule() { NumberSeqDatatype datatype = NumberSeqDatatype::construct(); datatype.parmDatatypeId(extendedTypeNum(ChangeId)); datatype.parmReferenceHelp(literalStr("Creating new ChangeId")); datatype.parmWizardIsManual(NoYes::No); datatype.parmWizardIsChangeDownAllowed(NoYes::No); datatype.parmWizardIsChangeUpAllowed(NoYes::No); datatype.parmWizardHighest(999999); datatype.parmSortField(1); datatype.addParameterType(NumberSeqParameterType::DataArea, true, false); this.create(datatype); } public NumberSeqModule numberSeqModule() { return NumberSeqModule::Proj; } [SubscribesTo(classstr(NumberSeqGlobal),delegatestr(NumberSeqGlobal,buildModulesMapDelegate))] static void buildModulesMapSubsciber(Map numberSeqModuleNamesMap) { NumberSeqGlobal::addModuleToMap(classnum(NumberSeqModuleRisk), numberSeqModuleNamesMap); } } 5. Write a job and run that static void ChangeId(Args _args) { NumberSeqModuleRisk numberSeqModuleRisk = new NumberSeqModuleRisk (); numberSeqModuleRisk .load(); } 6. Then run the wizard Organization Administration -> CommonForms -> Numbersequences -> Numbersequences -> Generate -> run the wizard. GO to Project management module -> setup -> Project management parameters form -> Num Seq 7. Now create methods as shown on Form below. [Form]
public class ChangeLog extends FormRun { NumberSeqFormHandler numberSeqFormHandler; /// <summary> /// /// </summary> NumberSeqFormHandler numberSeqFormHandler() { if (!numberSeqFormHandler) { numberSeqFormHandler=NumberSeqFormHandler::newForm(ChangeLog::numRefChangeId().NumberSequenceId, element, ChangeLog_DS, fieldNum(ChangeLog, ChangeId)); } return numberSeqFormHandler; } public void close() { if (numberSeqFormHandler) { numberSeqFormHandler.formMethodClose(); } super(); } [DataSource] class ChangeLog { public void create(boolean _append = false, boolean _extern = false) { element.numberSeqFormHandler().formMethodDataSourceCreatePre(); super(_append); if (!_extern) { element.numberSeqFormHandler().formMethodDataSourceCreate(true); } public void write() { super(); element.numberSeqFormHandler().formMethodDataSourceWrite(); } public boolean validateWrite() { boolean ret; ret = super(); ret = element.numberSeqFormHandler().formMethodDataSourceValidateWrite(ret) && ret; if (ret) { ChangeLog.validateWrite(); } return ret; } public void linkActive() { element.numberSeqFormHandler().formMethodDataSourceLinkActive(); super(); } public void delete() { element.numberSeqFormHandler().formMethodDataSourceDelete(); super(); } } } Now our custom number sequence is generated. Open your Form and check Num Seq by creating new record on your filed. In AX7 when ever we modify form there is an issue with menu item could not be opened. It is due to refresh. Follow below steps to open up the form :-)
1. Application suite Model -> Form -> CaseDetail = right click and Refresh. 2. Application suite Model -> Menuitem -> Display -> CaseDetail = Refreshed. 3. Application suite Model -> Menu Extensions -> Common menu = Refreshed. 4. IIS restart. something error looks like this. Print values using Set. Set will not allow duplicate values. (A010, A060,A010, A060) = A010,A06011/6/2016 static void SUNPreviousApproverName(Args _args)
{ str emplName; container approverContainer; str previousApprover; int i; Set set; SetEnumerator setEnum; str approver ; //return EmplTable::emplId2Name(this.PCISCMPreviousApprover); approverContainer += ["A010"];//,"A060","A010","A060"]; set = new Set(Types::String); for (i=1; i<= conlen(approverContainer); i++) { set.add(conpeek(approverContainer, i)); } setEnum = set.getEnumerator(); while(setEnum.moveNext()) { if (set.elements() == 1) { approver += setEnum.current(); } else { approver += setEnum.current() + ","; } } info(strfmt("%1",approver)); } Unable to cast object of type 'Dynamics.AX.Application.Forms.CaseDetail' to type 'Dynamics.AX.Application.FormControl'.
---- Try deleting new changes on form and re build the solution. Some may think delete c Error: “The target principal name is incorrect”.
Deploy reports using shell as admin with command: publish-AXReport -ReportName *. In powershell. If not: Reinstall AOS, configure reporting services, re deploy using shell :-) tatic void sun_createVendorInvoiceJournal(Args _args)
{ LedgerJournalCheckPost jourCheckPost; LedgerJournalTable jourTable; AxLedgerJournalTable header = new AxLedgerJournalTable(); AxLedgerJournalTrans trans = new AxLedgerJournalTrans(); container offsetDim; // The AP invoice journal name, could vary. LedgerJournalNameId ledgerJournalNameId = "GenJrn"; //110110-069-022 // This is the entry against the Vendor account. // It will have to pre-exist for this script to work. // It is probably created the first time such an entry is // made on a journal line. DimensionAttributeValueCombination davc; LedgerJournalACType accType, offsetAccType; BankAccountTable bankAccountTable; accType = LedgerJournalACType::Vend; offsetAccType = LedgerJournalACType::Ledger; header.parmJournalName(ledgerJournalNameId); header.parmJournalType(LedgerJournalType::VendInvoiceRegister); header.save(); trans.parmAccountType(accType); trans.parmJournalNum(header.ledgerJournalTable().JournalNum); offsetDim = ["001","110110","BusinessUnit"]; //First is Display value, followed by Main Account and then dimensions. trans.parmAccountType(LedgerJournalACType::Vend); // Note: This only works if the DimensionValueAttributeCombindation record // exists from before. select firstonly RecId from davc where davc.DisplayValue == "Vendor3"; //Vendor123 is the vendor account number. trans.parmLedgerDimension(davc.RecId); //There's a parm method for credit as well. trans.parmAmountCurDebit(99.15); trans.parmOffsetAccountType(offsetAccType); trans.parmOffsetLedgerDimension(AxdDimensionUtil::getLedgerAccountId(offsetDim)); trans.save(); jourTable = header.ledgerJournalTable(); if (jourTable.RecId > 0) { jourCheckPost = ledgerJournalCheckPost::newLedgerJournalTable(jourTable, NoYes::Yes, NoYes::Yes); // Post only if there is succesful validation. if (jourCheckPost.validate()) { //jourCheckPost.run(); } } } 1. On Form DS go to event right click and copy the event handler.
2. Create a class and paste the copied event handler. 3. Write logic to perform action. example: /// <summary> /// Runs the form <c>CaseDetail</c>. /// </summary> public static class CaseDetailExecQry { /// <summary> /// <For case management> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> [FormDataSourceEventHandler(formDataSourceStr(CaseDetail, CaseDetailBase), FormDataSourceEventType::QueryExecuting)] public static void CaseDetailBase_OnQueryExecuting(FormDataSource sender, FormDataSourceEventArgs e) { CaseDetailBase caseDetailBase; CaseCategoryHierarchyDetail detail; select firstonly detail where detail.CategoryType == CaseCategoryType::Property; while select * from caseDetailBase where caseDetailBase.CategoryRecId == detail.RecId { sender.query().dataSourceTable(tableNum(CaseDetailBase)).addRange(fieldnum(CaseDetailBase,CategoryRecId)).value(sysquery::value(detail.RecId)); }}} |
AuthorI'm Sunil Rakesh Kanchumarthy, technical professional having good exposure on axapta. Created this useful blog for knowledge sharing. Having good experience as an consultant on Microsoft Dynamics Axapta (ERP). Developed customization using X++, AOT, and knowledge on EP & AIF. Familiar with Axapta Installation of version 3.0, 4.0, Ax2009, Ax 2012 along with SQL Server. Done Axapta Reports in Ax 3.0, Ax 2009 & SSRS reports in Ax 2012. Customizations on D365 Operations (AX7). Experience on Integrations, using LogicApps, Knowledge on PowerApps development, and also in code deployment. Archives
September 2018
Categories |