Form
Form with filters
public class FormRun extends ObjectRun
{
QueryBuildRange qbrDlvDate;
}
public void dateModified()
{
date fromDate, toDate;
fromDate = fomDateHeader.dateValue();
toDate = toDateHeader.dateValue();
if (!toDateHeader.dateValue())
toDate = dateMax();
qbrDlvDate.value(queryRange(fromDate,toDate));
}
public void refreshGrid()
{
ProdTable_ds.executeQuery();
}
public void init() // (Init of the data source ProdTable_ds)
{
QueryBuildDataSource qbds;
QueryBuildRange qbr;
date fromDate,toDate;
super();
qbds = this.query().dataSourceName(this.name());
qbds.addSortField(fieldNum(ProdTable,Prod),SortOrder::Descending);
// To have a small range and not see a lot of lines
fromDateHeader.dateValue(systemDateGet() - 1);
toDateHeader.dateValue(systemDateGet());
fromDate = fromDateHeader.dateValue();
toDate = toDateHeader.dateValue();
qbrDlvDate = qbds.addRange(fieldNum(ProdTable,DlvDate));
qbrDlvDate.value(queryRange(fromDate,toDate));
}
public boolean modified() // (field dateEdit fromDateHeader)
{
boolean ret;
ret = super();
element.dateModified();
return ret;
}
public boolean modified() // (field dateEdit toDateHeader)
{
boolean ret;
ret = super();
element.dateModified();
return ret;
}
Init form
Init()
{
FormRun callerForm;
SalesLine callerSalesLine;
FormDataSource callerDataSource;
//------------TEST ARGS---------------------------
if (!element.args() ||
!element.args().record().TableId)
{
throw error("@SYS22539");
}
if (! element.args().caller() || ! element.args().record())
throw error("@SYS22539");
if (!element.args().caller())
{
// Form cannot be called directly.
throw error("@SYS96590");
}
if(element.args().parmEnumType() == enumnum(CurrentOperationsTax))
{
currentOperationsTax = element.args().parmEnum();
selectCurrentOperationsTax = true;
}
else
{
selectCurrentOperationsTax = false;
}
if (element.args().dataset() == tablenum(WMSShipment))
{
wmsShipment = element.args().record();
}
callerForm = element.args().caller();
callerSalesLine = element.args().record();
callerDataSource = element.args().record().dataSource();
super(); //the super() method call the init of the dataSource
}
//Interesting example : SmmOpportunityStatusUpdate (parm with 2 values with ;)
// Get value of ReasonId and CustAccount # from args.parm()
container parms;
;
parms = str2con(args.parm(), ";"); // ==========================
if (conLen(parms) != 2)
{
throw error(strFmt("@SYS54195",funcName()));
}
smmOpportunityStatusUpdate.parmReasonId(conPeek(parms, 1));
smmOpportunityStatusUpdate.paramCustAccountNo(conPeek(parms, 2));
smmOpportunityStatusUpdate.parmRemoveOpenActivities(args.refField());
// Another example
FormRun callerForm;
if (!element.args().caller() || !element.args().dataset())
throw error(strfmt("@SYS22678",element.name()));
callerForm = element.args().caller();
if (callerForm.name() == formStr(InventTableListPage))
InventTableDrag_ds.executeQuery();
// Another example to test if the caller is a form
if (SysDictClass::is(element.args().caller(), classnum(FormRun)))
{
parentForm = element.args().caller();
// Cast the caller and make sure it is the right form.
if (parentForm.name() == formstr(AifValueSubstitutionComponentConfig))
}
// Another example to test !!!!!!!!!!!!!!!!!!!!!!!!!!!
Object caller;
if (bomVersion.bomId)
return bomVersion.bomId;
else
{
caller = element.args().caller();
if (caller)
{
if (SysDictClass::isEqualOrSuperclass(classidget(caller),classnum(FormRun)))
{
if (formHasMethod(caller,identifierstr(bomId)))
return caller.bomId();
}
else
{
return caller.bomId();
}
}
}
Init Test Menu Item
Init()
{
switch (element.args().menuItemName())
{
case menuitemdisplaystr(SPLPsGasNominationWeekly):
isWeek = true;
break;
default:
isWeek = false; //(monthly)
}
super(); //the super() method call the init of the dataSource
}
Args with caller
Init()
{
FormRun callerForm;
SalesLine callerSalesLine;
FormDataSource callerDataSource;
//in the called form we twat from what form we are coming
if (args.dataset() == tablenum(BankAccountTrans) && args.caller().name() == formstr(BankReconciliation))
{
}
super(); //the super() method call the init of the dataSource
}
//In the caller
void clicked()
{
Args args;
;
args = new Args();
args.caller(element);
...
}
Init dataSource
//For a form in innerjoin use link
//For a form in DELAY use dynaLink
void init()
{
QueryBuildDataSource qbds;
super();
qbds = this.query().dataSourceTable(tablenum(InventDim));
//qbds = this.query().dataSourceName(this.name());
//qbds = this.query().dataSourceName(identifierstr(InventDimTransTo)); //if the name is not InventDim
qbds.clearLinks();
qbds.addLink(fieldnum(WMSOrderTrans,ToInventDimId),fieldnum(InventDim,InventDimId));
}
// Init : We put the display method in the cache
public void init()
{
super();
salesTable_ds.cacheAddMethod(tableMethodStr(SalesTable, customerName));
salesTable_ds.cacheAddMethod(tableMethodStr(SalesTable, invoiceName));
if (enableDirectedSelling)
{
salesTable_ds.cacheAddMethod(tableMethodStr(SalesTable, editContactPersonName));
}
}
formHasMethod
void updateCallerForm()
{
if (element.args() && element.args().caller() && formHasMethod(element.args().caller(), identifierstr(updateAddress)))
{
element.args().caller().updateAddress();
}
}
Refresh
Research : keep the filters but don't do the edit methods. (research on all the DS)
Refresh : refresh the line of the DS but don't do the edit methods. (refresh on one line)
// the refresh is use to show the modification of the DS.
// In our exemple, we cahnge a value of a field in a button,
// and we need the refresh to see the new value on the grid !
// The refresh doesn't read in the Table, the reread read in the table !
cacheAddMethod
//Init of the DS
public void init()
{
super();
this.cacheAddMethod(tablemethodstr(CustBillOfExchangeJour, bankRemittanceFileId));
}
ModifyField call
inventTable.modifiedField(fieldnum(InventTable,pbaAutoStart));
inventTable_ds.refresh();
Modify field, order : Form, DS, Table
// When modify, first the modify of the field is called.
The field call the super of the modify of the field in the DS,
The modify field of the data source call the super of the table :
==>
Infos Message (11:57:52) modify field level 3 form
Infos Message (11:57:52) modify field level 2 DS
Infos Message (11:57:52) modify field level 1 (table)
// Field in the form
public boolean modified()
{
boolean ret;
info("modify field level 3 form");
ret = super();
return ret;
}
public void modified()
{
info("modify field level 2 DS");
super();
element.setFieldVisible();
}
// Same field in the Table.
case fieldNum(SMAServiceOrderTable, SPLWasteQuotationType) :
this.CustAccount = "";
this.SPLWasteBusRelAccount = "";
info("modify field level 1 (table)");
break;
Modify field - enabled - disable
Table
Form
// We want that when we the field Approval is checked, the field user group is enable, other else the field is disable.
// In the table :
public void modifiedField(fieldId _fieldId)
{
super(_fieldId);
//15-02-2016-SBE-BEGIN
switch (_fieldId)
{
case fieldNum(InventJournalName,SPLIsNeedApproval) :
if (!this.SPLIsNeedApproval)
this.SPLApprovalUserGroupId = ""; // === Set blank, because the field will be disable !
break;
}
//15-02-2016-SBE-END
}
public boolean validateWrite()
{
boolean ret;
ret = super();
//15-02-2016-SBE-BEGIN
if (ret)
{
if (this.SPLIsNeedApproval)
{
if (!this.SPLApprovalUserGroupId)
{
// the field %1 is mandatory
ret = checkFailed(strfmt("@SYS84378",fieldpname(InventJournalName,SPLApprovalUserGroupId)));
}
}
else if (this.SPLApprovalUserGroupId)
{
// the field %1 must be empty
ret = checkFailed(strfmt("@SPL1979",fieldpname(InventJournalName,SPLApprovalUserGroupId)));
}
}
//15-02-2016-SBE-END
return ret;
}
// In the form :
public int active()
{
int ret;
ret = super();
//15-02-2016-SBE-BEGIN
InventJournalName_ds.object(fieldnum(InventJournalName, SPLApprovalUserGroupId)).allowEdit(InventJournalName.SPLIsNeedApproval);
//15-02-2016-SBE-END
return ret;
}
public void modified()
{
super();
InventJournalName_ds.object(fieldnum(InventJournalName, SPLApprovalUserGroupId)).allowEdit(InventJournalName.SPLIsNeedApproval);
}
Modify field - enabled - disable in the table !
// In the field of the form
public void modified()
{
super();
element.setInventDimId();
element.setAvailFields();
}
void setAvailFields()
{
Common callerRecord;
;
if (element.args() && element.args().record() && element.args().record().RecId)
{
callerRecord = element.args().record();
}
inventNonConformanceTable.setEditableFields(inventNonConformanceTable_ds, callerRecord);
}
// In the table :
///
/// Update the form showing this data so reference fields are properly enabled or disabled.
///
///
/// The form data source for this table.
///
///
/// The record passed in a as caller when creating a new record.
///
client void setEditableFields(FormDataSource _inventNonConformanceTable_ds, Common _callerRecord)
{
boolean modifyReference = true;
boolean showReference = true;
boolean fixCallerReference()
{
if (!_callerRecord.RecId)
{
return false;
}
switch (_callerRecord.TableId)
{
case (tablenum(SalesLine)) :
case (tablenum(PurchLine)) :
case (tablenum(ProdTable)) :
case (tablenum(InventQuarantineOrder)) :
case (tablenum(InventQualityOrderTable)) :
case (tablenum(InventBatch)) :
case (tablenum(InventTable)) :
return true;
}
return false;
}
;
if (this.InventNonConformanceType == InventNonConformanceType::Internal &&
_callerRecord.RecId &&
_callerRecord.TableId == tablenum(InventBatch))
showReference = false;
modifyReference = !fixCallerReference();
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventNonConformanceType)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, ItemId)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable,Rush)).allowEdit(this.InventNonConformanceType == InventNonConformanceType::Vend);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable,InventTestInfoStat)).allowEdit(this.RecId && !this.correctionsExist());
if (showReference || this.RecId)
{
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventRefId)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).allowEdit(modifyReference);
}
else
{
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventRefId)).visible(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).visible(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).visible(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).visible(modifyReference);
}
switch(this.InventNonConformanceType)
{
case InventNonConformanceType::Cust:
case InventNonConformanceType::Service:
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).allowEdit(modifyReference);
break;
case InventNonConformanceType::Vend:
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).allowEdit(modifyReference);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).allowEdit(modifyReference);
break;
case InventNonConformanceType::Production:
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).allowEdit(false);
break;
case InventNonConformanceType::Internal:
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, CustAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, VendAccount)).allowEdit(false);
_inventNonConformanceTable_ds.object(fieldnum(InventNonConformanceTable, InventTransIdRef)).allowEdit(modifyReference);
break;
}
}
Get or set value of a control
// do Autodeclaration
//String edit : StringEditAuto.text("valueText");
controlName
this.design().controlName('ProposalForDimension').enabled(false);
//comboBox
this.getEditText()); //value of the comboBox
//StringEdit
SPLWMSLocCustomer.text(wmsLocationSPL.SPLCustAccount); //set value for a string edit.
Get control or button in a form without autodeclaration
// my control name is "AccountNum" and form name is "FormAddress"
// The control:: enum enumerates all controls on the given form
element.control(control::AccountNum).enabled(false); //2009
In Dynamics AX 2012, we have a new method controlId() on the formRun class.
This in conjunction with the new intrinsic method formControlStr() can be used to get the control id.
element.control(element.controlId(formControlStr(FormAddress, AccountNum))).enabled(false);
// to check it we do element.control(element.controlId(formControlStr(FormAddress, AccountNum))).tostring() -> give the control class ex checkboxformcontrol : to check it
//To do a button enable, disable, Convert2CustomerCtrl is the name of the button without autodeclaration
element.design().controlName(identifierStr(Convert2CustomerCtrl)).enabled(enableCustomer);
edit method
public edit LPLSalesDealId LPLEditSalesDealId(
boolean _set,
LPLSalesDealId _LPLSalesDealId)
{
if (_set)
{
if (_LPLSalesDealId && LPLSalesDealTable::exist(_LPLSalesDealId) )
{
if (this.LPLSalesDealLineRecid == 0)
{
this.LPLSalesDealId = "";
info("@LPL1820");
}
}
else
{
this.LPLSalesDealId = "";
this.LPLSalesDealLineRecid = 0;
}
}
return this.LPLSalesDealId;
}
public edit SPLLineNumPair SPLEditLineNumPair(
boolean _set,
SPLLineNumPair _SPLLineNumPair
)
{
if (_set)
{
if (_SPLLineNumPair /*&& LPLSalesDealTable::exist(_LPLSalesDealId)*/ )
{
this.SPLLineNumPair = _SPLLineNumPair;
}
else
{
this.SPLLineNumPair = 0;
}
}
return round(this.SPLLineNumPair,0.01);
}
Edit method replace code -> name
Edit
public void jumpRef()
{
salesTable_ContactPersonId.jumpRef();
}
void lookup()
{
ContactPerson::lookupCustContactPerson(salesTable_contactPersonId,
salesTable.CustAccount,
this,
salesTable.ContactPersonId);
}
client server edit ContactPersonName editContactPersonName(boolean _set, ContactPersonName _name)
{
ContactPersonName name = _name;
ContactPerson contactPerson;
DirPartyTable partyTable;
ContactPersonId contactPersonId;
if (_set)
{
if (name)
{
contactPersonId = this.ContactPersonId;
contactPerson = ContactPerson::find(_name);
this.ContactPersonId = contactPerson.ContactPersonId;
if (this.ContactPersonId)
{
name = contactPerson.personName();
}
else
{
select contactPerson
where contactPerson.CustAccount == this.CustAccount
join Name from partyTable
where partyTable.RecId == contactPerson.Party &&
partyTable.Name like name;
if (contactPerson)
{
this.ContactPersonId=contactPerson.ContactPersonId;
name=partyTable.Name;
}
}
if (contactPersonId != this.ContactPersonId)
{
if (this.checkContactPerson())
{
this.initFromContactInfo();
if (this.dataSource())
{
this.dataSource().refresh();
}
}
else
{
this.ContactPersonId = contactPersonId;
}
}
}
else
{
this.ContactPersonId='';
}
}
else
{
name = this.contactPersonName();
}
return name;
}
MenuFunction
clicked()
{
MenuFunction menuFunction;
Args args = new Args();
;
//The menu is called with "Parameters"
menuFunction = new MenuFunction(menuitemactionstr(AssetCalendarCreateYear), MenuItemType::Action);
args.parm(calId);
menuFunction.run(args);
//The menu is called with a record
args.record(custInvoiceJour);
new MenuFunction(menuitemactionstr(InterCompanyTransferInventDim), MenuItemType::Action).run(args);
args.caller(element);
args.parmObject(purchParmLine_ds.queryRun().query());
//args.parmEnumType(enumnum(FormOpenMode)); //In all call of the nenuItem we don't need a parmEnumType
args.parmEnum(FormOpenMode::ForNew);
args.object(ledgerJournalEngine); //(for a class ?)
}
//for a display form, use identifierstr
menuFunction = new MenuFunction(identifierstr(InventOnhand), MenuItemType::Display);
MenuFunction, call the class directly
//Here we need to know the result of the class.
//If we call the menuitem Action, we don't know the result,
//Here we can know the result : roundId = SPLSalesRoundIdLookUp.parmRoundId()
clicked()
{
SPLYearWeek YearWeek;
;
YearWeek = SPLSalesRound::YearWeek(str2int(WeekDelivery.valueStr()));
SPLSalesRoundIdLookUp = SPLSalesRoundIdLookUp::construct();
SPLSalesRoundIdLookUp.parmYearWeek(YearWeek);
if (SPLSalesRoundIdLookUp.prompt())
{
SPLSalesRoundIdLookUp.run();
roundId = SPLSalesRoundIdLookUp.parmRoundId();
}
}
MenuFunction, example with parm
call with parm
void clicked()
{
SPLSalesRoundAddRemoveRouteId SPLSalesRoundAddRemoveRouteId;
MenuFunction menuFunction;
Args args = new Args();
;
menuFunction = new MenuFunction(menuitemactionstr(SPLSalesRoundAddRouteId), MenuItemType::Action);
if (splRoundRecIdCriteria)
{
args.parm(int642str(splRoundRecIdCriteria));
menuFunction.run(args);
WMSPickingRoute_ds.executeQuery();
}
}
//In the class
static void main(Args args)
{
SPLSalesRoundAddRemoveRouteId SPLSalesRoundAddRemoveRouteId;
boolean bAddRouteId;
SPLSalesRoundRecId SPLSalesRoundRecId;
;
SPLSalesRoundAddRemoveRouteId = SPLSalesRoundAddRemoveRouteId::construct();
switch (args.menuItemName())
{
case menuitemActionStr(SPLSalesRoundAddRouteId):
bAddRouteId = true;
break;
default:
bAddRouteId = false;
}
SPLSalesRoundRecId = str2int64(args.parm());
SPLSalesRoundAddRemoveRouteId.parmAddRouteId(bAddRouteId);
SPLSalesRoundAddRemoveRouteId.parmSPLSalesRoundRecId(SPLSalesRoundRecId);
if (SPLSalesRoundAddRemoveRouteId.prompt())
SPLSalesRoundAddRemoveRouteId.run();
}
Call form by form Name with wait
formRun.wait(true); -> the first form is blocked
formRun.wait(); -> the first form is not blocked but we cannot close it.
// example : (wait)
void clicked()
{
Args args;
FormRun formRun;
;
super();
...
args = new args();
args.parmObject(incomeCustGroupParameters);
args.name(formStr(SPLIncomeByCustomerGroup));
args.caller(element);
formRun = classFactory.formRunClass(Args);
formRun.init();
formrun.run();
}
// another example (detach)
// Launch results form
args = new Args();
args.caller(element);
args.name(formstr(AuditPolicyTestRule));
args.record(element.args().record());
args.parm(int642str(batchJob.RecId));
formRun = classfactory.formRunClass(args);
formRun.init();
formRun.run();
formRun.detach();
//another example
void browseChannelAddress(FormStringControl _control)
{
Args args;
MenuFunction menuFunction;
MenuItemNameDisplay browseMenuItem;
FormRun formRun;
AifIntegrationAdapter integrationAdapter;
integrationAdapter = AifAdapterManager::getIntegrationAdapter(aifChannel.AdapterClassId);
args = new Args();
browseMenuItem = integrationAdapter.getAddressDisplayMenuItem();
menuFunction = new MenuFunction(browseMenuItem, MenuItemType::Display);
args = new Args(menuFunction.object());
args.lookupValue(_control.text());
args.parm(aifInboundPort.Name);
formRun = ClassFactory::formRunClassOnClient(args);
formRun.init();
formRun.run();
if (!formRun.closed())
formRun.wait();
if (formRun.closedOk())
{
//aifChannel.TransportAddress = args.lookupValue(); //Original SYS Code
//Start MCS
if (_control.id() == element.controlId(formControlStr(AifInboundPort, AifChannel_McsTransportAddressProcessed)))
{
aifChannel.McsTransportAddressProcessed = args.lookupValue();
}
else
{
aifChannel.TransportAddress = args.lookupValue();
}
//End MCS
aifChannel_ds.active();
}
}
//Wait(true)
void clicked()
{
FormRun formRun;
Args args = new Args();
args.name(formstr(AssetImpairmentTestResultEntryList_JP));
args.record(AssetImpairmentTestResult_JP);
formRun = ClassFactory.formRunClass(args);
formRun.form().design().windowType(FormWindowType::PopUp);
formRun.init();
formRun.run();
formRun.wait(true);
AssetImpairmentTestResult_JP_DS.reread();
}
//Form run with menu : to test
void clicked()
{
BankStatementTaxDocument bankStatementTaxDocument;
Args args;
FormRun formRun;
if (bankStmtISOAccountStatement.Posted)
{
args = new Args();
args.caller(this);
args.record(bankStmtISOAccountStatement);
formRun = new MenuFunction(menuitemDisplayStr(TaxTrans), MenuItemType::Display).create(args);
formRun.run();
}
}
// form lookup : performFormLookup
public void lookup()
{
FormRun formRun;
Args args;
args = new Args(formStr(COSLedgerPeriodLookup));
args.caller(this);
args.parm(date2str(dateTo2.dateValue(), -1, -1, -1, -1, -1, -1, DateFlags::None));
args.parmEnumType(2);
formRun = ClassFactory::formRunClassOnClient(args);
formRun.init();
this.performFormLookup(formRun);
}
Call form by form Name with wait and test if OK
// In the clicked of the parent form
//==================================
void clicked()
{
FormRun SPLFormRun;
Args SPLargs = new Args();
boolean SPLIsOK;
object objectForm;
;
super();
SPLargs.name(formstr(SalCalculateItemSizes));
SPLargs.record(purchLine);
SPLargs.caller(element);
SPLFormRun = ClassFactory.formRunClass(SPLargs);
SPLFormRun.init();
SPLFormRun.run();
SPLFormRun.wait(true);
objectForm = SPLFormRun;
SPLIsOK = objectForm.parmOK();
if (SPLIsOK)
element.SPLRereadFromCalcSize();
}
// On the son form
//================
public class FormRun extends ObjectRun
{
Boolean OK;
}
public boolean parmOK(boolean _OK = OK)
{
;
OK = _OK;
return OK;
}
void clicked()
{
;
super();
if (purchLine && element.args().caller() && formHasMethod(element.args().caller(), identifierstr(SPLRereadFromCalcSize)))
{
element.parmOK(true);
}
else
source.reread();
element.close();
}
Call a menuItem by adding a DS delay in the form - Do the LinkActive
//If we call a menuItem and give a record the form called doesn't execute linkActive, only if we send the DS.
//So in a form that haven't a DS, we must add a DS in Delay that doesn't do nothing
DS
Splitter
//declaration
public class FormRun extends ObjectRun
{
#MACROLIB.Resource
InventDimParm inventDimParmPriceSetup;
InventDimCtrl_Frm inventDimFormSetup;
SysFormSplitter_Y _formSplitterVertical;
}
public void init()
{
super();
_formSplitterVertical = new SysFormSplitter_Y(ctrlSplitVertical, table, this);
}
int mouseUp(int x, int y, int button, boolean ctrl, boolean shift)
{
int ret;
ret = super(x, y, button, ctrl, shift);
return _formSplitterVertical.mouseUp(x, y, button, ctrl, shift);
}
int mouseMove(int x, int y, int button, boolean ctrl, boolean shift)
{
int ret;
ret = super(x, y, button, ctrl, shift);
return _formSplitterVertical.mouseMove(x,y,button,ctrl,shift);
}
int mouseDown(int x, int y, int button, boolean ctrl, boolean shift)
{
int ret;
ret = super(x, y, button, ctrl, shift);
return _formSplitterVertical.mouseDown(x, y, button, ctrl, shift);
}
splitter
splitter property
Field color
public int active()
{
int ret;
container contFieldError;
ret = super();
SPLSalesInterfaceLine_ds.allowEdit(SPLSalesInterfaceLine.Status != SPLSalesInterfaceLineStatus::Integrated);
// Red Color
contFieldError = SPLSalesInterfaceLineError::ErrorsContainer(SPLSalesInterfaceLine);
// for each group fields(should be NOT AUTO)
element.findControls(element.control(Control::Identification), ContFieldError);
element.findControls(element.control(Control::Status), ContFieldError);
element.findControls(element.control(Control::General1), ContFieldError);
element.findControls(element.control(Control::Reference), ContFieldError);
element.findControls(element.control(Control::Parameters), ContFieldError);
return ret;
}
void findControls(FormGroupControl _formGroupControl, container _contFieldError )
{
Counter controlCount;
int i;
Object formControl;
Boolean boRed;
Integer fieldId;
FieldName nameField;
formBuildDataSource formBuildDataSource;
tableName tableName;
refTableiD tableId;
;
controlCount = _formGroupControl.controlCount();
for (i = 1; i Less= controlCount; i++)
{
formControl = _formGroupControl.controlNum(i);
if (formControl.dataSource() && formControl.dataField())
{
formBuildDataSource = element.form().dataSource(formControl.dataSource());
tableID = formBuildDataSource.table();
nameField = fieldid2name(tableId, formControl.dataField());
fieldId = fieldname2id(tableId, nameField);
boRed = false;
if (conFind(_contFieldError, fieldId) != 0)
boRed = true;
element.ControlColor(formControl,boRed);
}
}
}
// 23/03/2009 SPL GPO-Geodis
void ControlColor(FormStringControl _FormControl, boolean _boRed)
{ ;
_FormControl.colorScheme(FormColorScheme::Auto);
_FormControl.backgroundColor(WindowsPalette::WindowBackground);
if (_boRed)
{
_FormControl.backgroundColor(WinApi::RGB2Int(255, 0, 0));
_FormControl.colorScheme(FormColorScheme::RGB);
}
}
//Field color of just one control in the grid
// 08/01/2017-aSPL_ARP_137_SalesUpdApproval
// SalesLine_SPLSalesStatusApproval is autoDeclaration yes in the grid
public void displayOption(SalesLine _salesLine, FormRowDisplayOption _options)
{
int myColor=WinApi::RGB2int(0,0,250);
;
if (_salesLine.SPLSalesStatusApproval == SPLSalesStatusApproval::Waiting)
{
_options.textColor(myColor);
_options.affectedElementsByControl(SalesLine_SPLSalesStatusApproval.id());
}
super(_salesLine, _options);
}
Show the column of selection in the grid
In the Grid ShowRowLabels = No -> The column of selection is not display
Selection column
Display method in a form
//The display method in a form is not for a grid. It is for a single line.
//If we put it on a grid, it displays the same value for all the Lines
display method
//To work in display method and read parameter global, we need to declare the display method in the DS of the form.
//For this, we need to send the Record in the function.
form_displaymethInDS.jpg
display DS
Join dataSource on DS with group by
//The display method in a form is not for a grid. It is for a single line.
//If we put it on a grid, it displays the same value for all the Lines
join with group by
Form with pack unpack
//We can add method Pack - Unpack in a form
//Ex SalesReleaseOrderPicking : In this exemple We save a Query in the Pack - Unpack
//To use this we need to add method : LastValueType, LastValueUserId ...
final class FormRun extends ObjectRun
{
SysQueryRun selectSalesLines;
container salesLinesQueryPacked;
SysLastValue sysLastValue;
#define.CurrentVersion(1)
#localmacro.CurrentList
salesLinesQueryPacked
#endmacro
}
// Template method, must be named lastValueType
private UtilElementType lastValueType()
{
return UtilElementType::Form;
}
// Template method, must be named lastValueUserId
private UserId lastValueUserId()
{
return curUserId();
}
...
Form with tmpFrmVirtual
//in 2009, we can use a special column link to a temporary table to kown if a line is selected
//Example BOMExpandSales.
form with tmpFrmVirtual
code for tmpFrmVirtual
Form Master - detail
// Table Master - detail.
The aims is to explain that in the bouton Refresh :
- the refresh is good is the execute query of the line is done before the execute query of the master
- Or we must put the filter of the line before the execute query of the master:
Ex :
Refresh :
master_ds.executeQuery();
line_ds_range.value("x");
line_ds.executeQuery; ----> Not GOOD
//----------------------------------------------------------------------//
line_ds_range.value("x");
master_ds.executeQuery();
line_ds.executeQuery; ----> GOOD
//=============================================================================================//
// Init Master
public void init()
{
queryBuildDataSource queryBuildDataSource;
queryBuildRange queryBuildRangeDate;
super();
queryBuildDataSource = this.query().dataSourceTable(tablenum(SMAAgreementTable));
queryBuildDataSource.addRange(fieldNum(SMAAgreementTable,StartDate)).value(queryRange(dateNull(),systemDateGet()));
queryBuildRangeDate = queryBuildDataSource.addRange(fieldNum(SMAAgreementTable,EndDate));
queryBuildRangeDate.value(queryValue(dateNull()));
queryBuildRangeDate = queryBuildDataSource.addRange(fieldNum(SMAAgreementTable,EndDate));
queryBuildRangeDate.value(queryRange(systemDateGet(),dateMax()));
queryBuildDataSource.addRange(fieldNum(SMAAgreementTable,Suspended)).value(queryValue(NoYes::No));
qbrAgreementId = queryBuildDataSource.addRange(fieldNum(SMAAgreementTable,AgreementId));
if (SMAAgreementIdCaller)
{
HeaderAgreementId.text(SMAAgreementIdCaller);
qbrAgreementId.value(queryValue(SMAAgreementIdCaller));
}
}
//ExecuteQuery Master
public void executeQuery()
{
if (HeaderAgreementId.text())
qbrAgreementId.value(queryValue(HeaderAgreementId.text()));
else
qbrAgreementId.value("");
super();
}
//=============================================================================================//
// Init Line //
public void init()
{
queryBuildDataSource queryBuildDataSource;
super();
queryBuildDataSource = this.query().dataSourceTable(tablenum(SPLWasteSMAFormula));
qbrNextRevisionDate = queryBuildDataSource.addRange(fieldNum(SPLWasteSMAFormula,NextRevisionPeriodDate));
}
//ExecuteQuery Line
public void executeQuery()
{
//date dateStart,dateEnd;
// this part is to put in the button refresh before execute query of the master
//if (HeaderDateMonthYear.dateValue())
//{
// dateStart = dateStartMth(HeaderDateMonthYear.dateValue());
// dateEnd = dateEndMth(HeaderDateMonthYear.dateValue());
// qbrNextRevisionDate.value(queryRange(dateStart,dateEnd));
//}
//else
// qbrNextRevisionDate.value(queryRange(dateNull(),dateMax()));
super();
}
//=============================================================================================//
//Refresh button // === NOT GOOD ===
void clicked()
{
super();
SMAAgreementTable_ds.executeQuery();
SPLWasteSMAFormula_ds.executeQuery();
ProjTable_ds.executeQuery();
}
//======================================//
void clicked() // ==== GOOD ====
{
date dateStart,dateEnd;
;
super();
// Filter for SPLWasteSMAFormula <=============Range of line before the master executeQuery
if (HeaderDateMonthYear.dateValue())
{
dateStart = dateStartMth(HeaderDateMonthYear.dateValue());
dateEnd = dateEndMth(HeaderDateMonthYear.dateValue());
qbrNextRevisionDate.value(queryRange(dateStart,dateEnd));
}
else
qbrNextRevisionDate.value(queryRange(dateNull(),dateMax()));
SMAAgreementTable_ds.executeQuery();
SPLWasteSMAFormula_ds.executeQuery();
ProjTable_ds.executeQuery();
}
Master-detail
Reference Datasource
//We can add a reference Data source with a relation key to use it in a form.
Run - sum from dataSource
//It is possible to do a sum in the run, the run goes after the execute query.
public void run()
{
SPLGuarantee localSPLGuarantee;
real receivedTotal, givenTotal;
;
TotalReceived.realValue(0);
TotalGiven.realValue(0);
super();
for (localSPLGuarantee = SPLGuarantee_ds.getFirst(false);localSPLGuarantee;localSPLGuarantee = SPLGuarantee_ds.getNext())
{
if (!localSPLGuarantee.Closed)
{
if (localSPLGuarantee.GuaranteeDirection == SPLGuaranteeDirection::Given)
{
givenTotal += localSPLGuarantee.AmountCalcMst;
}
else
{
receivedTotal += localSPLGuarantee.AmountCalcMst;
}
}
}
TotalReceived.realValue(receivedTotal);
TotalGiven.realValue(givenTotal);
}
Close , canClose
Close is called when we click on the button Close or on X of the Window.
When we click on the button Close or on X of the Window, we first call the CanClose.
1 - CanClose
2 - LeaveRecord... , write...
3 - Close
//Code To refresh the caller record
public void close()
{
Common common;
FormDataSource callingFormDataSource;
if(SPLWASTEBSDTable.ServiceOrderId && SPLWASTEBSDTable.ServiceOrderLineNum)
SMAServiceOrderLine::SPLWasteUpdateQtyFromBSD(SPLWASTEBSDTable.ServiceOrderId,SPLWASTEBSDTable.ServiceOrderLineNum);
common = element.args().record();
if (common)
{
callingFormDataSource = common.dataSource();
if (callingFormDataSource)
{
// Referenced datasources must be reread before calling research as data has been modified behind the scenes
// without calling research will fail to position selection correctly
callingFormDataSource.reread();
callingFormDataSource.rereadReferenceDataSources();
callingFormDataSource.research(true);
}
}
super();
}
Example of form without button close : SalesCreateOrder
Icone in a grid
//PurchParmTable
//BP Deviation documented
display ImageRes checkIfLines()
{
#resAppl
;
// Invoices and Invoice Approval Journals with an error log should show the error warning icon
if ((this.Log != '') &&
(this.Ordering == DocumentStatus::Invoice || this.Ordering == DocumentStatus::ApproveJournal))
{
return #ImageError;
}
if (PurchParmLine::existTableRefId(this.ParmId, this.TableRefId))
{
return #ImageOK;
}
return #ImageWarning;
//return 0 -> empty
}
Prompt in run
//In the run we can call the prompt to apply a filter
public void run()
{
SysQueryRun queryRunCriteria;
super();
queryRunCriteria = new SysQueryRun(spldrivertable_ds.query());
queryRunCriteria.promptAllowAddDataSource(false);
if (queryRunCriteria.prompt())
{
spldrivertable_ds.query(queryRunCriteria.query());
}
spldrivertable_ds.executeQuery();
}
Call a dialog and refresh the form
// Refresh the caller form !
// Case of a form that call a dialog
class SPLSalesImportXls extends RunBase
{
Object objectForm;
}
static void main(Args args)
{
SPLSalesImportXls.setObject(args.caller());
....
if (SPLSalesImportXls.prompt())
SPLSalesImportXls.run();
}
public void run()
{
FormRun formRun;
#Task
try
{
if (this.checkDir(fileNameOpen))
{
this.readfileXLS();
}
}
catch (Exception::Deadlock)
{
retry;
}
formRun = objectForm;
formRun.task(#taskFormRefresh_F5); //(2012 TaskF5))
}
public Object setObject(Object _object)
{
;
objectForm = _object;
return objectForm;
}
JumpRef - Go to main table
// On a control in a form to see, Right click -> Go to main table
// We need to override the jumpref method
public void jumpRef()
{
Args SPLArgs;
MenuFunction SPLMenuFunction;
InventTransferTable inventTransferTable;
;
if (salesLine.InventRefType == InventRefType::InventTransfer && salesLine.InventRefId)
{
inventTransferTable = InventTransferTable::find(salesLine.InventRefId);
SPLArgs = new Args();
SPLMenuFunction = new MenuFunction(menuitemDisplayStr(InventTransferOrder), MenuItemType::Display);
SPLArgs = new Args(SPLMenuFunction.object());
SPLArgs.caller(element);
SPLArgs.record(inventTransferTable);
SPLMenuFunction.run(SPLArgs);
}
else
super();
}