繁体   English   中英

引用不同子语句中的变量。 下标超出范围

[英]Referencing Variables in a Different Sub Statement. Subscript Out of Range

这里的第一次程序员,几天前就开始自学VBA了。 目标是让代码能够引用两个非常量的工作簿。 一个由用户选择,另一个正在运行宏。 我之前在子语句中定义了工作簿,但是当我尝试在该行的子语句中引用它时,我得到错误'9'“下标超出范围。” 我尝试过使用call但它也提出了未定义的错误(可能是我不理解'call'语句)。

如果你有额外的时间来查看我的公式,并确保它的格式正确,这将是一个很大的帮助。 我才知道,当我到达那里时,这将是一个巨大的问题。

PS我只是注意到我的代码一直在拼写引用错误。 来吧,笑吧。

'''
Sub Openfile()

    Dim FileToOpen As Variant, wbRefrence As Workbook
    Dim wbOracle As Workbook
    Set wbOracle = ThisWorkbook

FileToOpen = Application.GetOpenFilename(FileFilter:="Excel Workbooks (*.xls*),*.xls*", Title:="Open Database File")
    If FileToOpen = False Then
    MsgBox "No file selected, cannot continue." 'If the user does not open a file this message is displayed
    Exit Sub 'If no file is selected the program stops running
    End If

    Set wbRefrence = Workbooks.Open(FileToOpen)

    Workbooks.Open (FileToOpen) 'If a file is selected it opens that file.

Call LoopTest1

End Sub


Sub LoopTest1()

Dim BlankCell As Boolean
Dim i As Long
    'Loop until a blank cell is encountered
    Do While BlankCell = False
    i = i + 1

    If Cells(i, "C").Value = "" Then
    BlankCell = True 'When it reaches a blank cell BlankCell will now be true which ends the do while formula.
    End If

    Application.Workbooks("wbOracle").Sheets("Cancel Requisition Lines").Range("C16").Select

'Formula for "do while" condition
Selection.Formula = "=IF(INDEX(['wbRefrence']Sheet1!'A2000:M2000',MATCH(1,(['wbRefrence']Sheet1!'D:D'=['wbOracle']'Cancel Requisition Lines'!'C16')*(['wbRefrence']Sheet1!'E:E'=['wbOracle']'Cancel Requisition Lines'!'I16')*(['wbRefrence']Sheet1!'F:F'=['wbOracle']'Cancel Requisition Lines'!'J16'),0),9)>=['wbOracle']'Cancel Requisition Lines'!M:M, ""materials supplied"","""")"

Loop

End Sub

'''

你的代码开始很好,所以这里有一些东西可以帮助你顺利完成...

  1. 始终使用Option Explicit
  2. 尽量将变量定义为尽可能接近第一次使用(您当前的代码足够短,无关紧要,只是习惯进入)。
  3. Call使用已被弃用,不需要。 如果要调用函数或子函数,只需使用该例程的名称即可。
    • 此外,如果您在单个语句中有一个单独的子调用,则不需要包含参数的parens。 如果您在复合或赋值语句中进行调用,则必须使用parens。
  4. 一个好习惯是始终清楚地表明您每次使用完全限定的参考引用的工作簿,工作表和范围。 这一件事使许多VBA用户绊倒了。

例如,在LoopTest1代码中,您指的是Cells 没有任何限定参考,VBA代码假定您指的是当前活动的工作表(无论哪个和哪个)。 因此,定义一些中间变量并明确说明(参见下面的示例)。

  1. 为了帮助清除LoopTest1子中的任何混淆,我添加了一些参数,以便您可以处理您选择的任何两个工作簿。
  2. 我自己的偏好是在一个单独的字符串变量中构建一个复杂的公式,以便我可以在调试器中检查它并确保它完全正确。 所以你可以看到我定义了一个formulaText字符串并构建了你的公式。
  3. 我“纠正了”我在公式中找到的一些东西( 但我不能告诉你它会起作用 ),包括:
    • 使用公式中两个工作簿的FullName属性(所以你从来没有硬编码)
    • 使用工作表的Name属性(所以你从来没有硬编码)
    • 正确安排单刻度标记以获得正确的工作簿/工作表参考(总体而言,您在公式中使用了太多的单刻度)

只有您可以确定公式是否实际上是您想要的以及它是否有效。 但那可能是一个单独的问题:)

Option Explicit

Sub Openfile()
    Dim wbOracle As Workbook
    Set wbOracle = ThisWorkbook

    Dim FileToOpen As Variant
    FileToOpen = Application.GetOpenFilename( _
                          FileFilter:="Excel Workbooks (*.xls*),*.xls*", _
                          Title:="Open Database File")
    If FileToOpen = False Then
        MsgBox "No file selected, cannot continue."
        Exit Sub
    End If

    Dim wbReference As Workbook
    Set wbReference = Workbooks.Open(FileToOpen)
    Workbooks.Open FileToOpen

    LoopTest1 wbOracle, wbReference, "Cancel Requisition Lines"
End Sub

Sub LoopTest1(ByRef wbOracle As Workbook, _
              ByRef wbReference As Workbook, _
              ByVal oracleSheetName As String)
    Dim wsOracle As Worksheet
    Set wsOracle = wbOracle.Sheets(oracleSheetName)

    Dim wsReference As Worksheet
    Dim referenceCell As Range
    Set wsReference = wbReference.Sheet1
    Set referenceCell = wsReference.Range("C1")

    Dim formulaText As String
    Do While Not IsEmpty(referenceCell)
        formulaText = "=IF(INDEX('[" & wbReference.Name & _
                      "]Sheet1'!A2000:M2000,MATCH(1,(['" & wbReference.FullName & _
                      "]Sheet1'!D:D=['" & wbOracle.FullName & _
                      "]" & wsOracle.Name & "'!C16)*('[" & wbReference.FullName & _
                      "]Sheet1!E:E=[" & wbOracle.FullName & _
                      "]" & wsOracle.Name & "'!'I16')*([" & wbReference.FullName & _
                      "]Sheet1!F:F=[" & wbOracle.FullName & _
                      "]" & wsOracle.Name & "'!'J16'),0),9)>=[" & wbOracle.FullName & _
                      "]" & wsOracle.Name & "'!M:M, ""materials supplied"","""")"
        wsOracle.Range("C16").Formula = formulaText
        Set referenceCell = ReferenceCell.Offset(1, 0)
    Loop
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM