I was importing items into Microsoft Dynamics AX 2009 using the following job
static void ItemsImport(Args _args)
{
InventTable InventTable;
container c;
TextIo io;
str 130 fileName;
TextBuffer b;
integer inc;
ItemId ItemId;
AxInventTable axInventTable;
;
fileName = #"C:\Users\mom\Desktop\Items.csv";
b = new Textbuffer();
io = SysLicenseCodeReadFile::openFile(fileName,'r');
if (!io)
throw error(strfmt("#SYS18678",fileName));
io.inFieldDelimiter(";");
c = io.read();
b = new Textbuffer();
ttsbegin;
while (io.status() == IO_Status::Ok)
{
c = io.read();
inc++;
if (io.status() != IO_Status::Ok)
break;
ItemId = conpeek(c,1);
select InventTable
where InventTable.ItemId == ItemId;
axInventTable = new axInventTable();
axInventTable.parmItemId(conPeek(c, 1));
axInventTable.parmItemName(conPeek(c, 2));
axInventTable.parmNameAlias(conPeek(c, 3));
axInventTable.parmItemGroupId("PRD_CHF");
axInventTable.parmModelGroupId("PMP");
axInventTable.parmDimGroupId("Teinture");
axInventTable.axInventTableModule_Sales().parmUnitId("Kg");
axInventTable.axInventTableModule_Purch().parmUnitId("Kg");
axInventTable.axInventTableModule_Invent().parmUnitId("Kg");
axInventTable.parmBOMUnitId("g");
axInventTable.axInventItemInventSetup().axInventDim().parmInventSiteId("FIMA");
axInventTable.axInventItemPurchSetup().axInventDim().parmInventSiteId("FIMA");
axInventTable.axInventItemInventSetup().axInventDim().parmInventSiteId("FIMA");
axInventTable.axInventItemInventSetup().axInventDim().parmInventLocationId("MG_PRD_CHI");
axInventTable.axInventItemPurchSetup().axInventDim().parmInventLocationId("MG_PRD_CHI");
axInventTable.axInventItemInventSetup().axInventDim().parmInventLocationId("MG_PRD_CHI");
axInventTable.save();
}
ttscommit;
pause;
}
The records are created correctly in the table but when I open the default orders settings/Site specific order settings order form for the product,
all fields are still greyed out as if no records exists.
http://www.hostingpics.net/viewer.php?id=756928801.png
http://www.hostingpics.net/viewer.php?id=553431712.png
Has anybody faced this problem ? how I can correct the x ++ code ?
Any help would be appreciated.
Thanks,
You most likely need to change this line:
axInventTable = new axInventTable();
to this line:
axInventTable = axInventTable::newInventTable(inventTable);
This worked for me:
static void updateInventOrderSettings(Args _args)
{
InventTable inventTable;
InventItemInventSetup inventItemInventSetup;
InventItemPurchSetup inventItemPurchSetup;
InventItemSalesSetup inventItemSalesSetup;
InventDim inventDim;
;
ttsBegin;
inventTable = InventTable::find("00001", true);
inventTable.ItemGroupId = "Planning";
//.. other inventTable fields
inventTable.update();
inventDim.initValue();
inventDim.InventSiteId = "Site2";
inventDim.inventLocationId = "ARC";
inventDim = InventDim::findOrCreate(inventDim);
//Site specific setup
inventItemInventSetup.initValue();
inventItemInventSetup.InventDimId = inventDim.inventDimId;
inventItemInventSetup.ItemId = inventTable.ItemId;
inventItemInventSetup.insert();
inventItemPurchSetup.initValue();
inventItemPurchSetup.InventDimId = inventDim.inventDimId;
inventItemPurchSetup.ItemId = inventTable.ItemId;
inventItemPurchSetup.insert();
inventItemSalesSetup.initValue();
inventItemSalesSetup.InventDimId = inventDim.inventDimId;
inventItemSalesSetup.ItemId = inventTable.ItemId;
inventItemSalesSetup.insert();
//Default order settings
inventItemInventSetup= inventItemInventSetup::findDefault(inventTable.itemId, true);
inventItemInventSetup.InventDimIdDefault = inventDim.inventDimId;
inventItemInventSetup.update();
inventItemPurchSetup = inventItemInventSetup::findDefault(inventTable.itemId, true);
inventItemPurchSetup.InventDimIdDefault = inventDim.inventDimId;
inventItemPurchSetup.update();
inventItemSalesSetup= inventItemInventSetup::findDefault(inventTable.itemId, true);
inventItemSalesSetup.InventDimIdDefault = inventDim.inventDimId;
inventItemSalesSetup.update();
ttsCommit;
}
Related
I need to modify Purchase Order Form, so user can select and save PO as PDF in destination folder
I created a new Button, so after user selects data and clicks the button, system creates a PDF file and saves it to the destination folder.
This is my code
public static void main(Args _args)
{
PurchTable purchTable,purchTable2, row;
PurchPurchaseOrderController purchPurchaseOrderController ;
PurchPurchaseOrderContract purchPurchaseOrderContract;
SrsReportRunImpl srsReportRun;
VendPurchOrderJour vendPurchOrderJour;
FormDataSource purchTable_ds;
str PDFName;
int tot = 0;
Args args ;
ReportName reportName = "PurchPurchaseOrder.ReportPRI";
;
if(_args.record().TableId == tableNum(PurchTable))
{
purchTable2 = _args.record();
purchTable_ds = purchTable2.dataSource();
}
if (purchTable_ds.anyMarked())
{
row = purchTable_ds.getFirst( 1, false );
info("a1");
while(row)
{
tot++;
info(row.PurchId);
args = new Args();
args.record(row);
select firstFast purchTable where purchTable.RecId == row.RecId ;
select firstFast vendPurchOrderJour where vendPurchOrderJour.PurchId == purchTable.PurchId ;
PDFName = strFmt("C:\\SharePDF\\%1.pdf",strReplace(purchTable.PurchId,'/','_'));
purchPurchaseOrderController = new PurchPurchaseOrderController();
purchPurchaseOrderController.parmReportName(ReportName);
purchPurchaseOrderContract = purchPurchaseOrderController.parmReportContract().parmRdpContract();
purchPurchaseOrderContract.parmRecordId(vendPurchOrderJour.RecId);
purchPurchaseOrderController.parmArgs(args);
srsReportRun = purchPurchaseOrderController.parmReportRun() as SrsReportRunImpl;
purchPurchaseOrderController.parmReportRun(srsReportRun);
purchPurchaseOrderController.parmReportContract().parmReportExecutionInfo(new SrsPrintMgmtExecutionInfo());
purchPurchaseOrderController.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::File);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().overwriteFile(true);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().fileFormat(SRSReportFileFormat::PDF);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().fileName(PDFName);
purchPurchaseOrderController.runReport();
row = purchTable_ds.getNext();
}
}
info(strFmt("%1",tot));
}
This code is running and will create a pdf file, but only for the last PO.
Any suggestions how to fix this problem? Thanks
Appear your error is in this line row = purchTable_ds.getFirst( 1, false ); you need a MultiSelectionHelper class.
Try with this code:
public static void main(Args _args)
{
PurchTable purchTable,purchTable2, row;
PurchPurchaseOrderController purchPurchaseOrderController ;
PurchPurchaseOrderContract purchPurchaseOrderContract;
SrsReportRunImpl srsReportRun;
VendPurchOrderJour vendPurchOrderJour;
FormDataSource purchTable_ds;
str PDFName;
int tot = 0;
Args args ;
ReportName reportName = "PurchPurchaseOrder.ReportPRI";
//New
PurchTable _PurchTable;
MultiSelectionHelper _helper = MultiSelectionHelper::construct();
//New end
;
//New
_helper.parmDatasource(purchTable_ds);
_PurchTable = _helper.getFirst();
while(_PurchTable.RecId != 0){
Purchtable = _PurchTable;
//New end
tot++;
//info(row.PurchId);
//args = new Args();
//args.record(row);
//select firstFast purchTable where purchTable.RecId == row.RecId ;
select firstFast vendPurchOrderJour where vendPurchOrderJour.PurchId == purchTable.PurchId ;
PDFName = strFmt("C:\\SharePDF\\%1.pdf",strReplace(purchTable.PurchId,'/','_'));
purchPurchaseOrderController = new PurchPurchaseOrderController();
purchPurchaseOrderController.parmReportName(ReportName);
purchPurchaseOrderContract = purchPurchaseOrderController.parmReportContract().parmRdpContract();
purchPurchaseOrderContract.parmRecordId(vendPurchOrderJour.RecId);
purchPurchaseOrderController.parmArgs(args);
srsReportRun = purchPurchaseOrderController.parmReportRun() as SrsReportRunImpl;
purchPurchaseOrderController.parmReportRun(srsReportRun);
purchPurchaseOrderController.parmReportContract().parmReportExecutionInfo(new SrsPrintMgmtExecutionInfo());
purchPurchaseOrderController.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::File);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().overwriteFile(true);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().fileFormat(SRSReportFileFormat::PDF);
purchPurchaseOrderController.parmReportContract().parmPrintSettings().fileName(PDFName);
purchPurchaseOrderController.runReport();
//New
_PurchTable = _helper.getNext();
//New end
}
info(strFmt("%1",tot));
}
This is has been solved. Thanks for All.
This is my complete Code
public static void main(Args _args)
{
PurchTable purchTable,purchTable2, row;
PurchPurchaseOrderContract purchPurchaseOrderContract;
VendPurchOrderJour vendPurchOrderJour;
FormDataSource purchTable_ds;
SRSPrintDestinationSettings settings;
SrsReportRunController controller ;
str folderPath;
dialog d;
DialogField dialogFilename;
str PDFName, FilePath;
int tot = 0;
Args args;
ReportName reportName = "PurchPurchaseOrder.ReportPRI";
PurchTable _PurchTable;
MultiSelectionHelper _helper = MultiSelectionHelper::construct();
;
d = new dialog();
d.caption("select a folder");
dialogFilename = d.addField(extendedTypeStr(FilePath));//add a field where you select your file in a specific path
d.run();
if(d.closedOk())
{
folderPath = dialogFileName.value();//return path file value
if(folderPath == '')
{
folderPath = 'C:\\SharePdf';
}
if(_args.record().TableId == tableNum(PurchTable))
{
purchTable2 = _args.record();
purchTable_ds = purchTable2.dataSource();
}
if (purchTable_ds.anyMarked())
{
row = purchTable_ds.getFirst( 1, false );
while(row)
{
tot++;
args = new Args();
select firstFast purchTable where purchTable.RecId == row.RecId ;
select firstFast vendPurchOrderJour where vendPurchOrderJour.PurchId == purchTable.PurchId ;
PDFName = strFmt("%2\\%1.pdf",strReplace(purchTable.PurchId,'/','_'), folderPath);
controller = new SrsReportRunController();
purchPurchaseOrderContract = new PurchPurchaseOrderContract();
controller.parmReportName(ReportName);
controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);
controller.parmShowDialog(false);
purchPurchaseOrderContract.parmRecordId(vendPurchOrderJour.RecId);
args.record(row);
controller.parmReportContract().parmRdpContract(purchPurchaseOrderContract);
controller.parmArgs(args);
settings = controller.parmReportContract().parmPrintSettings();
settings.printMediumType(SRSPrintMediumType::File);
settings.fileFormat(SRSReportFileFormat::PDF);
settings.overwriteFile(true);
settings.fileName(PDFName);
controller.startOperation();
row = purchTable_ds.getNext();
}
}
info(strFmt("%1 Total",tot));
}
}
I need to collect data and add it to temporary table in AX 2012 R3 using X++.
This is the Query on SQL
select store, receiptid, itemid, str(qty,16,0) as Qty, str(price,16,0) as Price, str(DISCAMOUNT,16,0) DiscAmount, str(taxamount,16,0) SalesTaxAmount ,convert(date, transdate) transdate, DATAAREAID from RETAILTRANSACTIONSALESTRANS
where DATAAREAID in ('5740','5760') and transdate >='2016-03-21' and transdate <='2016-03-27' and store in ('JTJDRN1','JNUSADP','JOFFICE')
and INVENTSTATUSSALES='2' and itemid in ('10010038') and receiptid in (select receiptid from RETAILTRANSACTIONPAYMENTTRANS where transdate >='2016-03-21' and transdate <='2016-03-27')
order by transdate
User can input transDate, itemid and storeid
this is what form looks like
this is my code so far
private void RetailPromoReport()
{
str receiptId, curDatetxt,fileLocation, filePath, itemtxt, startPtxt, endPtxt,
storetxt, item_txt, item2, receiptId2, rcptid_txt, store_txt, store2;
FileName fileName;
str 50 item, itemid, store;
container items, receiptid_con, stores;
int i,x, ware, itm, tot, y,z, rcptLen, storeLen;
Date emptyDate, startP, endP;
RetailTransactionPaymentTrans rtpt;
RetailTransactionSalesTrans rtst;
ReportRetailTemp rrpi_tmp, rrpi_tmp2;
QueryBuildRange qbr1, qbr2, qbr3, qbr4, qbr5;
QueryRun queryRun;
Query query, query2;
QueryBuildDataSource qbdsRetailTransactionPaymentTrans, qbdsRetailTransactionSalesTrans;
RecordInsertList recordILCRppi_tmp = new RecordInsertList(tableNum(ReportRetailTemp),false,false,false,false,false,rrpi_tmp);
;
startP = DateFrom.dateValue();
endP = DateTo.dateValue();
tot = 0;
delete_from rrpi_tmp;
while select receiptId from rtpt group by rtpt.receiptId where rtpt.transDate >= startP && rtpt.transDate <= endP
{
receiptid_con += rtpt.receiptId;
}
query = new Query();
qbdsRetailTransactionSalesTrans = query.addDataSource(tableNum(RetailTransactionSalesTrans));
qbr1 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,TransDate));
qbr1.value(strfmt('(%3.transDate>=%1) && (%3.transDate<=%2)',Date2StrXpp(startP),Date2StrXpp(endP),qbdsRetailTransactionSalesTrans.name()));
qbr2 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,inventStatusSales));
qbr2.value(queryValue(enum2str(RetailInventStatusSales::Posted)));
items = msCtrlCust.getSelectedFieldValues();
itemtxt = multilookupItem.valueStr();
stores = msCtrlStore.getSelectedFieldValues();
storetxt = multilookupStore.valueStr();
if(itemtxt != "")
{
item_txt = conPeek(items,1);
item2 = strFmt('(%2.itemId == "%1") ',queryValue(conPeek(items,1)),qbdsRetailTransactionSalesTrans.name());
itm = conlen(items);
if(itm > 1)
{
for (i = 2; i <= itm;i++)
{
item = conPeek(items,i);
item2 = strFmt('%1 || (%3.itemId == "%2") ',item2, queryValue(item),qbdsRetailTransactionSalesTrans.name());
}
}
qbr3 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId));
qbr3.value(strFmt("%1",item2));
}
rcptLen = conlen(receiptid_con);
receiptId2 = strFmt('(%2.receiptId == "%1") ',queryValue(conPeek(receiptid_con,1)),qbdsRetailTransactionSalesTrans.name());
if(rcptLen > 1)
{
for (y = 2; y <= rcptLen; y++)
{
rcptid_txt = conPeek(receiptid_con,y);
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
}
}
qbr4 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, receiptId));
qbr4.value(strFmt("%1",receiptId2));
if(storetxt != '')
{
store_txt = conPeek(stores,1);
store2 = strFmt('(%2.store == "%1") ',queryValue(conPeek(stores,1)),qbdsRetailTransactionSalesTrans.name());
storeLen = conlen(stores);
if(storeLen > 1)
{
for (z = 2; z <= storeLen;z++)
{
store = conPeek(stores,z);
store2 = strFmt('%1 || (%3.store == "%2") ',store2, queryValue(store),qbdsRetailTransactionSalesTrans.name());
}
}
qbr5 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, store));
qbr5.value(strFmt("%1",store2));
}
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, transDate),SortOrder::Ascending);
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, itemId),SortOrder::Ascending);
queryRun = new QueryRun(query);
while (queryRun.next())
{
rtst = queryRun.getNo(1);
rrpi_tmp.store = rtst.store;
rrpi_tmp.receiptId = rtst.receiptId;
rrpi_tmp.itemId = rtst.itemId;
rrpi_tmp.qty = rtst.qty;
rrpi_tmp.price = rtst.price;
rrpi_tmp.discAmount = rtst.discAmount;
rrpi_tmp.SalestaxAmount = rtst.taxAmount;
rrpi_tmp.transDate = rtst.transDate;
recordILCRppi_tmp.add(rrpi_tmp);
tot++;
}
ttsBegin;
recordILCRppi_tmp.insertDatabase();
ttsCommit;
ReportRetailTemp_ds.research(true);
ReportRetailTemp_ds.refresh();
if(tot > 0)
{
Box::info(strFmt("%1 row data",tot));
}
else
{
Box::info(strFmt("No Data",tot));
}
}
My code doesn't show any error in short period but because receiptId is stored in str,
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
there is limitation and show error for long periode
Can someone make my code more efficient and
is there any way to create Query in x++ that have same function like "IN" on SQL
You have two options:
You can use more than one query range for the same field; it will automatically count as an or
for (i = conLen(items); i > 0; i--)
qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId)).value(queryValue(conPeek(items,i)));
You may need special handling, if the container is empty!
Often it is better to use an (exists) join instead
ds = qbdsRetailTransactionSalesTrans.addDatasource(tableNum(RetailTransactionPaymentTrans));
ds.joinMode(JoinMode::ExistsJoin);
ds.relations(true); // Or do ds.addLink(...) etc.
I am not sure I follow the correct logic here :)
If you need to do crosscompany selections, do so using the interface for that:
qbdsRetailTransactionSalesTrans.allowCrossCompany(true);
qbdsRetailTransactionSalesTrans.addCompanyRange('5740');
qbdsRetailTransactionSalesTrans.addCompanyRange('5760');
I want to insert data into 12 different tables on a single click of a button. For this I am using single stored procedure. But my problem is when I am doing this and if there is any exception occurs my data is getting inserted partially i.e values is getting inserted in some tables and some remains empty and due to this problem occurs since all are related to one another. So wanted to know is there any way to perform Rollback so that if any exception occurs entire query is rolled back and data is not inserted in any of the table.
This is the code I am currently using for inserting values.
public int Sp_InsertUpdateDelete(string s, SqlParameter[] spa)
{
SqlConnection sc = new SqlConnection(cs);
sc.Open();
SqlCommand scm = new SqlCommand(s, sc);
scm.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter sql in spa)
{
scm.Parameters.Add(sql);
}
int k = scm.ExecuteNonQuery();
sc.Close();
return k;
}
protected void btnHostingSubmit_Click(object sender, EventArgs e)
{
string select = "select * from tbl_Hosting where Customer_Id='" + ddlCustomerName.SelectedValue + "'";
DataSet s = gs.select(select);
if (s.Tables[0].Rows.Count > 0)
{
Response.Write("<script>alert('Customer Already Exist');</script>");
}
else
{
if (ddlHosting.SelectedValue == "Yes")
{
SqlParameter[] spa = new SqlParameter[29];
spa[0] = new SqlParameter("#Customer_Id", Convert.ToInt16(ddlCustomerName.SelectedValue));
spa[1] = new SqlParameter("#Type", 2);
//Hosting
if (txtHostingSDate.Text == "" || txtHostingSDate.Text == null)
{
spa[2] = new SqlParameter("#Hosting_start_date", null);
}
else
{
spa[2] = new SqlParameter("#Hosting_start_date", Convert.ToDateTime(txtHostingSDate.Text));
}
if (txtHosingEDate.Text == "" || txtHosingEDate.Text == null)
{
spa[3] = new SqlParameter("#Hosting_end_date", null);
}
else
{
spa[3] = new SqlParameter("#Hosting_end_date", Convert.ToDateTime(txtHosingEDate.Text));
}
spa[4] = new SqlParameter("#Hosting_provider", ddlHostingPro.SelectedItem.ToString());
spa[5] = new SqlParameter("#Hosting_type", ddlHostingType.SelectedItem.ToString());
spa[6] = new SqlParameter("#Hosting_server", ddlHostingServer.SelectedItem.ToString());
spa[7] = new SqlParameter("#Hosting_total_id", Convert.ToInt16(txtHostingId.Text));
spa[8] = new SqlParameter("#Hosting_mail_tracking", ddlHostingMailTracking.SelectedItem.ToString());
spa[9] = new SqlParameter("#Hosting_mail_tracking_users", Convert.ToInt16(txtHostingMtUser.Text));
spa[10] = new SqlParameter("#Hosting_dns", ddlHostingDns.SelectedItem.ToString());
spa[11] = new SqlParameter("#Hosting_mail", ddlHostingMail.SelectedItem.ToString());
spa[12] = new SqlParameter("#Hosting_web", ddlHostingWeb.SelectedItem.ToString());
spa[13] = new SqlParameter("#Hosting_manage_dns", ddlHostingMngDns.SelectedItem.ToString());
if (ddlHostingDns.SelectedValue == "No" && (ddlHostingMail.SelectedValue == "Yes" || ddlHostingWeb.SelectedValue == "Yes"))
{
spa[14] = new SqlParameter("#Hosting_ns1", txtNS1.Text);
spa[15] = new SqlParameter("#Hosting_ns2", txtNS2.Text);
}
else
{
spa[14] = new SqlParameter("#Hosting_ns1", ddlHostingNS1.SelectedItem.ToString());
spa[15] = new SqlParameter("#Hosting_ns2", ddlHostingNS2.SelectedItem.ToString());
}
spa[16] = new SqlParameter("#Hosting_rec_ip", txtHostingARecordIp.Text);
spa[17] = new SqlParameter("#Hosting_mx_rec1", txtMXRecord1.Text);
spa[18] = new SqlParameter("#Hosting_mx_rec2", txtMXRecord2.Text);
spa[19] = new SqlParameter("#Hosting_mx_ip1", txtHostingMxIp1.Text);
spa[20] = new SqlParameter("#Hosting_space", ddlHostingSpace.SelectedItem.ToString());
spa[21] = new SqlParameter("#Hosting_mx_ip2", txtHostingMxIp2.Text);
spa[22] = new SqlParameter("#Hosting_data_transfer", ddlhostingDataTrans.SelectedItem.ToString());
spa[23] = new SqlParameter("#Hosting_manage_dns_amt", txtHostingMangDnsAmt0.Text);
spa[24] = new SqlParameter("#Hosting_amt", txtHostingAmt0.Text);
spa[25] = new SqlParameter("#Hosting_c_ns1", txtHostingNS1.Text);
spa[26] = new SqlParameter("#Hosting_c_ns2", txtHostingNS2.Text);
spa[27] = new SqlParameter("#Hosting_c_ns3", txtHostingNS3.Text);
spa[28] = new SqlParameter("#Hosting_c_ns4", txtHostingNS4.Text);
int k = gs.Sp_InsertUpdateDelete("Sp_Hosting", spa);
if (k > 0)
{
Response.Write("<script>alert('Hosting Added Success');</script>");
}
Clear();
}
using(SqlConnection conn = new SqlConnection())
{
try
{
conn.Open();
SqlTransaction tran = conn.BeginTransaction("Transaction1");
Cmd = new SqlCommand(sQuery, Conn);
Cmd.Transaction = tran;
//Your Code
tran.Commit(); //both are successful
}
catch(Exception ex)
{
//if error occurred, reverse all actions. By this, your data consistent and correct
tran.Rollback();
}
}
https://msdn.microsoft.com/en-us/library/a90c30fy.aspx
You need to modify your Stored procedure and use Transactions for this feature.
Something like this:
DECLARE #TranName VARCHAR(20);
SELECT #TranName = 'MyTransaction';
BEGIN TRANSACTION #TranName;
USE AdventureWorks2012;
DELETE FROM AdventureWorks2012.HumanResources.JobCandidate
WHERE JobCandidateID = 13;
COMMIT TRANSACTION #TranName;
GO
MSDN Reference
This code should be able to run on any AX system (change item & warehouse). The issue is that CustInvoiceJour is not being returned sometimes. What is odd, is if I just do a "select custInvoiceJour" with the same relations, it DOES find it? How is this possible?
static void Job59(Args _args)
{
CustInvoiceTrans custInvoiceTrans;
CustInvoiceJour custInvoiceJour;
InventTable inventTable;
QueryBuildRange rangeItem;
Query query;
QueryBuildDataSource qbds1;
QueryBuildDataSource qbds2;
QueryBuildDataSource qbds3;
QueryRun qr;
;
query = new Query();
qbds1 = query.addDataSource(tablenum(CustInvoiceTrans));
qbds2 = qbds1.addDataSource(tablenum(CustInvoiceJour));
qbds2.relations(true);
qbds2.addRange(fieldnum(CustInvoiceJour, SalesType)).value('!' + enum2str(SalesType::ReturnItem));
rangeItem = qbds1.addRange(fieldnum(CustInvoiceTrans, ItemId));
qbds1.addRange(fieldnum(CustInvoiceTrans, InvoiceDate)).value(queryRange(#'8/1/2011', #'8/31/2011'));
qbds2.orderMode(OrderMode::OrderBy);
qbds2.addOrderByField(fieldnum(CustInvoiceJour, DlvCountryRegionId));
qbds2.addOrderByField(fieldnum(CustInvoiceJour, DlvState));
qbds3 = qbds1.addDataSource(tablenum(InventDim));
qbds3.relations(true);
qbds3.joinMode(JoinMode::ExistsJoin);
qbds3.addRange(fieldnum(InventDim, InventLocationId)).value(SysQuery::value('FG'));
select firstonly inventTable
where inventTable.ItemId == '44831';
info (strfmt("%1", inventTable.ItemId));
rangeItem.value(inventTable.ItemId);
qr = new QueryRun(query);
while (qr.next())
{
custInvoiceTrans = qr.get(tablenum(CustInvoiceTrans));
custInvoiceJour = qr.get(tablenum(CustInvoiceJour));
if (!custInvoiceJour)
{
info ("Not found");
select firstonly custInvoiceJour
where custInvoiceJour.SalesId == custInvoiceTrans.SalesId &&
custInvoiceJour.InvoiceId == custInvoiceTrans.InvoiceId &&
custInvoiceJour.InvoiceDate == custInvoiceTrans.InvoiceDate &&
custInvoiceJour.numberSequenceGroup == custInvoiceTrans.numberSequenceGroup;
if (custInvoiceJour)
info("Found it");
}
}
}
The debugger shows these as the queries:
NAME:
qbds1
VALUE:
SELECT * FROM CustInvoiceTrans ORDER BY CustInvoiceJour.DlvCountryRegionId ASC, CustInvoiceJour.DlvState ASC WHERE ((ItemId = N'44831')) AND ((InvoiceDate>={ts '2011-08-01 00:00:00.000'} AND InvoiceDate<={ts '2011-08-31 00:00:00.000'})) EXISTS JOIN * FROM InventDim WHERE CustInvoiceTrans.InventDimId = InventDim.inventDimId AND ((InventLocationId = N'FG'))
NAME:
qbds2
VALUE:
SELECT * FROM CustInvoiceJour WHERE CustInvoiceTrans.SalesId = CustInvoiceJour.SalesId AND CustInvoiceTrans.InvoiceId = CustInvoiceJour.InvoiceId AND CustInvoiceTrans.InvoiceDate = CustInvoiceJour.InvoiceDate AND CustInvoiceTrans.numberSequenceGroup = CustInvoiceJour.numberSequenceGroup AND ((NOT (SalesType = 4)))
NAME:
qbds3
VALUE:
SELECT * FROM InventDim WHERE CustInvoiceTrans.InventDimId = InventDim.inventDimId AND ((InventLocationId = N'FG'))
Your qbds1 value doesn't show JOIN * FROM CustInvoiceJour WHERE ... (joined qbds2).
Add qbds2.fetchMode(QueryFetchMode::One2One); to your code and everything should be alright.
P.S. I would suggest to do it the other way round: CustInvoiceJour in qbds1, and CustInvoiceTrans in qbds2 (with default fetchMode), then you wouldn't have this problem at all.
I am creating an X++ report, and the requirement is that the user can multi-select on a form and when they click the report menu button the values are pulled in based on the selection.
So far this is easy enough, and I can pull in Str ranges i.e. order numbers, item id's etc, but I want to be able to pull in a date range based on selection.
I have used a method which several MorphX reports use, with use of 3 key methods in X++ reporting;
setQuerySortOrder
setQueryEnableDS
and the main key one which is;
setQueryRange
The code for setQuery Range is as follows;
private void setQueryRange(Common _common)
{
FormDataSource fds;
LogisticsControlTable logisticsTable;
QueryBuildDataSource qbdsLogisticsTable;
QueryBuildRange qbrVanRun;
str rangeVanRun;
QueryBuildRange qbrLogId;
str rangeLogId;
QueryBuildRange qbrExpStartDate;
str rangeExpStartDate;
set vanRunSet = new Set(Types::String);
set logIdSet = new Set(Types::String);
set expStartDate = new Set(Types::Date);
str addRange(str _range, str _value, QueryBuildDataSource _qbds, int _fieldNum, Set _set = null)
{
str ret = _range;
QueryBuildRange qbr;
;
if(_set && _set.in(_Value))
{
return ret;
}
if(strLen(ret) + strLen(_value) + 1 > 255)
{
qbr = _qbds.addRange(_fieldNum);
qbr.value(ret);
ret = '';
}
if(ret)
{
ret += ',';
}
if(_set)
{
_set.add(_value);
}
ret += _value;
return ret;
}
switch(_common.TableId)
{
case tableNum(LogisticsControlTable):
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrVanRun = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMServiceCenterID));
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrLogId = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, LogisticsId));
// qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
// qbrExpStartDate = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMExpDateJobStart));
fds = _common.dataSource();
for(logisticsTable = fds.getFirst(true) ? fds.getFirst(true) : _common;
logisticsTable;
logisticsTable = fds.getNext())
{
rangeVanRun = addrange(rangeVanRun, logisticsTable.APMServiceCenterID, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMServiceCenterID), vanRunSet);
rangeLogID = addrange(rangeLogID, logisticsTable.LogisticsId, qbdsLogisticsTable, fieldNum(LogisticsControlTable, LogisticsId), logIdSet);
// rangeExpStartDate = addrange(rangeExpStartdate, logisticsTable.APMExpDateJobStart, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);
}
qbrLogId.value(rangeLogID);
qbrVanRun.value(rangeVanRun);
break;
}
}
Use queryValue to format your dates correctly for the query:
set expStartDate = new Set(Types::String);
rangeExpStartDate = addrange(rangeExpStartdate, queryValue(logisticsTable.APMExpDateJobStart), qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);