ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VBA宏指令写的方法突然不能用了:用TaoToken统一Key排查ADODB连接SQL Server的Recordset报错

VBA宏指令写的方法突然不能用了:用TaoToken统一Key排查ADODB连接SQL Server的Recordset报错 1. VBA宏里ADODB连SQL Server突然失效Recordset报错的真实场景Excel 里跑了好几年的 VBA 宏某天早上打开就报错这种体验做自动化测试的人基本都遇到过。我手上这个项目就是典型一个用 VBA 写的雕刻查重工具逻辑很简单——读 F5 单元格的 SN去 SQL Server 的CarveSN表里查这个 SN 有没有被雕刻过有就弹「已雕刻」没有就弹「可以继续雕刻」。代码是前任同事留下的跑了很久都没事最近系统更新后开始出问题。表面看代码没毛病ADODB.Connection打开连接ADODB.Recordset执行 SQL然后CInt(Conn.Execute(intSQL)(0))拿第一列的值做判断。但实际运行时fqty是个未定义的值跟 0 比较直接异常。调试时发现Rst只有在Open那一行有值连接状态是 1已连接但记录集本身的状态不对还伴随两个报错当前记录集不支持更新。SQLSERVER错误 BOF 或 EOF 中有一个是「真」或者当前的记录已被删除所需的操作要求一个当前的记录。这两个报错指向的是同一个根因Recordset 的光标类型和锁定方式跟你的操作不匹配。Rst.Open intSql, Conn这种最简写法用的是默认光标仅向前、只读当你试图用Conn.Execute的返回值去做CInt转换或者用Rst.RecordCount统计行数时默认光标根本不支持这些操作。网上搜到的说法五花八门有说数据库没主键导致映射失败的有说光标不对应的其实核心就三处连接字符串、认证方式、网络端点。这篇就按这个真实场景把排查路径拆成三步先用最小测试宏确认 ADODB 本身能不能通再逐项替换连接字符串和认证参数最后用 TaoToken 统一 Key 通道验证网络端点连通性。适合所有在 Excel VBA 里维护老宏、被 ADODB 报错卡住的同学。2. TaoToken 统一 Key 通道给 ADODB 排查加一层可控变量排查 ADODB 报错最头疼的地方在于变量太多。连接字符串、驱动版本、认证方式、网络端点、SQL Server 配置任何一个出问题都表现为「Recordset 打不开」。你改一个参数报错变了但不知道是改对了还是碰巧绕过了。所以我习惯在排查前先引入一个可控的中间层把「网络端点」这个变量单独拎出来验证。TaoToken 在这里的角色就是一个统一 Key 通道。它本身是面向大模型 API 调用的聚合入口但它的 API Key 机制和 Base URL 结构正好可以用来做一件事验证你这台机器到外部端点的网络连通性和认证链路是否正常。当你的 VBA 宏连 SQL Server 报错时先用一个已知可用的 Key 通道测一下网络就能快速排除「是不是公司网络策略变了」「是不是某个端点被拦了」这类问题。具体来说TaoToken 提供两个地址官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 端点https://taotoken.net/api这个不加 UTM直接用于请求你可以在 TaoToken 控制台创建一个 API Key然后用它去请求模型对话接口。如果这个请求能通说明你的机器出网正常、DNS 解析正常、TLS 握手正常那 VBA 连 SQL Server 的问题就大概率出在连接字符串或认证方式上而不是网络。如果这个请求也不通那先解决网络问题别在 VBA 代码里瞎改。这个思路的关键是把「网络端点」和「代码逻辑」解耦。ADODB 报错时你分不清是 SQL 写错了、连接串写错了、还是网络断了。引入一个独立的 Key 通道做对照就能把排查范围缩小一半。创建 Key 的路径进 TaoToken 控制台 → API Keys → 新建 Key。拿到 Key 后先别急着写 VBA用 curl 或 Postman 测一下模型对话接口确认返回正常。这一步花两分钟能省后面半小时的瞎猜。注意TaoToken 的 Key 是用于 API 调用的不是数据库密码。它的作用是验证网络和认证链路不是替代 SQL Server 的登录凭据。两者不要混用。3. 可复制的 ADODB 最小测试宏与连接参数对照表排查的第一步是写一个最小测试宏把变量降到最少。下面这段代码可以直接贴进 Excel 的 VBA 编辑器AltF11 → 插入模块改掉SERVER、DATABASE、UID、password四个值就能跑。Sub TestADODBConnection() Dim Conn As Object Dim Rst As Object Dim sqlStr As String Dim fqty As Long Set Conn CreateObject(ADODB.Connection) Set Rst CreateObject(ADODB.Recordset) 连接字符串先用最简形式确认能连上 Conn.Open DRIVERSQL Server;SERVER你的服务器IP;DATABASE你的库名;UID你的账号;PASSWORD你的密码 关键设置客户端光标让 Recordset 支持 RecordCount 和字段访问 Rst.CursorLocation 3 adUseClient sqlStr SELECT COUNT(*) AS Total FROM [HTDRepair].[dbo].[CarveSN] WHERE SNTEST001 Debug.Print sqlStr 用 adOpenStatic adLockReadOnly只读统计场景最稳 Rst.Open sqlStr, Conn, 3, 1 adOpenStatic3, adLockReadOnly1 If Not Rst.EOF Then fqty Rst.Fields(Total).Value Else fqty 0 End If Debug.Print 查询结果 fqty fqty If fqty 0 Then MsgBox 该SN已雕刻, 48, 雕刻查重 Else MsgBox 该SN未雕刻可以继续雕刻, 48, 雕刻查重 End If Rst.Close Conn.Close Set Rst Nothing Set Conn Nothing End Sub这段代码跟原代码的区别有三处每一处都对应一个常见坑第一处是Rst.CursorLocation 3。这个值对应adUseClient意思是把光标放在客户端。默认情况下 ADODB 用的是服务端光标服务端光标对RecordCount的支持取决于驱动版本和 SQL Server 配置经常返回 -1。改成客户端光标后RecordCount和字段访问都稳定了。第二处是Rst.Open sqlStr, Conn, 3, 1。第三个参数3是adOpenStatic静态光标适合只读统计第四个参数1是adLockReadOnly只读锁定。原代码只传了两个参数用的是默认的仅向前光标这种光标不支持RecordCount也不支持随机字段访问。第三处是把CInt(Conn.Execute(intSQL)(0))换成了Rst.Fields(Total).Value。Conn.Execute返回的也是一个 Recordset但它的光标类型是固定的仅向前只读而且(0)这种索引访问在字段名不明确时容易出错。直接用Rst.Fields(Total)按字段名取值可读性和稳定性都更好。连接字符串的参数对照表如下排查时逐项核对参数常见写法排查要点DRIVERSQL Server老驱动兼容性好但功能少可换SQL Server Native Client 11.0SERVERIP 或 主机名\实例名带实例名时用反斜杠如192.168.1.10\SQLEXPRESSDATABASE库名不要带方括号除非库名有空格UID登录名如果用 Windows 认证这项和 PASSWORD 都去掉PASSWORD密码密码含分号时要用引号包裹如PWDab;cdTrusted_ConnectionYesWindows 认证时加这项替代 UID/PASSWORD如果你要用 TaoToken 的 Key 通道做网络对照可以在同一个宏里加一段 HTTP 请求测试。VBA 里用MSXML2.XMLHTTP发请求Sub TestTaoTokenConnectivity() Dim http As Object Set http CreateObject(MSXML2.XMLHTTP) Dim url As String url https://taotoken.net/api/v1/chat/completions http.Open POST, url, False http.setRequestHeader Content-Type, application/json http.setRequestHeader Authorization, Bearer 你的TaoTokenKey Dim body As String body {model:gpt-4o-mini,messages:[{role:user,content:ping}]} http.send body Debug.Print HTTP 状态码: http.Status Debug.Print 返回内容: Left(http.responseText, 200) End Sub如果这段返回 200 并且有正常内容说明你的机器出网、DNS、TLS 都没问题VBA 连 SQL Server 的报错就聚焦在连接字符串和认证上。如果返回 401说明 Key 不对如果超时说明网络端点有问题。4. 验证请求与成功结果从报错到正常返回的完整过程跑最小测试宏的时候建议把Debug.Print打开VBA 编辑器里 CtrlG 打开立即窗口每一步都看输出。正常流程应该是这样的第一步Conn.Open执行后如果连接字符串正确不会报错。如果报「[Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server 不存在或访问被拒绝」说明 SERVER 参数或网络有问题。如果报「用户 xxx 登录失败」说明 UID/PASSWORD 不对。第二步Rst.Open执行后如果光标设置正确Rst.RecordCount会返回实际行数这里是 1因为 COUNT(*) 只返回一行。如果还是报「当前记录集不支持更新」说明光标类型没设对检查CursorLocation和Open的第三、四个参数。第三步Rst.Fields(Total).Value取值正常应该返回一个整数。如果报「BOF 或 EOF 中有一个是真」说明查询结果为空这时候要先判断Rst.EOF再取值。第四步fqty跟 0 比较正常输出「该SN未雕刻可以继续雕刻」或「该SN已雕刻」。我实测下来原代码最大的问题就是Conn.Execute(intSQL)(0)这个写法。Conn.Execute返回的 Recordset 是仅向前只读的(0)索引访问的是当前行的第一个字段但如果没有先MoveFirst或者结果集为空这个访问就会失败。而且CInt转换一个空值或 Null 值会直接抛异常。改成Rst.Fields(Total).Value并加EOF判断后问题就消失了。用 TaoToken 做网络对照时预期返回是这样的{ id: chatcmpl-xxx, object: chat.completion, created: 1700000000, model: gpt-4o-mini, choices: [ { index: 0, message: { role: assistant, content: pong }, finish_reason: stop } ] }看到choices数组里有内容就说明 Key 通道正常。如果返回{error:{message:Invalid API key,type:invalid_request_error}}那就是 Key 写错了或者过期了去 TaoToken 控制台重新生成一个。这一步的价值在于当你 VBA 连 SQL Server 报错时先用这个 Key 通道测一下如果 Key 通道正常那问题 100% 在 VBA 代码或 SQL Server 配置上不用怀疑网络。如果 Key 通道也不正常那先修网络别动 VBA 代码。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 对照排查过程中遇到的报错按出现频率排一下每个都给出对照原因和修法。401 Unauthorized。这个在 TaoToken Key 通道测试里最常见原因是 Authorization 头里的 Key 不对。检查三点Key 有没有复制完整前后不能有空格、Bearer 后面有没有空格、Key 有没有过期。在 TaoToken 控制台的 API Keys 页面可以重新生成。VBA 里拼接字符串时容易多一个空格用Trim()包一下。local proxy failed。这个报错通常出现在公司网络环境里意思是本地代理配置有问题。VBA 的MSXML2.XMLHTTP默认会读取系统代理设置如果系统代理指向了一个不可用的地址就会报这个。修法是改用ServerXMLHTTP它不读系统代理Set http CreateObject(MSXML2.ServerXMLHTTP.6.0)或者在http.Open之前设置http.setProxy 2, 直接连接。注意这里说的是本地代理配置问题不是让你去用什么特殊网络工具公司内网环境该走什么通道就走什么通道。reading choices 报错。这个一般出现在解析 TaoToken 返回的 JSON 时。VBA 没有内置 JSON 解析器如果你用字符串截取的方式取choices字段很容易因为返回格式变化而报错。建议用ScriptControl或者引入VBA-JSON库来解析。简单场景下用InStr定位content再截取也行但要处理转义字符。OAuth 相关报错。如果你在 VBA 里调用了需要 OAuth 认证的接口报invalid_grant或invalid_client检查 client_id、client_secret、refresh_token 三个值。OAuth 的 token 有有效期过期后要用 refresh_token 换新的。VBA 里做 OAuth 比较麻烦建议把 token 刷新逻辑放在外部脚本里VBA 只读结果。ADODB 报「未找到提供程序」。这是驱动没装或位数不匹配。Excel 是 32 位的ODBC 驱动也要装 32 位的Excel 是 64 位的驱动装 64 位的。在「ODBC 数据源管理器」里看「驱动程序」标签页确认SQL Server驱动存在。如果只有SQL Server Native Client把连接字符串里的DRIVERSQL Server改成DRIVERSQL Server Native Client 11.0。Recordset 的 RecordCount 返回 -1。这是光标类型问题回到第 3 节设置Rst.CursorLocation 3并用adOpenStatic打开。如果还是 -1说明数据量太大客户端光标加载慢可以改用SELECT COUNT(*)单独统计。BOF 或 EOF 为真。查询结果为空。加If Not Rst.EOF Then判断或者在 SQL 里用COUNT(*)保证至少返回一行。原代码用SELECT *然后取第一行结果为空时就报这个错。改成SELECT COUNT(*)后永远返回一行不会为空。「当前记录集不支持更新」。这个报错跟你的操作有关。如果你只是查询用adLockReadOnly如果要更新用adLockOptimistic并确保表有主键。原代码里Rst.Open intSql, Conn用的是默认锁定然后试图用Conn.Execute的返回值做更新判断光标和锁定都不匹配。统一改成只读查询 COUNT(*)就绕开了。6. 用 TaoToken 统一 Key 通道收尾把排查变成可复用的流程这套排查流程跑通之后我把它固化成了一个习惯任何 VBA 连数据库的报错先跑最小测试宏再跑 Key 通道对照最后才动业务代码。最小测试宏确认 ADODB 本身能通Key 通道确认网络端点正常两个都过了问题就一定在业务逻辑或 SQL 语句上。TaoToken 在这里的价值不是替代 SQL Server而是提供一个独立的、可控的认证和网络验证通道。它的 API Key 机制简单直接创建和验证都快适合在排查时快速排除网络变量。你可以在 TaoToken 控制台管理 Key在模型对话页面测试连通性在接入文档里查具体的请求格式。具体操作路径创建 Key进 TaoToken 控制台 → API Keys → 新建测试连通用模型对话接口发一个 ping看返回查文档接入文档里有完整的请求示例和参数说明长期编码或 Agent 场景可以看 Coding Plan把 Key 通道用在日常开发流程里回到最初的问题VBA 宏里 ADODB 连 SQL Server 的 Recordset 报错根因就三处——连接字符串的驱动和认证参数、Recordset 的光标类型和锁定方式、网络端点的连通性。用最小测试宏锁定代码问题用 TaoToken Key 通道锁定网络问题两边一夹报错就无处可藏。原代码里Conn.Execute(intSQL)(0)和CInt的写法是典型的「能跑但脆弱」改成SELECT COUNT(*)Rst.Fields(Total).ValueEOF判断后稳定性和可读性都上了一个台阶。
返回列表