Как я могу ссылаться на ячейку, используя переменные?Казалось бы, «правильный» диапазон объектов возвращает ошибку 1004 VBA - PullRequest
1 голос
/ 05 июля 2019

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

Sub LoopTest1(ByRef wbOracle As Workbook, ByRef wbReference As Workbook)

    Dim wsOracle As Worksheet
    Set wsOracle = wbOracle.Worksheets(1)
    Dim wsReference As Worksheet
    Set wsReference = wbReference.Worksheets(1)
    Dim ReferenceCell As Range 'will be used for Offset when I get to writing the looping part
    Set ReferenceCell = wsReference.Range("E16")
    Dim formulaText As String
    'Formula below searches for a match on 3 criteria and if there is a match it will write "materials supplied" granted column 9 is >= wsOracle quantity.
   formulaText = "={IF(INDEX('[" & wbReference.FullName & "]Worksheets(1)'!$A$2000:$M$2000,MATCH('[" & wbOracle.FullName & "]Worksheets(1)'!$E16&$I16&$J16,'[" & wbReference.FullName & "]Worksheets(1)'!$D:$D&'[" & wbReference.Name & "]Worksheets(1)'!$E:$E&'[" & wbReference.Name & "]Worksheets(1)'!$F:$F,0),9)>=$M16,""materials supplied"","""")}"
    wsOracle.Range("C16").Formula = formulaText 'Problem line

End Sub

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

Ответы [ 3 ]

2 голосов
/ 05 июля 2019

Попробуйте определить formulaText следующим образом ...

formulaText = "=IF(INDEX('[" & wbReference.Name & "]" & wsReference.Name & "'!$A$2000:$M$2000,MATCH('[" & wbOracle.Name & "]" & wsOracle.Name & "'!$E16&$I16&$J16,'[" & wbReference.Name & "]" & wsReference.Name & "'!$D:$D&'[" & wbReference.Name & "]" & wsReference.Name & "'!$E:$E&'[" & wbReference.Name & "]" & wsReference.Name & "'!$F:$F,0),9)>=$M16,""materials supplied"","""")"

Тогда, поскольку у вас есть формула массива, используйте FormulaArray вместо Formula ...

wsOracle.Range("C16").FormulaArray = formulaText

EDIT

Чтобы обойти ограничение на количество символов, попробуйте следующее ...

Sub LoopTest1(ByRef wbOracle As Workbook, ByRef wbReference As Workbook)

    Dim wsOracle As Worksheet
    Set wsOracle = wbOracle.Worksheets(1)

    Dim wsReference As Worksheet
    Set wsReference = wbReference.Worksheets(1)

    Dim ReferenceCell As Range 'will be used for Offset when I get to writing the looping part
    Set ReferenceCell = wsReference.Range("E16")

    Dim formulaPart1 As String
    Dim formulaPart2 As String
    Dim formulaPart3 As String

    formulaPart1 = "'[" & wbReference.Name & "]" & wsReference.Name & "'!$A$2000:$M$2000"
    formulaPart2 = "'[" & wbOracle.Name & "]" & wsOracle.Name & "'!$E16&$I16&$J16"
    formulaPart3 = "'[" & wbReference.Name & "]" & wsReference.Name & "'!$D:$D&'[" & wbReference.Name & "]" & wsReference.Name & "'!$E:$E&'[" & wbReference.Name & "]" & wsReference.Name & "'!$F:$F"

    With wsOracle.Range("C16")
        .FormulaArray = "=IF(INDEX(X_X_X,MATCH(Y_Y_Y,Z_Z_Z,0),9)>=$M16,""materials supplied"","""")"
        .Replace "X_X_X", formulaPart1
        .Replace "Y_Y_Y", formulaPart2
        .Replace "Z_Z_Z", formulaPart3
    End With

End Sub
0 голосов
/ 05 июля 2019
Sub LoopTest1(ByRef wbOracle As Workbook, ByRef wbReference As Workbook)

    Dim wsOracle As Worksheet, wsReference as Worksheet
    Dim wref as String, oref as String, cref(1 To 6) As String

    Set wsOracle = wbOracle.Worksheets(1)
    Set wsReference = wbReference.Worksheets(1)
    wref = "'" & wbReference.Path & "\[" & wbReference.Name & "]" & wsReference.Name & "'!"
    oref = "'" & wbOracle.Path & "\[" & wbOracle.Name & "]" & wsOracle.Name & "'!"
    cref(1) = wref & "$A$2000:$M$2000" : cref(2) = oref & "$E16&$I16&$J16"
    cref(3) = wref & "$D:$D" : cref(4) = wref & "$E:$E"
    cref(5) = wref & "$F:$F" : cref(6) = "$M16"

    With wsOracle.Range("C16")
        .FormulaArray = "=IF(INDEX(CR1, MATCH(CR2, CR3&CR4&CR5, 0), 9) >= CR6, ""materials supplied"","""")"
        .Replace "CR1", cref(1)
        .Replace "CR2", cref(2)
        .Replace "CR3", cref(3)
        .Replace "CR4", cref(4)
        .Replace "CR5", cref(5)
        .Replace "CR6", cref(6)
    End With

End Sub
0 голосов
/ 05 июля 2019

Действительно, формула должна быть .FormulaArray, и что-то вроде этого работает вполне нормально, как упомянуто @ Domenic :

`formulaText = "=IF(INDEX(Tabelle1!$A$2000:$M$2000,MATCH(Tabelle1!$E16&$I16&$J16,Tabelle1!$D:$D&Tabelle1!$E:$E&Tabelle1!$F:$F,0),9)>=$M16,""materials supplied"","""")"`

В любом случае, это случай VBA, где некоторые тестовые разработки могут быть полезны, чтобы иметь возможность сделать это самостоятельно. В чем идея тестирования? Одним предложением вы продолжаете писать код, пока ваш код не будет соответствовать ожидаемым значениям.

Итак, очевидно, что вы можете написать формулу самостоятельно в Excel, не используя VBA. Вы хотите использовать VBA по какой-то причине (и причина в том, что это отличный язык программирования). Таким образом, вы пишете формулу в Excel в ячейке C15 и продолжаете работать, пока не получите ту же формулу с VBA в C16. Тест может выглядеть следующим образом, отображая различия в двух формулах:

Sub FirstTest()
    With Worksheets(1)
        Debug.Print .Cells(16, "C").Formula = .Cells(15, "C").Formula
        Debug.Print .Cells(16, "C").Formula
        Debug.Print .Cells(15, "C").Formula
    End With
End Sub

Если вы запустите код сейчас, ничего не написав, он вернет False и разницу двух ячеек. Итак, в VBA вы можете начать с выбора уже работающей формулы и запустить следующий код:

Public Sub PrintMeUsefulFormula()

    Dim strFormula  As String
    Dim strParenth  As String

    strParenth = """"

    strFormula = Selection.Formula
    strFormula = Replace(strFormula, """", """""")

    strFormula = strParenth & strFormula & strParenth
    Debug.Print strFormula

End Sub

Затем посмотрите, что вы получаете в ближайшем окне Ctrl + G и замените его точно на месте формулы. Это выглядит так (в немецком Excel):

"=IF(INDEX(Tabelle1!$A$2000:$M$2000,MATCH(Tabelle1!$E16&$I16&$J16,Tabelle1!$D:$D&Tabelle1!$E:$E&Tabelle1!$F:$F,0),9)>=$M16,""materials supplied"","""")"

Теперь начинается самое интересное - у вас уже есть рабочий код, который проходит тесты - в Excel имена рабочих листов предварительно кодируются, поэтому все в порядке. Однако , вам нужно сделать формулы "гибкими" с переменными для рабочих листов и рабочих книг. Вот где тесты действительно ценны. Вы можете начать замену в строке формулы и убедиться, что она пройдет тесты до конца. Если что-то не получается, вы всегда можете вернуться к последнему изменению и продолжить попытки. Попробуйте:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...