Solver VBA代码运行时将目标单元格设为自身引用问题求助
问题:Solver将含公式单元格改为自身引用
以下代码会把所有检测到的含公式单元格修改为自身引用。该现象似乎出现在SolverOK代码段中——它能在Solver对话框里正确选中要修改的单元格,但会清除单元格内原有公式。
Private Sub SolverSolver() Dim ws1 As Worksheet Dim lRow As Long Dim cell As Range Set ws1 = Worksheets("Sheet1") ws1.Activate lRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'clears h2 to h4 because salarytotals puts the total for the first employee number there 3 times...idk why lol ws1.Range("H2:H4").ClearContents For Each cell In ws1.Range(Range("H2"), Range("H" & lRow)) If cell.HasFormula = True Then SolverOK setCell:=cell, _ MaxMinVal:=3, _ ValueOf:=70, _ byChange:=Range("C2:C" & Range("C2").End(xlDown).Row) SolverSolve UserFinish:=True End If Next cell End Sub
问题原因
- Solver默认行为:当使用
SolverOK指定含公式的单元格作为SetCell,执行SolverSolve后,Solver会默认覆盖目标单元格的公式;若求解过程出现异常(比如无解),可能错误生成自身引用的循环公式。 - 未限定工作表的Range引用:代码中
Range("H2")、Range("C2")这类写法未绑定到ws1,若运行中工作表切换,会导致引用错误,间接引发Solver的异常行为。
修复方案
提前保存目标单元格的原公式,执行Solver后恢复公式;同时限定所有Range引用到指定工作表,避免跨表错误:
Private Sub SolverSolver() Dim ws1 As Worksheet Dim lRow As Long Dim cell As Range Dim originalFormula As String Dim changeRange As Range Set ws1 = Worksheets("Sheet1") lRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row ' 清除H2:H4内容,因salarytotals会重复计算第一个员工总计三次 ws1.Range("H2:H4").ClearContents ' 提前定义可变单元格范围,避免重复计算 Set changeRange = ws1.Range("C2:C" & ws1.Range("C2").End(xlDown).Row) For Each cell In ws1.Range(ws1.Range("H2"), ws1.Range("H" & lRow)) If cell.HasFormula = True Then ' 保存单元格原公式 originalFormula = cell.Formula ' 配置Solver参数,所有Range均绑定到ws1 SolverOK SetCell:=cell, _ MaxMinVal:=3, _ ValueOf:=70, _ ByChange:=changeRange ' 执行Solver SolverSolve UserFinish:=True ' 恢复原公式 cell.Formula = originalFormula End If Next cell End Sub
关键说明
- 保存并恢复公式:通过变量存储原公式,Solver运行后重新写入,确保目标单元格的公式不被覆盖。
- 限定工作表引用:所有
Range调用均通过ws1前缀限定,避免因工作表切换导致的引用错误。 - 若仍出现自身引用,可检查Solver的求解状态(添加
SolverFinish回调或判断返回值),确认是否存在无解的情况。
内容的提问来源于stack exchange,提问作者j.hyer116
相关产品推荐
相关产品推荐

