计量论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

[讨论] 保留位数EXCEL实现

[复制链接]
wangyiyong7703 发表于 2023-9-16 01:00:30 | 显示全部楼层 |阅读模式
A2输入待修约数字,B2输入保留小数点位数,C2输入公式

IF(B2=0,IF(OR(AND(ISEVEN(INT(A2)),A2-INT(A2)=0.5),A2-INT(A2)<0.5),INT(A2),INT(A2)+1),IF(LEN(IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)))=LEN(INT(A2)),IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2))&"."&REPT("0",B2),IF(LEN(INT(A2*POWER(10,B2)))+1>LEN((IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)))),(IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)))&REPT("0",LEN(INT(A2*POWER(10,B2)))-1-LEN((IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2))))),IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)))))

保留多少位小数点.xlsx

9.49 KB, 下载次数: 38, 下载积分: 金币 -1

 楼主| wangyiyong7703 发表于 2023-9-16 12:39:01 | 显示全部楼层
对9.99999这种情况不适用,还待改进
zcxxwxu 发表于 2023-9-18 16:23:20 | 显示全部楼层
点个赞,点个赞,点个赞,点个赞。
小阿飞飞 发表于 2023-9-28 15:34:44 | 显示全部楼层
=IF(MOD(ABS(R5*POWER(10,Y5)),2)<=0.5,ROUNDDOWN(R5,Y5),ROUND(R5,Y5))   
不用那么麻烦吧我用的是这个
 楼主| wangyiyong7703 发表于 2023-9-29 12:13:12 | 显示全部楼层
小阿飞飞 发表于 2023-9-28 15:34
=IF(MOD(ABS(R5*POWER(10,Y5)),2)

显然主逻辑程序是对的,但你要考虑特殊情况,在特殊情况下如0.999995,0.100005,您还能得出您想要的答案么。这个问题的难点就是特殊情况BUG,不考虑特殊情况,答案很多。还有浮点问题。好多。但怎样规避是个问题。
轩辕梦 发表于 2023-9-30 16:35:35 | 显示全部楼层
感谢分享,下载看看
路云 发表于 2023-9-30 23:16:49 | 显示全部楼层
本帖最后由 路云 于 2023-9-30 23:53 编辑
wangyiyong7703 发表于 2023-9-29 12:13
显然主逻辑程序是对的,但你要考虑特殊情况,在特殊情况下如0.999995,0.100005,您还能得出您想要的答案 ...

其实没那么复杂,只要建一个自定义函数,应用时直接调用即可。

465留双自定义函数:

Function Yround(ByVal a As Double, Optional ByVal d As integer)

        Yround=Round(CDec(a),d)

End Function

注:参数a为传值型双精度变量(拟修约数),参数d为可选整型参数(需保留的小数位数)。

如您1楼的例子,只需在A2单元格输入拟修约数,B2单元格输入欲保留的小数位数,在C2单元格中直接调用自定义函数(输入“=Yround(A2, B2)”)即可得到修约结果。无论A2单元格的拟修约数是正数还是负数,都会按自动按照“465留双”的修约规则进行修约。

a.png

 楼主| wangyiyong7703 发表于 2023-10-1 14:12:16 | 显示全部楼层
路云 发表于 2023-9-30 23:16
其实没那么复杂,只要建一个自定义函数,应用时直接调用即可。4舍6入5留双自定义函数:Function Yround(ByV ...

自定义函数也用到宏代码,不能这样操作,一般人用起来不方便
 楼主| wangyiyong7703 发表于 2023-10-1 14:14:02 | 显示全部楼层
路云 发表于 2023-9-30 23:16
其实没那么复杂,只要建一个自定义函数,应用时直接调用即可。4舍6入5留双自定义函数:Function Yround(ByV ...

我们的目标是避开宏代码,完全用内建函数实现
 楼主| wangyiyong7703 发表于 2023-10-1 14:53:51 | 显示全部楼层
本帖最后由 wangyiyong7703 于 2023-10-1 14:56 编辑

IF(IFERROR(FIND(".",IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)),1),0)=0,IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2))&"."&REPT("0",B2),IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2))&REPT("0",IFERROR(FIND(".",IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)),1),0)+B2-LEN(IF(OR(AND(ISEVEN(INT(A2*POWER(10,B2))),A2*POWER(10,B2)-INT(A2*POWER(10,B2))=0.5),A2*POWER(10,B2)-INT(A2*POWER(10,B2))<0.5),INT(A2*POWER(10,B2))/POWER(10,B2),(INT(A2*POWER(10,B2))+1)/POWER(10,B2)))))
 楼主| wangyiyong7703 发表于 2023-10-1 14:54:21 | 显示全部楼层
本帖最后由 wangyiyong7703 于 2023-10-1 15:16 编辑

代码进行了优化
适应范围更广,不用宏代码,完全避开了自定义函数和程序用到宏代码。
 楼主| wangyiyong7703 发表于 2023-10-1 15:17:34 | 显示全部楼层
从0.0001到100.0000,全部合格,保留2位小数
路云 发表于 2023-10-1 20:30:38 | 显示全部楼层
本帖最后由 路云 于 2023-10-1 20:41 编辑
wangyiyong7703 发表于 2023-10-1 14:12
自定义函数也用到宏代码,不能这样操作,一般人用起来不方便

建立自定义函数,目的就是要让普通用户能用起来呀。用时就像内部函数一样调用即可。你键入那么复杂的函数都能用,难道键入“=Yroug(A2, B2)”还更难?

您这个公式我试了一下,存在以下问题:

-1.035000000,修约结果没有按照“4舍6入5留双”的修约规则修约至-1.04,而是修约至-1.03。

a.png

 楼主| wangyiyong7703 发表于 2023-10-1 21:15:59 | 显示全部楼层
公式出现浮点问题,正在改进,新的方法有点问题,
 楼主| wangyiyong7703 发表于 2023-10-1 21:16:28 | 显示全部楼层
逻辑没有问题,避开浮点算法已经找到
 楼主| wangyiyong7703 发表于 2023-10-1 21:17:39 | 显示全部楼层
路云 发表于 2023-10-1 20:30
建立自定义函数,目的就是要让普通用户能用起来呀。用时就像内部函数一样调用即可。你键入那么复杂的函数 ...

然后有时候是正常的,两种情况都有
 楼主| wangyiyong7703 发表于 2023-10-1 21:41:25 | 显示全部楼层
路云 发表于 2023-10-1 20:30
建立自定义函数,目的就是要让普通用户能用起来呀。用时就像内部函数一样调用即可。你键入那么复杂的函数 ...

没有那容易,必须启用宏,如果启用宏,会带来很多麻烦
 楼主| wangyiyong7703 发表于 2023-10-1 23:15:54 | 显示全部楼层
IF(OR(AND(ISEVEN(MID(A2,FIND(".",A2)+B2,1)*1),MID(A2,FIND(".",A2)+B2+1,1)="5",IFERROR(RIGHT(A2,LEN(A2)-FIND(".",A2)-B2-1)*1,0)=0),MID(A2,FIND(".",A2)+B2+1,1)*1<5),LEFT(A2,FIND(".",A2,1)+B2),IF(IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2),1),0)=0,LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2)&"."&REPT("0",B2),LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2)&REPT("0",B2-(LEN(LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2))-IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2),1),0)))))
 楼主| wangyiyong7703 发表于 2023-10-2 10:02:30 | 显示全部楼层
=IF(OR(AND(ISEVEN(MID(A2,FIND(".",A2)+B2,1)*1),MID(A2,FIND(".",A2)+B2+1,1)="5",IFERROR(RIGHT(A2,LEN(A2)-FIND(".",A2)-B2-1)*1,0)=0),MID(A2,FIND(".",A2)+B2+1,1)*1<5),LEFT(A2,FIND(".",A2,1)+B2),IF(IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2),1),0)=0,LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2)&"."&REPT("0",B2),LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2)&REPT("0",B2-(LEN(LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2))-IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+1/POWER(10,B2),1),0))))) 用的新的算法欢迎指正
 楼主| wangyiyong7703 发表于 2023-10-2 10:19:28 | 显示全部楼层
IF(OR(AND(ISEVEN(MID(A2,FIND(".",A2)+B2,1)*1),MID(A2,FIND(".",A2)+B2+1,1)="5",IFERROR(RIGHT(A2,LEN(A2)-FIND(".",A2)-B2-1)*1,0)=0),MID(A2,FIND(".",A2)+B2+1,1)*1<5),LEFT(A2,FIND(".",A2,1)+B2),IF(IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+IF(A2*1<0,-1,1)/POWER(10,B2),1),0)=0,LEFT(A2,FIND(".",A2,1)*1+B2)*1+IF(A2*1<0,-1,1)/POWER(10,B2)&"."&REPT("0",B2),LEFT(A2,FIND(".",A2,1)*1+B2)*1+IF(A2*1<0,-1,1)/POWER(10,B2)&REPT("0",B2-(LEN(LEFT(A2,FIND(".",A2,1)*1+B2)*1+IF(A2*1<0,-1,1)/POWER(10,B2))-IFERROR(FIND(".",LEFT(A2,FIND(".",A2,1)*1+B2)*1+IF(A2*1<0,-1,1)/POWER(10,B2),1),0))))) 适合负数修约
路云 发表于 2023-10-2 22:45:28 | 显示全部楼层
wangyiyong7703 发表于 2023-10-1 21:41
没有那容易,必须启用宏,如果启用宏,会带来很多麻烦

不明白您说的很多麻烦到底是什么麻烦。我们单位在LIMS系统中应用这么多年,从来没有听说过遇到什么麻烦。网络版office安装时就已经进行了安全设置,自定义函数都放在安全可信路径下,原始记录等都已制作成了智能型空白模板,试验/检测人员调用模板生成原始记录的操作非常简单,对于选择项只需点击下拉列表框、复选框、控件等进行选择,只需录入检测数据,所有的数据处理和结果都是自动完成,试验/检测人员根本没有感觉,也无需其他任何操作,完全做成了一种“傻瓜型”的智能Excel模板。

 楼主| wangyiyong7703 发表于 2023-10-3 07:48:47 | 显示全部楼层
路云 发表于 2023-10-2 22:45
不明白您说的很多麻烦到底是什么麻烦。我们单位在LIMS系统中应用这么多年,从来没有听说过遇到什么麻烦。 ...

单机版的麻烦,您的网络版加持当然可以。
路云 发表于 2023-10-3 11:12:01 | 显示全部楼层
wangyiyong7703 发表于 2023-10-3 07:48
单机版的麻烦,您的网络版加持当然可以。

单机版的也一样,又不要用户去编辑宏代码,就像调用普通内部函数一样。

 楼主| wangyiyong7703 发表于 2023-10-3 13:53:41 | 显示全部楼层
那您发一个自定义的函数,我用二十多年了,没见过
路云 发表于 2023-10-4 08:14:59 | 显示全部楼层
本帖最后由 路云 于 2023-10-4 10:02 编辑
wangyiyong7703 发表于 2023-10-3 13:53
那您发一个自定义的函数,我用二十多年了,没见过

我说的“用户”,不是指OFFICE用户,而是指具体填写原始记录的检测/校准人员。如果见过,那就不叫“自定义函数”了。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|计量论坛 ( 闽ICP备06005787号-1—304所 )
电话:0592-5613810 QQ:473647 微信:gfjlbbs闽公网安备 35020602000072号

GMT+8, 2024-5-5 01:32

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表