Getting the current record of the lookup table - axapta

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);

Related

Lookup Filtering on D365 x++

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

Modified table value

I want to create condition that check other table field in same datasource before modify/update table data.
For example I have table student, field in that table is "status", "name" and "score". Status is enum type and default is "not allow". User can change status field using data grid form.
I want to create condition that Status can change to "allow" if score > 50 else it can't be change. Thanks
As Jan already wrote, one way to solve this would be to overwrite the validateField method of your student table. This method is called every time a field of the table is changed by the user in the form of the table. In the method you could write some code to handle changes to the Status field like e.g.
public boolean validateField(FieldId _fieldId)
{
boolean ret;
ret = super();
switch (_fieldId)
{
case fieldNum(MyStudentTable, Status):
if (this.Status == MyStatus::Allow
&& this.Score <= 50)
{
ret = checkFailed("Score must be greater than 50 to Change the Status."); // TODO create a label
}
break;
}
return ret;
}
What about using validation?
Using validateField or validateWrite on the table or datasource you can test whether the chosen value is valid.
Also the validate method on the datasource or control could be used.
Search the Tables or Forms node of the AOT for thousands of examples.
This answer applies to most "check the value of an entered field".

how to change people picker value in infopath form after every form updating

I have a state machine workflow and related task. Task can be edited until it satisfy some conditions. Task formed by infopath. These task contains one people picker field. I assign 3 fields with these values:
private void createTask_Operator_MethodInvoking(object sender, EventArgs e)
{
this.createTask_Id = Guid.NewGuid();
this.createTask_Properties.ExtendedProperties["ows_TaskDisplayName"] = "user1";
this.createTask_Properties.ExtendedProperties["ows_TaskAccountId"] = #"SP\user1";
this.createTask_Properties.ExtendedProperties["ows_TaskAccountType"] = "User";
}
It is works, I can see in my form value these user. But when I change the user(for example: "user2") and submit the form, I cannot retrieve my manually changed field value, it always returns values of "user1".
private void onTaskChanged_Operator_Invoked(object sender, ExternalDataEventArgs e)
{
this.onTaskChanged_AfterProperties = this.onTaskChanged.AfterProperties;
this.onTaskChanged_BeforeProperties = this.onTaskChanged.BeforeProperties;
// here I cannot retrieve changed field value, always returns: SP\user1
this.workflowProperties.Item["UserName"] =
this.onTaskChanged_AfterProperties.ExtendedProperties["TaskAccountId"].ToString();
this.workflowProperties.Item.Update();
}
Please, if you faced such problem, help me with that...
I'm having a little trouble understanding your problem, but here are two answers. To successfully set the value of a people picker field, you have to correctly populate all three fields: DisplayName, AccountId, and AccountType. AccountType is always "User", but the other two have to align with your AD or wherever you're getting your user data from. To get data from a people picker, the best solution often includes the double eval trick: eval(eval(person, "concat(my:AccountId, ';')"), "..") This handles multiple entries correctly, if you mean that you're only getting the first in the list.

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

Preventing empty strings becoming NULL in asp.net dynamic-data

I have a standard ASP.NET 4 Dynamic Data site (using Linq to SQL).
In my SQL-Server database I have hundreds of varchar fields that are set to NOT NULL, but have a default value of an empty string. They should never be NULL, but they may have an empty string as content.
When editing these fields on the dynamic data site, the internal logic sees the field as NOT NULL and somewhere between TextBox1.Text (which is an empty string) and calling the UPDATE sql it sets the value to NULL and they update fails.
I can see the System.Web.DynamicData.MetaColumn has a property 'ConvertEmptyStringToNull' but is is read-only.
What can I do to prevent the empty string becoming NULL without having to change properties for all the hundreds of fields?
Do you have a single procedure for calling your database?
If so you can check the fields values here, or just append a blank string to each value.
In FieldTemplates/Text_Edit.ascx.cs change the behavior for strings, first remove the
validators because they prevent the form from being submitted:
protected void Page_Load(object sender, EventArgs e) {
TextBox1.MaxLength = Column.MaxLength;
if (Column.MaxLength < 20)
TextBox1.Columns = Column.MaxLength;
TextBox1.ToolTip = Column.Description;
if (Column.IsString)
{
this.Controls.Remove(RequiredFieldValidator1);
this.Controls.Remove(RegularExpressionValidator1);
this.Controls.Remove(DynamicValidator1);
}
else
{
SetUpValidator(RequiredFieldValidator1);
SetUpValidator(RegularExpressionValidator1);
SetUpValidator(DynamicValidator1);
}
}
The piece of code that converts the empty string to NULL is somewhere in the ConvertEditedValue method, so skip that for strings:
protected override void ExtractValues(IOrderedDictionary dictionary)
{
if (Column.IsString)
{
dictionary[Column.Name] = TextBox1.Text;
}
else
{
dictionary[Column.Name] = ConvertEditedValue(TextBox1.Text);
}
}
Now you can update tables with empty strings, the problem of course is now you can set empty strings for all varchar fields not only the ones with a default value.
I don't see anywhere in the Linq to SQL or EF datamodels where I can find out about my SQL-Server default value. There is a property DefaultValue but it is always NULL.
Since you wish to set the default value (empty String) in the database and not in the application consider using metadata on the columns in question to default to the database's initialization:
[Column(IsDbGenerated = true, UpdateCheck = UpdateCheck.Never, AutoSync=AutoSync.Never)]
public object MyColumn { get; set; }

Resources