如何舍入 Excel 中的小数列表,使整数之和等于定义的总数?
How to round a list of decimals in Excel, so that the sum of the whole numbers equal a defined total?
难以开发 excel 将小数列表四舍五入的函数,以便所有数字的总和等于原始数字或定义的总数。
编辑
我想这样做的一种方法是编写一个函数,首先搜索最大的数字并将它们四舍五入到最接近的整数。然后计算这个整数,函数继续下一个,直到总数等于目标总数。
我 运行 遇到的问题是,如果有太多接近 0 的数字,那么该函数将永远不会等于目标总数。所以该函数需要做的是识别最大的小数,将它们四舍五入,计数,然后继续下一个,直到计数的总和等于目标总数。剩下的数据可以舍入为 0。
抱歉,我希望这更清楚....
我正在处理更大的数据集,其中四舍五入整数的总和与原始总和的偏差更大。
如果这可以用 excel 函数来完成,那就更好了,否则我也愿意在 VBA 中做。
谢谢!
编辑 3:这是一个示例数据集:
我同意@pghcpa 的观点,这是一道算术题。
一种解决方案:
- 按小数部分降序排列数字
- 每个人都发言(即忽略分数)
- 取这些楼层的总和
- 将该总和与所需总和进行比较,取差
这样你 可能 有一个正的差异,所以你可以从顶部开始,向下每个数字加 1,直到差异消失。
请研究我的项目VBA.Round。
浏览到段落 Rounding a series of numbers to a sum
这里的代码太多 post,但是包含一个示例工作簿供下载。
示例:
此函数将读取分布值的范围,对总和进行四舍五入,并用四舍五入的值 2 和零小数填充两个范围,总计为请求的总数(已通过公式确认):
' Practical example for using Excel ranges for RoundSum
'
' Source URL:
'
'
' 2020-09-14. Gustav Brock, Cactus Data ApS, CPH.
'
Public Sub RoundDistribution()
' Named ranges. These should pairwise match in row size.
Const VolumeName As String = "Volume"
Const PercentValuesName As String = "Percent_Distribution"
Const ValuesName As String = "Distribution"
Const RoundedValuesName As String = "Rounded_Distribution"
Dim Range As Excel.Range
Dim Values() As Currency
Dim Results() As Currency
Dim Total As Integer
Dim Index As Integer
' Read percent distribution values from the named range.
Set Range = ThisWorkbook.Names(PercentValuesName).RefersToRange
' Read original volume value.
Total = ThisWorkbook.Names(VolumeName).RefersToRange(1, 1)
' Dim input and output arrays.
ReDim Values(1 To Range.Rows.Count)
ReDim Results(1 To Range.Rows.Count)
' Fill input array.
For Index = LBound(Values) To UBound(Values)
Values(Index) = Range(Index, 1)
Next
' Round total and retrieve array with distribution values.
Results = RoundSum(Values, RoundMid(Total), 2)
' Fill named range with distribution values.
For Index = LBound(Results) To UBound(Results)
ThisWorkbook.Names(ValuesName).RefersToRange(Index, 1) = Results(Index)
Next
' Round total and retrieve array with rounded distribution values.
Results = RoundSum(Values, RoundMid(Total))
' Fill named range with rounded distribution values.
For Index = LBound(Results) To UBound(Results)
ThisWorkbook.Names(RoundedValuesName).RefersToRange(Index, 1) = Results(Index)
Next
End Sub
输出:
请注意,该函数能够四舍五入到任意小数位数,并且 select 仅 值 0.34 的一个实例以获得匹配。
完整的演示(Excel 工作簿)和代码仍在 GitHub上下载。
难以开发 excel 将小数列表四舍五入的函数,以便所有数字的总和等于原始数字或定义的总数。
编辑 我想这样做的一种方法是编写一个函数,首先搜索最大的数字并将它们四舍五入到最接近的整数。然后计算这个整数,函数继续下一个,直到总数等于目标总数。
我 运行 遇到的问题是,如果有太多接近 0 的数字,那么该函数将永远不会等于目标总数。所以该函数需要做的是识别最大的小数,将它们四舍五入,计数,然后继续下一个,直到计数的总和等于目标总数。剩下的数据可以舍入为 0。
抱歉,我希望这更清楚....
我正在处理更大的数据集,其中四舍五入整数的总和与原始总和的偏差更大。
如果这可以用 excel 函数来完成,那就更好了,否则我也愿意在 VBA 中做。
谢谢!
编辑 3:这是一个示例数据集:
我同意@pghcpa 的观点,这是一道算术题。 一种解决方案:
- 按小数部分降序排列数字
- 每个人都发言(即忽略分数)
- 取这些楼层的总和
- 将该总和与所需总和进行比较,取差 这样你 可能 有一个正的差异,所以你可以从顶部开始,向下每个数字加 1,直到差异消失。
请研究我的项目VBA.Round。
浏览到段落 Rounding a series of numbers to a sum
这里的代码太多 post,但是包含一个示例工作簿供下载。
示例:
此函数将读取分布值的范围,对总和进行四舍五入,并用四舍五入的值 2 和零小数填充两个范围,总计为请求的总数(已通过公式确认):
' Practical example for using Excel ranges for RoundSum
'
' Source URL:
'
'
' 2020-09-14. Gustav Brock, Cactus Data ApS, CPH.
'
Public Sub RoundDistribution()
' Named ranges. These should pairwise match in row size.
Const VolumeName As String = "Volume"
Const PercentValuesName As String = "Percent_Distribution"
Const ValuesName As String = "Distribution"
Const RoundedValuesName As String = "Rounded_Distribution"
Dim Range As Excel.Range
Dim Values() As Currency
Dim Results() As Currency
Dim Total As Integer
Dim Index As Integer
' Read percent distribution values from the named range.
Set Range = ThisWorkbook.Names(PercentValuesName).RefersToRange
' Read original volume value.
Total = ThisWorkbook.Names(VolumeName).RefersToRange(1, 1)
' Dim input and output arrays.
ReDim Values(1 To Range.Rows.Count)
ReDim Results(1 To Range.Rows.Count)
' Fill input array.
For Index = LBound(Values) To UBound(Values)
Values(Index) = Range(Index, 1)
Next
' Round total and retrieve array with distribution values.
Results = RoundSum(Values, RoundMid(Total), 2)
' Fill named range with distribution values.
For Index = LBound(Results) To UBound(Results)
ThisWorkbook.Names(ValuesName).RefersToRange(Index, 1) = Results(Index)
Next
' Round total and retrieve array with rounded distribution values.
Results = RoundSum(Values, RoundMid(Total))
' Fill named range with rounded distribution values.
For Index = LBound(Results) To UBound(Results)
ThisWorkbook.Names(RoundedValuesName).RefersToRange(Index, 1) = Results(Index)
Next
End Sub
输出:
请注意,该函数能够四舍五入到任意小数位数,并且 select 仅 值 0.34 的一个实例以获得匹配。
完整的演示(Excel 工作簿)和代码仍在 GitHub上下载。