【问题标题】:Passing cell.value from a range to another sub将 cell.value 从一个范围传递到另一个子
【发布时间】:2019-05-13 13:17:22
【问题描述】:

我有以下代码:

Dim WS1, WS2 As Worksheet
Dim chatRange As Range
Dim cell As Range
Dim txt As String
    
Sub NameTest()
    
    Set WS1 = ActiveWorkbook.Sheets("Page 1")
    Set WS2 = ActiveWorkbook.Sheets("Sheet1")
    x = 2
    lRow1 = WS1.Cells(Rows.Count, "B").End(xlUp).Row
    
    Set chatRange = WS1.Range("B" & x, "B" & lRow1)
    
    For Each cell In chatRange
        If cell.Offset(0, 11).Value = "Accepted" Then
            txt = cell.Offset(0, 18).Value
            NameSplit
        End If
    Next cell
    
End Sub

Sub NameSplit()
    Dim i As Integer
    Dim FullName As Variant
    Dim x As String, cell As Range
    Dim lRow2 As Long

    FullName = RemoveBlankLines(Split(txt, vbLf))
    lRow2 = WS2.Cells(Rows.Count, 2).End(xlUp).Row + 1
    WS2.Cells(lRow2, 1).Value = cell.Value                 '<===================
    WS2.Cells(lRow2, 2).Value = cell.Offset(0, 2).Value    '<===================
    WS2.Cells(lRow2, 3).Value = cell.Offset(0, 6).Value    '<===================
    WS2.Cells(lRow2, 4).Value = cell.Offset(0, 18).Value   '<===================
End Sub

这是读取一张纸然后将信息传递给另一张纸的测试代码的一部分。

我想使用第一个 sub 中设置的范围内的“单元格”中的信息来传输第二个 sub 中的详细信息。它适用于在顶部声明的 WS1 和 WS2,但它对范围的作用不同。

带箭头的四行是我正在努力解决的部分。 cell.value 回来了:

运行时错误“91”:对象变量或未设置块变量

我知道最好的办法是把它全部放在一个潜艇上,但如果可能的话,我想把它分开。

【问题讨论】:

  • 您将cell 声明为范围(在 NameSplit 函数中第二次),但从未设置它。这就是您至少收到错误的原因。我会尝试修复您的代码并作为答案发布。
  • 您需要将cell 作为范围参数传递给您的Namesplit 子。
  • 旁注:您的WS1 变量是Variant,您的行应如下所示:Dim WS1 as Worksheet, WS2 as Worksheet
  • 如果这些宏是同一模块的一部分,您可以使用Public 变量将您声明的内容传递给其他宏。另请注意,单元格很容易与单元格混淆!

标签: excel vba range cell


【解决方案1】:

始终使用Option Explicit,尽管在这种情况下它不会突出显示问题。

如前所述,您将cell 声明为范围(在 NameSplit 函数中第二次),但从未设置它。这就是你至少得到错误的原因..

正如其他人提到的,如果您先声明它们,您可以轻松地将这些值传递给您的其他子。查看基于您的示例(未经测试)代码:

Option Explicit
'Use global variables only if really needed, but was a good try.

Sub NameTest()
    Dim WS1 As Worksheet, WS2 As Worksheet
    Dim chatRange As Range
    Dim cell As Range
    Dim txt As String

    Set WS1 = ActiveWorkbook.Sheets("Page 1")
    Set WS2 = ActiveWorkbook.Sheets("Sheet1")

    x = 2

    lRow1 = WS1.Cells(WS1.Rows.Count, "B").End(xlUp).row

    Set chatRange = WS1.Range("B" & x, "B" & lRow1)

    For Each cell In chatRange
        If cell.Offset(0, 11).Value = "Accepted" Then
            txt = cell.Offset(0, 18).Value
            Call NameSplit(WS2, cell, txt)
        End If

    Next cell

End Sub

Sub NameSplit(wsDest As Worksheet, rngCell As Range, strTxt As String)    'You can pass any objects through. By default they are passed ByRef (search for ByRef vs ByVal)
    Dim i As Integer
    Dim FullName As Variant
    Dim x As String
    Dim lRow2 As Long

    FullName = RemoveBlankLines(Split(strTxt, vbLf))
    lRow2 = WS2.Cells(WS2.Rows.Count, 2).End(xlUp).row + 1

    wsDest.Cells(lRow2, 1).Value = rngCell.Value
    wsDest.Cells(lRow2, 2).Value = rngCell.Offset(0, 2).Value
    wsDest.Cells(lRow2, 3).Value = rngCell.Offset(0, 6).Value
    wsDest.Cells(lRow2, 4).Value = rngCell.Offset(0, 18).Value
End Sub

编辑: 完全限定 Rows.CountWS1.Rows.Count 和分别 WS2.Rows.Count 以防止错误,并更正评论中的默认值。 (感谢@chris neilsen 指出)。

【讨论】:

  • 我还在学习,有时可能会令人沮丧,感谢您抽出宝贵时间回答。完美运行。
  • 我从一个初学者那里看到了很多糟糕的代码,我会说你是在正确的轨道上!跟上,干得好。
  • VBA 中的默认参数传递实际上是ByRefSee here
  • 存在不合格的单元格引用,可能会导致错误。 WS2.Cells(Rows.Count, 2) 应该是 WS2.Cells(WS2.Rows.Count, 2)
  • 感谢@chrisneilsen 的更正,我已经更新了答案。 @madmiddle,克里斯提到的教训是,您应该始终限定您的引用,否则:WS2.Cells(Rows.Count, 2) 相当于 WS2.Cells(ActiveSheet.Rows.Count, 2)
【解决方案2】:

你的NameSplit() 过程应该这样声明:

Sub NameSplit(WS2 as Worksheet, cell as Range)
'
'
'your code here
'
'
End Sub

它应该像这样调用:

call NameSplit(WS2, cell)

您可以从NameSplit() 的声明中删除cell as Range

【讨论】:

  • 不要使用过时的Call 语句。应该只是NameSplit cell
  • @chris neilsen:为什么?这只是口味问题。
  • 我发现使用Call function(arg1, arg2, arg3, etc) 的语句比function arg1, arg2, arg3, etc 更易读。它在实际调用外部函数/子的代码中也很突出。
  • 我不会称Call 声明已过时。如果想要使用括号而不改变 Subs 的 ByRef/ ByVal 行为,这是很有用的
  • 我发现Call 很有用,因为对我来说,调用 Sub 就像调用 void 函数一样。或者调用我对返回值不感兴趣的函数。
猜你喜欢
  • 2017-06-10
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多