Lookup Filtering on D365 x++ - axapta

I am a beginner at d365 finance and operations. I have service and sub-service lookup fields in a form. This field's data sources have a one-to-many relationship with a foreign key. When I select a record in the service field, I want to see only sub-services that belong to the selected 'service' record in the 'sub-services lookup field. I need a lookup filtering for this with X++ but I do not know-how.
I would be really appreciated it if someone can help me with this.
Here is my code but I really confused all the tables and fields name and I probably write the wrong names in the wrong places.
//My main form that includes lookup fields is inventSite
// Control names of lookup fields are InvenSite_ServiceRefRecId and InventSite_SubServiceRefRecId
//The name of the form that includes service and subservice records is Service
// the table that includes subservice records is SubService
Here is my Service form
[FormControlEventHandler(formControlStr(InventSite, InventSite_SubServiceRefRecId), FormControlEventType::Lookup)]
public static void InventSite_SubServiceRefRecId_OnLookup(FormControl sender, FormControlEventArgs e)
{
SysReferenceTableLookup sysRefTableLookup;
Query query = new Query();
QueryBuildDataSource qbds;
FormRun formRun;
FormControl formCtrl;
ServiceName serviceName;
FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;
sysRefTableLookup = SysReferenceTableLookup::newParameters(tableNum(Service), sender);
qbds = query.addDataSource(tableNum(Service));
formRun = sender.formRun();
formCtrl = formRun.design().controlName(formControlStr(InventSite, InventSite_SubServiceRefRecId));
serviceName = formCtrl.valueStr();
qbds.firstOnly(true);
qbds.addRange(fieldNum(Service, ServiceName)).value(queryValue(serviceName));
sysRefTableLookup.parmQuery(query);
sysRefTableLookup.addLookupfield(fieldNum(Service, ServiceName));
sysRefTableLookup.addLookupfield(fieldNum(Service, ServiceDescription));
sysRefTableLookup.performFormLookup();
ce.CancelSuperCall();
}

You need to overide lookup. Please find an example here in community blog. https://community.dynamics.com/365/financeandoperations/b/365foandaxtechnicalworld/posts/override-lookup-ax7-amp-d365fo

Related

Getting the current record of the lookup table

I need to get the value from a lookup field and need to auto-write this value to another string field. I used Modified field event to auto-populate string fields but when it comes to lookup I cannot get the value. I am dealing with this for 3 days. I would be really grateful if anyone can help...
I used this code to populate sting fields. And there needs to be field 3 which is lookup.
[
FormDataFieldEventHandler(formDataFieldStr(InventSite, InventSite, Field1), FormDataFieldEventType::Modified),
FormDataFieldEventHandler(formDataFieldStr(InventSite, InventSite, Field2), FormDataFieldEventType::Modified)
]
public static void Field1_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
{
// get the form DataSource
FormDataSource dataSource = sender.datasource();
// get current record
InventSite inventSite = dataSource.cursor();
// contatenate string values
str details = strFmt("%1, %2", inventSite.Field1, inventSite.Field2);

How to get RecId selected from lookup method?

I want to get the RecId selected from lookup method?
In lookup method in StringEditLookup_ZipCode
public void lookup()
{
Query query = new Query();
QueryBuildDataSource queryBuildDataSource;
QueryBuildRange queryBuildRange;
SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(LogisticsAddressZipCode), this);
sysTableLookup.addLookupField(fieldNum(LogisticsAddressZipCode, ZipCode));
sysTableLookup.addLookupField(fieldNum(LogisticsAddressZipCode, City));
sysTableLookup.addSelectionField(fieldNum(LogisticsAddressZipCode, RecId));
queryBuildDataSource = query.addDataSource(tableNum(LogisticsAddressZipCode));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
//super();
}
In modified method I would want to get ad read and use the RecId taken.
I want to populate the StringEditLookup_ZipCode with the ZipCode value.
It's possible to take a RecID ?
The LogisticsAddressZipCode Table is's not indexed by ZipCode
for this I need to take the RecID.
There is a way to save in a global variable or somehow recid selected in the lookup method or another point?
Thanks all,
enjoy!
As far as I know this cannot be done with the SysTableLookup Framework. Basically you want your lookup to return two values, the ZipCode and the RecId. But the framework can only return one value.
So instead of the framework you will need to implement your own lookup by creating a new lookup form. From this form you can then retrieve the selected record in the lookup method. Here is some code to give you an idea how the lookup method could look like:
public void lookup()
{
FormRun lookupFormRun;
Args args;
LogisticsAddressZipCode myLookupZipCode;
args = new Args();
args.name(formStr(MyNewLookupForm));
lookupFormRun = classFactory.formRunClass(args);
lookupFormRun.init();
this.performFormLookup(lookupFormRun);
lookupFormRun.wait();
if (lookupFormRun.closedOk())
{
myLookupZipCode= formRun.docCursor();
}
}
From there you can save the RecId of myLookupZipCode to a class variable and then later use it in the modified method.
Also take a look at Lookup form returning more than one value for additional Information.
What you have there is exactly what I would've tried. What happens when you choose a value from the lookup? If that isn't working, I'd try adding RecId as one of the lookupFields. It's probably something where it isn't selecting the field so it's always blank. That's the first thing I would try.

How to join multiple table's data in one GridView in ASP.Net Webform on button_click

I am populating all Transaction data on one button click in a GridView. However, Transaction table in the database does not contain Dimension table (e.g. Account table) data such as Transaction table contains AccountID but it does not have AccountName property which I have to bring from the Account table. In the DataAccess layer the method (GetAllTransactions()) does contain the join between Transaction and Account table on AccountID, but when I try to select account.AccountName it does not work.
I just need to show few tables from Transaction table where the AccountID mataches and show the AccountName column instead of AccountID from the Transaction table.
The DataAccess method looks like:
public static IEnumerable<Transaction>GetAllTransactions()
{
List<Transaction> allTransactions = new List<Transaction>();
using (var context = new CostReportEntities())
{
allTransactions = (from t in context.Transactions
join account in context.Accounts on t.AccountID equals account.AccountID
select t).ToList();
}
return allTransactions;
}
and the Code behind the .aspx page is as follows:
protected void _UIButtonSubmit_Click(object sender, EventArgs e)
{
IEnumerable<Transaction> transactions = ts.GetAllTransactions();
_UITransactionGridView.DataSource = transactions;
_UITransactionGridView.DataBind();
_UITransactionGridView.PageIndex = 0;
}
tried few things with the following also, but I am not getting the LINQ idea. The following gives error.
...select new {t.*, account.AccountName}).ToList();
I need a direction which way should I be looking at to make the task work to populate data from multiple tables in one GridView. Thanks.
Since my Model for Transaction did not have any property of Account table I had to create a ViewModel type class which returns custom data of AccountNumber for every Transaction.
Tha code that I used to solve the problem is this

How to create a lookup with fields from more than one datasource?

I need to create Dynamic lookup in my form field which should display fields from two different datasources.. I am trying to perform it as:
public void lookup()
{
query = new Query();
sysTableLookup = SysTableLookup::newParameters(tableNum(smmBusRelTable), this);
qbds = query.addDataSource(tablenum(smmBusRelTable));
// qbds.addDataSource(tableNum(DirPartyTable));
//qbds.relations(true);
sysTableLookup.parmQuery(query);
sysTableLookup.addLookupField(fieldNum(smmBusRelTable, Busrelaccount));
//sysTableLookup.addLookupfield(fieldNum(DirPartyTable, Name));
sysTableLookup.performFormLookup();
}
Commented lines are the operation I am trying to perform to add different datasource.
As far as I know the SysTableLookup class does not support showing fields from other tables. The addLookup() method doesn't take a TableId and assumes all fields are in the first datasource of the query.
You could write your own version of SysTableLookup that supports referencing fields from various tables. A simpler and more practical (and less expensive) approach might be to create a display method on SmmBusRelTable to fetch the name from DirPartyTable (if it doesn't already exists) and use that as a field in the lookup. Display methods on the main table are supported if I remember correctly.
Depending on what exactly you're trying to accomplish there might be an even simpler way. You could add the display method to the AutoLookup table field group of SmmBusRelTable and avoid having to override the lookup() method.
It is actually very easy to combine multiple datasources in a sysTableLookup. Here is the trick I used to be able to filter on the name from the EcoResProductTranslation in the lookup for items.
1) Create a view that combines all your datasources and add the fields you would like to see in your lookup to the view.
2) Create a query from the view created in step 1.
3) Use these to perform your lookup as follows...
static client void lookupItemActive(FormStringControl _ctrl)
{
SysTableLookup sysTableLookup = SysTableLookup::newParameters(tablenum(<ViewName>),_ctrl);
Query query = new Query(queryStr(<QueryName>));
sysTableLookup.addLookupfield(fieldnum(<ViewName>, ItemId));
sysTableLookup.addLookupfield(fieldNum(<ViewName>, Name));
sysTableLookup.addLookupfield(fieldNum(<ViewName>, ItemGroupId));
sysTableLookup.addLookupfield(fieldnum(<ViewName>, Status));
sysTableLookup.addLookupfield(fieldnum(<ViewName>, RevId));
sysTableLookup.addLookupfield(fieldnum(<ViewName>, ItemType));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}

Issue with LINQ to SQL insert . .

i was looking at an example of how to do an insert in Linq to SQL and here it was it said:
NorthwindDataContext context = new NorthwindDataContext();
context.Products.Add(new Product(..));
context.SubmitChanges();
but when i look at the below, (in my case the Table is UserInfo), the Table doesn't have an "Add" method:
public System.Data.Linq.Table<UserInfo> UserInfos
{
get
{
return this.GetTable<UserInfo>();
}
}
any clue what i am doing wrong here?
You should use the InsertOnSubmit method:
NorthwindDataContext context = new NorthwindDataContext();
context.Products.InsertOnSubmit(new Product(..));
context.SubmitChanges();
The Add method exist on the EntitySet members, is mostly used when adding Child entities to a Parent one, for example:
var category = new Category{ Name = "Breveages"};
category.Products.Add(new Product{ Name = "Orange Juice"});
category.Products.Add(new Product{ Name = "Tomato Juice"});
category.Products.Add(new Product{ Name = "Cola"});
//...
context.Categories.InsertOnSubmit(category);
// This will insert the Category and
// the three Products we associated to.
EDIT: To do update operations, you just need to retrieve the entity by doing a query, or attaching it, for example:
var customer = context.Customers.Single( c => c.CustomerID == "ALFKI");
customer.ContactName = "New Contact Name";
context.SubmitChanges();
The DataContext tracks the changes of its related entities and when the SubmitChanges method is called, it will detect that change, and generate an Update SQL statement behind the scenes to do the update operation...

Resources