MICROSOFT

EP04. “Bills and Coins 钞票与硬币找零计算”

首页 Microsoft 工具 Excel · VBA · Events · EP04
约 5 分钟· #EP04#Excel#Events
🔒 登录后可标记已读
  • 用 Worksheet 的 Change 事件 + 双层循环,实现「输入一个金额,自动算出要用几张 / 几个各面额的钞票和硬币才能凑出这个金额」的找零计算器
  • 面额可以套用马来西亚令吉(RM)的实际纸币/硬币面额
  • 前置知识:EP01 的事件绑定方法和基本的 For / Do While 循环
  • 学完能理解怎么用 Do While 循环反复扣减金额来做进位分解

重点内容


适用版本

桌面版通用(Excel 365 / 2021 / 2019 等)。


表格结构

  • A 列(A5:A16):从大到小列出各种面额(钞票、硬币,依实际货币面额而定)
  • B 列(B5:B16):对应每个面额需要用几张 / 几个(由程序算出)
  • B2:输入要拆解的金额

绑定 Change 事件

  1. 打开 VBE,双击 Sheet1
  2. 左边下拉选 Worksheet,右边下拉选 Change

完整代码

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim amount As Double, i As Integer

    If Target.Address = "$B$2" Then
        amount = Range("B2").Value
        Range("B5:B16").Value = ""

        For i = 5 To 16
            Do While amount >= Cells(i, 1).Value
                Cells(i, 2).Value = Cells(i, 2).Value + 1
                amount = amount - Cells(i, 1).Value
            Loop
        Next i
    End If
End Sub
  • If Target.Address = "$B$2" Then:只有当用户改动 B2 这个单元格时才执行下面的逻辑,避免改动其他单元格也误触发
  • 先把 B5:B16(上一次计算的结果)清空
  • For i = 5 To 16:从最大面额(第 5 行)依序走到最小面额(第 16 行)
  • Do While amount >= Cells(i, 1).Value:只要剩余金额还大于等于目前这个面额,就持续扣减——这是这个例子的核心技巧,用 Do While 而不是简单除法取整,逻辑更直观
  • 每扣一次,对应面额的数量(B 列)加 1,剩余金额减掉这个面额

实操示例

在 B2 输入一个金额(例如 RM 178.65),观察 B5:B16 是否自动算出对应各面额需要的数量,加总后等于这个金额。A 列可以照马来西亚实际流通面额填:RM100、RM50、RM20、RM10、RM5、RM1、50 sen、20 sen、10 sen、5 sen。

[截图:B2 输入金额后,B5:B16 自动算出的各面额钞票/硬币数量明细]


学完你会

  • ✅ 用 Target.Address 判断这次改动是不是发生在指定单元格,避免其他改动误触发
  • ✅ 用 Do While 循环做「贪心法」找零:从大面额开始,能扣就一直扣
  • ✅ 知道金额类变量要用 Double 而不是 Integer,避免角分被截断

常见错误

  • A 列的面额顺序如果不是「从大到小」排列,Do While 逻辑会算错(要先用大面额扣减,才不会出现大量小面额堆积)
  • amount 用 Integer 声明会导致小数金额(角分)被截断,这里特意用 Double
  • 每次改 B2 前忘记清空 B5:B16,结果会跟旧结果叠加出错(这个例子已经处理了,但自己改写时容易漏掉这步)

Sources

Blog / Website:

  1. Bills and Coins