Ссылки на переменные в другом подчиненном утверждении. Индекс вне диапазона - PullRequest
3 голосов
/ 01 июля 2019

Первый программист здесь, начал учить себя VBA несколько дней назад, чтобы написать это.Цель состоит в том, чтобы код мог ссылаться на две рабочие книги, которые не являются константами.Один выбирается пользователем, а другой запускает макрос.Я определил рабочие книги в предыдущем утверждении sub, но когда я пытаюсь сослаться на него в дополнительном утверждении ниже по строке, я получаю сообщение об ошибке «9» «индекс вне диапазона».Я пытался использовать вызов, но он также обнаружил неопределенные ошибки (может быть, я не понимаю оператор вызова).

Если у вас есть дополнительный момент, чтобы просмотреть мою формулу и убедиться, что она правильно отформатирована, это также очень поможет.Я просто знаю, что когда я туда доберусь, это станет огромной проблемой.

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 Ответ

1 голос
/ 01 июля 2019

Вы отлично начали свой код, поэтому вот несколько вещей, которые помогут вам продвинуться по пути ...

  1. Всегда используйте Option Explicit.
  2. Постарайтесь определить ваши переменные как можно ближе к их первому использованию (ваш текущий код достаточно короткий, чтобы не иметь большого значения, это просто привычка вникать).
  3. Использование Call устарело и не требуется. Если вы хотите вызвать функцию или подпрограмму, просто используйте имя этой подпрограммы.
    • Кроме того, если у вас есть дополнительный вызов, который сам по себе находится в одном выражении, паренсы НЕ обязательны для включения параметров. Если вы делаете вызов в составном или операторе присваивания, вы ДОЛЖНЫ использовать символы скобок.
  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...