【问题标题】:Code stops when copying and pasting in VBA [duplicate]在 VBA 中复制和粘贴时代码停止 [重复]
【发布时间】:2021-01-03 21:34:17
【问题描述】:

我在用 ** 表示的行上遇到应用程序定义或对象定义错误。我的语法错了吗?

Sub MonthLines()

Dim wkb As Workbook, shifts As Worksheet, inputs As Worksheet, StartDate As Range, EndDate As Range, InputDate As Range, numshifts As Integer, monthstart As Double
Dim monthend As Double, i As Double, n As Double, p As Double

Set wkb = Excel.Workbooks("Call Center Headcount Model v2.xlsm")
Set shifts = wkb.Worksheets("Shifting")
Set inputs = wkb.Worksheets("Inputs")

Set StartDate = wkb.Worksheets("Inputs").Range("C9")
Set EndDate = wkb.Worksheets("Inputs").Range("C10")
Set InputDate = wkb.Worksheets("Shifting").Range("B5")

monthstart = StartDate.Value
monthend = EndDate.Value

Application.Calculation = xlCalculationManual
p = 1

    For i = monthstart To monthend
        InputDate.Value = i
        Calculate
        numshifts = wkb.Worksheets("Shifting").Range("E5").Value
        For n = 21 To numshifts + 21
            With Sheets("Shifting")
            .Range(Cells(n, 1), Cells(n, 6)).Copy
            **wkb.Worksheets("Shift Output").Range(Cells(p, 1), Cells(p, 6)).PasteSpecial Paste:=xlPasteValues**
            End With
        Next n
    p = p + n
    
    Next i
    End Sub

【问题讨论】:

  • 这不是我出错的那一行,而 WITH 语句之后的那一行在没有它们的情况下也能正常执行。

标签: excel vba syntax-error


【解决方案1】:

这是一个很好的例子,说明为什么完全限定所有范围对象总是有价值的,即使当时您认为它不是必要的。

确定您的first line below the With statement works,可能是因为您激活了该工作表。因此,VBA 隐式分配您在运行时到达该行时碰巧拥有的任何活动工作表。这就是为什么您的所有范围对象都应该是完全限定的,其中包括Range() 中的Cells()。您在工作表中很好地限定了Range(),但该限定扩展到Cells() 函数中:
.Range(Cells(n, 1), Cells(n, 6))
wkb.Worksheets("Shift Output").Range(Cells(p, 1), Cells(p, 6))

未经测试,但这应该可以工作:

Dim wsShift As Worksheet, wsSO As Worksheet
Set wsShift = wkb.Worksheets("Shifting")
Set wsSO = wkb.Worksheets("Shift Output")

For i = monthstart To monthend

    InputDate.Value = i
    Calculate
    numshifts = wkb.Worksheets("Shifting").Range("E5").Value
    
    For n = 21 To numshifts + 21
        wsShift.Range(wsShift.Cells(n, 1), wsShift.Cells(n, 6)).Copy
        wsSO.Range(wsSO.Cells(p, 1), wsSO.Cells(p, 6)).PasteSpecial Paste:=xlPasteValues
    Next n
    
    p = p + n

Next i

或者如果你真的想精通,放弃众所周知的慢循环 + .Copy/.Paste 方法并使用数组。读一次,一次正确,而不是读/写numShifts - 21 次:(再次,未经测试)

Dim dataArr() As Variant
dataArr = Workbooks("<ENTER WB>").Worksheets("Shifting").Range("A21:F" & numshifts + 21).Value
wkb.Worksheets("Shift Output").Range("A1:F" & numshifts + 21).Value = dataArr

【讨论】:

  • 您的第一个代码将出错,因为您没有分配变量p。您还需要在n loop 内增加p,以免粘贴到相同的范围内。你的第二个要好得多。
  • 哦,是的,我的意图不是很清楚,因为变量声明显示声明本身和内部 For Loop 之间没有中断。我只是在修改第二个循环,并没有触及第一个/第二个之间的任何代码。感谢您指出这一点,以便我做出澄清!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多