【C#】MES消耗类数量逻辑处理(物料消耗、打包装箱、生产订单派工等)

系列文章

【C#】最全业务单据号生成(支持定义规则、流水号、传参数)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787

【C#】日期范围生成器(开始日期、结束日期)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129040663

【C#】组件化开发,调用dll组件方法

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129492112

【C#】数据实体类使用

本文链接:https://blog.csdn.net/youcheng_ge/article/details/128816638

【C#】单据审批流方案

本文链接:https://blog.csdn.net/youcheng_ge/article/details/128972545

【C#】条码管理操作手册

本文链接:https://blog.csdn.net/youcheng_ge/article/details/126589496

【C#】IIS平台下,WebAPI发布及异常处理

本文链接:https://blog.csdn.net/youcheng_ge/article/details/126539836

【C#】代码模板生成工具

本文链接:https://blog.csdn.net/youcheng_ge/article/details/126890673

【C#】MySQL数据库导入工具(批量Excel插入)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/126427323

【C#】简单二维码制作和打印工具

本文链接:https://blog.csdn.net/youcheng_ge/article/details/126884228

【C#】最全单据打印(打印模板、条形码&二维码、字体样式、项目源码)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129415723

【C#】Windows服务(Service)安装及启停方案

本文链接:https://blog.csdn.net/youcheng_ge/article/details/124053794

【C#】穿透Session隔离,服务调用外部程序(无窗体界面解决)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/124053033

【C#】任务计划实现,使用Quartz类

本文链接:https://blog.csdn.net/youcheng_ge/article/details/123667723

【C#】源码解析正则表达式

本文链接:https://blog.csdn.net/youcheng_ge/article/details/118337074

【C#】软件版本和文件MD5记录(XML操作)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/112513871

【C#】测试网络是否连通

本文链接:https://blog.csdn.net/youcheng_ge/article/details/110137288

【C#】根据名称获取编码(Dictionary获取key方法)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129816701

【C#】数据建模,你是使用DataTable还是List?

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129792726

【C#】GridControl控件和数据集双向绑定

本文链接:https://blog.csdn.net/youcheng_ge/article/details/129423755

【C#】GridControl动态更换DataSource,数据查询异常处理

本文链接:https://blog.csdn.net/youcheng_ge/article/details/130305424

【C#】GridControl日期字段显示时分秒

本文链接:https://blog.csdn.net/youcheng_ge/article/details/130718303

【C#】GridControl增加选择列(不用二次点击)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/130763713

【C#】数据库检查工具(可跨库访问)

本文链接:https://blog.csdn.net/youcheng_ge/article/details/97172329

【C#】代码解析--打印数据集

本文链接:https://blog.csdn.net/youcheng_ge/article/details/131431829

【C#】代码解析--截取整个方法函数

本文链接:https://blog.csdn.net/youcheng_ge/article/details/109817809

【C#】反射机制,动态加载类文件

本文链接:https://blog.csdn.net/youcheng_ge/article/details/131435110


文章目录


前言

我能抽象出整个世界,但是我不能抽象你。 想让你成为私有常量,这样外部函数就无法访问你。 又想让你成为全局常量,这样在我的整个生命周期都可以调用你。 可惜世上没有这样的常量,我也无法定义你,因为你在我心中是那么的具体。

哈喽大家好,本专栏为【项目实战】,有别于【底层库】专栏,我们可以发现增加 了『问题描述』、『项目展示』章节,十分贴合项目开发流程,让读者更加清楚本文能够解决的问题、以及产品能够达到的效果。本专栏收纳项目开发过程中的解决方案,是我项目开发相对成熟、可靠方法的总结,在不涉及职务作品保密协议 的前提下,我将问题的解决方案重新梳理,撰写本文分享给大家,大家遇到类似问题,可按本文方案处理。

本专栏会持续更新,不断完善,专栏文章关联性较弱(文章之间依赖性较弱,没有阅读顺序)。大家有任何问题,可以私信我。如果您对本专栏感兴趣,欢迎关注吧,我将带你用最简洁的代码,实现复杂的功能。

·提示:本专栏为项目实战篇,未接触项目开发的同学可能理解困难,不推荐阅读。


一、问题描述

本文主要解决MES消耗类数量逻辑处理,比如:物料消耗、打包装箱、生产订单派工等。好几个产出单子的数量合计,去完成订单数。

这个问题用纯文字很难描述,以下会引入一个小小的需求,说明一下。

二、解决方案

本文的解决方案,不会直接拿项目进行讲解,而是引入一个问题原型,采用迭代的方式,逐步细化需求,从而达到解决的目的。

2.1 问题1.0版本

需求:

1、根据图片描述,我们已经有剩余箱数的列表:15, 44, 56,合计115。

2、我们需要按照每50箱一个大箱子的规则,将剩余箱数打包成大箱子,并存储在一个列表中。

3、满50箱,为一个大箱子的整箱;不足50箱,也可以包装一个大箱子,为一个大箱子的不足箱。例如:115/50=2.3,取整为2,就是2个大箱子的整箱(里面有50个箱子);115%50=15,就是1个大箱子的不足箱(里面有15个箱子)

分析:

1、计算剩余箱数的总和。

2、计算完整的大箱子(每50箱)的数量,以及不足50箱的余数。

3、将完整的大箱子(每箱50箱)添加到列表中,然后将不足50箱的余数作为一个大箱子(如果余数大于0)添加到列表。

4、注意题目要求满50箱为一个大箱子的整箱,不足50箱也可以包装一个大箱子(即不足箱)。因此,我们得到的大箱子列表应该包含2个50和1个15。

2.2 问题2.0版本

需求增补:

1、只要每满50箱打包成一个大箱子(整箱),不足50箱的仍然保留在剩余箱数中。

2、需要从剩余箱数中取出足够的箱数来组成整箱,直到剩余箱数不足以组成一个整箱。

分析:

1、先计算总剩余箱数,然后从总剩余箱数中提取整箱(50箱)放入大箱子列表。

2、但是注意:用户要求大箱子列表只包含整箱(50箱),不足的保留在剩余箱数中。

3、然而,原始数据是三个独立的剩余箱数记录,我们可能需要重新分配这三个记录的剩余箱数,使得能够组合出整箱,同时保留不足整箱的部分。

4、注意原始剩余箱数数据是一个列表,我们需要从中组合出整箱。但是组合时,可能会跨记录组合。例如,第一个记录有15箱,第二个记录有44箱,我们可以从这两个记录中组合出一个50箱的整箱,然后这两个记录剩余的箱数分别为0和9(因为15+44=59,用去50,剩余9)。然后第三个记录56箱,可以再组合出一个50箱的整箱,剩余6箱。

2.3 问题解决步骤

步骤:

1、初始化一个整箱列表(largeBoxes)为空。

2、初始化一个临时变量boxesToDeduct为0,用于记录当前累计的箱数。

3、遍历remainingBoxes列表,对于每个记录,将其剩余箱数加到boxesToDeduct上。

4、然后,只要boxesToDeduct >= 50,我们就从boxesToDeduct中减去50,并将一个整箱(50)加入largeBoxes。

5、处理完一个记录后,将这个记录的剩余箱数更新为currentBoxes(注意,此时currentBoxes可能已经减去了一些整箱,所以是当前记录处理后的剩余箱数)。但是注意,当我们处理第一个记录时,我们可能已经将第一个记录和第二个记录的一部分组合了,所以实际上我们是在处理每个记录时,将当前记录和之前记录的剩余箱数合并处理。

但是,这样处理会导致前面记录的剩余箱数被清零(因为被取走了),而最后一个记录可能会有剩余。

三、软件开发(源码)

3.1 代码

采用的最新的net版本,项目有些变化,无主函数,需要说明。

csharp 复制代码
// See https://aka.ms/new-console-template for more information

//1、 初始化剩余箱数数据
List<int> remainingBoxes = new List<int> { 15, 44, 56 };

Console.WriteLine("原始剩余箱数数据:");
Console.WriteLine($"[{string.Join(", ", remainingBoxes)}]");

//2、装箱规则(50个小箱子,包装一个大箱子。类似理解为12个啤酒瓶,包装成一个箱子)
int packingCapacity = 50;

//3、计算总箱数
int totalBoxes = 0;
foreach (int boxes in remainingBoxes)
{
    totalBoxes += boxes;
}

Console.WriteLine($"总箱数: {totalBoxes}");

//4、整箱、剩余箱数计算
int fullLargeBoxes = totalBoxes / packingCapacity; // 整箱数 2
int packedBoxes = fullLargeBoxes * packingCapacity; // 整箱中小箱子数量合计 100
int remainingBoxesCount = totalBoxes % packingCapacity; // 剩余零散的小箱子 15

Console.WriteLine($"可打包完整大箱子数量: {fullLargeBoxes} (共{packedBoxes}箱)");
Console.WriteLine($"剩余箱数: {remainingBoxesCount}");

// 5、生成大箱子列表
List<int> largeBoxes = new List<int>();
for (int i = 0; i < fullLargeBoxes; i++)
{
    largeBoxes.Add(packingCapacity);
}

Console.WriteLine($"\n大箱子列表 (largeBoxes):");
Console.WriteLine($"[{string.Join(", ", largeBoxes)}]");

//6、定义 更新剩余箱数数据:扣除已经打包的箱数
List<int> updatedRemainingBoxes = new List<int>();
int boxesToDeduct = packedBoxes; // 需要扣除的箱数:100箱

//7、从前往后扣除箱数
for (int i = 0; i < remainingBoxes.Count && boxesToDeduct > 0; i++)
{
    if (remainingBoxes[i] >= boxesToDeduct)
    {
        // 当前记录的箱数足够扣除
        updatedRemainingBoxes.Insert(i, remainingBoxes[i] - boxesToDeduct);
        boxesToDeduct = 0;

        // 前面的记录保持不变(插入到列表后面)
        for (int j = i + 1; j < remainingBoxes.Count; j++)
        {
            updatedRemainingBoxes.Insert(i, remainingBoxes[j]);
        }
    }
    else
    {
        // 当前记录的箱数不足,全部扣除
        boxesToDeduct -= remainingBoxes[i];
        updatedRemainingBoxes.Insert(i, 0);
    }
}


Console.WriteLine($"\n更新后的剩余箱数数据 (updatedRemainingBoxes):");
Console.WriteLine($"[{string.Join(", ", updatedRemainingBoxes)}]");

//8、验证总和
int updatedSum = 0;
foreach (int boxes in updatedRemainingBoxes)
{
    updatedSum += boxes;
}
updatedSum += packedBoxes; // 加上打包的大箱子数量
Console.WriteLine($"更新后总箱数: {updatedSum} (应与更新前的总箱数{totalBoxes}一致)");


Console.WriteLine("Hello, World!");

3.2 结果

bash 复制代码
原始剩余箱数数据:
[15, 44, 56]
总箱数: 115
可打包完整大箱子数量: 2 (共100箱)
剩余箱数: 15

大箱子列表 (largeBoxes):
[50, 50]

更新后的剩余箱数数据 (updatedRemainingBoxes):
[0, 0, 15]
更新后总箱数: 115 (应与更新前的总箱数115一致)
Hello, World!

四、项目展示

五、资源链接

相关推荐
半夏知半秋2 小时前
kcp学习-skynet中的kcp绑定
开发语言·笔记·后端·学习
扶苏-su2 小时前
Java--标准输入输出流
java·开发语言
奋斗的小青年!!2 小时前
Flutter跨平台开发OpenHarmony应用:个人中心实现
开发语言·前端·flutter·harmonyos·鸿蒙
状元岐2 小时前
上位机通信-通信介质与通信协议关系
c#
石头wang2 小时前
jmeter java.lang.OutOfMemoryError: Java heap space 修改内存大小,指定自己的JDK
java·开发语言·jmeter
LawrenceLan2 小时前
Flutter 零基础入门(十五):继承、多态与面向对象三大特性
开发语言·前端·flutter·dart
zh_xuan3 小时前
kotlin对象表达式
开发语言·kotlin
froginwe113 小时前
ECharts 旭日图:全面解析与应用指南
开发语言
yaoxin5211233 小时前
292. Java Stream API - 使用构建器模式创建 Stream
java·开发语言