Using x++ how to create a job to read each value of a column in a table in Microsoft dynamics AX 2009?
This code will display all the column values for a record.
static void Job1(Args _args)
{
DictTable dictTable = new DictTable(tableNum(CustTable));
DictField dictField;
int counter, fieldId;
CustTable custTable;
anytype value;
select firstonly custTable;
for (counter = 1; counter <= dictTable.fieldCnt(); counter++)
{
fieldId = dictTable.fieldCnt2Id(counter);
dictField = new DictField(tableNum(CustTable), fieldId);
if (!dictField.isSystem())
{
value = custTable.(fieldId);
if(value)
{
info(strFmt('%1 = %2',
dictField.label(),
any2str(value)));
}
}
}
}
For getting all the values for a specific column, please use Carlos Heuberger's code.
One possibility: in the AOT (Ctrl-D) right-click on Jobs and select New Job. In the new window enter something like (using the correct table and column name you want to read):
static void Job()
{
YourTable yourTable;
;
while select TheColumn from yourTable
{
// process yourTable.TheColumn
info(strFmt("value: %1", yourTable.TheColumn));
}
}
but thera are some other ways: Select Statements
Just a slight mod, took out any2str to make my table work:
strFmt('%1 = %2 \r\n', dictField.label(), value);
Related
I want to loop through columns(fields) in grid control in AX 2012 form. I have this logic to loop through fields :
static void Job1(Args _args)
{
SysDictTable dictTable = new SysDictTable(tableNum(PurchLine));
SysDictField dictField;
TreeNode treeNode;
FieldId fieldId = dictTable.fieldNext(0);
while (fieldId)
{
dictField = dictTable.fieldObject(fieldId);
if (dictField.isSql() && !dictField.isSystem())
{
treeNode = dictField.treeNode();
info(strFmt("%1 | %2 | %3",
dictField.name(), // Field name
treeNode.AOTgetProperty("Label"), // Label id
SysLabel::labelId2String(treeNode.AOTgetProperty("Label")))); // Label string
}
fieldId = dictTable.fieldNext(fieldId);
}
}
This loop through table, I need similar logic to loop through grid fields but in RUNTIME.
For example if grid data source has 5 columns and 3 are removed in UI, i want to loop just through these 2 that are left in the grid.
So my question is how to get grid fields in runtime( not from datasource table) ?
The below assumes your grid is named "GridOverview". You call it like:
::outputGridControls(element) where element is your form.
public static void outputGridControls(FormRun _formRun)
{
int i;
FormGridControl formGridControl;
FormControl formControl;
formGridControl = _formRun.control(_formRun.controlId(identifierStr(GridOverview)));
if (formGridControl)
{
for (i=1; i<=formGridControl.controlCount(); i++)
{
formControl = formGridControl.controlNum(i);
if (formControl && formControl.visible())
{
info(strFmt("%1 (%2)", formControl.name(), formControl.labelText()));
}
}
}
}
What you're doing above is reflecting on the AOT table, but you need to be looking at the FormRun and not the actual table or even the DataSource.
How does one create a job which finds all tables containing a particular extended data type?
I found this JOB, but it gives me an error: https://fredshen.wordpress.com/2006/02/05/find-out-tables-containing-specific-edt/
Use the Cross Reference Tool.
It will show code uses as well.
try this:
static void findEdtinTable(Args _args)
{
treeNode childNode;
treeNode fields;
treenodeIterator it, itFld;
str properties;
str table;
str field;
str extendedDataType;
str searchType = "PurchInternalInvoiceId"; // EDT
int x;
treeNode t = TreeNode::findNode('\\Data Dictionary\\Tables');
it = t.AOTiterator();
childNode= it.next();
while (childNode)
{
Table = childNode.treeNodeName();
itFld = t.AOTfindChild(childNode.treeNodeName()).AOTfindChild("Fields").AOTiterator();
fields = itFld.next();
while (fields)
{
field = fields.treeNodeName();
properties = fields.AOTgetProperties();
extendedDataType = findProperty(properties, "ExtendedDataType");
if (extendedDataType == searchType)
{
info(strfmt("%1 / %2 – ExtendedDataType: %3", table, field, extendedDataType));
}
fields = itFld.next();
}
childNode= it.next();
}
}
I am trying to bring the vendor name on each line in the TransAccountForm.
I have written a small piece of code which gets the vendor name when LedgerDimension from LedgerJournalTrans is available:
static void GetVendorName(Args _args)
{
CustAccount custAccount;
VendTable vendTable;
LedgerJournalTrans ledgerJournalTrans;
while select ledgerJournalTrans
{
if (ledgerJournalTrans.AccountType == LedgerJournalACType::Vend)
{
custAccount = DimensionStorage::ledgerDimension2AccountNum(LedgerJournalTrans.LedgerDimension);
select firstOnly vendTable
where vendTable.AccountNum == custAccount;
info(strFmt("Vendor Name: %1, Voucher: %2", DirPartyTable::getName(vendTable.Party), ledgerJournalTrans.Voucher));
}
}
}
But how can I get to run this code in order to bring that new column with the vendor name?
Thanks to Jan B. Kjeldsen I got to this solution:
One of the data source in LedgerTransAccount is GeneralJournalEntry on wich i add the display method.
With the help of SubLedgerVoucher i am able to get one line from LedgerJournalTrans.
public display Name VendorName()
{
Name ret;
LedgerJournalTrans ledgerJournalTrans;
select firstFast firstOnly ledgerJournalTrans
where ledgerJournalTrans.Voucher == this.SubledgerVoucher &&
ledgerJournalTrans.TransDate == this.AccountingDate;
ret = ledgerJournalTrans.AccountType == LedgerJournalACType::Vend ?
vendTable::find(DimensionStorage::ledgerDimension2AccountNum
(ledgerJournalTrans.LedgerDimension)).name() : '';
return ret;
}
After this, I just drag and drop this method on my form's grid.
You can add a display method to the ledgerJournalTrans table:
[SysClientCacheDataMethodAttribute(true)]
display VendName vendName()
{
return this.AccountType == LedgerJournalACType::Vend ? vendTable::find(DimensionStorage::ledgerDimension2AccountNum(this.LedgerDimension)).name() : '';
}
A one-liner.
I'm using tutorial_Form_Table.
The table has dynamically assigned values, something like:
for (col = 1; col <= 5; col++)
{
for (row = 1; row <= 5; row++)
{
if ((col == 2) || (col == 4))
{
if (row > 1)
table.cell(col,row).data(row*col);
else
table.cell(col,row).data("Text "+int2str(row*col));
}
else
table.cell(col,row).data("Text "+int2str(row*col));
}
}
I need to get the position of the cell when I enter new value in it, so I can update the corresponding table with the value entered.
Thank you.
Table has two properties: row() and column() which return values of current active cell.
public void activeCellChanged()
{
super();
info(strFmt('%1 %2 %3', Table.row(), Table.column(), Table.cell(Table.column(), Table.row()).data()));
}
On each of the controls you add to the table control you can override the modified method to see the new value you entered.
public boolean modified()
{
boolean ret;
ret = super();
info(strFmt('New data that we need to save: %1, %2 -> %3', Table.row(), Table.column(), Table.cell(Table.column(), Table.row()).data()));
return ret;
}
If you are working with a lot of data you should consider using some other control such as .NET grid control because of performance issues.
Essentially, this is what I'm faced with:
I want to modify the InventTrans form
By default, it has the entire InventTrans datasource set to AllowEdit = No
I want to enable editing on ONE new Enum field (NoYes type)
Should I set the InventTrans datasource to AllowEdit = Yes and then painfully change 40+ fields in the datasource to be AllowEdit = No, OR is there a way to programmatically iterate through the fields of the datasource and set this property by name? (Please say there is, or an equally easy way to do this!)
Thanks in advance!
This is how I would try to disable editing to all fields:
DictTable dictTable;
DictField dictField;
int fldCnt;
;
dictTable = new DictTable(tablenum(InventTrans));
for (fldCnt = 1; fldCnt <= dictTable.fieldCnt() ; fldCnt++)
{
dictField = new DictField(tablenum(InventTrans), dictTable.fieldCnt2Id(fldCnt));
info(strfmt("%1", dictField.id(),dictField.name()));
InventTrans_DS.object(dictField.id()).allowEdit(false);
}
EDIT: Better approach to iterate through form's DS'es fields only:
DictTable dictTable;
DictField dictField;
int fldCnt;
QueryBuildFieldList qBFL;
;
qBFL = InventTrans_DS.query().dataSourceTable(tablenum(InventTrans)).fields();
for (fldCnt = 1; fldCnt <= qBFL.fieldCount() ; fldCnt++)
{
dictField = new DictField(tablenum(InventTrans), qBFL.field(fldCnt));
info(strfmt("%1 %2 ", dictField.id(),dictField.name()));
if(InventTrans_DS.object(qBFL.field(fldCnt))) //exception recVersion for example
{
InventTrans_DS.object(qBFL.field(fldCnt)).allowEdit(false);
}
}
I have a scenario in which I want to allow editing of ItemID in the InventJournalTrans form, based on an enum value in ANOTHER form. Is this possible?
Can args() class(parm method) be used to fetch the value of the checkbox? along with on the below condition in the active()?
My codes:
public int active()
{
int ret;
;
ret = super();
if([datasource table name].[Column 1 field name] == [Column1 value to
deactivate Column 3])
{
[datasource table name]_ds.object(fieldNum([datasource table name],
[Column 1 field name])).allowEdit(false);
}
else
{
[datasource table name]_ds.object(fieldNum([datasource table name],
[Column 1 field name])).allowEdit(true);
}
return ret;
}