VBA CommandButton_Click编译错误:Object required求助
嘿,我来帮你搞定这个编译错误,顺便把代码优化得更可靠——作为VBA新手,这些细节坑确实容易踩,咱们一步步来:
先明确核心错误原因
Compile error: Object required的直接诱因:你用了Set LastRow = ...,但LastRow是Long数值类型(用来存行号),Set关键字只能给对象类型(比如Worksheet、Range)赋值,直接去掉Set就能解决这个编译错误!
但你的代码还有其他几个关键问题,会导致即使编译通过也运行出错,咱们一起修正:
其他关键问题&修正思路
避免使用Select/Selection,直接引用对象:
用Select切换工作表容易导致对象引用混乱,直接通过工作表名称(比如Sheets("Today_Data"))来操作单元格,代码更稳定。Range对象的错误写法:
你用Range(Cells(nRow,1), Cells(nRow,2), ...)这种多参数写法是错误的,Range的多单元格引用应该用Resize、连续地址或者Union函数,比如选第nRow行的1-4列,直接写Sheets("Today_Data").Cells(nRow, 1).Resize(1, 4)更简洁。PasteSpecial的用法错误:
PasteSpecial不能直接带Destination参数这么用,应该先定位目标区域,再调用PasteSpecial;更高效的方式是直接赋值(不用复制粘贴),速度更快还不容易出错。未限定工作表的Cells/Range:
比如Cells(eRow, 1)没有指定工作表,VBA会默认用当前活动工作表,很容易导致数据粘贴到错误位置,必须写成Worksheets("Test").Cells(eRow, 1)这种带工作表前缀的引用。CutCopyMode的错误时机:
你在复制后立刻设置Application.CutCopyMode = False,会直接取消复制操作,导致后面的PasteSpecial失败,应该放在粘贴完成后。
修正后的完整代码
Public Sub CommandButton1_Click() ' 声明变量,明确每个变量的作用 Dim sourceSheet As Worksheet Dim targetSheet As Worksheet Dim lastRow As Long Dim nRow As Long Dim targetStartRow As Long ' 提前绑定工作表对象,避免Select/Selection Set sourceSheet = ThisWorkbook.Sheets("Today_Data") ' 源数据所在工作表 Set targetSheet = ThisWorkbook.Sheets("Test") ' 目标数据所在工作表 ' 获取源表A列最后一行行号(不用Select) lastRow = sourceSheet.Range("A" & sourceSheet.Rows.Count).End(xlUp).Row ' 遍历源表第5行到最后一行,查找当日数据 For nRow = 5 To lastRow ' 检查当前行A列是否为今日日期 If sourceSheet.Cells(nRow, 1).Value = Date Then ' 获取目标表A列最后一行的下一行(用来粘贴新数据) targetStartRow = targetSheet.Range("A" & targetSheet.Rows.Count).End(xlUp).Row + 1 ' --- 第一部分:复制1-4列(不转置),直接赋值更高效 sourceSheet.Cells(nRow, 1).Resize(1, 4).Copy targetSheet.Cells(targetStartRow, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats ' --- 第二部分:复制7-19列的奇数列(7,9,11...19)并转置 ' 用Union合并多个不连续单元格 Union(sourceSheet.Cells(nRow, 7), _ sourceSheet.Cells(nRow, 9), _ sourceSheet.Cells(nRow, 11), _ sourceSheet.Cells(nRow, 13), _ sourceSheet.Cells(nRow, 15), _ sourceSheet.Cells(nRow, 17), _ sourceSheet.Cells(nRow, 19)).Copy ' 转置粘贴到目标表的第7列开始的位置(转置后一行变一列,所以从targetStartRow开始向下) targetSheet.Cells(targetStartRow, 7).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Transpose:=True ' --- 第三部分:复制6-20列的偶数列(6,8,10...20)并转置 Union(sourceSheet.Cells(nRow, 6), _ sourceSheet.Cells(nRow, 8), _ sourceSheet.Cells(nRow, 10), _ sourceSheet.Cells(nRow, 12), _ sourceSheet.Cells(nRow, 14), _ sourceSheet.Cells(nRow, 16), _ sourceSheet.Cells(nRow, 18), _ sourceSheet.Cells(nRow, 20)).Copy targetSheet.Cells(targetStartRow, 6).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Transpose:=True ' 取消复制状态 Application.CutCopyMode = False End If Next nRow ' 提示完成 MsgBox "当日数据提取完成!", vbInformation End Sub
额外优化说明
- 我把源表和目标表提前绑定为对象变量,代码更清晰,也避免了活动表切换的问题;
- 用
Union函数处理不连续的列,比你之前的写法更规范; - 把
targetStartRow只计算一次,避免重复查找,提升效率; - 最后加了完成提示,方便你确认操作结果。
内容的提问来源于stack exchange,提问作者Pedro Montanari

