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
英文地址,請注明出處:http://en.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;如鎖競爭導致的線程阻塞、上下文切換…