Excel VBA已声明工作表对象仍需Select才能正常运行的原因咨询
问题原因
- 核心错误是代码中未显式声明Cells对象所属的工作表:VBA中所有没有指定父工作表的
Cells、Range对象,默认会指向当前处于激活状态的工作表。 - 你代码中类似
ws2.Range(Cells(i, 1), Cells(m, 1))的写法存在逻辑缺陷:外层Range虽然指定了属于ws2,但内部的两个Cells没有绑定工作表,当当前激活表不是ws2时,Cells会指向其他工作表,用两个不同工作表的单元格构造Range会直接触发运行时错误。 - 你添加
ws2.Select之后,ws2变成了活动工作表,所有未绑定父对象的Cells默认都指向ws2,刚好匹配外层Range的所属工作表,因此代码可以正常运行。
修复方案
只需要给所有未指定父对象的Cells添加上对应的工作表前缀,即可完全不需要Select操作,同时可以用直接赋值替代复制粘贴操作提升运行效率,修正后代码如下:
Sub TranspNewLine() Dim i As Long, j As Long, n As Long, m As Long, c As Long, p As Long, ws1 As Worksheet, ws2 As Worksheet Set ws1 = Worksheets("Tabelle1") Set ws2 = Worksheets("Tabelle2") ws2.Rows.Clear n = ws1.Range(ws1.Cells(1, 1), ws1.Cells(ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row, 1)).Rows.Count For i = 1 To n m = ws1.Range(ws1.Cells(i, 2), ws1.Cells(i, ws1.Cells(i, ws1.Columns.Count).End(xlToLeft).Column)).Columns.Count If i = 1 Then ' 给Cells添加上ws2前缀,明确所属工作表 ws2.Range(ws2.Cells(i, 1), ws2.Cells(m, 1)).Value = ws1.Cells(i, 1).Value c = i For j = 2 To m + 1 ws2.Cells(c, 2).Value = ws1.Cells(i, j).Value c = c + 1 Next j Else p = ws2.Range(ws2.Cells(1, 2), ws2.Cells(ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row, 2)).Rows.Count ' 给Cells添加上ws2前缀,明确所属工作表 ws2.Range(ws2.Cells(p + 1, 1), ws2.Cells(p + m, 1)).Value = ws1.Cells(i, 1).Value c = p + 1 For j = 2 To m + 1 ws2.Cells(c, 2).Value = ws1.Cells(i, j).Value c = c + 1 Next j End If Next i End Sub
内容的提问来源于stack exchange,提问作者StingerWolf
相关产品推荐
相关产品推荐

