Как преобразовать массив из (x, y) (z) измерений в (x, y) измерения? - PullRequest
2 голосов
/ 07 ноября 2019

Я работаю с API Bloomberg в VBA и хочу иметь возможность брать массивы, которые API выдает при запросе исторических данных, и помещать их в таблицу с именами полей. Однако массив, который дает мне API, представлен в следующем формате: (x, y) (Z), но я не могу использовать его для вставки в таблицу. Я также хочу иметь возможность добавлять другой массив данных в массив, пока я преобразую из одной формы в другую

Я пытался просто пройти через массив Bloomberg и заменить каждый элемент в другом массиве, но основнойУ меня есть проблемы, связанные с невозможностью узнать, насколько большим должен быть массив, и как я собираюсь пройтись по API Bloomberg, не выходя из индекса и не получая ошибку. Я пытался использовать Ubound, но он не работает так, как я задумал.

Это код, который я пытался использовать, чтобы преобразовать мой массив и затем вставить его. Он просто вставляет пустые значения и ничего не помещает в таблицу

Sub mWriteToTable(vTableName As String, ByVal vArray As Variant, vCUSIPS As Variant, vFields As Variant)
On Error GoTo ErrorHandler
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim x As Long, y As Long
    Dim TEST As String
    Dim DataArray() As Variant

    Set db = CurrentDb
    Set rs = db.OpenRecordset(vTableName, dbOpenDynaset, dbSeeChanges)
    TEST = ""
    Dim xBound As Integer, yBound As Integer, ThirdBound As Integer, fieldcount As Integer, NewBoundY As Integer, Z As Integer

    Dim Boundarynum As Integer
    Boundarynum = 0
    Dim Boundarynum1 As Integer
    Boundarynum1 = 0
    fieldcount = UBound(vFields, 1) + 1
    xBound = UBound(vArray, 1)
    yBound = UBound(vArray, 2)
    NewBoundY = fieldcount * (fieldcount + 1)
    ReDim DataArray(0 To 20, 0 To (xBound + 1))
    'using a static size for the array for now. Will try and make it the same size as the bloomberg array


   'TRANSFORMING ARRAY FROM BLOOMBERG


    For x = 0 To xBound
        For y = 0 To NewBoundY
            For Boundarynum1 = 0 To yBound
        On Error Resume Next
        DataArray(Boundarynum, Boundarynum1) = vArray(x, y)(Boundarynum1)

        Next
        Boundarynum = Boundarynum + 1
       Next
            Next
    'TRANSFORMING ARRAY FROM BLOOMBERG

    'set CUSIP in array
    y = 0
    Dim counter As Integer
    counter = 0
    For Z = 0 To 20

    If DataArray(Z, 0) = "" Then
    Debug.Print ("")
    counter = 1
    ElseIf counter = 1 And DataArray(Z, 0) <> "" Then
    y = y + 1
    DataArray(Z, 3) = vCUSIPS(y)
    counter = 0
    Else
     DataArray(Z, 3) = vCUSIPS(y)
        End If
        Next
    'set CUSIP in array

   For x = 0 To 20

        With rs
            .AddNew
            For y = 0 To yBound

'                    On Error GoTo Line1
'                     If vArray(x, y) = "NA" Then
'                    TEST = "This is a test"
'                    End If
'Line1:

                    .fields(y) = DataArray(x, y)







            Next
            .Update


        End With
    Next
    'Call fImmediateWindow(vArray)

ErrorHandler:

    If Err.Number <> 0 Then
        Dim vMsg As String
        vMsg = "Error # " & Str(Err.Number) & " was generated by " & Err.Source & Chr(13) & "Error Line: " & Erl & Chr(13) & Err.Description
        MsgBox vMsg, , "Error", Err.HelpFile, Err.HelpContext
    End If

    rs.Close
    Set rs = Nothing
    db.Close
    Set db = Nothing
End Sub
'''

enter image description here

Так выглядит массив Bloomberg, когда я получаюЭто. Я не уверен, как действительно обойти это. Массив из вышеприведенной программы просто становится пустым.

1 Ответ

2 голосов
/ 07 ноября 2019

Каждый элемент массива Bloomberg возвращает 2 набора данных. Ключ состоит в том, чтобы ваш массив имел удвоенное количество элементов в массиве Bloomberg верхнего уровня.

Sub ConvertBloombergTestData()
    Dim r As Variant
    r = getBloombergTestData

    Dim Values  As Variant
    Dim n As Long
    Dim j As Long
    Dim Item
    ReDim Values(1 To (UBound(r) + 1) * 2, 1 To 2)
    For n = LBound(r) To UBound(r)
        j = j + 1
        Item = r(n, 0)
        Values(j, 1) = Item(0)
        Values(j, 2) = Item(1)
        Item = r(n, 1)
        j = j + 1
        Values(j, 1) = Item(0)
        Values(j, 2) = Item(1)
    Next

End Sub

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

Sub Test()
    Dim r As Variant, Values  As Variant
    r = getBloombergTestData
    Values = ConvertBloombergArrayTo2d(r)
End Sub

Function ConvertBloombergArrayTo2d(BloombergArray)
    Dim Map As New Collection

    FlattenArray Map, BloombergArray

    Dim Results As Variant
    ReDim Results(1 To Map.Count / 2, 1 To 2)
    Dim n As Long, j As Long

    For n = 1 To Map.Count Step 2
        j = j + 1
        Results(j, 1) = Map.Item(n)
        Results(j, 2) = Map.Item(n + 1)
    Next
    ConvertBloombergArrayTo2d = Results
End Function

Sub FlattenArray(Map As Collection, Element As Variant)
    If Right(TypeName(Element), 2) = "()" Then
        Dim Item
        For Each Item In Element
            FlattenArray Map, Item
        Next
    Else
        Map.Add Element
    End If
End Sub

Locals Window

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