How to refresh/load RTD Bloomberg function (BDH) in excel in vba - vba

I would like to know if there's a way in VBA code forcing the bloomberg functions (In spreadsheet) to update its value( Any BDH functions)
Targeting Developers have faced similar issue/ have Bloomberg terminal
What have I tried--
Application.RTD.RefreshData
Application.RTD.throttleInterval = 0
Application.CalculateFull
The BDH function do not reload themselve.
The only way I can refresh them now is : I click the "Refresh WorkBook" Button on the Ribbon of the BloomBerg add-in.
Since the Bloomberg Add-in is locked in VBE, I cannot find out the necessary code.
Am I missing any Bloomberg Reference? Can any Bloomberg expert/user point me in the right direction? Thanks.

I did a searching of the keyword "refresh" in the xla by opening it in notepad. Found the following targets:
RefreshAllWorkbooks
blpmain.xla!RefreshAllStaticData
blpmain.xla!'RefreshWorkbookFundamentalsData
blp.xla!IsBlpRefreshAvailable
I tried them out one by one,
the first 2 works by calling:
Application.run "RefreshAllWorkbooks"
Application.run "RefreshAllStaticData"
But not calling them alone ( I guess it's because I somehow can call protected PUBLIC procedure using Application.run)
RefreshAllWorkbooks
or
RefreshAllStaticData
Thanks for all the help

I recently received this answer from bbg chat. I think this is what we are all looking for...
bbg helpdesk: Normally we don''t provide help on VBA on the Help Desk but I have found the below.
You can use the following VBA commands to refresh BDx() formulas:
Refresh based on default option setting: Application.Run "RefreshData"
Refresh current selection: Application.Run "RefreshCurrentSelection"
Refresh current worksheet: Application.Run "RefreshEntireWorksheet"
Refresh current workbook: Application.Run "RefreshEntireWorkbook"
Refresh all workbooks: Application.Run "RefreshAllWorkbooks"
Note: When using VBA macros to refresh Bloomberg formulas,
the formulas cannot complete requesting data while the macro that triggered the refresh is running.
You must use Application.OnTime() to schedule a second function to run after the sub-routine that triggered the refresh exits.
The following code snippet demonstrates the VBA code to refresh all workbooks, followed by a 10 second delay before calling the processSheet sub-routine:
Sub refreshSheet()
Application.Run "RefreshEntireWorksheet"
Application.OnTime (Now + TimeValue("00:00:10")), "processSheet"
End Sub
Sub processSheet()
' perform processing here
End Sub

I've found that changing something in the BDH formula would cause a refresh. Find and replace the = sign would do the tick.
Public Sub Recalc()
Dim ws As Worksheet, FormulaCells As Range, c As Range
Application.Calculation = xlCalculationManual
For Each ws In ThisWorkbook.Worksheets
On Error Resume Next
ws.Activate
Set FormulaCells = ws.UsedRange.SpecialCells(xlCellTypeFormulas).Cells
If Err = 0 Then
For Each c In FormulaCells
c.Formula = Replace(c.Formula, "=", "=")
Next 'c
Else
Err.Clear
End If
Next 'ws
Application.Calculation = xlCalculationAutomatic
End Sub

I have never managed to do what you ask for. The only reliable way I have found to get up-to-date data is by calling the API directly from VBA with BLP_DATA_CTRLLib.BlpData, waiting for the answer, and putting the result into a sheet.
With regards to opening password protected VBA code, a google or stackoverflow search should give you your answer.

This works for me:
WS.Select
WS.Range("A5").Select 'the cell that contains the BDH function
Application.Run "RefreshCurrentSelection"

Related

Workbook.Activate method acting strangely

I have an Excel add-in running a procedure that displays an OKOnly MsgBox if a certain criteria is not met, and attempts to close a userform, activate a specific workbook, and terminate code execution. In the UserForm_Terminate() event I have:
Private Sub UserForm_Terminate()
Debug.Print ActiveWorkbook.Name
Application.ScreenUpdating = True
wbk.Activate
sht.Activate
Debug.Print ActiveWorkbook.Name
End
End Sub
If I begin running the procedure with a new blank workbook active, that workbook is still the active workbook when code terminates, but both print statements above indicate that the target wbk is actually active. However if I use a breakpoint and step through wbk.Activate, the target wbk is activated as expected. The workbook and worksheet objects are both available and there is no error. Any ideas why Workbook.Activate is not behaving as expected during execution? I expected turning screenupdating on would solve my issue but no dice.
#barX He's not relying on ActiceWorkbook for code, he's just checking it to see if it's working ....
BTW Welcome to the Excel 2013 SDI bug!
Maybe following the proper way of initializing/using a Userform will help. See Mathieu's RubberDuck article on Userform.Show
On a related note, maybe changing the Parent Window Handle for the form before closing might work as well. See Keeping Userforms On Top Of SDI Windows In Excel 2013 And Up
I'm not sure if the SDI bug is my issue but it did lead me to an answer (thanks #Profex). I was not able to reproduce that bug, and there is also another path in my procedure that ends with the same Userform_Terminate() event and does reactivate the target wbk, though I can't determine what is causing the differing functionality. Nonetheless, one solution to that issue was to hide and then show the active window and that suffices in this case, though probably not ideal in many situations:
Private Sub UserForm_Terminate()
Dim win As Window
wbk.Activate
sht.Activate
Set win = Application.ActiveWindow
win.visible = False
win.visible = True
End
End Sub

How to make vba code to run auto-close only on active workbook?

Here's the scenario. I have multiple excel workbooks that copy and paste data among each other. So the macro works to open.copy.close from one workbook then open.paste.close to another. I am working on creating a function to auto run macro when file is closed.
Here's the issue, when I click macro button in workbook 1, it is supposed to open.copy.close from workbook 2. However, because of the auto run when file is closed function in workbook 2, an error will occur (2 macros cannot run at the same time)Any solution for this? I am looking for a solution to only auto run macro when file is closed IF IT IS AN ACTIVE WORKBOOK. Here is what I have now:
Workbook 1
Sub workbook_beforeclose(cancel As Boolean)
Application.Run "Sheet1.UpdateYellowTabs_Click"
End Sub
Workbook 2
Sub Workbook_BeforeClose(Cancel As Boolean)
Workbook.BeforeClose
Application.Run "Sheet12.UpdateGreen_Click"
End Sub
How do I code it in the workbook code to only make this run only when it's active/closed by a human user and not when open/close by macro?
Thanks!
Well I am not sure to understand your final goal from this, but I can answer the "technical" question. Technically, if you want to check if a given workbook is active: If Application.ActiveWorkbook Is Me,
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not Application.ActiveWorkbook Is Me Then Exit Sub ' <-- add this test
''''''''''''''''''''''''''
' Whatever code goes here
''''''''''''''''''''''''''
End Sub
EDIT
But problem is that invoking wb2.close will make the workbook wb2 the "active" one during the execution of the macro. So this method won't work. Another method is to disable events before closing the workbook; so that the event Workbook_BeforeClose will not fire. After that, you can enable events back if needed. The code looks like this:
' ... open wb2 and do the work with it
Application.EnableEvents = False
wb2.Close False
Application.EnableEvents = True
notice, if you had already disabled events at the beginning of the current macro, which is usually recommended, then this additional code wouldn't be needed.

Close a workbook at a specific time

I have looked everywhere to get an answer to this and can't figure it out. I'm looking for a way to close and save a workbook automatically at midnight every night because it has important information that people keep losing because they don't save it. I've got the closing and saving part down, if I manually click the X to close Excel, but I can't get it to do it at a predetermined time. I've used Application.OnTime without any success. Here is the code that I'm using to close and save the workbook. I just need the code to have it run at midnight if the workbook is still open.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Sheet1.Activate
Sheet1.Range("AB18:AD18").Select
Selection.ClearContents
ActiveWorkbook.Save
End Sub
I had trouble referencing the Worksheet .CodeName property but not with the Worksheet .Name property.
Module1 code sheet
Option Explicit
Sub ScheduleClose()
Application.OnTime Now + TimeSerial(0, 0, 4), "Kamikaze"
End Sub
Sub Kamikaze()
Debug.Print "boom"
Application.DisplayAlerts = False
With ThisWorkbook
.Worksheets("Sheet1").Activate
.Worksheets("Sheet1").Range("AB18:AD18").ClearContents
.Save
.Close savechanges:=False
End With
End Sub
Of course, the workbook must be already saved (i.e. not Book1) since no name is provided but a Workbook.SaveAs method could be used if the workbook habitually is not already saved.
This will also leave 'orphaned' VBA projects within the Excel application 'instance'. VBA cannot kill itself as it has to be running to complete the command.

Shared Excel Document

I've got a Excel documents with macros with input and update forms for information, the document is used as a monthly database where you can run reports from as well.
The issue is that when using the document sometimes the input and update options are used at the same time causing information loss. Both the input and output save at the end of the macro to minimise the losses, but I was wondering if there is anyway of checking at runtime if there is a macro being use by another user and if so delay the next macro run until the other user is finished?
There is one way I can think of. Logically it should work. However I have not tested it.
Create a temp sheet and hide it
When anyone runs a macro, check if cell A1 of that sheet is empty or not
If it is empty then run the macro
Before running the macro, write to that cell and once the macro is run, clear the contents of the other cell
Sandwich your macro code as mentioned below
Code
Sub Sample()
Dim ws As Worksheet
ThisWorkbook.Save
Doevents
Set ws = ThisWorkbook.Sheets("HiddenSheetName")
If Len(Trim(ws.Range("A1").Value)) = 0 Then
ws.Range("A1").Value = "Macro Starts"
ThisWorkbook.Save
Doevents
'
'~~> Rest of your code goes here
'
ws.Range("A1").ClearContents
ThisWorkbook.Save
Doevents
Else
MsgBox "Please try after some time. There is a macro running... Blah Blah"
End If
End Sub
CAUTION: Once the code runs, you cannot undo the changes since the code save the file programatically. The changes are permanent. In a file which is not shared, you can undo by closing the file without saving and re-opening it.

Setting calculation mode to automatic in Excel workbook activate event disables inter-workbook copy-paste

I have a workbook with the following VBA code to ensure the formula calculation mode is set to automatic:
Private Sub Workbook_Activate()
Application.Calculation = xlCalculationAutomatic
End Sub
If I open that workbook (let's call it WB1) and then any other workbook (WB2, opened under the same EXCEL.EXE instance), then I can't copy cells from WB2 to WB1. By "can't" I mean that when I press ctrl-v I hear Windows' "ding" sound and nothing happens.
If I use the following code instead, everything works fine.
' Now in Workbook_Open instead of Activate
Private Sub Workbook_Open()
Application.Calculation = xlCalculationAutomatic
End Sub
Is that behavior expected? Is this documented anywhere? Or is this a bug? Somehow I feel like I can't be the first person to do this.
I've tried with a C# Excel Add-In and using the equivalent Excel Interop code yields the same result.
Ok so I figured this out as I was typing the question but I'll answer anyway if someone else ever wonders...
The issue is that calling Application.Calculation = xlCalculationAutomatic makes the original workbook lose focus (the moving lines around the cells to be copied disappear, as if I had pressed escape).
Since I put my code in Workbook_Activate, it was called every time I went to copy in WB1 and caused my issue.
Moving the code to Workbook_Open is a good enough solution for me, but I like to think that making Excel non-interactive while I'm changing the calculation mode would have worked. I did not test this solution tough.