Skip to main content

Posts

Showing posts from October, 2011

You can use the following code in order to achieve the requirement.

You can use the following code in order to achieve the requirement.You need to write it in the fetch method- str todayDate; ; element.printJobSettings().SetTarget(PrintMedium::File); element.printJobSettings().format(printFormat::PDF); todaydate = Date2str(SystemDateGet(),213,2,0,2,0,2); element.printJobSettings().FileName(strfmt('c:\\Report%1.pdf',todaydate));

Set report ranges using code..?

I'm calling report using output menuItem from specified form. what i really want is to set the report Ranges by the caller record from the form so the following is the situation: 1. Output meneItem on the form. 2. On the init() method in the report the following tableBuffer = element.args().record(); 3. The required now is to set the report query (Ranges) by using one of the TableBuff fields. I see what you are saying. Basically, if you start from a menu item with NO record, you want to basically NOT use what is stored in usage data. At that point, couldn't you do something like this: public void init() { CustTable ct; ; super(); if (element.args().record()) { this.query().dataSourceTable(TableNum(CustTable)).addRange(FieldNum(CustTable,Name)).value(ct.Name); } else { this.query().datasourceTable(TableNum(CustTable)).addRange(FieldNum(CustTable,Name)).value(""); } } Granted, the range value would hav to make sense based on the field

Send a report, but change the filename according to caller

My customers has grown tired by the filename 'Axapta report' in class Info -> method reportsend(). I need to change the filename to the name of the caller. But how do I find the caller in class Info -> Method reportsend() ? Let's see if it works this time.... (it's only the SIXTH time that I try to post this answer :( ) There seems to be no way to get a reference to the ReportRun object; the method PrintJobSettings.ReportRun always seems to return null in reportSendMail. You could set a property of PrintJobSettings in your report and use that to fill the filename. Another possible solution (no guarantees) is the following: Add the following to infolog.reportSendMail: if (globalCache.isSet(curuserid(),classidget(p1))) { fileName = globalCache.get(curuserid(),classidget(p1)); globalCache.remove(curuserid(),classidget(p1)); } And to the method SysReportRun.print add the next code (before calling super). SysGlobalCache

Dynamics AX in the Field

Have you installed one of the new Report Builders-- version 2 or version 3-- and can't get AX to launch it? This posting addresses the issue and walks you through the steps to point AX to the new version. The first step is that you will need to get Report Builder 2.0 or 3.0 installed on your report server. You should be able to access the Report Builder through the Internet Explorer first. In addition, you should already be able to access Report Builder 1.0 from AX. If you don't have this working you will need to revisit the installation guides. Once you have Report Builder 1.0 working through AX and the newer version of Report Builder working outside of AX than you can make the following changes. Try this in a Test Environment prior to performing this on a production environment and as always make sure you have good backups. Get into Dynamics AX and access the AOT. 1) Locate the SRSConfiguration class (Classes >>SRSConfiguration). 2) Edit the getReportBuilderU

transfer Images to Word from AX

I need to transfer the employee`s image to an automatic generated word document. It is possible to transfer Text to COM word object with [bookmark, bookmarkValue] = ['EmplTable_FullName', LtabDirParty.Name]; if (this.gotoBookmark(bookmark)) this.insertValue(bookmarkValue, 0); whereby Textmarker within Word = EmplTable_FullName Method gotoBookmark() COMrange = COMdocument.goTo(#wdGotoBoomark,COMArgument::NoValue,COMArgument::NoValue,bookmark); Method inertValue() COMrange.insertAfter(value); Does anybody know how to transfer the Empl-Image (as an image) from AX to word? binData.setData( CompanyImage::find(LtabEmpl.dataareaId, LtabEmpl.TableId, LtabEmpl.RecId).Image; binData.base64Encode() transfers a binary string which will be displayed as a binary text. But how can I display the image as real Image? The idea was the right one. In my case I wanted to move the image to word without having the image stored to the filesystem. Herefore I had to use

Populating a form Grid through a Temp table using a query

Hello All, I'm working in AX 2009. I have a form with a grid control, which I am trying to populate by using a Temporary table and an X++ query. The query is joining 4-tables, i.e., CustInvoiceTrans, CustInvoiceJour, InventDim, and CustTable. The only range is on CustInvoiceTrans, InvoiceDate. I have set "Relations" to true for each, as CustInvoiceTrans.InvoiceId == CustInvoiceJour.InvoiceId and CustInvoiceTrans.InventDimId == InventDim.InventDimId and CustInvoiceJour.OrderAccount == CustTable.AccountNum. The fields on the grid are from the temp table, which I dragged to the form's grid. I have used a temp table before with success, but I am unable to get my grid to populate with data, although by placing a breakpoint in code and stepping thru the debugger I have been able to see data. I have 3-methods in my project, the classDeclaration, the init, and a method named populateRecords, where I define the query class objects. The following is my code

AX 2009 - How to Transfer Security Settings to a Production Server

Option 1 – Use the Security Export/Import Process In this option, you use the built-in Export and Import functions on the User group permissions form. Export from STAGING Log into STAGING system Go to Administration | Setup | Security | User group permissions Select the User group and Domain for which you want to export Click the Export to button Enter the file name and location of the export file (e.g., SalespersonExport.asg) Click OK The User group/Domain security is exported into a *.asg file Import in PRODUCTION Log into PRODUCTION system Go to Administration | Setup | Security | User group permissions Select the User group and Domain for which you want to import the new security settings Click the Import button Browse to the .asg file created in step 7 above Click OK The security settings from the .asg file are imported into the User group/Domain you selected in step 3 Option 2 – Use the Standard Export/Import Process In this option, you use the standard built-in

Managing Client Versions

How do you know if you have updated all of your client machines to the correct and current AX version? For a lot of companies that have distributed clients, managing the client software can be somewhat of a headache for the IT staff. As the roll out of new kernel builds are released, it is important to make sure the client applications are updated as well. It is especially difficult if the client applications are located on mobile machine or computers that may not be inaccessible locations due to a variety of business requirements. The following code suggestion can be put into the AOD to help prevent client side applications from logging into the production system when it has not been updated to the correct kernel version. When our Premier Field Engineer team performs a Health Check , we will check the client executable to make sure they are on the same kernel version as the AOS. This helps improve the AX environments stability. 1) Within the AOT, create a new class a.

Create Payment Journal with X++

static server boolean processCheckPayment(CAM_CheckModule _checkModule) { LedgerJournalName ledgerJournalName; LedgerJournalTable ledgerJournalTable; LedgerJournalTrans ledgerJournalTrans; LedgerJournalCheckPost ledgerJournalCheckPost; Common common; NumberSeq numberseq; CustTrans custTrans; CustTransOpen custTransOpen; Specification specOffsetVoucher; CAM_Parameters parameters = CAM_Parameters::find(); CustTable custTable = CustTable::find(_checkModule.CustAccount); boolean result = false; InvoiceId invoiceId; ; while select custTransOpen where custTransOpen.RefRecIdCheck == _checkModule.RecId && custTransOpen.UseRefRecId { custTrans = custTransOpen.custTrans(); invoiceId = custTrans.Invoice; try { ttsbegin; select firstonly ledgerJournalName where ledgerJournalName.JournalName == parameter

I would like to add a field to InventJournalTable that will be copied into an identically named field in InventTrans after posting. The fields are added, and the Journal currently contains the correct value, but after posting, the InventTrans table only c

You should create a new InventMovement method like this: public MyNewFieldType myNewField() { return MyNewFieldType::DefaultValue; // suppose your new field is an enum } Then modify \Classes\InventMovement\initInventTransFromBuffer void initInventTransFromBuffer(InventTrans _inventTrans, InventMovement _movement_orig) { // ... _inventTrans.MyNewField = this.myNewField(); } And finally overload the new method in the InventMov_Journal class: public MyNewFieldType myNewField() { return inventJournalTrans.MyNewField; }

Using right click by code

public int showContextMenu(int _menuHandle) {     int ret;     int myItemIdx;     PopupMenu popupMenu = PopupMenu::create(_menuHandle, this.hWnd());     ;     myItemIdx = popupMenu.insertItem("Click here");     ret = popupMenu.draw();     if (ret == myItemIdx)     {         info("Clicked");     }     return ret; }

How to transfer new fields from LedgerjournalTrans to LedgerTrans when posting

We added some new fields to both ledgerJournalTrans and LedgerTrans tables. I would like to copy those fields when posting, but i can't seem to find where i can put the code. I don't know where the data from LedgerJournaltrans is transferred to LedgerTrans. Solved: this is done in LedgerVoucherTransObject class. I added parm methods for new fields and corrected newTransLedgerJournal method to include their transfer to LedgerTrans. LedgerJournalCheckPost Classdelaration DTAccruedExpensesContractId xxContractId; public DTAccruedExpensesContractId parmContractId(DTAccruedExpensesContractId _xxContractId) { ; xxContractId = _xxContractId; return xxContractId; }

How to have a pattern like XXX-XX-XXXX in a string control in a form

I want to have XXX-XX-XXXX pattern automatically genrated in my string control in my form, so, as the user enter's the value e.g. 123456789, it automatically show's 123-45-6789. In your edit-method you can also use NumberSeq::numInsertFormat() with a format string like "###-##-####" You can use an edit method with something like (not the same formatting, but that's detail). edit str editMyString(boolean _set, str _value) { //format string in XXX-XXX-XXX..... str _format(str _unformatted) { str formatted; int i,len; ; len = strlen(_unformatted); for(i=1;i<=len;i+=3) { formatted += (formatted ? '-' : '')+substr(_unformatted,i,3); } return formatted; } ; if (_set) { //store string without formatting myString = strrem(_value,'-'); } //display a formatted string return _format(myString); }

Code for Excel import by choosing file in Axapta

This is a very useful code for importing excel into DAX table. Developer can add/modify their logics while importing excel into DAX table. This is a simple and compact code. Developers have to change this code as per their requirements. Note: Here excel file will be 3 columns, 1. Vendor Code, 2. vendor Group and 3. vendor Currency. You can add or less fields in excel but same incorporation should be done in this job (bold area). While you incorporate this type of procedure then I recommend to all do this code into a class instead of job. static void Raj_ExcelUploadByFile(Args _args) { #AviFiles FilenameOpen filename; dialogField dialogFilename; Dialog dialog= new Dialog("Excel Upoad"); Container vendCont[]; int rowIdx; Counter linesImported; int lastRow; boolean ok = true; str c1,c2,c3; str input; SysExcelApplication application; SysExcelWorkBooks workBooks; SysExcelWorkSheets workSheets; SysExcelWorkSheet workSheet; SysExcelCells cells; S

Cross company reports [AllowCrossCompany] in Dynamics AX , X++

This report example will help you to get the data from selected companies or all companies using AllowCrossCompany property In the AOT, query node objects have the AllowCrossCompany property listed in the Properties window. For new queries the default value is No (which is equivalent to false in X++ code). To make a query cross-company you need to set AllowCrossCompany to Yes. The classes QueryRun and Query both have the AllowCrossCompany property, but their values always equal each other. When you read AllowCrossCompany from QueryRun, QueryRun reads it from Query. When you set AllowCrossCompany on QueryRun, it sets in on Query. Please follow me to get the report from multiple companies as shown below. Right click on AOT >> Reports and Create a new report by name “SR_CrossCompanyItems” as shown below Expand the datasources and add InventTable as datasource. On the Query Node, right click and go to property and set the AllowCrossCompany peroperty to “Yes” as shown below.

What does this mean: "The form datasource query object does not support changing its AllowCrossCompany property after the form has executed the query."?

I have made a form with datasources vendtable and vendtrans. Inside vendtable_ds.executequery() looks like this: QueryBuildDataSource queryBuildDatasource ,queryBDS_VendTrans_Invoice; ; queryBuildDatasource = this.query().dataSourceTable(tablenum(vendtable)); queryBDS_VendTrans_Invoice = this.query().dataSourceTable(tablenum(vendtrans)); if (curext() == "MASTERCOMP") { this.query().allowCrossCompany(true); } else { this.query().allowCrossCompany(false); } //FilterVendorName = stringedit control on form if (FilterVendorName.text()) { queryBuildDatasource.addRange(fieldNum(VendTable,Name)).value(strfmt("*%1*", FilterVendorName.text())); } else { queryBuildDatasource.clearRange(fieldNum(VendTable,Name)); } //FilterInvoiceNumber = stringedit control on form if (FilterInvoiceNumber.valueStr() == "") { queryBDS_VendTrans_Invoice.enabled(false); } else { queryBDS_VendTrans_Invoice.enabled(true); queryBDS_VendTrans_In

How to access other data in other company accounts in Axapta / Cross Company

First of all we have to understand the concept of Axapta, that one AOS (Application Object Service) of Axapta can have many company accounts, one AOS can be described as one Group of company, and each company accounts in Axapta can be described as sub ordinary of the company group. Just say one group company who implemented Axapta wants to put all their sub ordinary company to one AOS, that mean we have to setup the parameter so that can have more than one company accounts, each company accounts can have their own setup parameters. There is one feature in Dynamics Ax 2009 which is can access other data in other company accounts through the code or through Data Source object, we called it cross company . For example cross company in DataSource. Each Form or Report object have DataSource to pull the data into it. We can add Table/Query object as DataSource or we can call them at runtime. This is the example how to setup the DataSource to enable the cross company feature below :

How to limit a process to one session?

I'm able to scan all call stacks, here is a working example: MyClass myClass; str callStack; xSession session; Counter i; int classNamePos; #AOT ; myClass = MyClass::construct(); for (i = 1; i <= xSession::maxSessionId(); i++) { session = new xSession(i, true); if (session && session.userId() && session.sessionId() != sessionId()) { callStack = con2Str(xSession::xppCallStack()); classNamePos = strScan(callStack, #ClassesPath + '\\' + classstr(myClass), 1, strLen(callStack)); if (classNamePos > 0) { warning(strFmt("%1 is currently running this function.", (select userInfo where userInfo.Id == session.UserId()).Name)); return; } } }

Create Payment Journal with X++

static server boolean processCheckPayment(CAM_CheckModule _checkModule) {       LedgerJournalName         ledgerJournalName;       LedgerJournalTable         ledgerJournalTable;       LedgerJournalTrans         ledgerJournalTrans;       LedgerJournalCheckPost ledgerJournalCheckPost;      Common common;      NumberSeq numberseq;      CustTrans custTrans;      CustTransOpen custTransOpen;      Specification specOffsetVoucher; CAM_Parameters parameters = CAM_Parameters::find(); CustTable custTable = CustTable::find(_checkModule.CustAccount); boolean result = false; InvoiceId invoiceId; ; while select custTransOpen where custTransOpen.RefRecIdCheck == _checkModule.RecId && custTransOpen.UseRefRecId { custTrans = custTransOpen.custTrans(); invoiceId = custTrans.Invoice; try { ttsbegin; select firstonl

Changing the language at runtime in X++

We recently had a case where the customer wanted to change the language being used for a given AX user at runtime. The customer had sorted out how to change the language displayed in forms and reports but the buttons on the navigation pane were not getting updated. Here is a way to handle this scenario: In the setSetup method of the SysUserSetup form within the if clause add the following: if (infolog.language() != userinfo.language) { infolog.language(userinfo.language); infolog.navPane().loadStartupButtons(); }

Calling a web service from X++ code

This post describes how to call the AIF sales order service from X++ code. The same approach can be used for calling any web service. In the AOT under the References node add a service reference specifying the wsdl location of the service, a .NET code namespace and a reference namespace. An example of a wsdl url is: http://myMachine.myDomain/MicrosoftDynamicsAXAif50/salesorderservice.svc?wsdl Once the reference has been created, in X++ create a new class that runs on the server. In a method in the class write the code that calls the service. An example of how to call the sales order service is below. Once the code in the class compiles close the AX client. Go to the Appl\Standard\ServiceReferences directory and copy the app.config and the generated assembly to the Server\bin directory. SalesOrder.SalesOrderServiceClient proxyClient; SalesOrder.AxdSalesOrder salesOrder; SalesOrder.AxdEntity_SalesTable salesTable; SalesOrder.AxdEntity_SalesLine salesLine; SalesOrder.AxdEntity

Research method on X++ forms

In AX2009 if you call the research() method on a form passing true, the cursor position within a grid should be retained. However, this is true only if the query created by the form uses inner joins. Any outer joins, aggregations, temp tables, etc. cause the cursor to go to either the first or last record (depending upon the StartPosition property for that data source). In 2009 if you want to keep the cursor position and use joins other than inner joins you have to keep track of the cursor position. Code like the following will do this: int pos; super(); pos = salesQuotationTable_ds.getPosition(); salesQuotationTable_ds.research(); salesQuotationTable_ds.setPosition(pos);

Tutorial: refresh, reread, research, executeQuery - which one to use?

    Loading... X++ developers seem to be having a lot of trouble with these 4 datasource methods, no matter how senior they are in AX. So I decided to make a small hands-on tutorial, demonstrating the common usage scenario for each of the methods. I have ordered the methods based on the impact on the rows being displayed in the grid. 1. Common mistakes Often, developers call 2 of the mentioned methods in the following order: formDataSource.refresh() formDataSource.research() or formDataSource.reread() formDataSource.research() or formDataSource.research() formDataSource.executeQuery() or formDataSource.research() formDataSource.refresh() / formDataSource.reread() All of these are wrong, or at least partially redundant. Hopefully, after reading the full post, there will be no questions as to why they are wrong. Leave a comment to this post if one of them is still unclear, and I will try to explain in more detail. 2. Refresh This method basically ref

Creating Custom Pop-Up and Email Alerts in Dynamics AX 2009

There could be occasions where an alert and/or email needs to be sent to a Dynamics AX user informing them of something that has taken place in the system that cannot be set up using the standard Dynamics AX alert such as generating an alert while running custom X++ code. To perform this function the following two snippets of code can be utilized to create pop-up alerts and/or email alerts that will be sent by Dynamics AX using the existing alert processing batch jobs. The following example would send a pop up alert to a user notifying them that a customer record has changed: static void create_alert( … parms if needed …) { EventNotificationSource source; EventNotification event = EventNotification::construct(EventNotificationSource::Sync); … Any Tables or variables that may be needed … CustTable custTable = CustTable::find(’1000′); ; event.parmRecord(custTable); event.parmUserI

Using RunBaseBatchPrintable class

RunBase framework is used when we develop a class to run an operation within Dynamics AX, such as posting a sales order or used in any data manipulation operation. If we need to batch the operation, we will commonly use the RunBaseBatch framework by extending the RunBaseBatch class. Dialog for a class that extends RunBaseBatch The RunBaseBatch class does not provide the access to printer such as when running a report. If you need to provide the printer support to allow users to specify the printer options in the operation, you can extend the RunBaseBatchPrintable class instead of RunBasebatch class. Dialog for a class that extends RunBaseBatchPrintable When extending the RunBaseBatch class, you need to override the pack() and unpack() methods. If query is used in the operation, you may need to also override the initParmDefault(), queryRun(), and showQueryValues() methods. When extending the RunBaseBatchPrintable class, in addition to the above methods, you would

Create Alert using X++ codes

Sometimes Infolog message is not sufficient enough for prompting information to users. It is possible to create alert message using code as an alternative. It is fairly simple to create alert message manually by just inserting a new record in EventTable where all the alert messages are stored. Below is a code snippet for creating alert using code in AX 2009. static void CreateAlertUsingCode(Args _args) { EventInbox inbox; ; inbox.initValue(); inbox.ShowPopup = NoYes::Yes; inbox.Subject = "This is the Alert subject"; inbox.Message = "This is the Alert message"; inbox.AlertedFor = "This alert is just information no links are available"; inbox.SendEmail = false; inbox.UserId = curuserid(); inbox.TypeId = classnum(EventType); inbox.AlertTableId = tablenum(Address); inbox.AlertFieldId = fieldnum(Address, Name); inbox.TypeTrigger = EventTypeTrigger::F

AX 4.0 client slow in startup / logon

On a fresh AX 4 installation (yes, I know it’s still AX 4), we found out that the AX client is slow in startup and it takes about 10 seconds after double-clicking the Dynamics AX icon before the application is fully loaded. It's really simple to resolve this. Go to IE > Internet Options > Advanced tab > Security node > verify that the "Check for publisher's certificate revocation" checkbox is unchecked. Once this is done, AX client is loaded almost instantly after double-clicking the icon.

.NET Business Connector Reset

Eğer AX ile dış ortamlar arasında bir entegrasyon üzerinde çalışıyorsanız, AX tarafında değiştirdiğiniz kodların Business Connector (BC) tarafında yenilenmediğini ve hala eski şekli ile çalıştırıldığını görürsünüz. Bunun temel nedeni AOS’un kod performansını artırmak üzere kullandığı önbellek (cache) mekanizmasıdır. Canlı kullanımda olan bir projede normal olsa da, development esnasında oldukça sıkıntı veren bu durumu atlatmak için alttaki çözümü deneyebilirsiniz : Bir web servisi yayınladıktan sonra her değişiklik yaptığınızda alttaki yolu izleyin: 1. Ax tarafında alttaki gibi bir job yazıp çalıştırın.   1 static void FlushBC(Args _args) 2 { 3 ; 4 xSession::removeAOC(); 5 SysTreeNode::refreshAll(); 6 SysFlushDictionary::doFlush(); 7 xSession::updateAOC(); 8 } 2. IIS stop / start yapın. 3. BC’yi kullanarak AX nesnelerine eriştiğiniz metodlarda Garbage Collector’u çalıştırın.   01 [WebMethod] 02 public string testWS( string uid, string

Pack – Unpack Tasarım Deseni (Pack – Unpack Design Pattern)

          Bir nesneye ait durumunu (parametrelerini, değerlerini vb : saved state) kaydederek daha sonra tekrar kullanmak gerektiğinde Pack – Unpack yapısı kullanılmalıdır. Böylece aynı nesne aynı değerlerle tekrar oluşturulabilir. Ayrıca nesnenin katmanlararası (istemci – sunucu : client – server) geçişi sözkonusu ise değerlerin transferi için yine Pack – Unpack yapısı gereklidir. Dynamcis AX’ta debug yaparken değişkenlerin birden sıfırlandığına şahit olduysanız, ya da dialog metodu ile kullanıcıdan aldığınız değerlerin bir türlü işleme dahil olmadığını görüyorsanız sorun pack – unpack yapısının kullanılmamış olmasıdır. Çünkü nesne katmanlar aarası taşınırken değerleri taşınamaz. Nesnelerin o anki istenen değerlerini kaydetmek için (save state) pack metodu kullanılır. Bu metod belirtilen değerleri bir container’e yazar ve kaydeder. Kaydedilmiş değerleri alıp kullanmak için ise Unpcak metodu kullanılmalıdır. Pack ve unpack metodları oldukça standart metodlardır ve genel olarak