It has the similar syntax as we use to follow as shown below.
[ExtensionOf(formControlStr(FormToExtend, Button1))]
final class FormButton1_Extension
]]>
class CustomizedLookup extends RunBase
{
DialogField fieldAccount;
CustAccount custAccount;
DialogField dialogField , dialogText1, dialogText2, dialogText3 , dialogText4;
str refundreason, commentcs, nextOwnership;
DGS_RefundType refundType;
DGS_RefundRegister existingRefund;
real _refundAmount, _maxRefundAmount;
SalesId salesId;
public Object dialog()
{
FormBuildStringControl _stringControl;
//Dialog dialog = new Dialog();
DialogRunbase dialog = super();
str strMessage = strFmt("Are you sure you want to create refund register for %1, please provide below details.", salesId);
str strTitle = "create refund register";
;
DGS_SalesTableCalculation salesTableCal = DGS_SalesTableCalculation::find(SalesId);
select sum(refundamount) from existingRefund where existingRefund.salesid == SalesId;
_refundAmount = (salesTableCal.TotalAmount > existingRefund.refundamount)? (salesTableCal.TotalAmount - existingRefund.refundamount):0;
if(_refundAmount)
{
_maxRefundAmount = _refundAmount;
Dialog.addText(strMessage);
if(salesTableCal.TotalAmount == _refundAmount)
{
dialogField = dialog.addField(enumStr(DGS_RefundType));
DialogField.value(DGS_RefundType::Full);
}
else
{
dialogField = dialog.addField(enumStr(DGS_RefundType));
DialogField.value(DGS_RefundType::Partial);
}
// add lookup on dialog
dialogText1 = dialog.addField(extendedTypeStr(ReasonComment));
_stringControl = dialogText1.control();
_stringControl.registerOverrideMethod(methodStr(FormStringControl, lookup),
methodStr(CustomizedLookup, refundTypelookup), this);
//dialogText1 = dialog.addField(extendedTypeStr(String50), 'Refund Reason');
//dialogText1.value('Internal issue');
dialogText2 = dialog.addField(extendedTypeStr(String50), 'Comment (CS)');
dialogText2.limitText(500);
dialogText3 = dialog.addField(extendedTypeStr(String50),'Next Ownership');
dialogText3.value('compliance');
dialogText4 = dialog.addField(extendedTypeStr(RealBase), 'Refund Amount');
dialogText4.value(_refundAmount);
}
else
{
Error(strFmt('%1 Full Refunded, please check via Refund Register.', SalesId));
}
return dialog;
}
public boolean getFromDialog()
{
refundType = dialogField.value();
refundreason = dialogText1.value();
commentcs = dialogText2.value();
nextOwnership = dialogText3.value();
_refundAmount = dialogText4.value();
return super();
}
public container pack()
{
return conNull();
}
public void run()
{
if(_refundAmount > _maxRefundAmount)
{
Error(strFmt('Refund amount %1 over max refund amount %2.', _refundAmount , _maxRefundAmount));
}
else
{
DGS_CreateRefundRegister::createRefundRegister(SalesId,refundType,refundreason,commentcs,nextOwnership, _refundAmount);
}
}
public boolean unpack(container _packedClass)
{
return true;
}
public static void main(Args _args)
{
CustomizedLookup custAmountCalculation = new CustomizedLookup();
if (CustAmountCalculation.prompt())
{
CustAmountCalculation.run();
}
}
public SalesId parmSalesId(SalesId _salesId = salesId)
{
SalesId = _salesId;
return SalesId;
}
public void refundTypelookup(FormStringControl _control)
{
Query query = new Query();
QueryBuildDataSource queryBuildDataSource;
SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(DGS_ReasonTable),
_control);
// Create lookup
sysTableLookup.addLookupField(fieldNum(DGS_ReasonTable, ReasonType));
sysTableLookup.addLookupField(fieldNum(DGS_ReasonTable, Reason), true);
// Setup query
queryBuildDataSource = query.addDataSource(tableNum(DGS_ReasonTable));
queryBuildDataSource.addRange(fieldNum(DGS_ReasonTable,ReasonType)).value(enum2Str(DGS_ReasonType::Refund));
sysTableLookup.parmQuery(query);
// Perform lookup
sysTableLookup.performFormLookup();
}
}
]]>
- Right click anywhere on the ribbon, and then click Customize the Ribbon.
- Under Customize the Ribbon, on the right side of the dialog box, select Main tabs (if necessary).
- Check the Developer check box.
- Click OK.
- You can find the Developer tab next to the View tab.
將幾萬條RECORD 分開不同SHEET:
Developer --> VB --> Insert Module
Sub test()
Dim lastRow As Long, myRow As Long, mySheet As Worksheet
lastRow = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For myRow = 2 To lastRow Step 900
Set mySheet = Worksheets.Add
Sheets("Sheet1").Rows(myRow & ":" & myRow + 899).EntireRow.Copy mySheet.Range("A1")
Next myRow
End Sub
Run Module
]]>
All Vendors
SELECT * FROM VENDTABLE WHERE VENDTABLE.DATAAREAID='CEU'
All Addresses - Vendor
SELECT * FROM DirPartyPostalAddressView JOIN VENDTABLE ON DirPartyPostalAddressView.PARTY =VENDTABLE.PARTY
WHERE VENDTABLE.DATAAREAID=''CEU'
All Addresses with Purpose
SELECT LOGISTICSLOCATIONROLE.*,DirPartyPostalAddressView.*,VENDTABLE.* FROM DirPartyPostalAddressView JOIN VENDTABLE ON DirPartyPostalAddressView.PARTY =VENDTABLE.PARTY
JOIN DIRPARTYLOCATIONROLE ON DIRPARTYLOCATIONROLE.PARTYLOCATION =DirPartyPostalAddressView.RECID
JOIN LOGISTICSLOCATIONROLE ON DIRPARTYLOCATIONROLE.LOCATIONROLE =LOGISTICSLOCATIONROLE.RECID
WHERE VENDTABLE.DATAAREAID='CEU'
(Click Organization administration > Setup > Global address book > Address and contact information purpose.)
All Contact Details - Vendor
select * from dirPartyContactInfoView JOIN VENDTABLE ON dirPartyContactInfoView.PARTY =VENDTABLE.PARTY
WHERE VENDTABLE.DATAAREAID='CEU'
--All Customers
--SELECT DIRPARTYTABLE.NAMEALIAS ,CUSTTABLE.* FROM CUSTTABLE JOIN DIRPARTYTABLE ON CUSTTABLE.PARTY =DIRPARTYTABLE.RECID
--WHERE CUSTTABLE.DATAAREAID='CEU'
--All Addresses - Customer
--SELECT DirPartyPostalAddressView.*,CUSTTABLE.PARTY FROM DirPartyPostalAddressView JOIN CUSTTABLE
--ON DirPartyPostalAddressView.PARTY =CUSTTABLE.PARTY
--WHERE CUSTTABLE.DATAAREAID='CEU'
--All Addresses with Purpose - Customer
--SELECT LOGISTICSLOCATIONROLE.NAME,DirPartyPostalAddressView.PARTY,CUSTTABLE.PARTY FROM DirPartyPostalAddressView JOIN CUSTTABLE
--ON DirPartyPostalAddressView.PARTY =CUSTTABLE.PARTY
--JOIN DIRPARTYLOCATIONROLE ON DIRPARTYLOCATIONROLE.PARTYLOCATION =DirPartyPostalAddressView.RECID
--JOIN LOGISTICSLOCATIONROLE ON DIRPARTYLOCATIONROLE.LOCATIONROLE =LOGISTICSLOCATIONROLE.RECID
--WHERE CUSTTABLE.DATAAREAID='CEU'
--All Contact Details - Customer
--select dirPartyContactInfoView.* from dirPartyContactInfoView JOIN CUSTTABLE ON dirPartyContactInfoView.PARTY =CUSTTABLE.PARTY
--WHERE CUSTTABLE.DATAAREAID='CEU'
--Bank Details Customer
--SELECT distinct CUSTTABLE.PARTY ,CUSTTABLE.DATAAREAID ENTITY, CUSTTABLE.ACCOUNTNUM, DIRPARTYTABLE.NAME,Address.ADDRESS ,
--CUSTTABLE.CURRENCY ,CUSTTABLE.CUSTGROUP ,
--CUSTTABLE.PAYMTERMID,CUSTTABLE.TAXGROUP VATGROUP ,CUSTTABLE.CASHDISC ,
--VendBankAccount.ACCOUNTID BankAccount ,VendBankAccount.NAME 'Bank Name' ,VendBankAccount.ACCOUNTNUM 'Bank account number',
--VendBankAccount.RegistrationNum 'Routing Number',VendBankAccount.SWIFTNo,VendBankAccount.BankIBAN
--from CUSTTABLE left outer JOIN VendBankAccount ON VendBankAccount.VENDACCOUNT = CUSTTABLE.ACCOUNTNUM --AND VendBankAccount.ACCOUNTID = CUSTTABLE.BANKACCOUNT
--left outer join DIRPARTYTABLE ON DIRPARTYTABLE.RECID = CUSTTABLE.PARTY
--left outer join LOGISTICSPOSTALADDRESS AS Address ON Address.LOCATION = DIRPARTYTABLE.PRIMARYADDRESSLOCATION
-- WHERE CUSTTABLE.DATAAREAID IN ('CEU') --and CUSTTABLE.ACCOUNTNUM ='test033'
--Order by CUSTTABLE.DATAAREAID,CUSTTABLE.ACCOUNTNUM
Below SQL Query to extract a quick customer contact list from Dynamics AX 2012.
REF
REF
SELECT
VENDTABLE.ACCOUNTNUM AS CUSTID,
DIRPARTYTABLE.NAME AS CUSTNAME,
CASE LOGISTICSELECTRONICADDRESS.TYPE WHEN 1 THEN 'Phone' WHEN 2 THEN 'Email' END AS CONTACTTYPE,
LOGISTICSELECTRONICADDRESS.DESCRIPTION AS CONTACTNAME,
LOGISTICSELECTRONICADDRESS.LOCATOR AS CONTACTDETAILS
FROM DIRPARTYTABLE AS DIRPARTYTABLE
INNER JOIN VENDTABLE ON DIRPARTYTABLE.RECID = VENDTABLE.PARTY
INNER JOIN DIRPARTYLOCATION ON DIRPARTYTABLE.RECID = DIRPARTYLOCATION.PARTY
INNER JOIN LOGISTICSELECTRONICADDRESS ON DIRPARTYLOCATION.LOCATION = LOGISTICSELECTRONICADDRESS.LOCATION
WHERE VENDTABLE.DATAAREAID='CEU'
ORDER BY DIRPARTYTABLE.NAME
Vendor Bank Details SQL Query in AX
Vendor Bank Address in X++ Code and save it in CSV in AX
Fetch Customers Primary Address or Vendor Primary Address having Transactions (SQL SERVER Query) in AX D365
Fetch Product Master
SELECT B.DISPLAYPRODUCTNUMBER,DESCRIPTION,NAME,B.SEARCHNAME FROM ECORESPRODUCTTRANSLATION A JOIN ECORESPRODUCT B ON A.PRODUCT =B.RECID WHERE B.DISPLAYPRODUCTNUMBER in ('A0001','A0002')
--Storage Dimensions
select ECORESSTORAGEDIMENSIONGROUPITEM.ITEMID ,ECORESSTORAGEDIMENSIONGROUP.NAME from INVENTTABLE JOIN ECORESSTORAGEDIMENSIONGROUPITEM ON
INVENTTABLE.ITEMID =ECORESSTORAGEDIMENSIONGROUPITEM.ITEMID AND
INVENTTABLE.DATAAREAID =ECORESSTORAGEDIMENSIONGROUPITEM.ITEMDATAAREAID
JOIN ECORESSTORAGEDIMENSIONGROUP ON
ECORESSTORAGEDIMENSIONGROUPITEM.STORAGEDIMENSIONGROUP =ECORESSTORAGEDIMENSIONGROUP.RECID
WHERE INVENTTABLE.DATAAREAID='CEU'
--Tracking Dimensions
select ECORESTRACKINGDIMENSIONGROUPITEM.ITEMID ,ECORESTRACKINGDIMENSIONGROUP.NAME from INVENTTABLE JOIN ECORESTRACKINGDIMENSIONGROUPITEM ON
INVENTTABLE.ITEMID =ECORESTRACKINGDIMENSIONGROUPITEM.ITEMID AND
INVENTTABLE.DATAAREAID =ECORESTRACKINGDIMENSIONGROUPITEM.ITEMDATAAREAID
JOIN ECORESTRACKINGDIMENSIONGROUP ON
ECORESTRACKINGDIMENSIONGROUPITEM.TRACKINGDIMENSIONGROUP =ECORESTRACKINGDIMENSIONGROUP.RECID
WHERE INVENTTABLE.DATAAREAID='CEU'
--Item Model Group Units
select * from INVENTTABLEMODULE where DATAAREAID='CEU'
--Released Products
Select * from INVENTTABLE where DATAAREAID='CEU'
--Item Group
select * from INVENTITEMGROUPITEM where ItemDATAAREAID='CEU'
Vend Open Trans
SELECT VENDTRANS.ACCOUNTNUM,VendTrans.VOUCHER,VendTrans.Invoice,VendTrans.TRANSDATE AS DueDate,VendTrans.AmountCur, VendTrans.AmountCur-VendTrans.SETTLEAMOUNTCUR as BalanceAmount
FROM VENDTRANS
where VENDTRANS.closed = 0
AND ((VendTrans.TransType = 36)
OR (VendTrans.TransType = 3) --Purch
OR (VendTrans.TransType = 14)) --Vend
AND ((VendTrans.AmountCur<=0)) AND ((VendTrans.Approved = 1))
--AND VENDTRANS.ACCOUNTNUM = '1001' AND VENDTRANS.DATAAREAID = 'USMF'
SELECT VENDTRANS.ACCOUNTNUM,VendTrans.VOUCHER,VendTrans.Invoice,VendTrans.TRANSDATE AS DueDate,VendTrans.AmountCur, VendTrans.AmountCur-VendTrans.SETTLEAMOUNTCUR as BalanceAmount ,*
FROM VENDTRANS where
--where VENDTRANS.closed = 0
--AND ((VendTrans.TransType = 36) OR (VendTrans.TransType = 3)
-- OR (VendTrans.TransType = 14)) AND ((VendTrans.AmountCur<=0)) AND ((VendTrans.Approved = 1))
VENDTRANS.DATAAREAID = 'pui'
SELECT VENDTRANS.ACCOUNTNUM,VendTrans.VOUCHER,VendTrans.Invoice,VendTrans.TRANSDATE AS DueDate,VendTrans.AmountCur, VendTrans.AmountCur-VendTrans.SETTLEAMOUNTCUR as BalanceAmount
FROM VENDTRANS
where VENDTRANS.closed = 0 and
VENDTRANS.DATAAREAID = 'pui'
AND ((VendTrans.TransType = 36) --RTax25_BadDebtDebitAmortisation
OR (VendTrans.TransType = 3) --Purch
OR (VendTrans.TransType = 14)) --Vend
AND ((VendTrans.AmountCur<=0)) AND ((VendTrans.Approved = 1))
--AND VENDTRANS.ACCOUNTNUM = '1001' AND VENDTRANS.DATAAREAID = 'USMF'
]]>
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE>TF.exe workspaces /owner:* /computer:*
也可以:
tf workspaces /owner:* /computer:COMPUTERNAME /collection:http://TFSSERVER:8080/tfs/COLLECTIONNAME
]]>1. 第一, 要先將自家的financial dimension 加入ODATA (之前有篇教學)
Visual Studio → Dynamics365 → Addins → Add financial dimensions to Odata option to seperate the financial dimensions to Odata option to seperate the financial dimensions into different columns
2. 在standard Excel Template 下做更新:
The standard Excel templates can be accessed from Organization Administration → Setup → Office → Integration → Document Templates.
]]>以下語句返回數據庫中 table id 9669的名稱,如上所述,我們正在尋找field id 為0的行。
如果我們運行腳本,結果將顯示在查詢下方,如下所示。
Table id from table name
另一種方法是簡單地做與上面相同的事情,但是我們要查找表的名稱,而不是id,這裡是PurchTable。
]]>
- On the Cloud-hosted environments page, click Add.
- On the Select environment topology page, select Azure.
- On the next Select environment topology page, select DEMO. (Now as a side note, you can select DEVTEST - however this requires that you have configured Visual Studio Team Services in your LCS project, which I have not shown yet.) I will post again about the differences between the two environments.)
- On the next Select environment topology page, select Dynamics 365 for Operations - Develop (Release 1611, Platform Update 4). (This is the most current release - but obviously you can pick any version of the software you want.)
- On the Deploy environment page, type a unique name in the Environment name field.
- In the grid for the virtual machines, Use the Size drop-down to select D13 v2 for both images. (This is the biggest, fastest server you can choose. This is not required, but you can pick any size you want really. This will change your costs for hosting the environment as well.)
- Click Advanced settings.
- On the Deployment settings page click the Visual Studio Team Services tab.
- In the Specify a name for the Build virtual machine field type a name.
- Click the Dynamics 365 for Operations tab.
- Select Enable in the Publish this environment to Dynamics 365 home page. This is quite literally the most important step. If you forget to do this, your image will not be available in the Dynamics Home page. With this type of environment it is also important to note that you cannot change this setting after you deploy it.
- Click the Customize virtual network tab.
- Type a name in the Virtual network name field.
- Click Done.
- Select the "By selecting this check box, you agree to the pricing and licensing terms below." check box.
- Click Next, and then click Deploy to confirm that you want to deploy an environment. If you receive an error, wait a few moments and then try again.
]]>
public class InventSum_View extends common
{
private static str prepareInventPhyStr(str key)
{
#define.ViewName(InventSum_View)
#define.DataSourceName("InventSum")
#define.FieldPostedQty("postedQty")
#define.FieldPostedValue("PostedValue")
#define.FieldPhysicalValue("PhysicalValue")
str sReturn,
postedQty,
postedValue,
PhysicalValue;
DictView dictView2;
// Construct a DictView object for the present view.
dictView2 = new DictView(tableNum(#ViewName));
postedQty = dictView2.computedColumnString
(#DataSourceName,
#FieldPostedQty,
FieldNameGenerationMode::FieldList,
true);
postedValue = dictView2.computedColumnString
(#DataSourceName,
#FieldPostedValue,
FieldNameGenerationMode::FieldList,
true);
physicalValue = dictView2.computedColumnString
(#DataSourceName,
#FieldPhysicalValue,
FieldNameGenerationMode::FieldList,
true);
switch(key)
{
case "Cost":
sReturn = "CASE WHEN sum(" + postedQty + ") = 0 OR sum(" + postedQty + ") IS NULL "
+ " THEN 0 "
+ " ELSE sum(" + postedValue + ") / sum(" + postedQty + ")"
+ " END";
break;
case "PostedQty":
sReturn ="sum("
+ postedQty
+ ")" ;
break;
case "PostedValue":
sReturn ="sum("
+ PostedValue
+ ")" ;
break;
}
return sReturn;
}
private static server str compCostMethod()
{
str sReturn;
sReturn = InventSum_View::prepareInventPhyStr("Cost");
return sReturn;
}
private static server str compPosteQtyMethod()
{
str sReturn;
sReturn = InventSum_View::prepareInventPhyStr("PostedQty");
return sReturn;
}
private static server str compPostedValueMethod()
{
str sReturn;
sReturn = InventSum_View::prepareInventPhyStr("PostedValue");
return sReturn;
}
}
2. CAL ROW VIEW:
public class DGS_EstByBUTableRowView extends common
{
private static str prepareSQLStr(str key)
{
#define.ViewName(DGS_EstByBUTableRowView)
#define.DataSourceName3("THK_EstByBUTable")
#define.FieldCalcuDate("CalcuDate")
#define.FieldWeight("Weight")
str sReturn,
Weight,
CalcuDate;
DictView dictView2;
// Construct a DictView object for the present view.
dictView2 = new DictView(tableNum(#ViewName));
CalcuDate = dictView2.computedColumnString
(#DataSourceName3,
#FieldCalcuDate,
FieldNameGenerationMode::FieldList,
true);
Weight = dictView2.computedColumnString
(#DataSourceName3,
#FieldWeight,
FieldNameGenerationMode::FieldList,
true);
switch(key)
{
case "pEstCost":
sReturn = "ROW_NUMBER() OVER (PARTITION BY BU, Weight order by Weight, CalcuDate DESC)";
break;
}
return sReturn;
}
private static server str compEstCostMethod()
{
str sReturn;
sReturn = DGS_EstByBUTableRowView::prepareSQLStr("pEstCost");
return sReturn;
}
}
]]>
[DataEventHandler(tableStr(CustTable), DataEventType::Inserting)]
public static void CustTable_onInserting(Common sender, DataEventArgs e)
{
CustTable custTable = sender as CustTable;
custTable.inventSiteId = InventParameters::find().DGS_MainInventSiteId;
CustTable.InventLocation = InventParameters::find().DGS_MainInventLocationId;
if(!CustTable.CustGroup)
CustTable.CustGroup = THK_FileInterfaceParameters::find().CustGroupId;
if(!CustTable.DGS_CustNature)
CustTable.DGS_CustNature = THK_FileInterfaceParameters::find().DGS_CustNature;
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
[PreHandlerFor(tableStr(CustTable), tableMethodStr(CustTable, validateWrite))]
public static void CustTable_Pre_validateWrite(XppPrePostArgs args)
{
CustTable custTable = args.getThis() as CustTable;
if(!CustTable.CustGroup)
CustTable.CustGroup = THK_FileInterfaceParameters::find().CustGroupId;
if(!CustTable.DGS_CustNature)
CustTable.DGS_CustNature = THK_FileInterfaceParameters::find().DGS_CustNature;
}
In Table Datasource Events --> right click on Init Value--> Copy Post Event Handlers
Create new Class and below code
Table Method Event Handler
class test_PurchTableEventHanlders
{
/// <summary>
///
/// </summary>
/// <param name="args"></param>
[PostHandlerFor(tableStr(PurchTable), tableMethodStr(PurchTable, initValue))]
public static void PurchTable_Post_initValue(XppPrePostArgs args)
{
PurchTable purchTable = args.getThis() as PurchTable;
purchTable.test_PrintNote=NoYes::Yes;
}
}
Form Event Handler - CustTableFormEventHandler
class CustTableFormEventHandler
{
[FormDataSourceEventHandler(formDataSourceStr(CustTable, CustTable), FormDataSourceEventType::Activated)]
public static void CustTable_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
{
CustTable custTable = sender.cursor();
FormDataSource custTable_ds = sender.formRun().dataSource("CustTable");
FormRun element = sender.formRun();
FormControl myNewButton = element.design(0).controlName("MyNewButton");
myNewButton.enabled(false);
}
}
Table Events Event Handler
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[DataEventHandler(tableStr(CustInvoiceTrans), DataEventType::Inserted)]
public static void CustInvoiceTrans_onInserted(Common sender, DataEventArgs e)
{
ValidateEventArgs event = e as ValidateEventArgs;
CustInvoiceTrans custInvoiceTrans=sender as CustInvoiceTrans;
SalesTable salesTable=SalesTable::find(custInvoiceTrans.salesid);
if(salesTable.SalesStatus==SalesStatus::Invoiced )
{
//code
}
}
Table Method's Post Event Handler (Table - SalesTable, method - updateBackStatus)
2.將所需要的程式碼填入其中
3.點擊「Form Text」
4.將產生出的碼複製
5.產生如此效果
]]> [DataSource]
class SalesTable
{
/// <summary>
///
/// </summary>
/// <param name = "_append"></param>
public void create(boolean _append = false)
{
SalesTableForm salesTableForm;
super(_append);
salesTableForm = SalesTableForm::construct(SalesTableFormId::None, element.args().record());
if (salesTableForm.create())
{
SalesTable newSalesTable = salesTableForm.salesTable();
if (newSalesTable)
{
// refresh screen on datasource:
salesTable.data(newSalesTable);
salesTable_ds.setCurrent();
salesTable_ds.executeQuery();
Args args = new Args();
args.record(newSalesTable);
MenuFunction menuFunction = new MenuFunction(menuitemDisplayStr(SalesTable), MenuItemType::Display);
menuFunction.run(args);
}
}
}
}
]]>
或使用formRun.detach(); 如果您要讓表格單獨運行。
]]>
final class DGS_InventOnhandItem_Extension
{
public display TransDate batchExpiryDate()
{
/// <summary>
/// 在POST Run時用新method 取代本來的method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[FormEventHandler(formStr(WMSJournalTable), FormEventType::PostRun)]
public static void WMSJournalTable_OnPostRun(xFormRun sender, FormEventArgs e)
{
FormDateControl formCtrl = sender.design().controlName(formControlStr(WMSJournalTable, WMSJournalTrans_DGS_ExpDate));
formCtrl.registerOverrideMethod(methodStr(FormDateControl, jumpRef), methodStr(DGS_WMSJournalTableForm_Extension, DGS_ExpDate_jumpRefId), sender);
FormFunctionButtonControl formMenuCtrl = sender.design().controlName(formControlStr(WMSJournalTable, PostJournal));
formMenuCtrl.registerOverrideMethod(methodStr(FormFunctionButtonControl, clicked), methodStr(DGS_WMSJournalTableForm_Extension, PostJournal_clicked), sender);
}
另外開一個extension:
[ExtensionOf(formStr(WMSJournalTable))]
final class DGS_WMSJournalTableForm_Extension
{
public void DGS_ExpDate_jumpRefId(FormControl _formControl)
{
InventBatch inventBatch;
MenuFunction menuFunction;
Args args = new Args();
TmpPdsBatchSelect TmpPdsBatchSelect;
// InventDim InventDim = InventDim::find(wmsJournalTrans.inventdimId);
if (!TmpPdsBatchSelect)
{
ttsbegin;
TmpPdsBatchSelect.ItemId = wmsJournalTrans.itemid;
TmpPdsBatchSelect.InventBatchId = wMSJournalTable.inventTransRefId;
TmpPdsBatchSelect.insert();
ttscommit;
}
if (!TmpPdsBatchSelect)
{
return;
}
args.record(TmpPdsBatchSelect);
menuFunction = new MenuFunction(menuitemDisplayStr(InventBatch), MenuItemType::Display);
menuFunction.run(args);
}
public void PostJournal_clicked(FormControl _formControl)
{
info('hihi');
WMSJournalTrans wmsJournalTrans1;
while select forupdate wmsJournalTrans1 where wmsJournalTrans1.journalId == wMSJournalTable.journalId
{
ttsbegin;
if(wmsJournalTrans1.qty==0)
{
wmsJournalTrans1.delete();
}
ttscommit;
}
wmsJournalTrans1.clear();
select firstonly wmsJournalTrans1 where wmsJournalTrans1.journalId == wMSJournalTable.journalId;
if(wmsJournalTrans1)
{
_sender.clicked();
//super();
//MenuFunction menuFunction;
//Args args = new Args();
//args.record(wMSJournalTable);
//menuFunction = new MenuFunction(menuItemActionStr(WMSJournalPost), MenuItemType::Action);
//menuFunction.run(args);
}
else
{
wMSJournalTable.selectforUpdate(true);
wMSJournalTable.delete();
Error("Deleted Item Arrival %1, as no Qty to Post!");
}
wMSJournalTable_ds.executeQuery();
}
}
]]>
前幾天,當我嘗試為Dynamics 365 Finance and Operations測試自定義數據實體時,收到此錯誤“Configuration key not enabled for the entity”。 我之前在另一個項目上曾見過該錯誤,但完全忘記瞭如何修復它。 如果是新刷新的環境,或者您創建了自定義數據實體,並嘗試首次使用它,則可能導致此錯誤。 解決方案是刷新數據實體列表,並且我將在本文中逐步詳細介紹如何進一步執行此操作。
如果在實體上向右滾動,則會出現此錯誤,因為您將看到未啟用配置密鑰。 刷新實體列表將解決此問題。
HOW TO REFRESH THE DATA ENTITY LIST
]]>Timezone description | TimeZone | TZId field |
---|---|---|
(GMT-12:00) International Date Line West | 24 | 24001 |
(GMT-11:00) Midway Island, Samoa | 65 | 65001 |
(GMT-10:00) Hawaii | 39 | 39001 |
(GMT-09:00) Alaska | 2 | 2001 |
(GMT-08:00) Pacific Time (US & Canada) | 58 | 58001 |
(GMT-08:00) Tijuana, Baja California | 59 | 59001 |
(GMT-07:00) Arizona | 75 | 75001 |
(GMT-07:00) Mountain Time (US & Canada) | 47 | 47001 |
(GMT-07:00) Chihuahua, La Paz, Mazatlan | 48 | 48001 |
(GMT-06:00) Central America | 15 | 15001 |
(GMT-06:00) Central Time (US & Canada) | 21 | 21001 |
(GMT-06:00) Guadalajara, Mexico City, Monterrey | 22 | 22001 |
(GMT-06:00) Saskatchewan | 11 | 11001 |
(GMT-05:00) Bogota, Lima, Quito, Rio Branco | 63 | 63001 |
(GMT-05:00) Eastern Time (US & Canada) | 29 | 29001 |
(GMT-05:00) Indiana (East) | 74 | 74001 |
(GMT-04:00) Atlantic Time (Canada) | 6 | 6001 |
(GMT-04:00) La Paz | 64 | 64001 |
(GMT-04:00) Manaus | 17 | 17001 |
(GMT-04:00) Santiago | 57 | 57001 |
(GMT-04:30) Caracas | 85 | 85001 |
(GMT-03:30) Newfoundland | 54 | 54001 |
(GMT-03:00) Brasilia | 28 | 28001 |
(GMT-03:00) Buenos Aires, Georgetown | 62 | 62001 |
(GMT-03:00) Greenland | 36 | 36001 |
(GMT-03:00) Montevideo | 83 | 83001 |
(GMT-02:00) Mid-Atlantic | 45 | 45001 |
(GMT-01:00) Azores | 10 | 10001 |
(GMT-01:00) Cape Verde Is. | 12 | 12001 |
(GMT) Casablanca, Monrovia, Reykjavik | 37 | 37001 |
(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, Londo | 35 | 35001 |
(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna | 79 | 79001 |
(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Pragu | 18 | 18001 |
(GMT+01:00) Brussels, Copenhagen, Madrid, Paris | 60 | 60001 |
(GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb | 19 | 19001 |
(GMT+01:00) West Central Africa | 78 | 78001 |
(GMT+02:00) Amman | 43 | 43001 |
(GMT+02:00) Athens, Bucharest, Istanbul | 38 | 38001 |
(GMT+02:00) Beirut | 46 | 46001 |
(GMT+02:00) Minsk | 27 | 27001 |
(GMT+02:00) Cairo | 30 | 30001 |
(GMT+02:00) Harare, Pretoria | 68 | 68001 |
(GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius | 33 | 33001 |
(GMT+02:00) Jerusalem | 42 | 42001 |
(GMT+02:00) Windhoek | 51 | 51001 |
(GMT+03:00) Baghdad | 5 | 5001 |
(GMT+03:00) Kuwait, Riyadh | 3 | 3001 |
(GMT+03:00) Moscow, St. Petersburg, Volgograd | 61 | 61001 |
(GMT+03:00) Nairobi | 25 | 25001 |
(GMT+03:00) Tbilisi | 34 | 34001 |
(GMT+03:30) Tehran | 41 | 41001 |
(GMT+04:00) Abu Dhabi, Muscat | 4 | 4001 |
(GMT+04:00) Baku | 9 | 9001 |
(GMT+04:00) Caucasus Standard Time | 84 | 84001 |
(GMT+04:00) Yerevan | 13 | 13001 |
(GMT+04:30) Kabul | 1 | 1001 |
(GMT+05:00) Ekaterinburg | 31 | 31001 |
(GMT+05:00) Islamabad, Karachi, Tashkent | 80 | 80001 |
(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi | 40 | 40001 |
(GMT+05:30) Sri Jayawardenepura | 69 | 69001 |
(GMT+05:45) Kathmandu | 52 | 52001 |
(GMT+06:00) Almaty, Novosibirsk | 50 | 50001 |
(GMT+06:00) Astana, Dhaka | 16 | 16001 |
(GMT+06:30) Yangon (Rangoon) | 49 | 49001 |
(GMT+07:00) Bangkok, Hanoi, Jakarta | 66 | 66001 |
(GMT+07:00) Krasnoyarsk | 56 | 56001 |
(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi | 23 | 23001 |
(GMT+08:00) Irkutsk, Ulaan Bataar | 55 | 55001 |
(GMT+08:00) Kuala Lumpur, Singapore | 67 | 67001 |
(GMT+08:00) Perth | 77 | 77001 |
(GMT+08:00) Taipei | 70 | 70001 |
(GMT+09:00) Osaka, Sapporo, Tokyo | 72 | 72001 |
(GMT+09:00) Seoul | 44 | 44001 |
(GMT+09:00) Yakutsk | 82 | 82001 |
(GMT+09:30) Adelaide | 14 | 14001 |
(GMT+09:30) Darwin | 7 | 7001 |
(GMT+10:00) Brisbane | 26 | 26001 |
(GMT+10:00) Canberra, Melbourne, Sydney | 8 | 8001 |
(GMT+10:00) Guam, Port Moresby | 81 | 81001 |
(GMT+10:00) Hobart | 71 | 71001 |
(GMT+10:00) Vladivostok | 76 | 76001 |
(GMT+11:00) Magadan, Solomon Is., New Caledonia | 20 | 20001 |
(GMT+12:00) Auckland, Wellington | 53 | 53001 |
(GMT+12:00) Fiji, Kamchatka, Marshall Is. | 32 | 32001 |
(GMT+13:00) Nuku’alofa | 73 | 73001 |
]]>
Create Number Sequence Setup page for Vendor account. Local > BL , Oversea > BO
]]>
UAT- Batch Job to rebuild
Dev - rebuild directly on Database:
]]>1 個value:
[QueryRangeFunctionAttribute()]
public static str includedInventLocationIds()
{
return InventParameters::find().DGS_MainInventLocationId;
}
Data Entity Add Range in DataEntityViewRange 而唔係係 datasource 度addrange!!
]]>> Data Entities : Entity
> Tables : EntityStaging
> Security Privileges : Maintain, View
]]>]]>
URLUtility urlUtility = new URLUtility();
curJournalId = urlUtility.getQueryParamValue("journalId");
Link Sample:
]]>
2. 用 broswer 開warehouse mobile
Warehouse management > Work > Work Process
]]>Settings> User Option:
public static int getSystemDateIntSequence()
SysInfologMessageStruct infoMessageStruct;
str errorStr, errorTxt;
......
catch (Exception::Error)
// find or create brand value
// brand (attribute) - find brand , if no, create new brand
EcoResAttributeType attribType;
EcoResEnumerationAttributeTypeValue attribTypeVal;
]]>
通過X ++創建產品並發布產品 (AX 2012):
public static void createProductInventItemAX2012(ItemId _itemid,ItemName _itemname, str dataareaId = curExt())
{
The Excel integration is one of the powerful tools in Microsoft Dynamics 365 for Finance and Operations. This is helpful tool for accountants to push journal entries through Excel to Microsoft Dynamics 365 for Finance and Operations. The out of the box Excel integration does not have the financial dimensions values, but it could be exposed to the Excel integrations. Of course, the importance of financial dimensions specially the entry will be validated based on the account structure setup.
This blog post will illustrate step by step how to Expose the Financial dimensions on Excel integration. This will need to follow certain steps on Dynamics 365 for Finance and Operations client, Visual Studio, and Excel.
Microsoft Dynamics 365 FFO client
- Add financial dimension configuration for integrating applications
Visual studio
- Add financial, dimensions for OData
- Build and synchronize the model
Excel
]]>Primary Table
Constrained Table
Policy Query
Context
- ContextString: Defines a specific application context on which security policy will be enabled. It is also called an application context.
- RoleName: Defines that the security policy will only be applied to a particular Role in the application.
- RoleProperty: Used to define multiple Roles for a single security policy.
how would we set that up?
- The first thing to do is to determine your Constraint and Primary tables, in this case the CustTable table is our constraint table and the CustGroup table is our primary table.
- Next we create the policy query around our CustGroup, we want this query to return the results that we want to restrict the constraint table with
- Create a new Query, set the data source of the query to the primary table and then perform any filtering or other joins that need to be done for this query to return the results you want to filter by
- In our case we are limiting the user to only be able to see customers that have a CustGroup of ’10’ and Name of ‘Major Customers’
- Now we can create our Security Policy, we set the following parameters
- We then add a constrained table to the policy, in our case CustTable and set the following parameters
- Now if we build the solution and do a database sync of our project our XDS policy becomes live, to show what this does I did a before and after using a user assigned the FpTestRole to show the affect of the XDS policy
User access without XDS policy applied
User access after applying XDS policy
]]>2. Find User:
3. new user > select groups > OK
4.
]]>]]>
utcDateTime transDateTime;
transDateTime = utcDateTimeNull();
transDateTime = DateTimeUtil :: utcNow();
transDateTime = DateTimeUtil :: getSystemDateTime();
utcNow方法在不應用任何時區偏移的情況下返回服務器上的當前系統時間。因此,此方法返回的日期/時間可能與您在計算機上看到的時間不匹配。
getSystemDateTime方法返回可以使用”文件”>“工具”>“會話日期和時間”對話框設置的會話日期/時間。
newDateTime方法使用指定的日期,TimeOfDay和時區參數實例化日期/時間。指定的時區偏移量將從結果日期/時間中刪除。
secondsElapsed = 14 * 60 * 60; // 02:00 PM
userTimeZone = DateTimeUtil :: getUserPreferredTimeZone();
transDateTime = DateTimeUtil :: newDateTime(today(),secondsElapsed);
]]>
Code to do above is as follows:
DimensionDynamicAccount ledgerAccount;
switch(<AccountType>)
{
case (LedgerJournalACType::Cust) :
ledgerJournalTrans.AccountType = LedgerJournalACType::Cust;
ledgerAccount = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(<AccountNum>, LedgerJournalACType::Cust);
ledgerJournalTrans.LedgerDimension = ledgerAccount;
break;
case (LedgerJournalACType::Ledger) :
ledgerJournalTrans.AccountType = LedgerJournalACType::Ledger;
ledgerAccount = LedgerDefaultAccountHelper::getDefaultAccountFromMainAccountRecId(MainAccount::findByMainAccountId(<AccountNum>).RecId);
if(<DefaultDimensionIntegrationValues string from integration>)
{
DefaultDimensionIntegrationValues ledgerString = <AccountNum> + enum2Str(DimensionParameters::find().DimensionSegmentDelimiter) + <DefaultDimensionIntegrationValues string from integration>;
LedgerAccountDimensionResolver dimResolver = LedgerAccountDimensionResolver::newResolver(ledgerString);
ledgerAccount = dimResolver.resolve();
}
ledgerJournalTrans.LedgerDimension = ledgerAccount;
break;
case (LedgerJournalACType::Vend) :
ledgerJournalTrans.AccountType = LedgerJournalACType::Vend;
ledgerAccount = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(<AccountNum>, LedgerJournalACType::Vend);
ledgerJournalTrans.LedgerDimension = ledgerAccount;
break;
}
you need to replace <AccountNum> with your Account number variable and <DefaultDimensionIntegrationValues string from integration> with your Financial dimension string.
---------------------------------------------------------------------------------------------------------------
]]>
{
static DimensionDefault buildDimension(DimensionDefault olddimensionDefault, str dimensionName, DimensionValue newDimensionValue)
{
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
On a TabPage control on forms there is a property called FastTabExpanded.
The property controls weather the FastTab appears expanded or collapsed and how this can be changed by the user.
The default value is Auto.
Values:
Auto
Default value. Decision is taken by the system. User settings are considered.
Yes
When a user opens the form for the first time, the FastTab appears expanded. As soon as the user collapses the FastTab, this is getting stored in the users usage data and the next time opening the form the FastTab appears collapsed (or whatever state the user defined for the FastTab before leaving the form).
No
Behaves like the option Yes but on the first opening the FastTab appears collapsed.
Always
The FastTab always appears expanded and the user cannot collapse the FastTab!
In this example below, the first FastTab has the property Alwaysand the second has the property Yes.
2. 初次化時 (X++ 方法)
tabFinancialDimensions.fastTabExpanded(FastTabExpanded::Always);
3. 每次進入畫面都用指定狀態顯示
/// <summary>
]]>
{
str packedQuery ;
ItemId qryItemid;
str errorMsg;
]]>
final class DGS_PurchTable_Form_Extension
{
/// <summary>
///
]]>
{
static DimensionDefault buildDimension(DimensionDefault olddimensionDefault, str dimensionName, DimensionValue newDimensionValue)
{
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;