VBA实现后入先出(LIFO)库存统计

先入先出(FIFO)比较容易理解,买入早的优先卖出。与之对应的是后人先出(LIFO),就是优先卖出最近买入的,例如:第8行卖出2K,当天还没有买入记录,只能找前一天的买入记录(即第7行),此示例中恰巧二者出入平衡,如果第7行买入数据不足,那么继续向前找(假设还有可用库存)。这只是一个最简单的粗略介绍,如果读者需要更深入了解LIFO的相关知识,请自行网络搜索。

接下来用几个辅助列粗略解释一下统计逻辑

  • I列为数量累加值,统计从期初到当前行的数量汇总值,如果数值为0,说明到当前行位置出入平衡
  • J列为当日的累加值,如果数值为0,说明该天出入平衡,例如:20250410

步骤1:确定起始日期,查找满足如下条件的最后一行日期(或者行号),结果为20250314(第5行),第6行将作为起始行。

  • 累加值(I列)为0 【满足此条件的有5行,标记为浅红色】
  • 某行是当日最后一条记录 【满足两个条件的有第3,5行,此处应取第5行】

步骤2:在累加列中从上到下查找首次出现的最终累加值(5800)作为终止日期,此示例中为20250409(行号20)。其中的逻辑是由于20行和第28行累加值相同,说明第21~28行的出入平衡,读者可以自行验证。

步骤3:对于起始日期(不包含)到截止日期之间的,剔除当日小计为零的日期,在每日最后一行提取均价作为最新价(填充H列),当日小计作为数量(填充G列)

结果如下图中G列和H列所示。

在这里插入图片描述

示例代码如下。

Sub Demo()Dim rngData As Range, i As Long, sKey As String, vDim iSum As Long, sStart As String, sEnd As StringDim objDic As Object: Set objDic = CreateObject("scripting.dictionary")Dim objDicDay As Object: Set objDicDay = CreateObject("scripting.dictionary")Set rngData = Range("A1").CurrentRegion.Offset(1)Dim arr: arr = rngData.ValueDim iTotal As Long: iTotal = Application.Sum(rngData.Columns(4))For i = LBound(arr) To UBound(arr) - 1sKey = arr(i, 1)iSum = iSum + arr(i, 4)objDicDay(sKey) = objDicDay(sKey) + arr(i, 4)objDic(sKey) = Array(i, iSum, objDicDay(sKey))If arr(i, 1) <> arr(i + 1, 1) ThenIf iSum = 0 Then sStart = arr(i, 1)If iSum = iTotal And sEnd = "" Then sEnd = arr(i, 1)End IfNext iRange("G:H").ClearContentsRange("G1:H1").Value = Array("数量", "最新价")For Each v In objDic.keysIf v <= sStart Or v > sEnd Or objDic(v)(1) = 0 Or objDic(v)(2) = 0 ThenobjDic.Remove vElsei = objDic(v)(0)Cells(i + 1, "G") = objDic(v)(2)Cells(i + 1, "H") = arr(i, 5)End IfNext
End Sub

【代码解析】
第4~5行代码创建字典对象。
第6行代码获取当前数据区域向下偏移一行的单元格区域,其目的在于

  • 去除标题行
  • 单元格区域末尾包含一个空行,后续代码中可以更简洁的定位每日最后数据行

第7行代码将数据读取到数组中。
第8行代码调用工作表函数获取数量列汇总值,也就是最终累加值。
第9~18行代码循环遍历数据表。
第10行代码获取第一列日期作为字典的键。
第11行代码获取数量累加值。
第12行代码使用objDicDay统计当日的汇总值。
第13行代码将数组保存在objDic中,数组包含三个元素

  • 第1个元素:当前数据所在行号(注意此处比数据在工作表中的实际行号少一,第6行代码区域偏移导致的)
  • 第2个元素:数量累加值
  • 第3个元素:当日数量小计

对于每个日期存在多行数据的情况,由于我们只关心最后数据行,所以此处无需使用Exists判断sKey是否存在于字典中。

第14行代码判断下一个数据行的日期是否与当前行相同,如果不同,说明当前行为当日最后一行数据。
第15行代码判断数量累加值是否为0,如果满足条件,那么该数据行的日期作为起始日期(sStart)。
第16行代码判断数量累加值是否与累加终值,并且结束日期为空,如果满足条件,那么该数据行的日期为结束日期(sEnd)。
第19行代码清空G和H列,用于保存结果。
第20行代码填充标题行。
第21~29行代码循环遍历字典对象objDic,将结果写入工作表。
第22行代码判断字典中数组是否满足如下任意条件

  • 行号小于等于起始行
  • 行号大于结束行
  • 数量累加为0
  • 当日数量小计为0

如果满足任意一个条件,第23行代码将从字典中删除该记录(并非必需)。
如果不满足任意条件,那么将结果写入工作表。
第25行代码获取数据行的行号。
第26行代码将当日数量小计写入G列。
第27行代码将均价写入H列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/79735.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/79735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python中的客户端和服务端交互的基本内容

目录 网络协议 网络的通信方式 需要安装的组件和需要导入的包模块 安装的组件 导入包模块 如何创建客户端 如何创建服务端 网络协议 IPV4&#xff1a;是互联网协议的第四版&#xff0c;也是目前广泛使用的网络协议。它使用32位地址格式&#xff0c;理论上可以提供约43亿…

【硬核攻坚】告别CUDA OOM!DeepSeek部署显存瓶颈终极解决方案:三大策略高效落地

目录 引言:大模型落地的“甜蜜”与“烦恼”DeepSeek剖析:为何它如此“吃”显存?CUDA OOM的“幽灵”:现象、根因与诊断破局之道:三大策略驯服显存“猛兽” 策略一:模型量化 - 给模型“瘦身”的艺术策略二:动态优化 - 榨干硬件潜能策略三:分布式扩展 - 集群的力量实战演练…

JavaSE核心知识点01基础语法01-01(关键字、标识符、变量)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 JavaSE核心知识点01基础语法01-01&#xff0…

【最新Python包管理工具UV的介绍和安装】

介绍 uv是一个非常快的 Python 包安装程序和 pip 解析器&#xff0c;用 Rust 编写&#xff0c;设计为pip-tools的直接替代品。 以下是官网给出的UV与其他包管理工具解决依赖&#xff08;左&#xff09;和安装包&#xff08;右&#xff09;的对比图。 可以看出UV是一个极快的 P…

麒麟、UOS系统在线打开word文件并提取修订痕迹

麒麟、UOS系统在线打开word文件并提取修订痕迹 查看本示例演示效果&#xff08;Windows版&#xff09; 查看本示例演示效果&#xff08;国产版&#xff09;本示例关键代码的编写位置&#xff0c;请参考“开始 - 快速上手”里您所使用的开发语言框架的最简集成代码 注意 本文中…

【SpringAI+阿里云百炼】AI对话4个Demo

基于SpringAI和阿里云百炼平台&#xff0c;实现了四个AI对话的小Demo 小团团对话机器人哄哄模拟器培训班智能客服仿ChatPDF 笔记如下:语雀知识笔记《SpringAI》

【数据结构】单链表的增删查改

本文是小编巩固自身而作&#xff0c;如有错误&#xff0c;欢迎指出&#xff01; 1.链表的概念 概念&#xff1a;链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的 指针链接次序实现的。 和之前的顺序表不同&#xff0c;顺序一般…

LeetCode 1128.等价多米诺骨牌对的数量:计数

【LetMeFly】1128.等价多米诺骨牌对的数量&#xff1a;计数 力扣题目链接&#xff1a;https://leetcode.cn/problems/number-of-equivalent-domino-pairs/ 给你一组多米诺骨牌 dominoes 。 形式上&#xff0c;dominoes[i] [a, b] 与 dominoes[j] [c, d] 等价 当且仅当 (a …

以太坊智能合约开发框架:Hardhat v2 核心功能从入门到基础教程

一、设置项目 Hardhat 项目是安装了 hardhat 包并包含 hardhat.config.js 文件的 Node.js 项目。 操作步骤&#xff1a; ①初始化 npm npm init -y②安装 Hardhat npm install --save-dev hardhat③创建 Hardhat 项目 npx hardhat init如果选择 Create an empty hardhat.…

安卓基础(无障碍点击)

无障碍点击核心代码 // 自定义无障碍服务类&#xff0c;继承自Android系统的AccessibilityService public class MyAccessibilityService extends AccessibilityService {// 当系统产生无障碍事件时的回调方法&#xff08;如界面变化、焦点切换等&#xff09;Overridepublic v…

阿里云服务迁移实战: 05-OSS迁移

概述 Bucket 复制分为两种&#xff0c;同区域复制和跨区域复制 同账号复制比较简单&#xff0c;根据提示填写信息即可&#xff0c;本文主要介绍跨账号复制。 同区域复制 授权角色选择 “AliyunOSSRole”, 创建方法见 “跨区域复制”。然后点击确定即可。 跨区域复制 假设我…

Qt 的信号与槽机制依赖元对象系统(Meta-Object System)实现

内部数据结构 在 Qt 中,信号和槽之间的连接主要通过 QObject 类及其相关的私有类进行管理。每个 QObject 实例都维护着一个指向其 QMetaObject 的指针,该对象包含了有关类的所有元信息,包括信号、槽等。此外,还有一个关键的数据结构用于存储信号与槽之间的连接信息,即 Co…

前端面试宝典---性能优化

一、加载优化 1. 第三方模块放在CDN 例如 leaflet通过cdn引入&#xff0c;这样就不会占用打包体积了 2. prefetch 预加载 例如&#xff0c;之后马上有个场景需要一个图片&#xff0c;我们就可以通过link 的 prefetch 对资源进行预先加载 再例如&#xff0c;我们公司是无网络开…

从零开始:Android Studio开发购物车(第二个实战项目)

一年经验的全栈程序员&#xff0c;目前头发健在&#xff0c;但不知道能撑多久。 文章目录 前言 一、页面编写 1. 顶部标签栏title_shopping.xml 2. 商品展现列表activity_shopping_channel.xml 3. 商品详情页面activity_shopping_detail.xml 4. 购物车页面activity_shopping…

PostgteSQL for Everybody基础部分笔记

笔记分享内容参考密歇根大学 Charles Russell Severance 开设的PostgreSQL课程&#xff1a;postgresql-for-everybody&#xff0c;网址为&#xff1a;https://www.coursera.org/specializations/postgresql-for-everybody#courses&#xff0c;在B站等也有相关视频分享。 我分享…

Python项目源码63:病历管理系统1.0(tkinter+sqlite3+matplotlib)

1.病历管理系统包含以下主要功能&#xff1a; 核心功能&#xff1a;病历信息录入&#xff08;患者姓名、年龄、性别、诊断结果、主治医生&#xff09;&#xff0c;自动记录就诊时间&#xff0c;病历信息展示&#xff08;使用Treeview表格&#xff09;&#xff0c;病历信息查询…

MCP底层协议完整通信过程

2025 年是智能体的元年, 也注定是智能体集中爆发的一年! 两个互联领域的重大挑战: 第一、 Agent 与 Tools (工具)的交互 Agent 需要调用外部工具和 API

docker:制作镜像+上传镜像+拉取镜像

1.dockerfile制作镜像 示例内容&#xff1a; 1.创建一个index.js的文件 console.log("hello world")2.在相同目录下创建名为dockerfile的文件 FROM node:alpine COPY index.js /index.js CMD node /index.js3.构建镜像 docker build -t minterra/hello-docker . …

docker制作python大模型镜像(miniconda环境),工程改造记录

**环境说明&#xff1a;**从系统镜像开始打造python大模型镜像&#xff0c;之前是人工手动装的方式&#xff0c;并且模型和依赖在公网中&#xff0c;对于离线交付环境不太友好&#xff0c;所以打造的离线化交付版本 Dockerfile: FROM centos:7.9 ENV PYTHONIOENCODINGutf-8 E…

Rust中避免过度使用锁导致性能问题的策略

一、引言 在 Rust 多线程编程中&#xff0c;锁是实现线程同步的重要工具&#xff0c;它可以防止多个线程同时访问和修改共享数据&#xff0c;从而避免数据竞争和不一致的问题。然而&#xff0c;过度使用锁会带来严重的性能问题&#xff0c;如锁竞争导致的线程阻塞、上下文切换…