【问题标题】:Excel VBA error 1004 when using range使用范围时 Excel VBA 错误 1004
【发布时间】:2018-01-04 14:37:48
【问题描述】:

我在 VBA 中有一项工作,我需要制作一个 512X512 (cellsXcells) 的正方形。 正方形假设与单元格的边界。 我将正方形的大小设为动态,以便用户可以插入他想要的大小(最大为 512)。

现在我尝试了几种技术来完成上述操作,但总是因为错误 1004 运行时间而失败。

Sub printGrid(gridSize)

Range(Cells(1, 1), Cells(gridSize, gridSize)).Select
With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With



With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

End With

End Sub

我的第二次尝试是逐个单元格地进行...

Sub printBorders(gridSize)
For i = 1 To gridSize ' right side
    Cells(i, 1).Select
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlThick
    End With
Next i


For i = 1 To gridSize ' bottom
    Cells(gridSize, i).Select
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlThick
    End With
Next i

For i = gridSize To 1 Step -1 ' top
    Cells(1, i).Select
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlThick
    End With
Next i

For i = 1 To gridSize ' center
    Cells(i, 64).Select
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThick
    End With
Next i



For i = 1 To gridSize ' left
    Cells(i, gridSize).Select
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThick
    End With
Next i

End Sub

在 printBorders 尝试制作左侧网格时我失败了。 (Cells(i, gridSize).Select)。

我开始认为这是 excel 中的一种限制。 感谢您的帮助!

编辑:

当我指的是动态时: 请尝试使用 64 或 512 等输入运行它。

Sub main()
Dim gridSize As Integer, numOfDots As Integer
Call setGrid
End Sub

Sub setGrid()
Dim size As Integer
Cells.Select
Selection.Delete Shift:=xlUp

gridSize = setGridSize()

Call printGrid2(1, 1, gridSize, gridSize)
'Call printGrid2(1, 1, gridSize, gridSize / 2)

End Sub

Function setGridSize()
Do While True
    gridSize = InputBox("Enter grid size:")
    If (IsNumeric(gridSize)) And (gridSize Mod 2 = 0) Then
        setGridSize = gridSize
        Exit Do
    End If
Loop
End Function

Sub printGrid2(x, y, rowSize, colSize)
Dim rng As Range
Set rng = Range(Cells(x, y), Cells(rowSize, colSize))


With rng.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With rng.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With rng.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

With rng.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlThick
End With

End Sub

【问题讨论】:

  • 工作表或其任何部分是否受保护?如果是这样,您可能无法选择或执行某些操作。另外,it's generally advisable to avoid relying on Select or Activate.
  • 所以不要使用Cells(i, 1).SelectWith Selection...,只需使用With Cells(i, 1).Borders(xlEdgeLeft)。但如果工作表受到保护,您仍然可能无法做到这一点。
  • Cells(i, 64).Select 的想法是什么?它转到列BL
  • 虽然使用正确分配的范围变量是个好主意,但在这种情况下似乎不太可能解决问题。 1004 通常表示保护问题,或者您定义了一个不可访问的对象(例如,Cells(0, 2) 将失败,因为它不/不能存在。
  • 值得注意的是,当我在空白工作簿中运行代码时,您的代码不会引发任何错误(除了编译错误,可以通过正确声明变量来解决)。

标签: vba excel range runtime-error


【解决方案1】:

这就是我“动态”运行代码的方式。在新的 Excel 上删除 Option Explicit 并尽量不查看选择后,它可以工作:

Sub DynamicTest()

    printBorders (10)
    printBorders (20)
    printBorders (30)
    printBorders (InputBox("Dynamically"))

End Sub

Sub printBorders(gridSize As Long)
    For i = 1 To gridSize    ' right side
        Cells(i, 1).Select
        With Selection.Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .Weight = xlThick
        End With
    Next i


    For i = 1 To gridSize    ' bottom
        Cells(gridSize, i).Select
        With Selection.Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .Weight = xlThick
        End With
    Next i

    For i = gridSize To 1 Step -1    ' top
        Cells(1, i).Select
        With Selection.Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .Weight = xlThick
        End With
    Next i

    For i = 1 To gridSize    ' center
        Cells(i, 64).Select
        With Selection.Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .Weight = xlThick
        End With
    Next i



    For i = 1 To gridSize    ' left
        Cells(i, gridSize).Select
        With Selection.Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .Weight = xlThick
        End With
    Next i

End Sub

这是我改变的:

来自: Sub printBorders(gridSize)

到: Sub printBorders(gridSize As Long)

或者您可以像这样在 InputBox 中要求输入数字: InputBox("Dynamically", Type:=1)。 (感谢大卫·泽门斯

一般来说,这就是出现错误的原因:

Cells 在 VBA 中采用 parameter overloading。这意味着,您可以使用以下两个中的任何一个来引用 Cell:

Cells(Long, Long) -> Cells(1,1)

Cells(Long, String) -> Cells(1,"A")

gridSize 是一个String,但是像这样在for-loop 中使用是没有问题的,因为它在内部被转换为一个数值。

但是,当您尝试选择 Cells(i, gridSize) 时,VBA 会首先查找函数 Cells(Long, String)。它期望String 是一个列名。但是,您没有名为 111 的列,因此会引发错误。

【讨论】:

  • 为什么要删除Option Explicit?似乎最好只声明变量i :)
  • @DavidZemens - 但你没有使用它Dynamically,从InputBox 传递一个String 值作为参数:) 然后,确实,你在某处得到1004 错误最后一个for-loop
  • @Vityata 这不是动态的。请看帖子。
  • 不,我不是,但这可以通过简单地对 InputBox 的返回进行类型转换来处理,或者要求 InputBox 返回数值 :)
  • @user3449011 - 查看编辑,现在它是动态的。另外,我从 InputBox 调用的 4. 时间。
【解决方案2】:

如果我没看错,您要做的就是绘制一个带有周围边框的方形网格。您不必执行单独的操作。

Option Explicit

Sub test()
    printGrid 6
End Sub

Sub printGrid(gridSize)
    With Worksheets("sheet1")
        With .Cells(1, 1).Resize(gridSize, gridSize)
            .BorderAround LineStyle:=xlContinuous, Weight:=xlThick
        End With
    End With
End Sub

录制的代码通常执行的功能远远超出所需。最好将其切碎到实际需要的程度。

【讨论】:

  • 只有边框,内部单元格没有边框。
  • 好的,根据您的上述要求进行调整。
  • 但是你没有选择单元格的动画效果:)
  • 好吧,也许我可以导入一些内核函数,让光标跳动一下。 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多