How to Update/Insert/Delete CrossCompany - axapta

is possible to make insert, update or delete crossCompany in axapta?
i am trying to do that, debugging in my query i have this:
select forUpdate crossCompany tlRemoteLocationInfo
where tlRemoteLocationInfo.RemoteLocationId == "someId";
if (tlRemoteLocationInfo.RecId)
{
ttsBegin;
changeCompany(tlRemoteLocationInfo.dataAreaId)
//then i make mi update to fields and then i make this:
tlRemoteLocationInfo.update();
ttsCommit;
}
i have a try catch, and debugging, fails to update in the method tlRemoteLocationInfo.update(), the exception is:
$exception {"Se produjo una excepción de tipo
'Microsoft.Dynamics.Ax.Xpp.ErrorException'."} System.Exception
{Microsoft.Dynamics.Ax.Xpp.ErrorException}
Am i missing someghing?

You can't do update operations using the crossCompany keyword. See here:
https://msdn.microsoft.com/en-us/library/cc518738.aspx
I rewrote your code so that it should work. And make sure to do an incremental CIL compile if this is running in CIL. The second method is if you wanted to do a while-select.
// Rewrite 1 - Notice removal of "forUpdate"
select firstOnly crossCompany tlRemoteLocationInfo
where tlRemoteLocationInfo.RemoteLocationId == "someId";
if (tlRemoteLocationInfo)
{
changeCompany(tlRemoteLocationInfo.dataAreaId)
{
// Notice this line
tlRemoteLocationInfo.selectForUpdate(true);
ttsBegin;
//then i make mi update to fields and then i make this:
tlRemoteLocationInfo.update();
ttsCommit;
}
}
// Rewrite 2 - Is a "while select" what you want?
while select crossCompany tlRemoteLocationInfo
where tlRemoteLocationInfo.RemoteLocationId == "someId"
{
changeCompany(tlRemoteLocationInfo.dataAreaId)
{
// Notice this line
tlRemoteLocationInfo.selectForUpdate(true);
ttsBegin;
//then i make mi update to fields and then i make this:
tlRemoteLocationInfo.update();
ttsCommit;
}
}

Related

Set default data in field x++ PurchCreateOrder

I want to set a default value based on curUserid() in PurchCreateOrder. How can I put data in my field on form extension ?
Is there any better option of doing this ? Fields are bound to datasource and I have different fields with differentdatasources.
My code is giving me abnormal termination error with nullreferences. XPPCompiler
[ExtensionOf(tableStr(PurchTable))]
final class PurchCreateOrderGetDefAdress_Extension
{
void initvalue(PurchaseType _purchaseType)
{
next initvalue(_purchaseType);
PurchTable purchtable;
LogisticsPostalAddress logpostadress;
UserInfoSz usrsz;
str user = curUserId();
select firstonly logpostadress where logpostadress.city == 'lub';
// select firstonly InventSiteId, InventLocationId from purchtable join usrsz where purchtable.InventSiteId == usrsz.InventSiteId && usrsz.IsDefault == true;
select firstonly InventSiteId from usrsz where usrsz.UserId == user && usrsz.IsDefault == true;
purchtable.initValue();
purchtable.deliveryname = 'asasasasas' ;//logpostadress.Address;
purchtable.inventsiteid = usrsz.InventSiteId;
purchtable.inventlocationid = usrsz.InventSiteId;
info(strFmt("%1, %2, %3", logpostadress.Address, usrsz.InventSiteId));
}
}
The error is straight forward.
Error The augmented class 'PurchTable' provides a method by this name, but this method cannot be used as a chain of command method since the parameter profile does not match the original method.
Take a look at the highlighted parameter profile and compare to yours.
Edit: Take a look at these links for more info on Chain of Command (CoC):
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/extensibility/method-wrapping-coc
https://channel9.msdn.com/Blogs/mfp/X-Chain-Of-Command (This video is excellent)

While select with if statement syntax - what is the purpose of the if statement?

I have come across a strange syntax that I have never seen in x++ before, but it compiles and works (as far as I can tell). I was curious if anybody has seen or used this before and could explain: what is the purpose of the if statement within the context of a while select?
InventBatch inventBatch;
InventTrans inventTrans;
InventTransOrigin inventTransOrigin;
InventDim inventDim;
ttsBegin;
while select Qty, DatePhysical from inventTrans
where inventTrans.StatusReceipt == StatusReceipt::Arrived
join inventTransOrigin
where inventTransOrigin.RecId == inventTrans.InventTransOrigin
&& inventTransOrigin.InventTransId == "SomeIdFromSomewhere"
join inventDim
where inventDim.inventDimId == inventTrans.inventDimId
&& inventDim.inventBatchId
if (inventTrans)
{
inventBatch = InventBatch::find(inventDim.inventBatchId, inventTrans.ItemId, true);
inventBatch.Field1 = inventTrans.Qty;
inventBatch.Field2 = inventTrans.DatePhysical;
inventBatch.update();
}
ttsCommit;
When you do a while select, generally you put {} to wrap your code, but you can also do the same thing as if statements, if you omit the {} and the immediately proceeding line gets executed for each loop.
if (true)
info("Hello World");
if (true)
{
info("Hello World");
}
while select SalesTable
info(SalesTable.SalesId);
while select SalesTable
{
info(SalesTable.SalesId);
}
Regarding the code you have typed above, it's idiotic. In AX, in older versions of the code if (common) would often only evaluate common.RecId != 0, but in later ones, I believe it will evaluate true if the buffer is returned with some data. In a while select however, it will always return true as the select is only returning records when it's true.
You could/should just delete literally only the if (inventTrans) line and leave the brackets and it will be readable/normal code.

Is there a way to improve this dynamics ax update job

I'm working on an AX 2009 installation. The job is to update the WMSOrderTrans table. Here is what I have got so far:
WMSOrderTrans wmsOrderTrans;
;
while select wmsOrderTrans
{
if (wmsOrderTrans.BBBpackingSlipExists())
{
ttsBegin;
wmsOrderTrans.selectForUpdate(true);
wmsOrderTrans.BBBPackingSlipExists = NoYes::Yes;
wmsOrderTrans.doUpdate();
ttsCommit;
}
}
The job takes about an hour to finish on the test system. This makes me worry about the performance on the production system.
At the moment the code has been written like this to have minimal locking issues (selectForUpdate is done for each row if it should be updated and is then immediatly committed). The reason is, that users will be working on the system, when the job is running.
My question is, if there is a reasonable way to implement this job in a way with less transaction overhead.
while select forUpdate ...
... does not seem to be an option, because it would lock the table until the job is finished.
Any input is appreciated.
This is the code for the BBBPackingSlipExists method:
display boolean BBBpackingSlipExists()
{
InventDim inventDimCur;
InventDim inventDimPackSlip;
InventTrans inventTransPackSlip;
;
select firstonly RecId from inventTransPackSlip
where inventTransPackSlip.InventTransId == this.inventTransId
&& (inventTransPackSlip.StatusIssue == StatusIssue::Deducted
|| inventTransPackSlip.StatusIssue == StatusIssue::Sold)
&& !inventTransPackSlip.PackingSlipReturned
exists join inventDimCur
where inventDimCur.inventDimId == this.inventDimId
exists join inventDimPackSlip
where inventDimPackSlip.inventDimId == inventTransPackSlip.inventDimId
&& inventDimCur.inventSerialId == inventDimPackSlip.inventSerialId
;
if (inventTransPackSlip.RecId != 0 && this.isReserved)
{
return true;
}
return false;
}
This looks like a prime candidate to convert to set based logic, I'd go for something like this. Please note that the job isn't tested at all since I don't have a 2009 environment handy (this doesn't even compile on 2012) so if you need to change the code feel free to edit it into my answer.
Note that the isreserved check is built into the query as well as the exists joins from the packingslipexists method
static void Job250(Args _args)
{
WMSOrderTrans wmsOrderTrans;
InventDim inventDimCur;
InventDim inventDimPackSlip;
InventTrans inventTransPackSlip;
;
wmsOrderTrans.skipDatabaseLog(true);
wmsOrderTrans.skipDataMethods(true);
wmsOrderTrans.skipEvents(true);
update_recordset wmsOrderTrans setting BBBPackingSlipExists = NoYes::Yes
where wmsOrderTrans.isReserved
exists join inventTransPackSlip
where inventTransPackSlip.InventTransId == wmsOrderTrans.inventTransId
&& (inventTransPackSlip.StatusIssue == StatusIssue::Deducted
|| inventTransPackSlip.StatusIssue == StatusIssue::Sold)
&& !inventTransPackSlip.PackingSlipReturned
exists join inventDimCur
where inventDimCur.inventDimId == wmsOrderTrans.inventDimId
exists join inventDimPackSlip
where inventDimPackSlip.inventDimId == inventTransPackSlip.inventDimId
&& inventDimCur.inventSerialId == inventDimPackSlip.inventSerialId;
}
See the documentation on update_recordset and why the skip* methods might be necessary

Phonegap - Assemble with a query result from another query - Sqlite Query

I can not make a selection via the result of the first
Goal is:
Do the query on the table "line" pick up your ID and search customers that line the "customer" table
This is my code:
db = window.openDatabase("test", "1.0", "Test DB", 1000000);
db.transaction(SelectData,erroSelect,sucessSelect);
function SelectData(tx)
{
tx.executeSql("select id from linha",[],function(tx, response)
{
for(i=0; i<response.rows.length; i++)
{
tx.executeSql("SELECT * FROM customers WHERE line= ?", [response.rows.item(i).id],
function (tx, results)
{
for(r=0; r<results.rows.length; r++)
{
alert(results.rows.item(r).nome); //never worked
}
}
}
},SelectError);
}
It is diffcult to understand from your post, where is the actual error.
Have you tried using console.log() call inside each tx.executeSql() to ascertain that the function is being executed.
Alternatively you can use a single query instead of using two SELECT statements.
Replace
select id from linha
with
SELECT customers.columnName1, customers.columnName2
FROM customers INNER JOIN linha ON customers.line = linha.id

How to pass out additional values with table in ref_cursor

I want to output an additional variable that's not in my table, can someone explain how to do this, or why it's not possible?
ie -
OPEN V_CURSOR FOR SELECT ee.EmployeeID, v_overtime_worked FROM EMPLOYEE_RECORDS ee;
So basically you want to store in that cursor, data from the table, and another variable v_overtime_worked, that has nothing to do with the table?
What error are you receiving?
What I know for sure is that this is working...so basically you can put another variable in the cursor:
declare
c_Curs SYS_REFCURSOR;
v_overtime_worked VARCHAR2(120) := '1000';
v_book_title VARCHAR2(255) := '';
v_xxx VARCHAR2(120);
BEGIN
OPEN c_Curs FOR SELECT book_title, v_overtime_worked FROM books;
LOOP
FETCH c_Curs INTO v_book_title, v_xxx;
EXIT WHEN c_Curs%NOTFOUND OR c_Curs IS NULL;
DBMS_OUTPUT.PUT_LINE(v_book_title || v_xxx);
end loop;
close c_Curs;
END;
As for your Java problem I'm afraid I don't know the answer..and i would need to do research :)
Maybe you need something like this :
#Override
public void execute(Connection con) throws SQLException {
CallableStatement call = con.prepareCall(ProcedureCalls.GET_ALL_BOOKS);
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute();
ResultSet rs = (ResultSet) call.getObject(1);
if(rs!=null){
while (rs.next ()) {
Book b = new Book();
b.setBookId(rs.getLong("book_id"));
b.setBookTitle(rs.getString("title"));
b.setBookYear(rs.getInt("book_year"));
b.setBookAuthor(rs.getString("author"));
book_list.add(b);
}
if(rs!=null) rs.close();
if(call!= null) call.close();
}
}

Resources