Обработчик событий VBA для возврата значения

У меня есть обработчик событий Sub, который прослушивает ответное сообщение от Bloomberg API и сохраняет его в массиве Dd.

Согласно MSDN, обработчики событий должны быть подчиненными, но я хотел бы провести дополнительный анализ данных в моем основном методе.

Как я могу сослаться на массив, созданный в обработчике событий, чтобы продолжить обработку данных?

Обработчик события:

Private Sub session_ProcessEvent(ByVal obj As Object)

    On Error GoTo errHandler

    Dim eventObj As blpapicomLib2.Event
    Set eventObj = obj

    If Application.Ready Then
        If eventObj.EventType = PARTIAL_RESPONSE Or eventObj.EventType = RESPONSE Then
            Dim it As blpapicomLib2.MessageIterator
            Set it = eventObj.CreateMessageIterator()
            Dim numResponse As Integer
            numResponse = 0
            Dim data() As Variant
            Do While it.Next()
                numResponse = numResponse + 1
                Dim msg As Message
                Set msg = it.Message
                Dim securityData As Element
                Dim securityName As Element
                Dim fieldData As Element
                Set securityData = msg.GetElement("securityData")
                Set securityName = securityData.GetElement("security")
                Set fieldData = securityData.GetElement("fieldData")
                Sheet1.Cells(currentRow, 4).Value = securityName.Value
                Dim numDates As Integer
                Dim numFields As Integer
                numDates = fieldData.NumValues
                numFields = fieldData.GetValue(0).NumElements
                ReDim data(numDates, numFields, numResponse)
                Dim b As Integer
                For b = 0 To numDates - 1
                    Dim fields As blpapicomLib2.Element
                    Set fields = fieldData.GetValue(b)
                    Dim a As Integer

                    For a = 0 To numFields - 1
                        Dim field As Element
                        Set field = fields.GetElement(a)
                        data(b, a, numResponse) = field.Value
                        Sheet1.Cells(currentRow, a + 5).Value = data(b, a, numResponse)
                    Next
                    currentRow = currentRow + 1
                Next b
            Loop

        '     skip a row for next security
            currentRow = currentRow + 1

        End If
    End If
    Exit Sub

errHandler:
    MsgBox Err.Description

End Sub

... и суб, я хотел бы обработать массив здесь...

Public Sub RefDataExample()

    ' Calculate the number of securities and fields
    Dim numSecurity As Integer
    Dim numFields As Integer

    numSecurity = 0
    numFields = 0

    ' clear data area
    Range("D4", "H60000").Clear

    Do While Cells(numSecurity + 4, 1).Value <> ""
        numSecurity = numSecurity + 1
    Loop

    Do While Cells(numFields + 4, 2).Value <> ""
        numFields = numFields + 1
    Loop

    Dim sSecurity() As String
    Dim sFields() As Variant

    ReDim sSecurity(0 To numSecurity - 1) As String
    ReDim sFields(0 To numFields - 1) As Variant

    Dim i As Integer

    For i = 0 To numSecurity - 1
        sSecurity(i) = Cells(i + 4, 1).Value
    Next i

    For i = 0 To numFields - 1
        sFields(i) = Cells(i + 4, 2).Value
    Next i

    bbControl.MakeRequest sSecurity, sFields

    'Process response array here

End Sub

person Michael Schweitzer    schedule 02.04.2018    source источник
comment
Добро пожаловать! См. минимальный воспроизводимый пример, а также Как спросить.   -  person ashleedawg    schedule 02.04.2018
comment
Привет, рад отредактировать мой вопрос, не могли бы вы уточнить, какому из этих стандартов это не соответствует? Запрос на самом деле не зависит от примера, поскольку в его основе лежит концептуальный вопрос о том, может ли обработчик событий вернуть значение. Тем не менее, пример завершен, хотя я полагаю, что его можно уменьшить, и его можно проверить.   -  person Michael Schweitzer    schedule 02.04.2018
comment
возможно, он имел в виду тот факт, что сабы не возвращают значения, в таком случае это вообще не вопрос. с другой стороны, почему бы не использовать общедоступную переменную для хранения массива, чтобы вы могли получить к нему доступ из обоих подпрограмм   -  person am05mhz    schedule 02.04.2018
comment
Как бы вы сделали переменную общедоступной? Например, я изменил имя обработчика событий с «Public Sub session_ProcessEvent (ByVal obj As Object)», а затем сделал тестовую подпрограмму «processData()», которая ссылается на переменную из обработчика событий, и она не распознается.   -  person Michael Schweitzer    schedule 02.04.2018


Ответы (1)


Удалять

Dim data() As Variant

из всех сабвуферов, в которых он в настоящее время появляется (например, из вашего session_ProcessEvent())

и место

Public data As Variant

в верхней части модуля, содержащего ваш саб (на самом деле вы можете разместить его в верхней части любого модуля, который вам нравится)

и у вас будут «данные», видимые из всех подпрограмм/функций вашего проекта.

person DisplayName    schedule 02.04.2018
comment
Итак, я пробовал это, но если данные представляют собой массив, я получаю сообщение об ошибке, говорящее мне, что массивы не могут быть общедоступными переменными. - person Michael Schweitzer; 03.04.2018
comment
кто тебе это говорит? В VBA это совершенно законно! Дважды проверьте все, что вы проецируете, и убедитесь, что: 1) нет затемнения какой-либо переменной data() внутри какой-либо подпрограммы/функции (при этом все ReDimmin оставлены на месте) 2) поместите Public data() As Variant в самый верх любого (т.е. любого, но только одного!) модуля - person DisplayName; 03.04.2018