如题,原值是2+20=22;但若新增了第3行有相同的主键ID,我想要的效果是首行22变为28,而不是22,第3行的新库存数也自动变更为28,而不是26.第2行没有相同的主键,不管它。如果能实现,就能保障库存数的准确性了。
注意:库存主键ID如果是多行出现相同的多组数据,而且可能会出现两次相同的主键ID,以此类推,能合计累加?用JS前端或后端怎么处理?大师们,能见到写个实现的案例吗?感谢!
如题,原值是2+20=22;但若新增了第3行有相同的主键ID,我想要的效果是首行22变为28,而不是22,第3行的新库存数也自动变更为28,而不是26.第2行没有相同的主键,不管它。如果能实现,就能保障库存数的准确性了。
注意:库存主键ID如果是多行出现相同的多组数据,而且可能会出现两次相同的主键ID,以此类推,能合计累加?用JS前端或后端怎么处理?大师们,能见到写个实现的案例吗?感谢!
我在网上找了很多的案例,得到了启发,研究测试了近半个月,今天终于解决了。这个是非常实用的技术。先看效果图:
JS部分:
//我用JQ3.7版,使用先引入库,你们可在网上下载,大把库文件(请勿直接使用他人连接,你懂的),若你不想用,可用原始的JS方法获取对象也行的。
<script type="text/javascript" src="../../../../Frame/jquery_3.7.1.min.js?v=3.7.1"></script>
<script language="javascript">
//【同主键ID的数量累积核算,必须引入JQ3.7版本文件,否则无法运行】 批量获取单选框已选内容回填到绑定数据表字段。传入单选框ID即可。采用"onClick"事件触发。
// StorageID是本表单固有的字段名过滤参数,暂无法用其它变量替代,因为数组里必须用它来过滤同类数组,最后在叠加数量。若用于其它表单,请批量修改该字段名即可。
// fid:库存主键ID、tpid:入库小计缓存ID、spid:合并数ID、exsid:旧库存数ID、stockid:新库存数ID
function getCheckboxValue(fid,tpid,spid,exsid,stockid){
//var f = document.getElementsByName(fid); //(原始方式)获取源数组对象集合,注意是本身就是数组对象哦,所以无需声明数组。等同于JQ的 $("[name='某某名']")
var f = $("[name='"+ fid +"']"); // [采用JQ库新方式]获取name为'StorageID'数组对象集合,不是单个元素,等同getElementsByName,提取属性值如:alert(f[0].value),使用范围广,不受文本框属性限制。
var t = $("[name='"+ tpid +"']"); // 入库小计,相当于缓存初始数
var s = $("[name='"+ spid +"']"); // 合并数
var exs = $("[name='"+ exsid +"']"); // 旧库存数(参考,以在流程属性中实时获取到为准,可能会有变更)
var stock = $("[name='"+ stockid +"']"); // 新库存数(参考,以在流程属性中实时公式计算为准,可能会有变更)
var n = f.length; // 获取明细表循环的行数集合数组,若为1表示单行数据
//var str = $("#"+tpid).val(); // JQ获取单个元素值,但通过JQ的对象获取后,只能用 f[0].value 输出某个数组方式,而不是val()哦
if (n==0){
return false; //如果数据为空行,不执行,否则抛出异常提示。
}
else {
var arrData=[],arrstr=[];
for(var k=0;k<n;k++){ //再次循环旧数组,以便格式化为自己想要的数组类型
var arrstr = { StID:f[k].value,num:Number(t[k].value) }; // 转换数组新格式,方便汇总同类数量,如:{StID: "8586",num: 122},注意数量要格式化。
arrData.push(arrstr); //逐个添加到新数组arrData
}
var newdata = [],dn = arrData.length; // 创建新数组,用于存放符合同名条件的单独数组
arrData.forEach((item,index,arr)=>{ // 循环原本的数组arrData,用于筛选符合同主键的数组存放到数组 newdata
if(newdata.some((item2,index2)=>{ // 判断新数组中有没有当前元素item,没有的往下执行会添加
// newdata有一个同名就会反true
if(item.StID == item2.StID){
return true;
}
})===false){ // 添加及合并操作:
newdata.push(item); // 将当前元素填入新数组中
arr.forEach((item3,index3)=>{ //并且循环原本数组去判断当前元素item的其他同名元素,去合并。 如果有同名元素,但是索引不同,就把num合并
if(item.StID == item3.StID&&index!==index3){
var nn = newdata.length;
newdata[nn-1].num += Number(item3.num); // 同名元素在新数组中一定是最后一位
}
});
// 因为每次循环会判断新数组是否有同名元素,所以后面的同名元素会跳过这部分操作
}
});
var nn = newdata.length;
for(var i=0;i<n;i++){ // 再次循环旧数组arrData,与新数组对比,检测出同名时,更新合计后的数量num
for(var j=0;j<nn;j++){ // 再次循环合并数量后的新数组newdata[]
var str1 = arrData[i].StID;
var str2 = newdata[j].StID;
if(str1 === str2){ //合并的条件参数,默认为对象名 "StID"
arrData[i].num = Number(newdata[j].num); // 若有符合同名合并后的旧数量,将用新的属性值替换旧的属性值
//t[i].value = ""; // 因它只是存储原始数据,不能更新缓存文本框值,否则会不断重复累计数量,造成数值翻倍错误(测试字段,已删除)
s[i].value = Number(newdata[j].num); // 更新文本框[合并数] 合计后,真实修改的是绑定数据库字段,【注意需要格式化为数字,下同】最关键步骤
stock[i].value = Number(exs[i].value) + Number(newdata[j].num); // 更新文本框[新库存数=旧库存数+合并数]
//console.log('合计后:',newdata[j].num); //打印调试数据
}
}
}
}
}
</script>
HTML部分采用.ASPX的表单:
只贴了字段的命名和ID,其它命名雷同,在JS部分有说明,这里获取的数组对象集合记得要使用“var f = $("[name='StorageID']")”,或采用原始方式获取对象集合 //var f = document.getElementsByName("StorageID"),否则无法获取多行数组的哦。
...
<textarea name="StorageID" id="StorageID" title="库存主键ID:更新库存唯一条件,无法修改" >
</textarea>
<textarea name="StorageID" id="StorageID" title="库存主键ID:更新库存唯一条件,无法修改" >
</textarea>
...
JS处理部分,给表单提交按钮增加点击鼠标经过动作事件后,触发JS函数:
Onmouseover = "getCheckboxValue('StorageID','SumQuantity','SameSumQuantity','ExStock','Stock')"
当然不局限于上述触发动作,你想怎么用都可以的呢。
好了,我想要的前端处理数据目的已达到,现在也分享给大家。至于你想用SQL后端处理也是可以的,但后者的弊端无法预览新数据,需要使用SQL内置窗体函数分类合并更新,后者解决方式,在我的其它问题里有哦。
再次感谢各位大师指点迷津!