Создание таблиц и получение результатов запроса с помощью Dynamics AX 2009 business connector
Я пишу инструмент командной строки C# для извлечения данных из AX и добавления данных (создания новых таблиц) в AX.
извлечение данных из таблицы AX легко и документировано здесь:http://msdn.microsoft.com/en-us/library/cc197126.aspx
добавление данных в существующую таблицу также легко:http://msdn.microsoft.com/en-us/library/aa868997.aspx
но я не могу понять, как сделать две вещи:
- создать новая AX таблица
- извлечение данных из запроса AX
может кто-то, пожалуйста, поделитесь примером кода или дать некоторые указатели на то, где начать искать. Мои поиски в Google и MSDN не выявлено.
примечание: Я не опытный разработчик AX или ERP.
4 ответов
вот способ создать новую таблицу AX из C# (это использование метода расширения):
public static bool CreateAXTable(this Axapta ax)
{
string TableName = "MyCustomTable";
string size = "255"; //You could load this from a setting
bool val = false;
if (!ax.TableExists(TableName))
{
AxaptaObject TablesNode = (AxaptaObject)ax.CallStaticClassMethod("TreeNode", "findNode", @"\Data Dictionary\Tables");
AxaptaObject node;
AxaptaObject fields;
AxaptaObject fieldNode;
TablesNode.Call("AOTadd", TableName);
node = (AxaptaObject)ax.CallStaticClassMethod("TreeNode", "findNode", "\Data dictionary\Tables\" + TableName);
fields = (AxaptaObject)ax.CallStaticClassMethod("TreeNode", "findNode", "\Data dictionary\Tables\" + TableName + "\Fields");
fields.Call("addString", "String1"); //add a string field
fieldNode = (AxaptaObject)fields.Call("AOTfindChild", "String1"); //grab a reference to the field
fieldNode.Call("AOTsetProperty", "StringSize", size);
fieldNode.Call("AOTsave");
fields.Call("addString", "String2"); //add a string field
fieldNode = (AxaptaObject)fields.Call("AOTfindChild", "String2"); //grab a reference to the field
fieldNode.Call("AOTsetProperty", "StringSize", size);
fieldNode.Call("AOTsave");
fields.Call("addString", "String3"); //add a string field
fieldNode = (AxaptaObject)fields.Call("AOTfindChild", "String3"); //grab a reference to the field
fieldNode.Call("AOTsetProperty", "StringSize", size);
fieldNode.Call("AOTsave");
fields.Call("addString", "String4"); //add a string field
fieldNode = (AxaptaObject)fields.Call("AOTfindChild", "String4"); //grab a reference to the field
fieldNode.Call("AOTsetProperty", "StringSize", size);
fieldNode.Call("AOTsave");
fields.Call("addReal", "Real1");
fields.Call("addReal", "Real2");
fields.Call("addReal", "Real3");
fields.Call("addReal", "Real4");
fields.Call("addDate", "Date1");
fields.Call("addDate", "Date2");
fields.Call("addDate", "Date3");
fields.Call("addDate", "Date4");
fields.Call("AOTsave");
node.Call("AOTsave");
AxaptaObject appl = ax.GetObject("appl");
appl.Call("dbSynchronize", Convert.ToInt32(node.Call("applObjectId")), false);
val = true;
}
else //Table already exists
{
val = true;
}
return val;
}
public static bool TableExists(this Axapta ax, string tableName)
{
return ((int)ax.CallStaticClassMethod("Global", "tableName2Id", tableName) > 0);
}
Я создал запрос в AOT и смог использовать C# для возврата данных. Найдите код ниже. Это запрос, который возвращает продажи, с которыми я создаю стареющие ведра. Надеюсь, это поможет.
[DataMethod(), AxSessionPermission(SecurityAction.Assert)]
public static System.Data.DataTable GetCustBuckets(String AccountNum)
{
//Report Parameters
Dictionary<string, object> d = new Dictionary<string, object>();
d.Add("CustTransOpen.AccountNum",AccountNum);
// Create a data table. Add columns for item group and item information.
DataTable table = new DataTable();
table = AxQuery.ExecuteQuery("SELECT * FROM epcCustomerAging",d);
DataTable tableBucket = new DataTable();
DataRow rowBucket;
tableBucket.Columns.Add("Current", typeof(double));
tableBucket.Columns.Add("Bucket31to60", typeof(double));
tableBucket.Columns.Add("Bucket61to90", typeof(double));
tableBucket.Columns.Add("Bucket91to120", typeof(double));
tableBucket.Columns.Add("Over120", typeof(double));
//Variables to hold BUCKETS
double dCurrent = 0;
double dBucket31to60 = 0;
double dBucket61to90 = 0;
double dBucket91to120 = 0;
double dOver120 = 0;
// Iterate through the results. Add the item group to the data table. Call the display method
foreach (DataRow TransRow in table.Rows)
{
DateTime TransDate = Convert.ToDateTime(TransRow["TransDate"].ToString());
double AmountCur = Convert.ToDouble(TransRow["AmountCur"].ToString());
DateTime Today= Microsoft.VisualBasic.DateAndTime.Now;
long nDays = Microsoft.VisualBasic.DateAndTime.DateDiff(Microsoft.VisualBasic.DateInterval.Day, TransDate, Today, 0, 0);
if (nDays <= 30)
{
dCurrent += AmountCur;
}
else if (nDays <= 60)
{
dBucket31to60 += AmountCur ;
}
else if (nDays <= 90)
{
dBucket61to90 += AmountCur;
}
else if (nDays <= 120)
{
dBucket91to120 += AmountCur;
}
else
{
dOver120 += AmountCur;
}
}
rowBucket = tableBucket.NewRow();
rowBucket["Current"] = dCurrent;
rowBucket["Bucket31to60"] = dBucket31to60;
rowBucket["Bucket61to90"] = dBucket61to90;
rowBucket["Bucket91to120"] = dBucket91to120;
rowBucket["Over120"] = dOver120;
tableBucket.Rows.Add(rowBucket);
return tableBucket;
}
вот пример выполнения запроса в C#:
(Примечание:это очень упрощенный метод, используя существующее определение запроса, вы также можете создать запрос с нуля, используя объекты QueryBuildDataSource и т. д...)
Axapta ax = new Axapta();
ax.Logon("", "", "", "");
//Create a query object based on the customer group query in the AOT
AxaptaObject query = ax.CreateAxaptaObject("Query", "CustGroupSRS");
//Create a queryrun object based on the query to fecth records
AxaptaObject queryRun = ax.CreateAxaptaObject("QueryRun", query);
AxaptaRecord CustGroup = null;
;
while (Convert.ToBoolean(queryRun.Call("next")))
{
//GetTableId function is defined here: .Net Business Connector Kernel Functions
CustGroup = (AxaptaRecord)queryRun.Call("get", ax.GetTableId("CustGroup"));
System.Diagnostics.Debug.WriteLine(CustGroup.get_Field("Name").ToString());
}
CustGroup.Dispose();
queryRun.Dispose();
query.Dispose();
ax.Logoff();
ax.Dispose();
Я честно не думаю, что можно создавать новые таблицы с помощью business connector. Это должно быть сделано в AX и AOT.
Что касается возврата смешанных данных, я бы, вероятно, использовал для этого объект контейнера. Контейнеры могут содержать суб-контейнеры или axaptarecords. AxaptaRecord содержит данные из одной определенной таблицы.