Показать сообщение отдельно
Старый 12.09.2018, 23:13   #1  
Blog bot is offline
Blog bot
Участник
 
25,475 / 846 (79) +++++++
Регистрация: 28.10.2006
Lookup and Modified methods for FormReferenceGroup fields in D365
Источник: http://alexvoy.blogspot.com/2018/09/...thods-for.html
==============

<div dir="ltr" style="text-align: left;" trbidi="on">Let's say we need to keep in Purchase line a manufacturer code for a particular product. So each Product/Manufacturer code combination is unique.



Three tables are referenced via RecId fields.





So once Manufacturer code field is placed in the form, we end up with a FormReferenceGroup.



We can easily override its lookup method by subscribing to the relevant event on it.

[FormControlEventHandler(formControlStr(PurchTable, avrEcoResManufacturerProduct_avrEcoResManufacturerProductRecId), FormControlEventType::Lookup)]
public static void avrEcoResManufacturerProduct_avrEcoResManufacturerProductRecId_OnLookup(FormControl sender, FormControlEventArgs e)
{
PurchLine purchLine = sender.formRun().dataSource(formDataSourceStr(PurchTable, PurchLine)).cursor() as PurchLine;
FormControlCancelableSuperEventArgs cancelableArgs = e as FormControlCancelableSuperEventArgs;

avrEcoResManufacturerProduct::lookupByItem(sender, purchLine.itemId);

cancelableArgs.CancelSuperCall();
}


public client static Common lookupByItem(FormReferenceControl _formReferenceControl, ItemId _itemId)
{
SysReferenceTableLookup sysReferenceTableLookup;
Query query;
QueryBuildDataSource avrEcoResMan;

sysReferenceTableLookup = SysReferenceTableLookup::newParameters(tableNum(avrEcoResManufacturerProduct), _formReferenceControl);
sysReferenceTableLookup.addLookupfield(fieldNum(avrEcoResManufacturerProduct, EcoResManufacturerRecId));
sysReferenceTableLookup.addLookupfield(fieldNum(avrEcoResManufacturerProduct, EcoResManufacturerPartNbr));

query = new Query();
avrEcoResMan = query.addDataSource(tableNum(avrEcoResManufacturerProduct));
avrEcoResMan.addRange(fieldNum(avrEcoResManufacturerProduct, EcoResProductRecId)).value(SysQuery::value(InventTable::find(_itemId).Product));

sysReferenceTableLookup.parmQuery(query);

return sysReferenceTableLookup.performFormLookup() as avrEcoResManufacturerProduct;
}





But what if the user wants to create new values in appropriate tables if them do not exist yet?



We can catch the modified event in order to create new values before failing the validation.
However, given that its content may be changed, it is impossible to get access to its fields at design time.

We can do it during run-time by means of getting sought field form controls by their names and overloading then their Modified() methods. (see the similar trick for AX 2012 https://alexvoy.blogspot.com/2014/01...reference.html)





The code you need to add.

[ExtensionOf(formStr(PurchTable))]
final class avrPurchTableForm_PurchTableManuf_Extension
{
private const str avrFieldNameDisplayProductNumber = 'EcoResManufacturerPartNbr';
private const str avrFieldNameEcoResManufacturerName = 'EcoResManufacturerName';
private FormStringControl avrFSCDisplayProductNumber;
private FormStringControl avrFSCEcoResManufacturerName;

// the only way to change the standard modified method for a control inside of a dynamically populated reference group
// is to get it by its name looping all form controls of this group during run-time. then to overload it
[FormEventHandler(formStr(PurchTable), FormEventType::Initialized)]
public void PurchTable_OnInitialized(xFormRun sender, FormEventArgs e)
{
FormDesign formDesign = sender.design();
FormReferenceGroupControl formReferenceGroupControl;
formReferenceGroupControl = formDesign.controlName(formControlStr(PurchTable, avrEcoResManufacturerProduct_avrEcoResManufacturerProductRecId)) as formReferenceGroupControl;
this.registerManufacturerNameOverload(formReferenceGroupControl);
}

private void registerManufacturerNameOverload(FormReferenceGroupControl _formReferenceGroupControl )
{
int i;
Object childControl;
FormStringControl formStringControl;

for (i = 1; i
public static avrEcoResManufacturerProduct findOrCreateEcoResManufacturerProduct(ItemId _itemId,
avrEcoResManufacturerName _manufacturerName,
avrEcoResManufacturerPartNbr _manufacturerPartNbr)
{
avrEcoResManufacturerProduct avrEcoResManufacturerProduct;
avrEcoResManufacturer avrEcoResManufacturer;
InventTable inventTable = InventTable::find(_itemId);
// item and part number are given and exist
if(inventTable.Product && _manufacturerPartNbr)
{
// such a manufacturer exists, so just try to find it for given combination
avrEcoResManufacturer = avrEcoResManufacturer::findOrCreateByName(_manufacturerName);
avrEcoResManufacturerProduct = avrEcoResManufacturerProduct::find(inventTable.Product, avrEcoResManufacturer.RecId);
if(!avrEcoResManufacturerProduct)
{
if(Box::confirm("Do you want to create new part number", strFmt(avrEcoResManufacturerProduct::txtNotExist(), _manufacturerPartNbr)))
{
try
{
avrEcoResManufacturerProduct.EcoResProductRecId = inventTable.Product;
avrEcoResManufacturerProduct.EcoResManufacturerRecId = avrEcoResManufacturer.RecId;
avrEcoResManufacturerProduct.EcoResManufacturerPartNbr = _manufacturerPartNbr;
avrEcoResManufacturerProduct.EcoResManufacturerDefault = NoYes::Yes;
if(avrEcoResManufacturerProduct.validateWrite())
{
avrEcoResManufacturerProduct.insert();
}
}
catch
{
Error("Failed to create new part number");
}
}
}
}
return avrEcoResManufacturerProduct;
}






Источник: http://alexvoy.blogspot.com/2018/09/...thods-for.html
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.