如何让交互式网格自动计算所有行的SDI值?
问题与解决方案
需求背景
需要根据RESULT、MEAN和SD值计算SDI值,已实现单行的JavaScript计算逻辑,现在希望网格加载数据时自动批量计算所有行的SDI列值。同时尝试用SQL直接计算SDI时遇到ORA-01733: 此处不允许虚拟列错误。
已实现的单行计算JavaScript代码
var mean = ($v("C_MEAN") != "") ? parseFloat($v("C_MEAN")) : 0; var sd = ($v("C_SD") != "") ? parseFloat($v("C_SD")) : 0; var result = ($v("C_RESULT") != "") ? parseFloat($v("C_RESULT")) : 0; var sdi = 0; if ( !isNaN(mean) && !isNaN(sd) && !isNaN(result) ) { sdi = (result - mean) / sd; } $s("C_SDI",sdi);
方案1:JavaScript批量计算所有行SDI
针对APEX交互式网格,可在网格加载完成后遍历所有行执行计算,步骤如下:
- 创建动态动作,触发时机选择
After Refresh(对应网格加载/刷新后) - 动作类型选择
Execute JavaScript Code,填入以下代码:
// 替换为你的网格区域ID var gridRegionId = "your_grid_region_id"; var ig = apex.region(gridRegionId).widget().interactiveGrid("getViews", "grid").model; // 遍历所有行计算SDI ig.forEach(function(row) { var mean = ig.getValue(row, "C_MEAN") !== "" ? parseFloat(ig.getValue(row, "C_MEAN")) : 0; var sd = ig.getValue(row, "C_SD") !== "" ? parseFloat(ig.getValue(row, "C_SD")) : 0; var result = ig.getValue(row, "C_RESULT") !== "" ? parseFloat(ig.getValue(row, "C_RESULT")) : 0; var sdi = 0; // 避免除以0的情况 if (!isNaN(mean) && !isNaN(sd) && !isNaN(result) && sd !== 0) { sdi = (result - mean) / sd; } // 设置当前行的SDI值 ig.setValue(row, "C_SDI", sdi); });
方案2:修复SQL查询的ORA-01733错误
报错原因是直接在主查询中定义的计算列(虚拟列)无法用于可编辑网格的数据源,可通过子查询包装解决,同时处理SD为0的异常:
SELECT id_no, TESTID, UNITID, result, MEAN, SD, SDI, LOW_LIMIT, HIGH_LIMIT, PERF_ID FROM ( SELECT id_no, TESTID, UNITID , result, MEAN, SD, -- 处理SD为0的情况,避免除以0错误 CASE WHEN SD <> 0 THEN (result - mean)/sd ELSE 0 END AS SDI, LOW_LIMIT, HIGH_LIMIT, PERF_ID FROM HAJJ_QC_RESULTS WHERE sample_id = :P13_SAMPLE AND program_id = :P13_PROGRAM AND machine_id = :P13_MACHINE AND hospital_no = :P13_HOSPITAL AND approved_date = :P13_FROMDATE )
如果网格不需要编辑SDI列,也可以在APEX中将SDI列设置为只读,配合原查询使用。
内容的提问来源于stack exchange,提问作者Ziad Adnan
相关产品推荐
相关产品推荐

