This blog is all about Microsoft Dynamics AX(formerly known as Axapta). This site contains some Microsoft Dynamics AX X++ Codes for use in your day to day use.
Tuesday, December 30, 2014
Monday, February 17, 2014
Exchange Rate field Enable in AX 2012
HI All
In standard AX, the AP invoice journal and the general journal contain the field for currency exchange rate. However, this field by default is not editable.
Path: Accounts payable à Journals à Payment journal à Lines à General tab
by default in standard this field is non editable .
Solution : To make this field as editable
AOT-->Classes-->LedgerJournalFormTrans-->setExchRateEnabled() Method. Just comment this whole code automatically Exchange rate and Secondary exchange rate fields should get enabled.
In standard AX, the AP invoice journal and the general journal contain the field for currency exchange rate. However, this field by default is not editable.
Path: Accounts payable à Journals à Payment journal à Lines à General tab
by default in standard this field is non editable .
Solution : To make this field as editable
AOT-->Classes-->LedgerJournalFormTrans-->setExchRateEnabled() Method. Just comment this whole code automatically Exchange rate and Secondary exchange rate fields should get enabled.
Monday, February 3, 2014
AX SSRS Error: The request failed with HTTP status 401: Unauthorized.
In AX, when certain users attempt to access an SSRS report in an environment, they are getting the error 'The request failed with HTTP status 401: Unauthorized' (Figure 1 below). This was occurring for all reports for this user. Other users were able to access the report perfectly fine. The user was able to run everything perfectly the day before. The answer was Troubleshooting step 5 below: Log out of Windows instance and log back in. I'll provide the long troubleshooting steps below in case someone else's issue was different.
This issue is a permissions issue somewhere. At this point, we need to determine if its an issue with the user accessing the report. You can do the below troubleshooting steps. This was the order I did it in but you don't have to do it in this order.
- SSRS server (server permissions)
- SSRS reports (SSRS permission restrictions)
- AX security issue (probably not but good to check)
- An issue with all users or just them
- An issue with local cache or something screwy with current windows session
To help the users identify this issue, I usually ask them to do the following on the server where they are receiving this error:
- Click on the Start menu in Windows
- Type 'cmd' in the 'Search programs and files' search line in the start menu
- In the command prompt, type 'ping CDBRS-MAX01'
- Take a screenshot of the command responses and send back the results.
- The results should come back with the standard ping response of 'Reply from XX.XX.X.XXX: bytes=32...''.
Troubleshoot 2:
Having established they can access the report server, have the user access the report through the SSRS server. Have them do the following in the server where the AX client is erroring and if necessary, the SSRS report server itself:
- Go to internet explorer and access the SSRS report server (commonly 'http://[SSRSSERVERNAMEHERE]/reports'
- Once here, go to 'Dynamics AX' folder
- click on the report that is erroring
- Run the report and see if it runs. Just make sure required fields are populated.
Troubleshoot 3:
Have the user run the report from a server other than the one where the user was encountering the error. I logged into the AOS on their machine under my name and did the hold shift+right click on the .axc file, enter their credentials so we were running AX as that user in my server instance, and try running the report.
Troubleshoot 4:
Have other users attempt to run that report as well as others. Determine if its an issue with just that user. If no one is able to run the report or others, the reports may need to be deployed or the SSRS server settings need to be checked.
Troubleshoot 5:
This actually resolved the issue. Something went wrong with the user's Windows server session. I wasn't exactly sure what the issue was but having the user log out and log back in to the server resolved.
In this test, do the following:
- go to the person's terminal and watch them try to run the report
- hold shift+right click on the .axc file they were using to run the report and run as a different user. Use your own user
- In AX under your user in their terminal session, try to run the troubled report.
- If it passes (it did in my instance), hold shift+right click on the .axc file and run as a different user, only this time use the person's credentials. For us, the user was able to run the report this way but not when just clicking on the .axc in the normal fashion
How To: Clear or Delete data from an AX container
Using the conDel Function [AX 2012], a user can delete certain elements from a container. When these elements are removed, the numbering in the container will adjust accordingly so that the numbers will always be sequential
There are three parameters container conDel(container container, int start, int number):
- container container
- the container that the user wishes to have the data deleted from
- int start
- the spot in the container to start deleting values
- If this number is 0, it will not delete anything
- The number given will actually be deleted (e.g. 2 will actually include element 2 in the deletion)
- int number
- the number of elements to delete in the container
- If this number is larger than the container, it will delete everything from the start value on
static void daxTestDelContainer(Args _args) { container test = ['a','b','c','d','e','f','g','h','i']; container testManip = test; int i;
info ("BEGIN TEST - the container data in full"); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); }
info ("TEST conDel(testManip, 0, 3) - Remove 3 at spot 0"); testManip = conDel(testManip, 0, 3); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); }
info ("TEST conDel(testManip, 1, 3) - Remove 3 at spot 1"); testManip = conDel(testManip, 1, 3); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); }
// Reset the container testManip = test;
info ("TEST conDel(testManip, 2, 3) - Remove 3 at spot 2"); testManip = conDel(testManip, 2, 3); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); }
// Reset the container testManip = test;
info ("TEST conDel(testManip, 3, 5) - Remove 5 at spot 3"); testManip = conDel(testManip, 3, 5); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); }
// Reset the container testManip = test;
info ("TEST conDel(testManip, 3, 50) - Remove 50 (more than container has) at spot 2"); testManip = conDel(testManip, 3, 50); // Cycle (iterate) through the container for (i=1; i <= conlen(testManip); i++) { info(strFmt("%1 - %2", i, conpeek(testManip, i))); } }
Count Number of Tables,Forms EDT's in AX 2012
To count number of Tables, EDT's, Form's.. etc all objects in AOT . Run the below job to get number of objects available in AOT.
static void daxCountTablesInAX(Args _args)
{
// Count of all the Objects.
info (strFmt("Tables in AX: %1", treenode::findNode('\\Data Dictionary\\Tables').AOTchildNodeCount()));
info (strFmt("Extended Data Types in AX: %1", treenode::findNode('\\Data Dictionary\\Extended Data Types').AOTchildNodeCount()));
info (strFmt("Forms in AX: %1", treenode::findNode('\\Forms').AOTchildNodeCount()));
info (strFmt("Parts-- Infoparts in AX: %1", treenode::findNode('\\Parts\\Info Parts').AOTchildNodeCount()));
info (strFmt("Part- Form Parts in AX: %1", treenode::findNode('\\Parts\\Form Parts').AOTchildNodeCount()));
info (strFmt("Part -- Cues in AX: %1", treenode::findNode('\\Parts\\Cues').AOTchildNodeCount()));
info (strFmt("Part-- Cue Groups in AX: %1", treenode::findNode('\\Parts\\Cue Groups').AOTchildNodeCount()));
info (strFmt("DataSets in AX: %1", treenode::findNode('\\Data Sets').AOTchildNodeCount()));
info (strFmt("SSRS Reports in AX: %1", treenode::findNode('\\SSRS Reports\\Reports').AOTchildNodeCount()));
info (strFmt("SSRS Reports report style templates in AX: %1", treenode::findNode('\\SSRS Reports\\Report Style Templates').AOTchildNodeCount()));
info (strFmt("SSRS Report report datasources in AX: %1", treenode::findNode('\\SSRS Reports\\Report Datasources').AOTchildNodeCount()));
info (strFmt("Report Images in AX: %1", treenode::findNode('\\SSRS Reports\\Report Images').AOTchildNodeCount()));
info (strFmt("Report Templates in AX: %1", treenode::findNode('\\Reports\\Report Templates').AOTchildNodeCount()));
info (strFmt("Report Section Templates in AX: %1", treenode::findNode('\\Reports\\Section Templates').AOTchildNodeCount()));
info (strFmt("Visual Studio Projects of Dynamics AX Model Projects in AX: %1", treenode::findNode('\\Visual Studio Projects\\Dynamics AX Model Projects').AOTchildNodeCount()));
info (strFmt("Visual Studio Projects of C Sharp Projects in AX: %1", treenode::findNode('\\Visual Studio Projects\\C Sharp Projects').AOTchildNodeCount()));
info (strFmt("Visual Studio Projects of Web Application Projects in AX: %1", treenode::findNode('\\Visual Studio Projects\\Web Application Projects').AOTchildNodeCount()));
info (strFmt("Visual Studio Projects of Analysis Services Projects in AX: %1", treenode::findNode('\\Visual Studio Projects\\Analysis Services Projects').AOTchildNodeCount()));
info (strFmt("Menus in AX: %1", treenode::findNode('\\Menus').AOTchildNodeCount()));
info (strFmt("Menu Items Display in AX: %1", treenode::findNode('\\Menu Items\\Display').AOTchildNodeCount()));
info (strFmt("Menu Items Output in AX: %1", treenode::findNode('\\Menu Items\\Output').AOTchildNodeCount()));
info (strFmt("MenuItems Action in AX: %1", treenode::findNode('\\Menu Items\\Action').AOTchildNodeCount()));
info (strFmt("Reports- Report Templates in AX: %1", treenode::findNode('\\Reports\\Report Templates').AOTchildNodeCount()));
}
Passing Multiple Records from one form to another through Args in Dynamics Ax 2012
The Scenario is when I select
multiple grids in Form A, those records will be passed to FormB and there FormB
will received the all those records and filter it and will show.
Step 1: Make one SampleTable
which has three fields named (SIno, name, AddressCity).
Step 2: Make FormA with datasource as SampleTable and drag the datasource
fields into the design Grid.
Step 3: Drag one button and override the click method and write the
following code.
step 4: Make one Display menuitem of FormB.
void clicked()
{
step 4: Make one Display menuitem of FormB.
void clicked()
{
int recordsCount;
SampleTable _sampleTable;
container con;
Args args;
str multiSelectString;
;
SampleTable _sampleTable;
container con;
Args args;
str multiSelectString;
;
args = new Args();
recordsCount = SampleTable_ds.recordsMarked().lastIndex(); // gets the total records selected
_sampleTable = SampleTable_ds.getFirst(1);
recordsCount = SampleTable_ds.recordsMarked().lastIndex(); // gets the total records selected
_sampleTable = SampleTable_ds.getFirst(1);
while (_sampleTable)
{
// storing recid of selected field in container
con = conIns(con,1,_sampleTable.RecId);
{
// storing recid of selected field in container
con = conIns(con,1,_sampleTable.RecId);
// converting container to string
with comma separated
multiSelectString = con2Str(con,’,');
multiSelectString = con2Str(con,’,');
_sampleTable =
SampleTable_ds.getNext(); // moves to next record
}
// passing string
args.parm(multiSelectString);
// calling menu item
new MenuFunction(menuitemDisplayStr(FormBMenuItem), MenuItemType::Display).run(args);
}
}
// passing string
args.parm(multiSelectString);
// calling menu item
new MenuFunction(menuitemDisplayStr(FormBMenuItem), MenuItemType::Display).run(args);
}
step 5: Make FormB with
datasource as same table for which you take for Form A i.e., SampleTable and
drag the fields in to the
Grid of design part.
Grid of design part.
step 6: write the following code in to the init method of FormB.
public void init()
{
container con;
int i;
str multipleRecords;
super();
// getting string value from caller
multipleRecords = element.args().parm();
public void init()
{
container con;
int i;
str multipleRecords;
super();
// getting string value from caller
multipleRecords = element.args().parm();
// string to container
con = str2con(multipleRecords,”,”);
con = str2con(multipleRecords,”,”);
// for sorting
for(i = 1;i<= conLen(con) ;i++)
{
SampleTbl_ds.query().dataSourceTable(Tablenum(SampleTbl)).addRange(fieldNum(SampleTbl,RecId)).value(SysQuery::value(conPeek(con,i)));
}
for(i = 1;i<= conLen(con) ;i++)
{
SampleTbl_ds.query().dataSourceTable(Tablenum(SampleTbl)).addRange(fieldNum(SampleTbl,RecId)).value(SysQuery::value(conPeek(con,i)));
}
}
Passing Args from one Form to another Form in Dynamics Ax 2012
Args concept in dynamics ax is awesome. one
can easily pass arguments from one Form to another Form with very less effort. Here, i am going to demonstrate how to pass
Arguments from Form to Form. The Scenario is when I select one grid in
Form A, that record will be passed to Form B and there Form B will received the
whole record and filter it and will show.
Step 1: Make one SampleTable
which has three fields named (SIno, name, AddressCity).
Step
2: Make FormA with datasource as SampleTable and drag the datasource fields
into the design Grid.
Step
3: Drag one button and override the click method and write the following code.
void clicked()
{
Args args;
FormRun formRun;
;
super();
args = new args(formstr(FormB)); // sending Args(record) to FormB
args.record(SampleTable);
formrun = classfactory.formrunclass(args);
formrun.init();
formrun.run();
formrun.wait();
formrun.detach();
{
Args args;
FormRun formRun;
;
super();
args = new args(formstr(FormB)); // sending Args(record) to FormB
args.record(SampleTable);
formrun = classfactory.formrunclass(args);
formrun.init();
formrun.run();
formrun.wait();
formrun.detach();
}
step 4: Make FormB with datasource as same
table for which you take for Form A i.e., SampleTable and drag the fields in to
the
Grid of design part.
Grid of design part.
step 5: write the following code in to the init method of FormB.
public void init()
{
SampleTable _sampleTable;
super();
_sampleTable = element.args().record();
SampleTable_ds.query().dataSourceTable(Tablenum(SampleTable)).addRange(fieldNum(SampleTbl,RecId)).
value(SysQuery::value(_sampleTable.Recid));
}
public void init()
{
SampleTable _sampleTable;
super();
_sampleTable = element.args().record();
SampleTable_ds.query().dataSourceTable(Tablenum(SampleTable)).addRange(fieldNum(SampleTbl,RecId)).
value(SysQuery::value(_sampleTable.Recid));
}
Thursday, January 30, 2014
Creating New Financial Dimension – Dynamics AX 2012
Financial Dimension – Dynamics AX 2012
New Financial Dimension
1.
First create the new code. Go to General Ledger
> Setup > Financial dimensions > Financial dimensions and create a new
financial dimension.
2.
After that
there you’ll notice that the ‘Use values from’ can be set to as above, but also there is a long list existing dimensions as
well.
3.
If you use an existing field, then you won’t have
to create any values for your new financial dimension – the system will use the
values already present in the database.
4.
If you’re going to use ‘Custom values’ for your new
financial dimension the next step is to define the valid values which may be
entered. Go to General ledger > Setup > Financial dimensions >
Financial dimensions > Financial dimension values:
5.
To set an entity to be dimensionable,
6.
Create a view
as directed below, Also, to integrate with the dimensions framework when
deleting or renaming the natural key of the backing entity, you must write
custom code on the backing table’s delete method, and also on either the update
or renamePrimaryKey method. See CustTable for an example of the pattern these
methods must follow
7.
The view name must be DimAttribute[yourentityname].
For example, DimAttributeProjGrant.
8.
The view must contain a root data source named BackingEntity
that points to your backing table to identify a surrogate key and natural key.
9.
The view must contain the following fields named
exactly as follows: • Key – Must
point to the backing entity’s SK field. For example, an int64 RecId field. • Value – Must point to the backing
entity’s NK field. For example, a str30 GrantId field. • Name – Must point to the source of an
additional description for the entity. For example, a str60 Description field
List of dimensionable entities are also cached on
both the client and server, so we have to execute the following line
of code within a job in order to load the new dimension:
static void
ClearDimensionCache(Args _args)
{
DimensionCache::clearAllScopes();
info(‘done’);
}
To add the newly
created Dimension to any form, we need to follow below link that explains it
very well
Monday, January 6, 2014
Filtering drop down list based on another drop down in SSRS
Reports
Senario:
Filter Customer Account’s based on Customer Group.
Steps:
1. Create a Query CustReportDemo
Add CustTable as Datasource to Query.
Select fields in the properties option Dynamics == Yes.
2. Now we have to move to classes, as
per the requirement we have to create 2 classes.
3. DataProvider Class, Contract Class,
UI Builder class.
4.
So,
Here is what we need to do.
First create a contract class as (I am hoping) we already know. Here I am using an example of Customer which will be filtered by Customer group. The code of class declaration will be:
First create a contract class as (I am hoping) we already know. Here I am using an example of Customer which will be filtered by Customer group. The code of class declaration will be:
[
DataContractAttribute
]
public class custReportContract
{
CustGroupId custGroup;
AccountNum cust;
}
Now creating 2 new methods for getting and setting these
parameters. 1 for cust group
[
DataMemberAttribute('CustGroup'),
SysOperationLabelAttribute(literalstr("@SYS11904"))
]
public CustGroupId parmCustGroup(CustGroupId _custGroup= custGroup)
{
custGroup = _custGroup;
return custGroup;
}
And the other one for customer
[
DataMemberAttribute('Cust'),
SysOperationLabelAttribute(literalstr("@SYS313797"))
]
public AccountNum parmCust(AccountNum _cust= cust)
{
cust = _cust;
return cust;
}
Your screen will look like this:
Nothing new in it. We all know it (I guess).
Moving forward and now we are creating another class for UI builder.
Create this new class and on the class
declaration method, type the following code
public class custReportUIBuilder extends SysOperationAutomaticUIBuilder
{
}
your screen will look like this
Now we have to create 2 dialog boxes. 1 for customer group and
customer each. To do this type the following code.
DialogField dialogCustGroup;
DialogField dialogCust;
We also have to define our contract class here, so declare the
contract class
custReportContract contract;
so, the class declaration method will look like this:
UI Builder Class:
public class custReportUIBuilder extends SysOperationAutomaticUIBuilder
{
DialogField dialogCustGroup;
DialogField dialogCust;
custReportContract contract;
}
Now, we have to draw the dialog boxes. For this reason, we will
create another method of build and type the following code In it.
public void build()
{
Dialog dialogLocal
= this.dialog();
custReportContract contract =
this.dataContractObject();
dialogLocal.addGroup("Customer");
this.addDialogField(methodStr(custReportContract,parmCustGroup), contract);
this.addDialogField(methodStr(custReportContract,parmCust), contract);
}
Now that we created the build method, let’s move into filling
the cust group drop down with the table CustGroup. We’ll create another method
for lookup and type the following code in it.
public void lookupCustGroup(FormStringControl _control)
{
Query query = new Query();
SysTableLookup sysTablelookup;
sysTablelookup
=SysTableLookup::newParameters(tableNum(CustGroup),_control);
sysTablelookup.addLookupfield(fieldNum(CustGroup,CustGroup));
sysTablelookup.addLookupfield(fieldnum(CustGroup,Name));
query.addDataSource(tableNum(CustGroup));
sysTablelookup.parmQuery(query);
sysTablelookup.performFormLookup();
}
We need to create another method so that when user selects any
record from cust group drop down, the customer drop down will be filtered with
that value, for this reason we will select the modified event of cust group and
then type the code:
public boolean custGroupModified(FormStringControl _control)
{
dialogCustGroup.value(_control.valueStr());
dialogCust.value('');
return true
}
Ok now we will create the lookup method for customer. Here is
the code
public void lookupCust(FormStringControl _control)
{
Query query = new Query();
SysTableLookup sysTablelookup;
sysTablelookup
=SysTableLookup::newParameters(tableNum(CustTable),_control);
sysTablelookup.addLookupfield(fieldNum(CustTable,AccountNum));
sysTablelookup.addLookupfield(fieldnum(CustTable,Party));
query.addDataSource(tableNum(CustTable));
query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable,
CustGroup)).value(dialogCustGroup.value());
sysTablelookup.parmQuery(query);
sysTablelookup.performFormLookup();
}
Note that I filtered the cust query with the value selected in
cust group drop down
query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable,
CustGroup)).value(dialogCustGroup.value());
we have almost completed our code for lookups and their filters.
Now we will bind our dialog boxes with the contract class params and also
override the modified method of cust group with the method we
just wrote. To do this we will create another method for postBuild. Here
we go
public void postBuild()
{
super();
// From binding info, get the dialog field for racecode
attribute and add button
dialogCustGroup =
this.bindInfo().getDialogField(
this.dataContractObject(),
methodStr(custReportContract,parmCustGroup));
if (dialogCustGroup)
{
dialogCustGroup.lookupButton(2);
}
// register override method for lookup cust Group
dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, lookup),methodStr(custReportUIBuilder,
lookupCustGroup), this);
// register override method for modified
dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, modified),methodStr(custReportUIBuilder,
custGroupModified), this);
//binding info for customer drop down
dialogCust =
this.bindInfo().getDialogField(
this.dataContractObject(),
methodStr(custReportContract,parmCust));
// register override method for lookup customer
dialogCust.registerOverrideMethod(methodStr(FormStringControl, lookup),methodStr(custReportUIBuilder,
lookupCust), this);
if (dialogCust)
{
dialogCust.lookupButton(2);
}
}
We may have to create some other methods as well in order to
functioning your code properly. They are getFromDialog, initializeFields and
postRun. Create three new methods each for getFromDialog, initializeFields and
postRun and copy the following code to them
GetFromDialog:
public void getFromDialog()
{
contract =
this.dataContractObject();
super();
}
InitializeFields:
public void initializeFields()
{
contract =
this.dataContractObject();
}
PostRun
public void postRun()
{
super();
}
We are done. But wait one last thing, open your contract class
and in the class declaration method, reference your UI builder class just below
the DataContractAttribute. Your code will become:
Contract Class
ClassDeclaration
[
DataContractAttribute,
SysOperationContractProcessingAttribute(classStr(custReportUIBuilder))
]
public class custReportContract
{
CustGroupId custGroup;
AccountNum cust;
}
We are now done. In this post we have tried to filter our
single value drop down based on another drop down. In the next post we will try
to repeat the same process for multi value drop down list.
Thank you all
Here is the screen shot of what we just did
DataProvider
Class:
To fetch information from TmpTable and print data in to
report, we have to update in ProcessReport Method.
ClassDeclaration:
[
SRSReportQueryAttribute(queryStr(CustReport)),
SRSReportParameterAttribute(classStr(custReportContract))
]
public class custreportDP extends SRSReportDataProviderBase
{
CustreportTmp
custreportTmp;
}
CustReportTmp
[ SRSReportDataSetAttribute(tableStr(CustreportTmp))
]
public CustreportTmp
custreportTmp()
{
select * from custreportTmp;
return custreportTmp;
}
ProcessReport
public void processReport()
{
QueryRun qr;
QueryBuildRange qbr;
Query query;
CustTable
custTable;
CustGroup
custGroup;
// Get a reference to the contract for this
report. The relevant contract class is
// defined by the
SRSReportParameterAttribute used in the class declaration.
custReportContract
contract =
this.parmDataContract() as
custReportContract;
boolean addLine;
query = this.parmQuery();
if(contract.parmCustGroup()
&& contract.parmCust())
{
query.dataSourceNo(1).clearRanges();
qbr = query.dataSourceNo(1).addRange(fieldNum(CustTable,custGroup));
qbr.value(contract.parmCustGroup());
qbr = query.dataSourceNo(1).addRange(fieldNum(CustTable,AccountNum));
qbr.value(contract.parmCust());
qr = new QueryRun(query);
while(qr.next())
{
CustTable = qr.get(tableNum(CustTable));
custreportTmp.clear();
custreportTmp.AccountNum =
CustTable.AccountNum;
custreportTmp.CustGroup =
CustTable.CustGroup;
custreportTmp.insert();
}
}
else if(contract.parmCustGroup())
{
qbr = query.dataSourceNo(1).addRange(fieldNum(CustTable,custGroup));
qbr.value(contract.parmCustGroup());
qr = new QueryRun(query);
while(qr.next())
{
CustTable = qr.get(tableNum(CustTable));
custreportTmp.clear();
custreportTmp.AccountNum =
CustTable.AccountNum;
custreportTmp.CustGroup =
CustTable.CustGroup;
custreportTmp.insert();
}
}
else if(contract.parmCust())
{
qbr = query.dataSourceNo(1).addRange(fieldNum(CustTable,AccountNum));
qbr.value(contract.parmCust());
qr = new QueryRun(query);
while(qr.next())
{
CustTable = qr.get(tableNum(CustTable));
custreportTmp.clear();
custreportTmp.AccountNum =
CustTable.AccountNum;
custreportTmp.CustGroup =
CustTable.CustGroup;
custreportTmp.insert();
}
}
else if (!contract.parmCust() &&
!contract.parmCustGroup())
{
qr = new QueryRun(query);
while(qr.next())
{
CustTable = qr.get(tableNum(CustTable));
custreportTmp.clear();
custreportTmp.AccountNum =
CustTable.AccountNum;
custreportTmp.CustGroup =
CustTable.CustGroup;
custreportTmp.insert();
}
}
}
OutPut:
Senario1:
Selecting CustomerGroup In lookup as 10 , Customers should
get filter based on the custgroup.
After selecting Customer Account as 1101. Final report is
Senario 2:
Selecting Only Customer Group as “10”
Senario3:
Selecting only Customer Account as “1101”
Senario 4:
Customer Account & Customer Group is Null.
Subscribe to:
Posts (Atom)