如何在D365FO导入Excel文件(How to import EXCEL using X++ in D365 FO)

开始之前的准备

  • 命名空间
  • 参考包(reference packages)
Using System.IO;
Using OfficeOpenXml;
Using OfficeOpenXml.ExcelPackage;
Using OfficeOpenXml.ExcelRange;

除了基本的包,我们还需要参考包:Directory

How to Import Records from Excel Using X++ Code in D365FO

第一部分代码

在这部分代码中,创建了一个导入对话框,在这里我们可以选择需要导入的文件,文件上传之后会被存储在临时的空间中

How to Import Records from Excel Using X++ Code in D365FO

第二部分代码

在这部分代码中,我们从导入的Excel中获取数据

How to Import Records from Excel Using X++ Code in D365FO

完整的代码

Using System.IO;
Using OfficeOpenXml;
Using OfficeOpenXml.ExcelPackage;
Using OfficeOpenXml.ExcelRange;
class RunnableClass1
{
    /// <summary>
    /// Runs the class with the specified arguments.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {
        /*---------part 1 ------------------*/
        System.IO.Stream stream;
        ExcelSpreadsheetName sheet;
        FileUploadBuild fileUpload,fileUploadBuild;
        DialogGroup dialogUploadGroup;
        FormBuildControl formBuildControl;
        Dialog dialog=new Dialog("Excel Import Example");
        dialogUploadGroup=dialog.addGroup("@SYS54759");
        formBuildControl=dialog.formBuildDesign().control(dialogUploadGroup.name());
        fileUploadBuild=formBuildControl.addControlEx(classStr(fileUpload),"UploadExcel");
        fileUploadBuild.style(FileUploadStyle::MinimalWithFilename);
        fileUploadBuild.fileTypesAccepted(".xlsx");
        if(dialog.run() && dialog.closedOk())
        {
            FileUpload fileUploadControl=dialog.formRun().control(dialog.formRun().controlId("Upload"));
            FileUploadTemporaryStorageResult
            fileUploadResult=file::GetFileFromUser(classStr(FileUploadTemporaryStorageStrategy));
            //fileUploadResult=fileUploadControl.getFileUploadResult();
            /*------------------part 1 end---------------------*/
            /*------------------part 2---------------------*/
            if(fileUploadResult!= null && fileUploadResult.getUploadStatus())
            {
                stream=fileUploadResult.openResult();
                using(ExcelPackage  package= new ExcelPackage(stream))
                {
                    int rowCount, iterator;
                    package.Load(stream);
                    ExcelWorksheet worksheet= package.get_workbook().get_worksheets().get_Item(1);
                    OfficeOpenXml.ExcelRange range=worksheet.Cells;              
                    rowCount = worksheet.Dimension.End.Row - worksheet.Dimension.Start.Row + 1;
                    for(iterator=2;iterator<=rowCount;iterator++)
                    {
                        Info(range.get_Item(iterator,1).Value);
                        Info(range.get_Item(iterator,2).Value);
                        Info(range.get_Item(iterator,3).Value);
                    }
                }
            }
            /*------------------part 2 end---------------------*/
        }
        else
        {
            Error("error occured.");
        }
    }
}

导入

运行上面的Job之后,系统会弹出导入对话框,然后选择下面的文件。

How to Import Records from Excel Using X++ Code in D365FO
How to Import Records from Excel Using X++ Code in D365FO
How to Import Records from Excel Using X++ Code in D365FO

以下是点击“OK”之后的结果:

How to Import Records from Excel Using X++ Code in D365FO

关于Excel导出功能,请参考一下链接:

如何在D365FO导出Excel文件(How to export to EXCEL using X++ in D365 FO)

步骤

创建一个Job

Create and Export excel files in d365 using xpp d365snippets

添加以下代码

class RunnableClass2
{
    public static void main(Args _args)
    {
        CustTable custTable;
        DocuFileSaveResult saveResult =
    DocuFileSave::promptForSaveLocation("@ApplicationPlatform:OfficeDefaultWorkbookFileName","xlsx", null, "excel create and export");
        if (saveResult&& saveResult.parmAction() != DocuFileSaveAction::Cancel)
        {
            saveResult.parmOpenParameters('web=1');
            saveResult.parmOpenInNewWindow(false);
            System.IO.Stream
      workbookStream = new System.IO.MemoryStream();
            System.IO.MemoryStream
      memoryStream = new System.IO.MemoryStream();
            using(var package = new OfficeOpenXml.ExcelPackage(memoryStream))
            {
                var worksheets = package.get_Workbook().get_Worksheets();
                var worksheet = worksheets.Add("Sheet1");
                var cells = worksheet.get_Cells();
                var currentRow=1 ;
                /*-------HEADER PART -------*/
                var cell = cells.get_Item(currentRow,1);
                cell.set_Value("Customer Name");
                cell=null;
                cell = cells.get_Item(currentRow,2);
                cell.set_Value("Customer Address");
                /*-------HEADER PART END-------*/
                /*-------RECORD 1-------*/
                currentRow=2;
                cell= cells.get_Item(currentRow, 1);
                cell.set_Value("ABCD Trading");
                cell= null;
                cell= cells.get_Item(currentRow, 2);
                cell.set_Value("ABCD Complex, P.O Box :xxxxxx, XYZ Street");
                /*-------RECORD 1 END-------*/
                /*-------RECORD 2-------*/
                currentRow=3;
                cell= cells.get_Item(currentRow, 1);
                cell.set_Value("XYZ Trading");
                cell = null;
                cell = cells.get_Item(currentRow, 2);
                cell.set_Value("XYZ Complex, P.O Box :xxxxxx, ABC Street");
                /*-------RECORD 2 END-------*/
                package.Save();
            }
            memoryStream.Seek(0,System.IO.SeekOrigin::Begin);
            //Download the file.
            DocuFileSave::processSaveResult(memoryStream,saveResult);
        }
    }
}

把这个Job设置为启动项,运行它后我们可以看到以下界面:

Create and Export excel files in d365 using xpp d365snippets2

点击下载按钮,Excel就会被导出到下载文件夹里面

Create and Export excel files in d365 using xpp d365snippets2

关于Excel导出功能,请参考一下链接:

为D365 Devbox 的Windows虚拟机设置静态IP

Hyper-V的虚拟机默认使用Default Switch虚拟网卡来连接宿主机的网络,好处是不需要自己单独配置网络,直接切换选择使用就可以。但倘若是物理机使用mstsc远程连接到当前的虚拟机里,默认的Default Switch虚拟网卡就不能很好的满足我们的需求了,毕竟那玩意儿ip重启就变……

Hyper-v 设置

简单说明

  • Default Switch :Hyper-V默认使用的网络
  • E0 :手动创建的虚拟内部网络

虚拟机内访问互联网的网络由Default Switch虚拟网卡提供。而E0虚拟网卡则通过设置任意的静态IP(非本地回环等一些特殊的ip地址),对宿主机提供内网服务。

1.错误方式

为了实现目的,曾经试过修改虚拟机里的网卡为静态IP,但结果嘛:重启还是关机,又或者变更网络后,默认的 Default Switch 网卡会dhcp获取与设置的静态ip不一致,导致虚拟机内部无法连接到互联网。

后来很长一段时间里,一直使用的是新建内部网络来设置静态IP供mstsc使用。但是有个问题,若虚拟机需要连接到互联网,这时候需要共享宿主机的网络到内部网络里,而且似乎只能选择一个内部网络共享?最伤的还是,有时候宿主机开机后,Windows11 6月份的补丁很容易导致无法连接网络,所以每次只能卸载6月份更新的内容,要不然就是取消共享网络,改用回默认网卡,很是不便利。

2.正确方式

某天点着Hyper-V的设置,突然想起可以给虚拟机设置多网卡啊,这样问题不就得到解决了?

确实如此:使用 Default Switch 虚拟网卡来访问互联网,而自建的 E0 虚拟网卡用来设置静态IP,供同宿主机连接访问使用。

这样的好处是:和Hyper-V对应的物理机平常连接互联网的速度一样。虚拟机内部访问互联网的网络由Hyper-V自带的 Default Switch 虚拟网卡来提供,虚拟机与宿主机直接的网络连接由 E0 虚拟网卡提供,两者互不冲突(前提是你ip不能设置为一样的)。而通过共享、桥接、将Default Switch 网卡设置为静态IP的等方式,多多少少需要等待一会儿才能访问互联网,而且很有可能还会出现连接失败、受限制的问题,这并不方便。

2.1 新建内部网络

设置,虚拟交换机管理器,添加一个内部网络,名称随意。为了方便记录,博主这里用的是 E0 。

2.2 使用内部网络

找到对应的虚拟机,设置,添加网络硬件,选择上面创建好的 E0 网卡,下方网络加入。

2.3 设置静态IP(虚拟机)

虚拟机里找到网络适配器,找到创建好的 E0 虚拟内部网卡,将其ipv4信息“任意”填写一下。注意,这里不能使用本地回环等一些特殊的IP地址。比如:可以填写我们常见的 192.168.x.x ,后面两段就随意了。

宿主机配置

端口转发

将一个RDP服务(远程桌面协议)转发到任意端口,将进来的流量从3340端口转发到标准的RDP端口3389,使用上面分配的IP地址

netsh interface portproxy add v4tov4 listenport=3340 listenaddress=192.168.1.2connectaddress=192.168.168.168 connectport=3389

查看系统中的所有转发规则是否生效:

netsh interface portproxy show all

删掉一个特定的端口转发规则:

netsh interface portproxy delete v4tov4 listenaddress=192.168.1.2 listenport=3340

远程连接

如果需要访问到该虚拟机,直接远程宿主机的IP地址和对应的端口号就行了。

Code upgrade snippets from AX2009 to AX2012 and D365FO

InventDimSearch

In Microsoft Dynamics AX 2009, the InventDimSearch class was used to get information about the
inventory dimension setup. This class has been deleted and several new classes have been
implemented to make it possible to get information about the dimension setup.

In order to determine whether a dimension for a specific field is active in Microsoft Dynamics AX 2009,
the following code could be used:

InventDimSearch inventDimSearch = new InventDimSearch();
InventDimGroupId dimGroupId = InventTable::find(ItemId). DimGroupId;
;
if (inventDimSearch.findActive(dimGroupId,fieldNum(InventDim,wmsPalletId)))
{
    info(strFmt("The palletId dimension is active for dimension group %1",dimGroupId));
}

In Microsoft Dynamics AX 2012 & D365FO, this can be achieved by the following code:

InventTable inventTable;
InventDimGroupSetup inventDimGroupSetup;
InventDimGroupFieldSetup inventDimGroupFieldSetup;
 
inventDimGroupSetup = InventDimGroupSetup::newInventTable(inventTable);
inventDimGroupFieldSetup =
inventDimGroupSetup.getFieldSetup(fieldNum(InventDim,WMSPalletId));
 
if (inventDimGroupFieldSetup.isActive())
{
    info(strFmt("The palletId dimension is active for dimension group
    %1",inventDimGroupSetup.getStorageDimensionGroup()));));
}

EmplTable

In Microsoft Dynamics AX 2009

In Microsoft Dynamics AX 2012 & D365FO , we have HcmWorkerHelper class which gives much information about worker such as department, primary position, current legal entity and so on.

HcmWorkerRecId   hcmWorkerRecId =  HcmWorker::userId2Worker(curUserId());
HcmPositionRecId hcmPositionRecId = HcmWorkerHelper::getPrimaryPosition(hcmWorkerRecId);
 
HcmWorker currentWorker = HcmWorker::find(HcmWorkerLookup::currentWorker());
OMOperatingUnit department = HcmWorkerHelper::getPrimaryDepartment(currentWorker.RecId);
 
HcmWorker currentWorker = HcmWorker::find(HcmWorkerLookup::currentWorker());
CompanyInfo legalEntity = HcmWorkerHelper::getLegalEntity(currentWorker.RecId);

Unit converter

In Microsoft Dynamics AX 2009

UnitConvert::qty(Qty,FromUnitId,ToUnitId,ItemId);
Unit::decimals()

In Microsoft Dynamics AX 2012 & D365FO

UnitOfMeasureConverter::convert(_salesQty,  
               UnitOfMeasure::unitOfMeasureIdBySymbol(_inventUnit),  
               UnitOfMeasure::unitOfMeasureIdBySymbol(_salesUnit),  
               NoYes::Yes,  
               InventTable::itemProduct(_itemId),  
               NoYes::Yes);  
UnitOfMeasure::unitOfMeasureDecimalPrecision(UnitOfMeasure::unitOfMeasureIdBySymbol(unitID));

CompanyInfo

In Microsoft Dynamics AX 2009

CompanyInfo::standardCurrency()
CompanyInfo::find().CurrencyCode

In Microsoft Dynamics AX 2012 & D365FO

Ledger::accountingCurrency(CompanyInfo::current())

Currency

In Microsoft Dynamics AX 2009

Currency::amountCur2MST(*)
Currency::Amount()
Currency::exchRate(*)
Currency::exchRateSecond(*)

In Microsoft Dynamics AX 2012 & D365FO

CurrencyExchangeHelper::amountCur2MST(*)
CurrencyExchangeHelper::amount(*);
ExchangeRateHelper::exchRate(*)
ExchangeRateHelper::exchRateSecond()
| Tagged 

如何配置D365FO本地开发机(How-to-configure-onebox-VM-on-local)

前言

现在如果要使用本地的开发机,微软需要我们先在 Azure 门户中创建一个 Web 应用程序,在您将用户设置为管理员之前,您还必须执行一个步骤,那就是生成自签名证书,这里我们使用Azure创建的应用程序 ID,为它配置证书。

配置Azure

打开 Azure 订阅,搜索App registrations

点击New registration

输入名称,选择允许的账户类型

Redirect URI,输入虚拟机中FO的网站地址,类型选择Web,等会我们还要加另外一条,这里点击Register

点击Redirect URIs 加入另外一条然后保存

配置虚拟机

打开桌面上的Generate Self Signed Certificates,这里输入刚刚创建的Application Id

自签名证书创建好之后,打开桌面上的AdminUserProvisioning,输入对应的邮箱即可。

如何通过命令行部署SSRS报表(Deploy-SSRS-reports-through-command-line-in-D365FO)

可以使用 Visual Studio 完成 D365 FO 中的SSRS报表的部署。但我们还有另一种方法可以更快地部署SSRS报表。

我们可以在环境中使用Windows Powershell来更快、更轻松地部署SSRS报表。以下是在 D365 FO 中使用 Windows Powershell 部署SSRS报表的步骤。

1. 以管理员身份打开 Windows Powershell

2. 使用下面的命令进入相关的文件夹

  • CD C:\AosService\PackagesLocalDirectory\Plugins\AxReportVmRoleStartupTask

3. 使用下面的命令部署SSRS报表

  • 所有报表
    • ./DeployAllReportsToSSRS.ps1 -PackageInstallLocation "C:\AosService\PackagesLocalDirectory"
  • 指定的报表
    • ./DeployAllReportsToSSRS.ps1 -Module ApplicationSuite -ReportName AssetDep*,TaxVatRegister.Report -PackageInstallLocation "C:\AosService\PackagesLocalDirectory"

如何将 UAT 的数据在上线时部署到生产环境(How-to-deploy-UAT-data-to-production-server-in-D365FO)

前言

首先这次的操作并不是官方推荐的,但是在绝大多数上线的时候,主数据都是在UAT环境配置和测试,并且绝大多数的应用顾问或者用户都不希望做这种重复劳动,他们太忙了吧~

然而系统并没有提供可以直接部署或者还原的功能,那么我们就创建一个Service Request给微软吧。

Service Request

登录 LCS,打开 Project Details ,创建一个新的Service request

如下图:

新建

如下图:

选择 Sandbox to production

如下图:

接下来需要选择 Sandbox sourcedowntime 等等

提交

勾选所有选项后提交吧,提示说这个过程至少需要5个小时的停机时间,但是绝大多数情况1小时左右就能完成了。

DynamicsAX与第三方系统(Using-webservice-to-connect-with-Dynamics-AX)

Webservice

第三方接口调用AX内部程序

SystemConnector

在”Csharp”代码中,我们可以直接调用”Systemconnector”提供的接口从而实现执行AX内部程序的功能。

如:axServiceProvider.handleAgileData("cig", _XMLStr);

实际上 “axServiceProvider” 是通过内置函数 “CallStaticClassMethod” 来实现调用AX内部程序。

string returnStr = (string)op.CallStaticClassMethod("AX Class", "Class Method", _legal, _XMLStr);

将第三方外部程序组织的XML数据主动传递给AX,AX内部只需要解析该XML数据即可执行相应的业务逻辑操作。

在 axServiceProvider 中我们可以设定AX2009的环境端口,用户,密码,公司等信息,同样可以构建更多的方法来调用Ax不同的功能。

下文是通过”Csharp”代码调用接口的样例:

Consume SystemConnector in VS

1

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using SystemConnector.DynamicsAX;
 
namespace CIG_WCF4AgileAX
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string ret = "";
            //string _XMLStr = GetXmlDocument(@"D:/AgileXml/HDC000076-utf.xml");
            //string _XMLStr = GetXmlDocument(@"E:/AgileXml/test1014/UPD-1014-33-01.xml");
            string _XMLStr = GetXmlDocument(@"E:/AgileXml/test1014/CIG000780.xml");
            //string _XMLStr = "AX-MES-RDIF-Go";
            try
            {
                AXServiceProvider axServiceProvider = new AXServiceProvider();
                //ret = axServiceProvider.handleRFIDData("cig", _XMLStr);
                ret = axServiceProvider.handleAgileData("cig", _XMLStr);              
            }
            catch (Exception ex)
            {
                ret= ex.ToString();
            }
            Response.Write(ret);
        }
 
        private static string GetXmlDocument(string xmlPath)
        {
            try
            {
                XmlDocument doc = null;
                if (File.Exists(xmlPath))
                {
                    doc = new XmlDocument();
                    doc.Load(xmlPath);               
                }
                return doc.InnerXml;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Write(ex.Message);
            }
            return null;
        }
    }
}

AX内部程序调用第三方接口

AX2009 调用外部接口只需要打开AOT-Reference-添加一个服务引用即可,添加引用时可以添加dll文件。

如下图:

2
3

这样就可以了。

如何在 DynamicsAX 中处理CLR对象报错的问题(Working-with-CLR-exceptions-in-Dynamics AX)

CLR对象报错

在 Dynamics AX 中 无论版本是2009还是2012或者D365,总是会遇到下面这两个报错:

  • Object ‘CLRObject’ could not be created
  • ClrObject static method invocation error

而且系统给出的日志实在是太简短了,让人摸不着头脑。不过一般出现这两个问题都是在AX中处理 .net 相关的 dll 或者在调用 web service、WCF。那么剩下的问题就是我们该怎么样得知在调用 .net 框架的时候究竟出了什么问题呢,一旦知道了具体原因就好办了。


好,那我们通过一个 Job 演示一下吧:

static void RaiseCLRException(Args _args)
{
    ;
    //Necessary if executed on the AOS
    new InteropPermission(InteropKind::ClrInterop).assert(); 
 
    try
    {
        //This will cause an exception
        System.Int32::Parse("abc");
    }
    catch(Exception::CLRError)
    {
        //Access the last CLR Exception
        info(CLRInterop::getLastException().ToString());
 
        //See AifUtil::getClrErrorMessage for another alternative
        //how to parse the Exception object 
 
    }
    //Revert CAS back to normal
    CodeAccessPermission::revertAssert();
}

执行上面代码我们可以得到如下信息:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> **System.FormatException: Input string was not in a correct format.**
  at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
  at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
  at System.Int32.Parse(String s)
  — End of inner exception stack trace —
  at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
  at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
  at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
  at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
  at ClrBridgeImpl.InvokeClrStaticMethod(ClrBridgeImpl* , Char* pszClassName, Char* pszMethodName, Char* assemblyName, Int32 argsLength, ObjectWrapper** arguments, Boolean* argsAreByRef, Boolean* isException)

=> The part System.FormatException: Input string was not in a correct format.

从这一段就可以看出到底是哪里出问题了。

如何安装和配置一台 Dynamics 365 FO的开发机(How-to-setup-a-d365fo-develop-machine)

配置开发机

以下是一些安装条件

从 Microsoft Dynamics Lifecycle Services 下载安装虚拟机文件

共用资产库

img

可下载的 VHD

img

此处略过如何挂载虚拟机…

远程桌面用户名密码: User name: Administrator Password: pass@word1

重命名开发机

在以下两种情况下需要重命名开发机:

  • Accessing a single Microsoft Azure DevOps project across multiple machines: 不同的开发机不能使用相同名称的机器名称来登录 Azure DevOps (但是可以使用相同的帐户)
  • Installing One Version service updates: 确保 D365 FO 的版本升级没有问题

在数据库中更新服务器名称

通过以下命令在 Microsoft SQL Server 2016 中更新:

sp_dropserver [old_name];
GO
sp_addserver [new_name], local;
GO

如果不记得了,可以通过以下命令得到老的服务器名称:select @@servername

img

更新报表服务器

需要在报表服务器配置中重新选择数据库

img

更新 Azure Storage Emulator

开始菜单,打开 Microsoft Azure,打开Microsoft Azure Storage Emulator

img

或者到路径 :C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Azure\Storage Emulator

执行命令:AzureStorageEmulator.exe start
AzureStorageEmulator.exe status
AzureStorageEmulator.exe init -server new_name
AzureStorageEmulator.exe init -forcecreate

更新财务报表

下载更新包后,找到下图目录:

img

以管理员身份打开 Microsoft Windows PowerShellcd <update folder>\MROneBox\Scripts\Update
.\ConfigureMRDatabase.ps1 -NewAosDatabaseName AxDB -NewAosDatabaseServerName new_name -NewMRDatabaseName ManagementReporter -NewAxAdminUserPassword AOSWebSite@123 -NewMRAdminUserName MRUser -NewMRAdminUserPassword MRWebSite@123 -NewMRRuntimeUserName MRUSer -NewMRRuntimeUserPassword MRWebSite@123 -NewAxMRRuntimeUserName MRUser -NewAxMRRuntimeUserPassword MRWebSite@123

参考文档:

标题 链接
Rename a local development (VHD) environment vso-machine-renaming

连接 VisualStudioTeamService

Azure DevOps (https://dev.azure.com)

Azure DevOps 添加项目

参考文档

标题 链接
添加一个项目 create-project

Azure DevOps 添加用户

这个地址不太好找,记录一下URL: https://dev.azure.com/OrganizationId/ProjectId/_settings/

img

选择 Project SettingsTeam 里面添加用户:

img

点击 Permission ,在 Contributor 中添加刚才创建的用户

img
img

参考文档

标题 链接
在项目中添加用户 add-users-team-project

连接 Azure DevOpsVisual Studio

参考文档

标题 链接
连接到团队资源管理器中的项目 connect-team-project

配置 Excel add ins

初始化 Office app 参数

路径:系统管理 -> 设置 -> Office App 参数 img 把其中三个页签内容全部初始化一遍。 img

Excel add ins

路径:Insert -> Add Ins -> Store -> 搜索 ‘dynamics’

按照下图添加即可。 img

img
img
img

登录 Dynamics 365 FO 实例

提供管理员帐户

img

登录 D365 FO 之前必须提供一个管理员帐户用来登录 D365 FO 环境

以管理员身份运行桌面上的 AdminUserProvisioning 工具

输入你的邮箱地址,建议用微软相关的邮箱,可以使用个人邮箱,然后点击提交

通过 URL 登录 Dynamics 365 FO 实例

https://usnconeboxax1aos.cloud.onebox.dynamics.com.