如何用VBA在名称后缀为(M)的工作表上执行指定If判断逻辑?
问题分析与修正方案
原宏失效的核心原因
- 依赖
Select/Selection操作:VBA中这类操作依赖当前激活的工作表,循环遍历工作表时容易出现激活状态不匹配的问题,导致代码执行异常。 AutoFill参数错误:使用xlFillValues会填充G8的计算值而非公式本身,后续又执行粘贴值操作,等于没有实际修改,这是宏无效果的关键原因。- 冗余操作:
ws.Range("A8").Select属于无意义操作,且会干扰工作表激活状态。
修正后的代码(匹配需求:复制G8公式到M8)
如果你的需求是仅将G8的公式复制到M8单元格,使用以下代码:
Sub MondayCalc() Application.ScreenUpdating = False Dim ws As Worksheet For Each ws In ActiveWorkbook.Worksheets ' 匹配后缀为"(M)"的工作表 If ws.Name Like "*(M)" Then ' 检查G8是否包含公式 If ws.Range("G8").HasFormula Then ' 直接将G8的公式赋值给M8 ws.Range("M8").Formula = ws.Range("G8").Formula End If End If Next ws Application.ScreenUpdating = True End Sub
修正后的代码(匹配原宏意图:填充公式到G8:M8后转值)
如果你的实际意图是将G8的公式填充到H8:M8,再把这些单元格转为值,使用以下代码:
Sub MondayCalc() Application.ScreenUpdating = False Dim ws As Worksheet Dim targetRange As Range For Each ws In ActiveWorkbook.Worksheets If ws.Name Like "*(M)" Then If ws.Range("G8").HasFormula Then ' 定义目标区域:G8到M8 Set targetRange = ws.Range("G8:M8") ' 填充公式到整个区域(使用FillRight,保留公式) ws.Range("G8").AutoFill Destination:=targetRange, Type:=xlFillDefault ' 直接将区域转为值,无需复制粘贴 targetRange.Value = targetRange.Value End If End If Next ws Application.ScreenUpdating = True End Sub
关键优化点
- 移除
Select/Selection:直接通过单元格对象操作,避免激活状态带来的问题,代码更稳定高效。 - 明确公式传递方式:使用
.Formula属性直接赋值公式,或用xlFillDefault填充公式而非值。 - 适配动态工作表:
For Each ws In ActiveWorkbook.Worksheets会自动遍历所有工作表,新增/删除工作表无需修改代码。 - 恢复屏幕更新:代码末尾重新开启
ScreenUpdating,避免Excel界面卡顿。
内容的提问来源于stack exchange,提问作者Nick Speake
相关产品推荐
相关产品推荐

