Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 在不同的子语句中引用变量。下标超出范围_Excel_Vba - Fatal编程技术网

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

Excel 在不同的子语句中引用变量。下标超出范围,excel,vba,Excel,Vba,第一次来这里的程序员,几天前开始自学VBA来写这个。目标是让代码能够引用两个不是常量的工作簿。一个由用户选择,另一个正在运行宏。我在前面的sub语句中定义了工作簿,但当我尝试在下一行的sub语句中引用它时,会出现错误“9”,即“下标超出范围”。我尝试使用call,但也出现了未定义的错误(可能是我不理解“call”语句) 如果您有额外的时间查看我的公式,并确保其格式正确,这也将是一个很大的帮助。我只知道当我到达那里时,这将是一个巨大的问题 顺便说一句,我刚刚注意到,我一直在拼写代码中的引用错误。去

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

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

顺便说一句,我刚刚注意到,我一直在拼写代码中的引用错误。去吧,笑吧

'''
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

'''

您的代码已经有了一个很好的开始,所以这里有一些东西可以帮助您继续前进

  • 尽量在第一次使用时定义变量(您当前的代码足够短,不重要,这只是一种习惯)
  • 调用
    用法已被弃用,不需要它。如果要调用函数或子程序,只需使用该例程的名称即可。
    • 此外,如果有一个子调用本身包含在单个语句中,则不需要将参数括起来。如果在复合语句或赋值语句中进行调用,则必须使用paren
  • 一个好习惯是每次都清楚地用引用什么工作簿、工作表和范围。这一点让很多VBA用户感到困惑
  • 例如,在
    LoopTest1
    代码中,您指的是
    单元格
    。在没有任何限定引用的情况下,VBA代码假定您引用的是当前活动的工作表(以当前活动的工作表为准)。因此,请定义一些中间变量并将其弄清楚(参见下面的示例)

  • 为了帮助清除
    LoopTest1
    sub中的任何混淆,我添加了一些参数,以便您可以使用所选的任意两本工作簿
  • 我自己的偏好是在一个单独的字符串变量中构建一个复杂的公式,这样我就可以在调试器中检查它并确保它完全正确。您可以看到我定义了一个
    formulaText
    字符串并建立了您的公式
  • 我“纠正”了我在公式中发现的一些事情(但我不能告诉你它会起作用),包括:
    • 在公式中使用两个工作簿的
      FullName
      属性(这样就不会对其进行硬编码)
    • 使用工作表的
      Name
      属性(这样您就不会对其进行硬编码)
    • 为正确的工作簿/工作表参考正确安排单勾号(总的来说,您在公式中使用了太多的单勾号)
  • 只有您才能确定公式是否符合您的实际需要,以及它是否有效。但这可能是另一个问题:)


    在上述情况下,变量不会传递到下一个子例程。是否需要两个子程序?此外,使用变量与文件名的用法不同,如果文件名为wbOracle.Sheets(“Sheetname”)而不是
    工作簿(“wbOracle”)
    。我现在将它们作为一个子例程,并尝试了两种方法,现在出现了错误“类型不匹配”我也很担心,因为“do while”命令应该引用用户选择的文件(“WBreference”),但公式应该在“wbOracle”中的选定单元格中运行。你太神奇了,我简直不敢相信你的响应是多么彻底!谢谢你的建议。我不知道这是一件事。我一直在线路设置表上遇到错误“下标超出范围”的路障,例如,
    Set wsOracle=wbcoracle.sheets(oracleSheetName)
    参考表也会出现这种情况。我为所有的问题道歉。我对编码及其工作方式非常陌生。这种特殊的错误可能是因为您要查找的工作表名称不存在(或者拼写有点不同——请查找多余的空格或其他内容)。还要注意,我试图在
    LoopTest1
    子部分中
    设置wsReference=wbReference.Sheet1
    。此语句使用工作表代码名而不是您在选项卡上看到的实际名称设置工作表变量。有关更多信息,请参见(第10项)。您可能没有代码名为
    Sheet1
    的工作表,因此请将其更改为您现有的工作表,或将语句更改为使用工作表名称。
    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