↓ 跳过正文
  1. 工作笔记/
  2. E9 Ecode/

根据主表字段控制明细表行数

·341 字·2 分钟· ·
泛微 E9 Ecode 代码块 明细表 WfForm
作者
molefool
目录

用途
#

根据主表字段的数字,自动控制某个明细表的行数。

这段代码里:

  • field54450 是主表控制字段。
  • detail_2 是明细表2。
  • 控制字段为空或不是有效数字时,不处理明细行。
  • 控制字段为 0 时,会把明细表2删到 0 行。
  • 用户手动新增或删除明细2行后,会延迟重新同步,避免行数和主表字段不一致。

代码
#

<script>
(function () {
  'use strict';

  var CONTROL_FIELD = 'field54450'; // 主表控制字段
  var DETAIL_MARK = 'detail_2';     // 明细表2
  var LOG_PREFIX = '[明细2行数控制]';

  var syncing = false;

  function isEmpty(value) {
    return value === undefined || value === null || String(value).trim() === '';
  }

  function parseTargetCount(value) {
    if (isEmpty(value)) {
      return null; // 空值不参与控制
    }

    var count = parseInt(String(value).trim(), 10);

    if (isNaN(count)) {
      console.warn(LOG_PREFIX, '控制字段不是有效数字,跳过控制:', value);
      return null;
    }

    // 从 0 开始控制,负数按 0 处理
    return Math.max(0, count);
  }

  function getDetailRowIndexes() {
    var rowIndexStr = WfForm.getDetailAllRowIndexStr(DETAIL_MARK) || '';

    if (rowIndexStr === '') {
      return [];
    }

    return rowIndexStr.split(',').filter(function (rowIndex) {
      return rowIndex !== '';
    });
  }

  function syncDetailRows(triggerSource) {
    if (syncing) {
      return;
    }

    var controlValue = WfForm.getFieldValue(CONTROL_FIELD);
    var targetCount = parseTargetCount(controlValue);

    if (targetCount === null) {
      console.log(LOG_PREFIX, triggerSource + ',字段为空或无效,不控制明细行数', controlValue);
      return;
    }

    syncing = true;

    try {
      var rowIndexes = getDetailRowIndexes();
      var currentCount = rowIndexes.length;

      console.log(LOG_PREFIX, triggerSource + ',开始同步', {
        controlValue: controlValue,
        targetCount: targetCount,
        currentCount: currentCount,
        rowIndexes: rowIndexes
      });

      if (currentCount < targetCount) {
        for (var i = 0; i < targetCount - currentCount; i += 1) {
          WfForm.addDetailRow(DETAIL_MARK, {});
        }
      }

      if (currentCount > targetCount) {
        var deleteCount = currentCount - targetCount;
        var deleteRows = rowIndexes.slice(targetCount).reverse();

        for (var j = 0; j < deleteCount; j += 1) {
          WfForm.delDetailRow(DETAIL_MARK, deleteRows[j]);
        }
      }

      console.log(LOG_PREFIX, '同步完成,目标行数:' + targetCount);
    } catch (error) {
      console.error(LOG_PREFIX, '同步明细2行数失败', error);
    } finally {
      window.setTimeout(function () {
        syncing = false;
      }, 300);
    }
  }

  jQuery(document).ready(function () {
    // 页面加载后先延迟 1 秒执行一次
    window.setTimeout(function () {
      syncDetailRows('页面加载1秒后');
    }, 1000);

    // 主表字段变化时实时更新
    WfForm.bindFieldChangeEvent(CONTROL_FIELD, function () {
      syncDetailRows('field54450变化');
    });

    // 防止用户手动增删明细后行数和主表控制字段不一致
    if (WfForm.ACTION_ADDROW && WfForm.registerAction) {
      WfForm.registerAction(WfForm.ACTION_ADDROW + '2', function () {
        window.setTimeout(function () {
          syncDetailRows('明细2手动新增后');
        }, 300);
      });
    }

    if (WfForm.ACTION_DELROW && WfForm.registerAction) {
      WfForm.registerAction(WfForm.ACTION_DELROW + '2', function () {
        window.setTimeout(function () {
          syncDetailRows('明细2手动删除后');
        }, 300);
      });
    }
  });
})();
</script>

调整位置
#

  • 改主表控制字段:修改 CONTROL_FIELD。
  • 改目标明细表:修改 DETAIL_MARK。
  • 如果目标不是明细2,ACTION_ADDROW + '2' 和 ACTION_DELROW + '2' 里的数字也要一起改成对应明细表序号。
  • 如果不希望控制字段为 0 时清空明细,可以在 parseTargetCount 里把小于 1 的值改成 1。

相关文章