Well, only easily possible if the columns object is undefined in the layout.jsonc.
The below works 100%, needs a Pre/Post on ExecuteBAQ, and a Post on GetApp.
@Carol_Di this is all your fault, I hate it when Epicor says things can’t be done, so I had to do this one out of spite. Let the Prinicpal Consultant know that they can consult with me if they like
Had I read your error more closely earlier, I would have seen Epicor told you it was a <List>DataSet, so that informs us how to read/write it.


ExecuteBaq Pre BPM:
if (queryID == "UBC_BAQ") {
QueryExecutionTableset qets = executionParams[0];
var r = qets.ExecutionSetting.FirstOrDefault(x => x.Name == "Select");
if (r != null) {
var cols = r.Value;
var kept = cols
.Split(',')
.Select(s => s.Trim())
.Where(s => !s.Equals("[bob]", StringComparison.OrdinalIgnoreCase))
.ToArray();
r.Value = string.Join(", ", kept);
}
}
ExecuteBaq Post BPM:
if (queryID == "UBC_BAQ") {
DataSet ds = result.FirstOrDefault();
if (ds != null) {
var t = ds.Tables["Results"];
if (t != null) {
t.Columns.Add(new DataColumn("bob", typeof(string)));
foreach (DataRow r in t.Rows) {
r["bob"] = "test";
}
}
}
}
Tricky Tricky Tricky…
This Post BPM on Ice.Lib.MetaFX.GetApp will properly dynamically add the column to the gridModel.columns array on the first component (which is the first panel)
That works, but now since the BAQ is set up in providermodel, Epicor sends a call to that BAQ with SELECT … [bob], and it fails because bob doesn’t exist in the BAQ’s columns collection.
So I think the methodology gets even more dicey in that we need to inject a property-set on Form_OnLoad, which will dynamically add the column after the gridmodel is painted.
Edit: Nope, the Pre BPM to remove the column before hitting ExecuteBaq was easier.
Ice.MetaFX.GetApp Post BPM:
//reference Ice.Lib.Contracts.MetaFX
//reference Newtonsoft.Json
//using Epicor.MetaFX.Core.Models;
//using Newtonsoft.Json;
//using Newtonsoft.Json.Linq;
EpMetaFxRequest mfxreq = request;
ViewMetadataResponse mfxresp = (ViewMetadataResponse)result;
if (mfxreq.id == "Erp.UI.UBC_ChecksInfo") {
JObject layout = JObject.Parse(mfxresp.Layout.ToString());
JArray columns = (JArray)layout["components"]?[0]?["model"]?["gridModel"]?["columns"];
if (columns != null) {
var copycol = (JObject)columns.Last;
var newcol = (JObject)copycol.DeepClone();
newcol["field"] = "bob";
newcol["title"] = "bob";
newcol["hidden"] = false;
columns.Add(newcol);
}
mfxresp.Layout = JObject.Parse(layout.ToString());
}
Result, added columns to Grid bound to ExecuteBaq on base layer, no layer customization needed, only BPM:
Base Layer: