You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MS Navision页面级使用FILTERGROUP(-1)实现OR过滤不生效咨询

现象梳理

  • 开发基础:基于Cronus-AG数据库的Customer表做扩展,新增Datefield(Date类型)、CodeField(Integer类型)两个自定义字段,基于Customer表创建自定义列表页面
  • 业务需求:页面仅展示满足「Datefield为空 或 CodeField为空」条件的客户记录
  • 已做的逻辑尝试:
    • 定义两个空变量:Date类型的date、Code类型的c20
    • 在页面OnOpenPage触发器中编写如下代码:
      CLEAR(date);
      CLEAR(c20);
      
      FILTERGROUP(-1);
      SETFILTER(DateField, '%1', date);
      SETFILTER(CodeField20Old, '%1', c20);
      FILTERGROUP(0); // 试过移除该行代码,问题无变化
      
  • 测试对照结果:
    • 上述代码在页面中运行时无任何筛选效果,页面展示全量客户数据
    • 完全相同的代码在独立Codeunit中运行时,可以正常生成过滤规则
    • 将代码中FILTERGROUP(-1)替换为FILTERGROUP(2)时,可以正常生成AND逻辑的过滤规则,但和预期的OR逻辑不符

核心原因拆解

很多新手对筛选组的逻辑连接关系存在误解,实际运行时的规则非常明确:

  • 所有筛选按所属的筛选组编号分层生效,不同编号筛选组之间的结果是AND关系——只有同时满足所有组筛选条件的记录才会被展示
  • 同一个筛选组内部:
    • 对不同字段设置的筛选条件,互相是AND关系
    • 对同一个字段设置的多个筛选值/表达式,互相是OR关系
  • 不同筛选组的权限边界:
    • FILTERGROUP(-1)是系统级受保护筛选组,默认只允许平台底层逻辑(比如权限校验、公司维度隔离、记录安全规则)写入筛选条件,不对业务自定义代码开放写入权限
    • FILTERGROUP(0)是页面默认的用户交互筛选组,用户可以通过页面筛选面板修改组内条件
    • 非0、非-1的筛选组(比如2、3这类编号)是开放的自定义筛选组,允许代码写入条件,不会被系统自动重置清空

页面端代码完全失效的原因

两个机制共同导致你写入的筛选被清空:

  • 首先是FilterGroup(-1)的权限限制:页面运行时,平台引擎会自动识别FilterGroup(-1)内的筛选来源,非平台内置的自定义条件会被直接清除。你在OnOpenPage里写入的两个空值筛选,在页面正式加载记录前就被引擎重置为空,自然不会产生任何过滤效果。哪怕移除后面的FILTERGROUP(0)切换语句,这个清空逻辑依然会触发,问题不会有改善。
  • 其次是页面层的空值筛选自动优化:页面引擎在加载筛选规则时,会自动识别空变量传参生成的、来自业务代码的空值匹配筛选,在系统级筛选组里直接剔除这类条件,进一步加剧了筛选失效的问题。

Codeunit中相同代码可以生效的原因

Codeunit的运行上下文没有上述两个限制:

  • Codeunit中操作的记录变量,FilterGroup(-1)是完全开放的,允许自定义代码写入任意筛选条件,不会被引擎重置
  • Codeunit运行时没有页面层的空值筛选自动优化逻辑,会完整保留写入的两个空值筛选。这时候你会观察到筛选生效——但实际上这两个条件属于同一个筛选组内的不同字段,生成的是AND逻辑(两个字段同时为空),并不是你预期的OR逻辑,只是测试时没完全校验条件边界,误以为实现了OR效果。

替换为FILTERGROUP(2)后生成AND逻辑的原因

当你切换到开放的自定义筛选组2时,系统不会清空你写入的条件:

  • 你在这个组里给DateField设置了空日期筛选,给CodeField设置了空值筛选
  • 按照同一筛选组内不同字段为AND连接的规则,最终生成的筛选逻辑是「DateField为空 AND CodeField为空」,这和你测试时观察到的AND效果完全一致,并不是筛选组规则发生了变化。

需求实现的合规路径

因为Navision原生的筛选视图语法不支持跨字段的OR逻辑(也就是不能直接写「字段A为空 OR 字段B为空」的单条筛选表达式),要实现这个需求有两个常用的实现方案:

  • 给Customer表新增一个FlowField类型的全局筛选字段,通过CalcFormula定义查询逻辑,筛选出满足「Date为空 OR Code为空」的记录,然后在页面OnOpenPage中给这个FlowField设过滤为1,直接生成对应的OR逻辑
  • 在页面的OnAfterGetRecord触发器中写逐行判断逻辑,当记录不满足「Date为空 OR Code为空」条件时,将Rec.Skip设为true,实现逐行过滤,不依赖筛选组的自动逻辑

内容的提问来源于stack exchange,提问作者Yoo oo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 16:45:03