合并库存交易记录

随着时间的推移,库存交易记录表 (InventTrans) 会继续增长,消耗更多数据库空间。 因此,针对表进行的查询将逐渐变慢。 本文介绍如何使用库存交易记录合并功能来合并有关库存交易记录的数据,以帮助提高系统性能。

注意

只有财务更新的库存交易记录可以在选定的已关闭分类帐期间内合并。 若要进行合并,财务更新的出站库存交易记录的发货状态必须为已售出,而入站库存交易记录的收货状态必须为已购买

合并库存交易记录时,所有相关交易记录都将移至 InventTransArchive 表。 库存发货交易记录和库存收货交易记录基于物料 ID (itemId) 和库存维度 ID (inventDimId) 的组合分别合并,并且它们会放入汇总发货和汇总收货交易记录中。

如果 itemIdinventDimId 组合仅包含一个收货或发货交易记录,该交易记录将不会进行合并。

注意

合并您的库存交易记录后,您可以使用利用 Dataverse 长期保留进行存档 功能将 InventTransArchive 记录移至 Microsoft Azure 数据湖,以进一步优化存储和系统性能。 有关详细信息,请参阅在 Dynamics 365 Supply Chain Management 中存档库存交易记录数据

在系统中开启此功能

如果您的系统尚未包含本文中所述的功能,请转到功能管理,然后打开库存交易记录合并功能。 此功能在启用后无法禁用。

合并库存交易记录之前要考虑的事项

在合并库存交易记录之前,应考虑以下业务应用场景,因为它们会受操作影响:

  • 当您审计相关单据(例如采购订单行)中的库存交易记录时,它们将显示为已合并。 若要查看已合并的交易记录,您必须转到库存管理 > 定期任务 > 清理 > 库存交易记录合并
  • 合并期间无法取消库存结转。
  • 合并期间无法执行标准成本转换。
  • 合并库存交易记录时,源自库存交易记录的库存报表会受到影响。 这些报表包括库存帐龄报表和库存值报表。
  • 如果库存预测在合并期间的时间范围内运行,可能会受到影响。

先决条件

库存交易记录只能在满足以下条件的期间合并:

  • 分类帐期间必须已关闭。
  • 库存结转必须在合并的到期日期或之后运行。
  • 期间必须至少为合并起始日期之前一年。
  • 不能进行任何现有的库存重新计算。

合并您的库存交易记录

若要合并库存交易记录,请按照以下步骤操作。

  1. 转到库存管理>定期任务>清理>库存交易记录合并

    库存交易记录合并页面将出现,并显示已合并流程记录的列表。

  2. 在操作窗格上,选择库存交易记录合并以创建库存交易记录合并。

  3. 库存交易记录合并对话框中,在参数快速选项卡上,设置以下字段:

    • 已关闭分类帐期间中的开始日期 - 选择要包括在合并中的最早的交易记录日期。
    • 已关闭分类帐期间中的结束日期 - 选择要包括在合并中的最新交易记录日期。

    注意

    只有满足先决条件的期间才可以选择。

  4. 在后台运行快速选项卡上,根据需要设置批处理详细信息。 按照 Microsoft Dynamics 365 Supply Chain Management 中批处理作业的通常步骤操作。

  5. 选择确定

  6. 您将收到一条消息,提示您确认您希望继续。 仔细阅读消息,如果您希望继续,选择

    您将收到一条消息,指出您的库存交易记录合并作业已添加到批处理队列中。 此作业将开始合并所选期间的库存交易记录。

查看合并的库存交易记录

库存交易记录合并页面将显示完整合并历史记录。 网格中的每一行显示合并创建日期、创建合并的用户以及合并的状态等信息。

在页面顶部的下拉列表中,选择以下值之一以筛选显示在网格中的合并:

  • 可用 - 仅显示可用合并。
  • 全部 - 显示全部合并。

对于网格中的每个合并,将提供以下信息:

  • 可用 - 指示合并处于可用状态的复选标记。
  • 开始日期 - 可以包含在合并中的最早交易记录的日期。
  • 结束日期 - 可以包含在合并中的最新交易记录的日期。
  • 计划者 - 创建合并的用户帐户。
  • 执行日期 - 创建合并的日期。
  • 停止当前更新 - 指示合并正在进行,但已暂停的复选标记。
  • 状态 - 合并的处理状态。 可能的值为等待进行中已完成

网格上方的工具栏提供以下按钮,可用于处理所选合并:

  • 已合并的交易记录 - 查看所选合并的全部详细信息。 出现的已合并的交易记录页面将显示合并中的所有交易记录。

    若要在已合并的交易记录页面上查看有关特定交易记录的详细信息,请在网格中选择它,然后在操作窗格上,选择已合并的交易记录详细信息。 出现的已合并的交易记录详细信息页面将显示分类帐过帐、相关子分类帐参考和财务维度等信息。

  • 暂停 - 暂停当前正在处理的所选存档。 暂停仅在生成存档任务后生效。 因此,暂停生效之前可能会有短暂的延迟。 如果合并已暂停,停止当前更新字段中会出现一个复选标记。

  • 恢复档 - 恢复当前暂停的所选存档的处理。

扩展代码以支持自定义字段

如果 InventTrans 表包含一个或多个自定义字段,则您可能需要扩展代码以支持它们,具体取决于它们的命名方式。

  • 如果 InventTrans 表中的自定义字段与 InventtransArchive 表中具有相同的字段名称,则表示 1:1 映射了它们。 因此,您可以只将自定义字段放入 inventTrans 表的 InventoryArchiveFields字段组中。
  • 如果 InventTrans 表中的自定义字段名称与 InventtransArchive 表中的字段名称不匹配,则需要添加代码以映射它们。 例如,如果您有一个名为 InventTrans.CreatedDateTime 的系统字段,则必须在 InventTransArchive 表中创建一个具有不同名称的字段(例如 InventtransArchive.InventTransCreatedDateTime),并将扩展添加到 InventTransArchiveProcessTaskInventTransArchiveSqlStatementHelper 类,如以下示例代码所示。

以下示例代码显示了一个关于如何将所需扩展添加到 InventTransArchiveProcessTask 类的示例。

[ExtensionOf(classStr(InventTransArchiveProcessTask))]
Final class InventTransArchiveProcessTask_Extension
{

    protected void addInventTransFields(SysDaSelection _selectionObject)
    {
        _selectionObject.add(fieldStr(InventTrans, ModifiedBy))
            .add(fieldStr(InventTrans, CreatedBy)).add(fieldStr(InventTrans, CreatedDateTime));

        next addInventTransFields(_selectionObject);
    }


    protected void addInventTransArchiveFields(SysDaSelection _selectionObject)
    {
        _selectionObject.add(fieldStr(InventTransArchive, InventTransModifiedBy))
            .add(fieldStr(InventTransArchive, InventTransCreatedBy)).add(fieldStr(InventTransArchive, InventTransCreatedDateTime));

        next addInventTransArchiveFields(_selectionObject);
    }
}

以下示例代码显示了一个关于如何将所需扩展添加到 InventTransArchiveSqlStatementHelper 类的示例。

[ExtensionOf(classStr(InventTransArchiveSqlStatementHelper))]
final class InventTransArchiveSqlStatementHelper_Extension
{
    private str     inventTransModifiedBy;  
    private str     inventTransCreatedBy;
    private str     inventTransCreatedDateTime;

    protected void initialize()
    {
        next initialize();
        inventTransModifiedBy = new SysDictField(tablenum(InventTrans), fieldNum(InventTrans, ModifiedBy)).name(DbBackend::Sql);
        inventTransCreatedDateTime = new SysDictField(tablenum(InventTrans), fieldNum(InventTrans, CreatedDateTime)).name(DbBackend::Sql);
        inventTransCreatedBy = new SysDictField(tablenum(InventTrans), fieldNum(InventTrans, CreatedBy)).name(DbBackend::Sql);
    }

    protected str buildInventTransArchiveSelectionFieldsStatement()
    {
        str     ret;

        ret = next buildInventTransArchiveSelectionFieldsStatement();
        
        if (inventTransModifiedBy)
        {
            ret += ',';
            ret += strFmt('%1',  new SysDictField(tablenum(InventTransArchive), fieldNum(InventTransArchive, InventTransModifiedBy)).name(DbBackend::Sql));
        }

        if (inventTransCreatedBy)
        {
            ret += ',';
            ret += strFmt('%1',  new SysDictField(tablenum(InventTransArchive), fieldNum(InventTransArchive, InventTransCreatedBy)).name(DbBackend::Sql));
        }

        if (inventTransCreatedDateTime)
        {
            ret += ',';
            ret += strFmt('%1',  new SysDictField(tablenum(InventTransArchive), fieldNum(InventTransArchive, InventTransCreatedDateTime)).name(DbBackend::Sql));
        }

        return ret;
    }

    protected str buildInventTransTargetFieldsStatement()
    {
        str     ret;

        ret = next buildInventTransTargetFieldsStatement();

        if (inventTransModifiedBy)
        {
            ret += ',';
            ret += strFmt('%1', inventTransModifiedBy);
        }

        if (inventTransCreatedBy)
        {
            ret += ',';
            ret += strFmt('%1', inventTransCreatedBy);
        }

        if (inventTransCreatedDateTime)
        {
            ret += ',';
            ret += strFmt('%1', inventTransCreatedDateTime);
        }

        return ret;
    }
}