How to create, compile and run code at RUNTIME.
In some situations the need for making "generic" code arises.
This is a little example that generates, compiles and runs code to delete the contents of table PBACustGroup.
The code is made as a job, but transforming this code into a method on a class, and calling this method with parameters that allows it to identify the table, suddenly makes us able to delete several selected tables with very little code.
It also allows for USER CONTROLLED actions, for example letting the user build a liste of tables he would like to delete, and then calling the code for each of these tables.
static void TestGenericCode(Args _args)
{
XppCompiler XppCompiler;
str code;
str tableName = "PBACustGroup"; // Here we define the name of the table
;
// A compile object is created
XppCompiler = new XppCompiler();
// Here the code to delete the tabel is created
code = "void x() {"+tableName+" "+tablename+"; ttsbegin; delete_from "+tableName+"; ttscommit; }";
// And compiled
if (XppCompiler.compile(code))
{
// If the compiler was satisfied with the code we run it
XppCompiler.execute();
// And inform the user that we deleted data
info("Deleted all record in table "+tableName);
}
else
{
// Otherwise the compiler lets us know the code was errorneous
info(XppCompiler.errorText());
info("fejl !!");
}
}
In some situations the need for making "generic" code arises.
This is a little example that generates, compiles and runs code to delete the contents of table PBACustGroup.
The code is made as a job, but transforming this code into a method on a class, and calling this method with parameters that allows it to identify the table, suddenly makes us able to delete several selected tables with very little code.
It also allows for USER CONTROLLED actions, for example letting the user build a liste of tables he would like to delete, and then calling the code for each of these tables.
static void TestGenericCode(Args _args)
{
XppCompiler XppCompiler;
str code;
str tableName = "PBACustGroup"; // Here we define the name of the table
;
// A compile object is created
XppCompiler = new XppCompiler();
// Here the code to delete the tabel is created
code = "void x() {"+tableName+" "+tablename+"; ttsbegin; delete_from "+tableName+"; ttscommit; }";
// And compiled
if (XppCompiler.compile(code))
{
// If the compiler was satisfied with the code we run it
XppCompiler.execute();
// And inform the user that we deleted data
info("Deleted all record in table "+tableName);
}
else
{
// Otherwise the compiler lets us know the code was errorneous
info(XppCompiler.errorText());
info("fejl !!");
}
}
Hello,
ReplyDeleteI've read your blog posts and I find them very interesting and helpful.
I have a task to accomplish, but don't know how. I'll explain you what's about and how I'd like to solve it.
I have to migrate selective subset of data from one aos to another (eg. all CustTable rows where name="John").
I thought to create a method on the first aos that gathers the data and send the table container to a web service. The WS would then write into the second aos instance.
I've also thought to code it using reflection to make it more generic and reusable, but since I'm not an expert X++ coder (I'm stronger in C# and Java) I'm stuck with this implementation.
Do you know a better way to solve my problem? Can you give me some ideas?
Thank you in advance and keep posting,
Francesco