报价数据需要随机上浮,但不能让下面规格的价格低于上面规格。这个需求看起来小,却很好地体现了 AHK + Excel COM 的价值:读取选区数组,按业务规则修改,再一次性写回。

这类脚本不只是“改几个单元格”,而是把人工规则固化成工具。

一、先限制选区

为了避免误操作,脚本应该只允许用户选择连续的一列数据。报价上浮通常是一列价格,如果选了多列,规则就不清楚了。

#Requires AutoHotkey v1.1
#NoEnv
#SingleInstance Force

F12::
    xl := ComObjActive("Excel.Application")
    sel := xl.Selection

    if !RegExMatch(sel.Address, "i)^(\$[A-Z]+)\$\d+:\1\$\d+$")
    {
        MsgBox, 请先选择连续的一列数据
        return
    }

    arr := sel.Value
    total := sel.Count
return

先判断选区,是实战脚本里很重要的习惯。不要让脚本在用户选错区域时继续执行。

二、按随机比例上浮

AHK v1 的 Random 可以按给定上下限取随机数。比如 1.03 到 1.08,就是随机上浮 3% 到 8%。

minRate := 1.03
maxRate := 1.08

Random, rate, %minRate%, %maxRate%
arr[1, 1] := arr[1, 1] * rate

实际工具可以用 GUI 让用户输入上下限。默认值不宜太激进,尤其是价格、工程量、报价表这类数据。

三、保持后续数据不低于上一行

素材里的核心思路是:从上往下处理,如果下一行原值太低,就动态提高随机下限,避免上浮后破坏递增关系。

minRate := 1.03
maxRate := 1.08

Random, rate, %minRate%, %maxRate%
arr[1, 1] := arr[1, 1] * rate

Loop, % total - 1
{
    i := A_Index + 1
    if !arr[i, 1]
        continue

    needRate := arr[i - 1, 1] / arr[i, 1]
    if (needRate > minRate)
        Random, rate, %needRate%, %maxRate%
    else
        Random, rate, %minRate%, %maxRate%

    arr[i, 1] := arr[i, 1] * rate
}

sel.Value := arr

这段逻辑的重点不是随机,而是“随机也要受业务约束”。否则脚本虽然自动化了,却可能生成不合理数据。

四、为什么用数组而不是逐格写

选区数据一次性读入 arr,处理完再写回 sel.Value,速度和稳定性都更好。数据量越大,越不应该逐格 COM 调用。

五、实战扩展

  • 加入 GUI 输入上下限,并校验必须是数字。
  • 处理前备份原选区到新列或新工作表。
  • 允许用户选择是否保留小数位。
  • 增加撤销方案,例如另存一份副本。
  • 对空值、文本、负数做单独提示。

结语

这个案例很适合新手理解“AHK 不是只能按键鼠”。真正有价值的办公脚本,往往是把 Excel 选区读成数组,再根据业务规则处理。报价上浮、批量折扣、价格校正、数量修正,都可以沿用这套思路。

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。