Hi all,
I’m working on a requirement involving the ExpenseJournalLineEntity. One of our ISVs includes a field called SID, which has a relationship with ActivityNumber. As part of the requirement, we implemented logic so that during import (via DMF), when a user provides an SID, the corresponding ActivityNumber is automatically looked up and populated.
That part works as expected — the ActivityNumber gets correctly filled during import.
However, the issue is with the SID field on the Expense Journal form. Even though the SID value was provided in the import file and was used to resolve the ActivityNumber, the SID field in the form appears blank.
Interestingly, if I click the dropdown on the SID field, it correctly navigates to the proper value — which makes me think the relation logic is working. From what I can tell, the SID field on the form is not a physical field but is instead derived from a display method (specifically, from a data method on the table).
So my question is:
Is there a way to have the SID value persist and display correctly in the journal form after import, even though it’s a data method and not a physical field?
We are passing the SID in the import file, and it is functioning for the lookup, but it would be helpful to show that same SID in the form for clarity to the users.
Any suggestions or workarounds are appreciated. Thanks!
It all depends on what the display method does. We can’t tell you how to make the method return the expected value without any information about the logic of the method. At least, you’ll need to look at the code. But even a better approach will be debugging the method to see what’s actually doing at runtime.
The SID field on the form uses a display method called ARPTaskWBSId, which is part of the ISV extension on LedgerJournalTrans_Project. Here’s the relevant portion of the code:
[wbsId, ledgerJournalTransProject.ActivityNumber] = ARPTasktools::TaskWBSId_edit(
ledgerJournalTransProject.projId,
'',
false,
wbsId,
ledgerJournalTransProject.ActivityNumber
);
This means the value is calculated at runtime — not stored based on ProjId and ActivityNumber. So when the data is imported via DMF, even though the ActivityNumber is present, the display method returns blank until the form is refreshed or manually triggered.
To support the export/import behavior we need, I’ve implemented this logic in the data entity extension:
// Handles export: populate SID from ActivityNumber
public void postLoad()
{
next postLoad();
LedgerJournalTrans_Project ledgerJournalTransProject;
ARPCBSNodeEntity node;
if (this.ActivityNumber)
{
select firstonly ledgerJournalTransProject
where ledgerJournalTransProject.ActivityNumber == this.ActivityNumber;
if (ledgerJournalTransProject)
{
select firstonly node
where node.DataAreaId == curext()
&& node.ProjId == ledgerJournalTransProject.ProjId
&& node.ActivityNumber == ledgerJournalTransProject.ActivityNumber;
if (node.ElementBSID)
{
this.SID = node.ElementBSID;
}
}
}
}
// Handles import: populate ActivityNumber from SID or vice versa
public void mapEntityToDataSource(
DataEntityRuntimeContext _entityCtx,
DataEntityDataSourceRuntimeContext _dataSourceCtx)
{
next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
if (_dataSourceCtx.name() == dataEntityDataSourceStr(PREFABExpenseJournalLineEntity, LedgerJournalTrans_Project))
{
LedgerJournalTrans_Project bufferLJP = _dataSourceCtx.getBuffer() as LedgerJournalTrans_Project;
// Case 1: SID is present, populate ActivityNumber
if (!this.ActivityNumber && this.SID && strLen(this.SID) > 0)
{
ARPCBSNodeEntity node;
select firstonly node
where node.DataAreaId == curext()
&& node.ProjId == bufferLJP.ProjId
&& node.ElementBSID == this.SID;
if (node.ActivityNumber)
{
this.ActivityNumber = node.ActivityNumber;
bufferLJP.ActivityNumber = node.ActivityNumber;
bufferLJP.modifiedField(fieldNum(LedgerJournalTrans_Project, ActivityNumber));
}
}
// Case 2: ActivityNumber is present, populate SID
else if (!this.SID && this.ActivityNumber)
{
ARPCBSNodeEntity node;
select firstonly node
where node.DataAreaId == curext()
&& node.ProjId == bufferLJP.ProjId
&& node.ActivityNumber == bufferLJP.ActivityNumber;
if (node.ElementBSID)
{
this.SID = node.ElementBSID;
bufferLJP.modifiedField(fieldNum(LedgerJournalTrans_Project, ActivityNumber));
}
}
}
}
This works perfectly in the Excel Add-in, but with DMF imports, the SID doesn’t persist on the journal line form after import — even though the ActivityNumber is correctly set and the dropdown navigates to the right SID. I’m assuming the data method isn’t being triggered/rendered during DMF post-processing?
Is there a way to force the data method to evaluate and display properly in the form after import? Or any best practices here for making the SID (from a display method) persist visually on import?
Your description is extremely confusing. Let me summarize my understand of your statements:
- SID is a display method.
- SID should persist on the journal line form after import. It contradicts the previous point saying that SID is calculated, not persisted.
- You have no idea what data the display method depends on and what’s the problem when it didn’t work.
- Data was imported correctly, you just need to refresh data currently displayed in a form. It means that the entity works correctly and there is nothing to change in its behaviour.
- You have code that assumes that that code in
modifiedField() for ActivityNumber must be executed for the display method to work correctly. This contradicts the previous point.
Please try to resolve the contradictions.
Also, explain the actual scenario to us. It seems that your actual problem is related to a form when you want to refresh displayed data after importing new data. What isn’t clear to me how running a DMF import project is related to the form. Also, isn’t refreshing the form the most logical step? What problem do you have with it? I’m assuming many questions will be answered when share the use case with us.
Yes,
- In the form LedgerJournalTransCost the SID field on there is calculated via Data Method instead of a physical field. When I said persist I meant that the value would stick instead of showing as blank. But yes I would want this to calculate
- I’m not using this in my entity, i’m using a physical field for my import
- Data is imported correctly, but as mentioned the SID field in LedgerJournalTransCost does not populate or calculate. This is where I am stuck.
The scenario is: A user will import data via DMF, filling in some data points such as ProjID, Project Category, SID. We want the ActivityNumber to be autopopulated as to save the users time. So when importing into the system the ActivityNumber will be autopopulated, however the SID is not being imported or calculated.
I did attempt to do a refresh of the lines, however it still didn’t seem to calculate:
public int active()
{
int ret = next active();
FormDataSource projDs = this;
LedgerJournalTrans_Project line = projDs.cursor() as LedgerJournalTrans_Project;
if (line && line.ActivityNumber && line.ProjId)
{
line.reread(); // Refresh buffer
projDs.refresh(); // Refresh the form to recalculate display methods like ARPTaskWBSId
}
return ret;
I hope this clears up some of the confusion.
Use the debugger to see why the method returns an empty string. You can’t expect me to tell you that, as I know neither the code nor the data in your environment.
Let me know if you don’t know how to use the debugger or you have a problem with it.
Thanks for your response — that makes sense. I’ll plan to use the debugger separately to step through and check why the method may be returning an empty string in this particular case.
As a side question, I’m also trying to understand: is it generally feasible to populate a field tied to a data method (not a real database field) through DMF import? Or would a manual refresh/recalculation typically be required after the record is created?
A display method is not field to populate - it’s a piece of code that returns value. If the method uses table fields to calculate the result, then you probably can use DMF to import their values. But not all field values can be imported, e.g. because they’re set by the system.
As you see, what the method does is absolutely critical to know which fields you need to populate and whether it can be done.