AB
AiBoss
チュートリアル

把 AI 从日常 Excel 操作里撤出来:用关键词先击匹配让宏直接跑

チュートリアル

把 AI 从日常 Excel 操作里撤出来:用关键词先击匹配让宏直接跑

与其每次都让 AI 直接操作 Excel,不如把 AI 关进「锻造场」只负责写宏,日常现场用关键词先击匹配直接调用宏。本文讲清这套做法的思路、前置条件、关键词注释的写法、匹配函数的实现、执行入口的改造,以及手顺书盘点与分发方式,并给出可跑通的最小示例与已知限制。

用 AI 直接操作 Excel 的做法,在演示里很漂亮,放到日常业务里却常常卡在三件事上:慢、依赖网络、发不出去。每次让模型推着表格走,都要等它一轮轮推理;同事的电脑上没有 Python 环境、没有 API 配置、没有登录好的命令行,再精巧的流程也带不过去。本文讲的是一套反向的配置:AI 只在「锻造场」里干活,负责把宏打出来;现场只保留一个关键词先击匹配的入口,用一句话直接命中已经锻好的宏。适合手头已经积累了一批 VBA 宏、又想让 AI 退到幕后的人;也适合正在纠结「要不要把 AI 接进表格流程」的团队做一次成本对照。它不解决需要人来判断的业务问题,也不适合结构完全没见过的新表型。

准备工作

这套做法对环境的依赖极低,但前期需要把几样东西备齐,否则后面的匹配函数没有可匹配的对象。

  • 一个已经装了宏的 Excel 工作簿或加载项。最终要交付给同事的是一个 .xlam 加载项文件,所以宏应当集中放在标准模块里,而不是散落在各个工作表的代码区。
  • 一批经过测试的宏。素材里的做法是在一个「表整理」模块里养了六十七本宏,每一本都经过多张测试表的撞击。数量不是门槛,质量才是:没有测过的宏进了货架,先击匹配只会把错误执行得更快。
  • 在每本宏的头部写一行关键词注释。这是整套机制的接口。格式是固定的前缀加若干用竖线分隔的词,例如:
' 依頼の語: 二重計上|二重払い|同日同額|同じ日付|同じ金額|重複
Sub 同日同額の二重計上を一覧にする()
    ' ...
End Sub

前缀后面跟的词,就是将来用户可能说出口的说法。写注释这一步不需要 AI,需要的是对业务语言的熟悉——把同事平时怎么描述这件事,原样记下来。

  • 一个可以调用 AI 写宏的通道。只在锻造阶段用得到,用来生成新宏、补测试用例。日常执行阶段完全不需要它,也不需要网络。
  • 一个执行入口。素材里用的是自建加载项上的一个执行按钮,按钮背后原本是把请求转给 AI 的逻辑。改造点就在这个按钮的头部。

需要提醒的是,加载项的保存格式、宏的签名与信任设置、以及不同 Excel 版本对 Application.Run 的支持细节,各版本之间可能有差异,具体以官网当前信息为准。

操作步骤

第一步:给货架上的每本宏补上关键词注释

先不要动代码逻辑,只做一件事——遍历现有模块,在每本宏的 Sub 语句上方补一行注释。关键词的选取原则是「用户会怎么说」,而不是「这个宏技术上叫什么」。同一个宏可以挂多个近义说法,用竖线分隔。词与词之间不要留多余空格,避免匹配时被空格干扰。

这一步做完,货架上的宏就从「只有名字」变成了「名字加一组触发词」。后面所有匹配都只读这一行注释,宏体本身不需要任何改动。

第二步:写匹配函数,按命中词的总长度打分

核心函数只有三十几行,职责是:扫描所有模块里带关键词注释的宏,把请求文本中出现的词挑出来,返回得分最高的那个宏名。打分的依据是命中词的长度之和——长词得分高,这样「二重计上」这种具体说法就不会输给「合计」这种泛词。

函数的大致结构如下(示意,具体实现按自己的模块组织方式调整):

Function 先击候補(ByVal 依頼文 As String) As String
    Dim 最良 As String, 最高点 As Long
    Dim 構成要素 As Object
    Set 構成要素 = ThisWorkbook.VBProject.VBComponents

    Dim 構成 As Object, 行 As Variant, 語 As Variant
    For Each 構成 In 構成要素
        If 構成.Type = 1 Then ' 標準モジュール
            Dim コード行 As Variant
            コード行 = Split(構成.CodeModule.Lines(1, 構成.CodeModule.CountOfLines), vbCrLf)
            Dim 現在のマクロ As String, 語リスト As String
            For Each 行 In コード行
                If InStr(行, "' 依頼の語:") > 0 Then
                    語リスト = Trim(Replace(行, "' 依頼の語:", ""))
                ElseIf InStr(行, "Sub ") = 1 Then
                    現在のマクロ = 抽出マクロ名(行)
                    Dim 点 As Long: 点 = 0
                    For Each 語 In Split(語リスト, "|")
                        If Len(語) > 0 And InStr(依頼文, 語) > 0 Then 点 = 点 + Len(語)
                    Next 語
                    If 点 > 最高点 Then 最高点 = 点: 最良 = 現在のマクロ
                End If
            Next 行
        End If
    Next 構成
    先击候補 = 最良
End Function

要点有三个:只扫标准模块;遇到关键词注释就先记下词表,遇到 Sub 行才结算一次得分;得分严格大于当前最高分才替换,保证结果稳定。读取 VBProject 需要在信任中心勾选「信任对 VBA 工程对象模型的访问」,否则会直接报错。

第三步:改造执行按钮,先击再兜底

执行入口原本的逻辑是「把输入框的文字交给 AI」。改造后,在原有逻辑之前插入十几行:先调用匹配函数拿候选,拿到就弹一次确认,用户点「是」就用 Application.Run 直接执行并结束;点「否」或者没匹配到,才继续走原来的 AI 通道。

Private Sub 実行ボタン_Click()
    Dim 依頼 As String: 依頼 = 入力欄.Value
    Dim 候補 As String: 候補 = 先击候補(依頼)

    If Len(候補) > 0 Then
        If MsgBox("「" & 候補 & "」で実行します", vbYesNo) = vbYes Then
            Application.Run 候補
            Exit Sub
        End If
    End If

    ' ここから下は従来どおり AI へ流す
    既存のAI呼び出し 依頼
End Sub

确认框只弹一次,是刻意的设计:它让「先击」保持可撤销,同时不把交互成本拉高。兜底分支的存在意味着,即使匹配失败,用户也只是多等几十秒,不会得到错误结果。

第四步:用真实说法做一轮回归

机制装好之后,拿平时真的会说出口的句子去撞一遍。素材里试过的几组对应关系可以作为参照:

输入的说法命中的宏
二重计上を一覧にして同日同額の二重計上を一覧にする
スパークラインを足してスパークライン折れ線を足す
ウォーターフォールにしてウォーターフォールグラフを作る
度数分布表を右に作って度数分布表を右に作る
年齢と勤続年数を足して年齢と勤続年数を足す
こんにちは(命中なし,转 AI)

最后一行的意义和前面几行一样重要:不命中时必须干净地落到兜底分支,而不是硬凑一个宏去执行。

第五步:盘点手顺书,把能烧的烧成宏

如果之前为了教 AI 做事,写过一批手顺书,这时候把它们摊开逐本过一遍。判断标准很简单:如果一本手顺书已经写清了开始条件、步骤和完成条件,说明中间已经没有需要人临场判断的余地,那它就可以直接烧成宏。素材里二十本手顺书的分布是这样的:

分类本数内容举例
货架上已有7月度汇总表、重复检查、带图报告、打印收尾、空白处理
按顺序调用现有宏即可7数据清洗、表格体检、公式审计、CSV 导入后的整形
确实需要新写6交接准备、图形与图片整理、命名区域整理

新写的六本里,还有三本在别的模块里有相近处理,可能只需调用即可。也就是说,真正要新锻的只有十三本左右。把这十三本写出来、补上关键词注释,手顺书就可以全部清空。

一个完整示例

下面走一遍从零到能跑的最小路径,假设货架上只有一本宏。

1. 在标准模块里放一本宏,并补上关键词注释。

' 依頼の語: 二重計上|二重払い|同日同額|同じ日付|同じ金額|重複
Sub 同日同額の二重計上を一覧にする()
    Dim ws As Worksheet: Set ws = ActiveSheet
    Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    Dim i As Long, j As Long
    Dim outRow As Long: outRow = lastRow + 2
    ws.Cells(outRow - 1, 1).Value = "重複候補"
    For i = 2 To lastRow - 1
        For j = i + 1 To lastRow
            If ws.Cells(i, 1).Value = ws.Cells(j, 1).Value _
               And ws.Cells(i, 2).Value = ws.Cells(j, 2).Value Then
                ws.Cells(outRow, 1).Value = ws.Cells(i, 1).Value
                ws.Cells(outRow, 2).Value = ws.Cells(i, 2).Value
                outRow = outRow + 1
            End If
        Next j
    Next i
End Sub

2. 把匹配函数放进同一个模块。直接使用前面第二步的 先击候補,注意信任中心的「信任对 VBA 工程对象模型的访问」必须打开,否则读取 VBProject 会失败。

3. 放一个按钮和输入框。按钮的点击事件使用第三步的代码,把 入力欄 换成实际输入框的名称。

4. 测试。在输入框里写「二重計上を一覧にして」,点执行。应当弹出一次确认框,点「是」后表格里出现重複候補区块,整个过程不产生任何网络请求。再输入「こんにちは」,应当不弹确认框,直接落到兜底分支。

5. 保存为加载项。把工作簿另存为 .xlam,在同事的电脑上加载这个文件,宏即可使用,对方不需要 Python、不需要 API 密钥、不需要登录任何命令行。

注意事项

  • 关键词匹配有天然边界。先击靠的是词面命中,说法离货架上的词太远就会落空。落空的代价只是「本来一秒结束的事变成几十秒」,不会产生错误结果,因为兜底分支还在。
  • 需要人来判断的业务,宏做不了。「这个数字该归到哪个科目」这类依赖上下文的问题,既不该交给宏,也不该整个甩给 AI,它属于人的职责范围。
  • 完全没见过的新表型,宏无能为力。这时候才需要回到锻造场,让 AI 打一本新宏出来,测试通过后再挂上关键词注释进货架。
  • 读取 VBProject 需要额外授权。信任中心的对应选项未开启时,匹配函数会直接报错,这是部署到新机器上最容易踩的坑。
  • 宏的测试强度决定这套机制的上限。先击把执行速度提到了近乎瞬时,也把「未测过的宏」的风险放大了同样的倍数。进货架前用多张测试表撞击,是这套做法不可省略的一环。
  • 关于加载项格式、信任设置与各版本 Excel 的行为差异,以官网当前信息为准。