I had to get the list of fields from a table with quite many fields to be used as properties in a class. quite and error prone task.
for example for CustTable you should have to do:
classDelaration
{
CustAccount accountNum;
CustInvoiceAccount invoiceAccount;
CustGroupId custGroup;
….
}
I made this job that using a bit reflection does the work for you:
static void JobEF_TableGetFieldsListForProperties(Args _args)
{
TableID tableID;
DictTable dictTable;
TableName tableName;
FieldId fieldId;
DictField dictField, dictFieldFrom;
Common buffer;
TableScope scope = TableScope::CurrentTableOnly;
ExtendedDataTypeName fieldType;
EnumName fieldEnum;
FieldName fieldName;
LabelString fieldTypeLabel, fieldEnumLabel;
IdentifierName fieldDataType;
TextBuffer txtb = new TextBuffer();
int i;
tableName = tableStr(CustTable);
tableID = tablename2id(tableName);
dictTable = new DictTable(tableID);
if (!dictTable)
throw error('invalid table');
buffer = dictTable.makeRecord();
fieldId = dictTable.fieldNext(0, scope);
while (fieldId && ! isSysId(fieldId))
{
dictField = new DictField(tableID, fieldId);
fieldType = Global::extendedTypeId2name(dictField.typeId());
fieldEnum = Global::enumId2Name(dictField.enumId());
fieldName = dictField.name();
fieldTypeLabel = Global::extendedTypeId2pname(dictField.typeId());
fieldEnumLabel = Global::enumId2pname(dictField.enumId());
fieldDataType = fieldType ? fieldType : fieldEnum;
if (i)
txtb.appendText('\n');
txtb.appendText(strFmt('%1 %2;', fieldDataType, MYD_Functions::stringLowerCaseFirst(fieldName)));
i++;
fieldId = dictTable.fieldNext(fieldId, scope);
}
info(txtb.getText());
}
I have a helper class where I have all my utility methods, one is the one used in this code:
public static str stringLowerCaseFirst(str string)
{
System.String myString, firstLetter;
str firstLetterLwr, stringEnd, stringNew;
if (strLen(string) < 2)
return strLwr(string);
myString = string;
firstLetter = myString.Substring(0, 1);
stringEnd = myString.Substring(1);
firstLetterLwr = firstLetter.ToLowerInvariant();
stringNew = strFmt('%1%2', firstLetterLwr, stringEnd);
return stringNew;
/*
NOTE:
you can do the same like \Classes\xppSource\parmMethod
stringNew = strLwr(subStr(string,1,1))+subStr(string,2,strLen(string));
I don't know which one is best. I come form C#
*/
}
I took it a step further and this other Job also auto generate the parm methods in a class for each table field.
To complete this task I used two Ax Foundation classes:
- ClassBuild
- XppSource
ClassBuild contains methods to programmatically create a class and methods
XppSource is the same class which you use behind the scene when you use shorcuts in the code editor or when you select a template under the script button in the editor toolbar.
static void JobEF_ClassMakeDataContractPerTblFields(Args _args)
{
TableID tableID;
DictTable dictTable;
TableName tableName;
FieldId fieldId;
DictField dictField, dictFieldFrom;
Common buffer;
TableScope scope = TableScope::CurrentTableOnly;
ExtendedDataTypeName fieldType;
EnumName fieldEnum;
FieldName fieldName;
LabelString fieldTypeLabel, fieldEnumLabel;
IdentifierName fieldDataType;
TextBuffer txtb = new TextBuffer();
int i;
ClassName className;
Source source;
ClassBuild classBuild;
XppSource xppSource;
MethodName paramMethodName;
str parmPrefixToFieldName;
boolean addDataContractAttribute;
//SET the table you want to get all fields from
tableName = tableStr(CustTable);
//SET the class you want the parm methods to be created
className = classStr(MYDataContractClass);
//SET optionally a prefix to all Table field names for the parm
parmPrefixToFieldName = '';
//SET if you want to add the [DataContractAttribute] attribute
addDataContractAttribute = true;
/*
the hob will run and create a parm for each field of the table in the class.
From the info log copy the parmeters and paste in the class declaration.
*/
tableID = tablename2id(tableName);
dictTable = new DictTable(tableID);
if (!dictTable)
throw error('invalid table');
buffer = dictTable.makeRecord();
fieldId = dictTable.fieldNext(0, scope);
while (fieldId && !isSysId(fieldId))
{
dictField = new DictField(tableID, fieldId);
fieldType = Global::extendedTypeId2name(dictField.typeId());
fieldEnum = Global::enumId2Name(dictField.enumId());
fieldName = strFmt('%1%2', parmPrefixToFieldName, dictField.name());
fieldTypeLabel = Global::extendedTypeId2pname(dictField.typeId());
fieldEnumLabel = Global::enumId2pname(dictField.enumId());
fieldDataType = fieldType ? fieldType : fieldEnum;
if (i)
txtb.appendText('\n');
txtb.appendText(strFmt('%1 %2;', fieldDataType, MYD_Functions::stringLowerCaseFirst(fieldName)));
i++;
classBuild = new ClassBuild(className);
xppSource = new XppSource();
source = xppSource.parmMethod(fieldDataType, fieldName);
paramMethodName = strFmt('parm%1%2', parmPrefixToFieldName, strUpr(subStr(fieldName,1,1))+subStr(fieldName,2,strLen(fieldName)));
if (addDataContractAttribute)
source = strFmt('[DataContractAttribute]\n%1', source);
classBuild.addMethod(paramMethodName, source);
fieldId = dictTable.fieldNext(fieldId, scope);
}
info(txtb.getText());
}
I hope it helps!
No comments:
Post a Comment