D365FO技术分享:使用X++优雅地处理Excel 新增行、合并单元格与格式化技巧

D365FO Tech Share: Handling Excel Elegantly with X++ Techniques for Adding Rows, Merging Cells, and Formatting 摘要 本文旨在分享在Dynamics 365 Finance and Operations (D365FO)环境中,如何运用X++代码,结合OfficeOpenXml库,对系统生成的Excel文件进行更灵活、更深入的控制。我们将重点探讨动态插入新行、精确复制行格式与行高、合并单元格以优化布局,以及对单元格进行赋值和应用特定样式等实用技巧。这些方法对于需要生成非标准化、高度定制化Excel报表的D365FO开发者而言非常有价值。 引言 在D365FO的开发与实施过程中,将数据导出至Excel是一项基础且频繁的需求。尽管系统提供了标准的数据导出功能,但在许多实际业务场景下,我们需要对导出的Excel文件进行超越标准功能的“二次加工”。例如,可能需要在指定位置插入小计行或明细行,按照预设模板的样式填充数据,为了报表美观和可读性合并表头或数据区域,或者对特定数据(如金额、日期、状态)应用特定的单元格格式。这时,直接通过X++代码操作Excel文档就显得尤为重要。本文将详细介绍如何使用D365FO推荐的OfficeOpenXml库来实现这些高级的Excel操作。 准备工作 开始编码前,请确保您的D365FO开发环境已就绪。OfficeOpenXml相关的程序集(如OfficeOpenXml.dll)通常在标准环境中是可用的。在您的X++代码(通常是类或方法)中,需要引入相应的命名空间: // X++ using 语句 using OfficeOpenXml; using OfficeOpenXml.Style; using System.Drawing; // 如果需要处理颜色等 本文后续的代码示例假设您已经成功创建了ExcelPackage对象(例如变量 _package)和ExcelWorksheet对象(例如变量 _worksheet),并且已经通过_worksheet.Cells获取了单元格的操作句柄(通常赋给一个类似 _cells 的ExcelRange变量)。 核心功能实现 1. 动态插入新行 在向Excel写入数据或应用格式前,有时需要在工作表的特定位置插入若干空行。OfficeOpenXml 提供了 InsertRow 方法来实现此功能: // 示例:在第 10 行(rowToInsertBefore = 10)的上方插入 5 行 int rowToInsertBefore = …

Continue reading ‘D365FO技术分享:使用X++优雅地处理Excel 新增行、合并单元格与格式化技巧’ »

分步指南:在 Dynamics 365 F&O 中构建自定义工作流(Step-by-Step Guide: Building a Custom Workflow in Dynamics 365 F&O)

在 Microsoft Dynamics 365 for Finance and Operations (D365 F&O) 中,工作流是定义业务流程自动化、文档审批和流转路径的核心机制。 本指南将详细演示如何为一个名为 Demo_WFDocument 的自定义文档表创建一个完整的工作流。 重要提示: 本教程假定你在与文档表相同的模型中创建工作流。如果跨模型操作,请注意,截至本文撰写时,某些步骤(特别是覆写 canSubmitToWorkflow() 方法)可能需要进行覆盖 (Overlaying) 操作。 让我们开始吧! 第 1 步:定义工作流状态 首先,我们需要一个基础枚举来定义文档在工作流中的各个状态。 接下来,在你的文档表 (Demo_WFDocument) 上: 第 2 步:实现核心表逻辑 我们需要在文档表 (Demo_WFDocument) 上实现一些关键方法: public boolean canSubmitToWorkflow(str _workflowType = ”) { boolean ret = super(_workflowType);   // 只有草稿状态的文档才能提交 ret = this.WorkflowStatus == Demo_WFDocumentStatus::Draft;   return ret; } public static void …

Continue reading ‘分步指南:在 Dynamics 365 F&O 中构建自定义工作流(Step-by-Step Guide: Building a Custom Workflow in Dynamics 365 F&O)’ »

如何在 D365FO 的现有量查询中增加字段和数据源(Add the new field or datasource in Inventory On hand form using X++ in D365FO)

我们需要为类 InventDimCtrl_Frm_OnHand 创建一个扩展,以使用方法 modifiedQueryBasedOnDatasourceName 来实现这种Inventory On hand定制。 通过这种方式,我们可以在网格中添加带有过滤选项的新字段。(不使用显示方法)。根据需求,我们可以在表单中添加来自现有数据源以及新数据源的字段。 [ExtensionOf(classStr(InventDimCtrl_Frm_OnHand))] final class InventDimCtrl_Frm_OnHandClass_Extension { public void modifyQueryBasedOnDatasourceName( Query _inventSum_DS_Query, str _inventSum_DS_Name, FormDataSource _inventDim_DS) { Query query; QueryBuildDataSource qbds; QueryBuildDataSource qbdsInventOnHandItemListView; QueryBuildDataSource qbdsInventTable; Counter loop; boolean qbdsExists; next modifyQueryBasedOnDatasourceName(_inventSum_DS_Query, _inventSum_DS_Name, _inventDim_DS);       query =   _inventSum_DS_Query;       qbdsInventTable = query.dataSourceTable(tableNum(InventTable));       if (qbdsInventTable)     {         qbdsInventTable.addGroupByField(fieldNum(InventTable, BinLocation));         qbdsInventTable.addGroupByField(fieldNum(InventTable, ItemStatus)); …

Continue reading ‘如何在 D365FO 的现有量查询中增加字段和数据源(Add the new field or datasource in Inventory On hand form using X++ in D365FO)’ »

| Tagged 

如何在D365FO使用视图在窗体上显示某一个财务维度(Financial dimensions)

在这篇文章中,我们将了解如何使用视图将财务维度(Financial dimensions)显示为表单网格中的字段,该视图将使用计算列直接从表中检索信息。这是一种快速获取信息以将其显示在列表中的方法,并且能够使用控件按维度值进行筛选。 解决方案: 如何做: 步骤 1:创建视图 我们创建一个新的视图 ( FTDDimensionSetView ),使用 DimensionAttributeValueSet 作为数据源,并添加 RecId 作为视图字段。请注意,此 RecId 将是  表中我们想要显示维度的DefaultDimension字段(本例中为CustTrans  ),这就是为什么我在视图中也将其命名为 DefaultDimension。 步骤 2:创建计算列方法 我们将对要添加到视图中的每个维度值使用一个静态方法。标准 DimensionSetEntity 实体需要对其进行概括,并且仅使用一个复杂的方法,在配置好所有维度后,使用插件加载所有维度,这些维度会自动创建,因为每个实现都有不同的维度……在我们的例子中,我们不需要额外的复杂性,因为我们已经知道并拥有我们想要显示的维度。保持简单! 这里有 3 种方法(我决定将逻辑放在一种通用方法中,所以有 4 种)。 public class FTDDimensionSetView extends common { private static str getSQLStringForDimension(DimensionRefFieldName _dimensionName) { DimensionAttribute dimensionAttribute = DimensionAttribute::findByName(_dimensionName);   return dimensionAttribute.DimensionValueColumnName; }   private static str getDepartment() { return FTDDimensionSetView::getSQLStringForDimension(FTDDimensionUtils::Department); }   private static str getCostCenter() { return FTDDimensionSetView::getSQLStringForDimension(FTDDimensionUtils::CostCenter); } …

Continue reading ‘如何在D365FO使用视图在窗体上显示某一个财务维度(Financial dimensions)’ »

Tax is regulated on purchase ID xxx. Purchase orders cannot be rearranged when individual purchase orders are tax regulated.

The reason why you get this error message is because you made the tax adjustment first at the individual invoice Level. Later on then you consolidated (rearranged) two or more invoices(PO partially invoiced) and AX says that it does not like that. To get this fixed try the following: 1) Open the invoice for which …

Continue reading ‘Tax is regulated on purchase ID xxx. Purchase orders cannot be rearranged when individual purchase orders are tax regulated.’ »

如何D365FO使用视图使Display方法可以被过滤(How to create a filter on display method using view in D365FO)

基于Display的方法的表单字段不可过滤,但在某些情况下,客户希望这些字段可过滤(Filter on display method)。有两种方法可以使显示字段可过滤,我们将在本博客中仅解释最佳方法(使用最佳实践)。 在我们的案例中,供应商名称字段是一个基于Display方法的字段,并且不可过滤。 1.创建一个视图: – metadata: 我们需要获取将替换显示字段的字段以及将用于与表单数据源创建关系的字段的表。(在我们的例子中是 VendTable 和 DirPartyTable) – fields: 将替换显示字段的字段和我们将用于与表单数据源创建关系的字段。(在我们的例子中是 Name 和 AccountNum) 2.在 FormDatasource(我们的案例 PurchLine)表上,我们需要添加一个与我们创建的 VendTableName 视图的新关系。 3. 在我们的表单上添加视图 VendTableName 作为数据源,并在 VendTableName FormDatasouce 属性上与主数据源(PurchLine)创建连接。 4. 最后一步是在表单网格上添加我们想要的视图数据字段。 输出结果:

| Tagged 

如何在D365FO工作流中使用审核编辑功能(how to use approval editable in d365fo workflow)

在Dynamics 365 F&O工作流开发过程中,配置采购订单工作流时,有两个审批元素可供使用,一个是“审批采购订单”,另一个是“可编辑的审批采购订单”(下文也将对其进行突出显示)。我的问题是关于第二个元素的开发,即“可编辑的审批采购订单”。根据我的测试,如果在配置过程中将此元素关联起来,系统将允许审批人编辑采购订单,然后在之后进行审批操作。 可编辑的审批仅允许审批人编辑所选记录(他们正在审批的)。您可以按照以下步骤实现相同的功能: public boolean editAllowed() { WorkflowElementTable workflowElementTable; WorkflowWorkItemTable workflowWorkItemTable;   select * from workflowWorkItemTable where workflowWorkItemTable.RefRecId == this.RecId && workflowWorkItemTable.Status == WorkflowWorkItemStatus::Pending && workflowWorkItemTable.UserId == curUserId() && workflowWorkItemTable.CompanyId == this.DataAreaId;   select * from workflowElementTable where workflowElementTable.ElementId == workflowWorkItemTable.ElementId;   return workflowElementTable.ElementName == workflowApprovalStr(CaseDetailBaseApprovalEdit) || this.CaseWFStatus == CaseWFStatus::Draft; } public int active() …

Continue reading ‘如何在D365FO工作流中使用审核编辑功能(how to use approval editable in d365fo workflow)’ »

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

开始之前的准备 Using System.IO; Using OfficeOpenXml; Using OfficeOpenXml.ExcelPackage; Using OfficeOpenXml.ExcelRange; 除了基本的包,我们还需要参考包:Directory 第一部分代码 在这部分代码中,创建了一个导入对话框,在这里我们可以选择需要导入的文件,文件上传之后会被存储在临时的空间中 第二部分代码 在这部分代码中,我们从导入的Excel中获取数据 完整的代码 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 …

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

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

步骤 创建一个Job 添加以下代码 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"); …

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