2011-12-29 95 views
8

Estoy ejecutando una macro en un libro de Excel 2007 en blanco en una PC con licencia de Bloomberg. La macro inserta las funciones de Bloomberg en la hoja 1 que extrae los datos de la curva de rendimiento. Los resultados de algunas funciones adicionales dependen de que las primeras funciones terminen y muestren correctamente los datos Bberg. Cuando paso por el programa, solo muestra '# N/A Requesting Data'. . . ' en lugar de los resultados de la consulta, no importa lo lento que voy. Debido a que algunas de las funciones dependen de que se llenen los resultados de cadena y de campo numérico, el programa alcanza un error de tiempo de ejecución en ese código. Cuando dejo de depurar, terminando de ejecutar el programa, aparecen todos los valores Bberg que deberían haberse llenado. Quiero que estos valores aparezcan mientras el programa todavía se está ejecutando.Los datos de Bloomberg no se completan hasta que finaliza la macro de Excel VBA

He intentado utilizar una combinación de DoEvents y Application.OnTime() para devolver el control al sistema operativo y hacer que el programa espere mucho tiempo para la actualización de datos, pero ninguno de los dos funcionó. Cualquier idea sería útil. Mi código está abajo. wb es un libro de trabajo de nivel global y ws1 es una hoja de trabajo de nivel global.

Public Sub Run_Me()

'Application.DisplayAlerts = False 
'Application.ScreenUpdating = False 

Call Populate_Me 
Call Format_Me 

'Application.DisplayAlerts = True 
'Application.ScreenUpdating = True 

End Sub

Private Sub Populate_Me()

Dim lRow_PM As Integer 
Dim xlCalc As XlCalculation 

Set wb = ThisWorkbook 
Set ws1 = wb.Sheets(1) 

'clear out any values from previous day 
If wb.Sheets(ws1.Name).Range("A1").Value <> "" Then 
    wb.Sheets(ws1.Name).Select 
    Selection.ClearContents 
End If 


xlCalc = Application.Calculation 
Application.Calculation = xlCalculationAutomatic 

Range("A1").Value = "F5" 
Range("B1").Value = "Term" 
Range("C1").Value = "PX LAST" 

Range("A2").Select 
ActiveCell.FormulaR1C1 = "=BDS(""YCCF0005 Index"",""CURVE_MEMBERS"",""cols=1;rows=15"")" 
BloombergUI.RefreshAllStaticData 

Range("B2").Select 
ActiveCell.FormulaR1C1 = "=BDS(""YCCF0005 Index"",""CURVE_TERMS"",""cols=1;rows=15"")" 
BloombergUI.RefreshAllStaticData 

Application.OnTime Now + TimeValue("00:00:10"), "HardCode" 

'******more code*******' 
End Sub 

Sub codificar()

Range("C2").Select 
ActiveCell.FormulaR1C1 = "=BDP($A2,C$1)" 
BloombergUI.RefreshAllStaticData 

End Sub

Respuesta

4

Busqué en Google para BloombergUI.RefreshAllStaticData y fue llevado inmediatamente a esta página Sr. Excel: http://www.mrexcel.com/forum/showthread.php?t=414626

No se supone colocar respuestas que son únicos enlaces en caso que enlazan desaparece y toma la respuesta a ella. Sin embargo, no estoy seguro de entender la pregunta o la respuesta lo suficientemente bien como para resumirla.

El enlace de Google probablemente existirá para el futuro previsible.

Dentro de Mr Excel, la cadena es: MrExcel Message Board> Foros de preguntas> Excel Questions> Bloomberg links and macros.

La información clave parece ser:

en su terminal Bloomberg si escribe en WAPI < GO> encontrará listados de la API de Bloomberg y ejemplos descargables.

Utilizando la información del archivo de ayuda en esa área, podemos construir una solución más robusta para esto utilizando la Biblioteca de tipos de datos de Bloomberg. Ve a Herramientas | Referencias y agregar una referencia a esta biblioteca. Este código se puede utilizar para rellenar las celdas:

Sub Test2() 
    Dim vResults, vSecurities, vFields 
    Dim objBloomberg As BLP_DATA_CTRLLib.BlpData 

    'fill our arrays - must be 1 dimension so we transpose from the worksheet 
    With Application.WorksheetFunction 
     vSecurities = .Transpose(Sheet1.Range("B2:B4").Value) 
     vFields = .Transpose(.Transpose(Range("C1:H1").Value)) 
    End With 

    Set objBloomberg = New BLP_DATA_CTRLLib.BlpData 
    objBloomberg.AutoRelease = False 

    objBloomberg.Subscribe _ 
      Security:=vSecurities, _ 
      cookie:=1, _ 
      Fields:=vFields, _ 
      Results:=vResults 

    Sheet1.Range("C2:H4").Value = vResults 
End Sub 

Una vez que haya probado la solución del Sr. Excel, tal vez usted podría actualizar esta respuesta para el beneficio de los futuros visitantes.

+1

me gusta que me recomienda el uso de la WAPI, pero no creo que se refiere a la pregunta original de por qué hoja de cálculo de la fórmula de BBG no calculan hasta que las macros dejan de funcionar. – rex

6

Una manera de evitar este problema es poner todos los subtítulos, etc que desea ejecutar después de tirar de los datos de Bloomberg en una sub diferente. Debe hacer esto cada vez que llame a Bloomberg información. Si llama a otro sub en el sub "maestro" después de la aplicación.OnTime Now + TimeValue ("00:00:15"), fallará, debe colocar todos los subs en un nuevo sub maestro.

Por ejemplo: En lugar de

Sub Master1() 
Application.Run "RefreshAllStaticData" 
Application.OnTime Now + TimeValue("00:00:15"), "OtherSub1" 
'This will cause the Bloomberg Data to not refresh until OtherSub2 and 3 have run 
OtherSub2 
OtherSub3 
End Sub 

Debe ser

Sub Master1() 
Application.Run "RefreshAllStaticData" 
Application.OnTime Now + TimeValue("00:00:15"), "Master2" 
End Sub 

Sub Master2() 
OtherSub1 
OtherSub2 
OtherSub3 
End Sub 

Espero que ayude

+1

¿Qué haces cuando tienes un bucle for? – JohnAndrews

+0

Todo el asunto simplemente no funcionó cuando hay un bucle for. – mynameisJEFF

0

Recogí un poco de información de toda la web y escribí lo que en mi humilde opinión es una versión mejorada en comparación con todo lo que he encontrado hasta ahora:

Private WaitStartedAt As Double 
Private Const TimeOut As String = "00:02:00" 

Public Function BloomCalc(Callback As String) As Boolean 
    Dim rngStillToReceive As Range 
    Dim StillToReceive As Boolean 
    Dim ws As Worksheet 
    StillToReceive = False 
    If WaitStartedAt = 0 Then 
     WaitStartedAt = TimeValue(Now()) 
    End If 
    If TimeValue(Now()) >= WaitStartedAt + TimeValue(TimeOut) Then 
     GoTo errTimeOut 
    End If 
    For Each ws In ActiveWorkbook.Worksheets 
     Set rngStillToReceive = ws.UsedRange.Find("*Requesting Data*", LookIn:=xlValues) 
     StillToReceive = StillToReceive Or (Not rngStillToReceive Is Nothing) 
    Next ws 
    If StillToReceive Then 
     BloomCalc = False 
     Application.OnTime Now + (TimeSerial(0, 0, 1)), Callback 
    Else 
     WaitStartedAt = 0 
     BloomCalc = True 
    End If 
    Exit Function 
errTimeOut: 
    Err.Raise -1, , "BloomCalc: Timed Out. Callback = " & Callback 
End Function 

Debería una tarea arbitraria llamando a un sub como HacerAlgo()

Public Sub DoSomething() 
    DoSomethingCallback 
End Function 

que llama a una función "callback" que va a llamarse a sí mismo hasta que los datos han sido renovados o el plazo alcanzado

Public Sub AutoRunLcbCallback() 
    If BloomCalc("AutoRunLcbCallback") Then 
     MsgBox "Here I can do what I need with the refreshed data" 
     ' for instance I can close and save the workbook 
     ActiveWorkbook.Close True 
    End If 
End Sub 

Cualquier comentario es apreciado. Una posible mejora podría ser permitir que el libro de trabajo y/o la hoja de trabajo sean una entrada de la función, pero realmente no vi la necesidad de eso.

Saludos

Cuestiones relacionadas