Does anyone know the VBA Code that I need to use so that I can automatically “Refresh” and “Refresh All” using EPM (Hyperion) Smartiew? The “Refresh” function pulls the data into Excel on the active tab where the “Refresh” all function refreshes all tabs in the Workbook.
I’d like to create a simple macro attached to a command button in Excel and I’m not sure which VBA code to use.
I tried recording a macro where by I simply starting recording clicked refresh and stop recording although this did not work.
I tried this code just for the refresh:
Declare Function HypMenuVRefresh Lib "HsAddin.dll"() As Long
Sub MRetrieve()
X = HypMenuVRefresh()
End Sub
But received an error message saying that I had to update the declare method for use with a 64 bit system (I am using a 64 bit system).
Does anyone know how I could create this automatic Macro to refresh the data?
Any help would be much appreciated!
The declaration for x64 in VBA is not correct.
Try:
Private Declare PtrSafe Function HypMenuVRefresh Lib "HsAddin" () As Long
Sub refreshWS()
Dim Count, i As Integer
i = 1
Count = Worksheets.Count
Do While i <= Count
Sheets(i).Select
MsgBox Sheets(i).Name
Call HypMenuVRefresh
i = i + 1
Loop
MsgBox "done"
End Sub
Use the function calls that basically simulate pressing the buttons!
Refresh current worksheet
Declare Function HypMenuVRefresh Lib "HsAddin.dll" () As Long
lngReturn = HypMenuVRefresh()
Refresh All Worksheets
Declare Function HypMenuVRefreshAll Lib "HsAddin.dll" () As Long
lngReturn = HypMenuVRefreshAll()
*NOTE : Return value of 0 is 'OK'
HypRetrieveRange can refresh or update a range of information, there are also a number of other functions that might suit what you want depending on how much information you need to refresh. Did you import the entire smartview.bas file like they recommended?
Sub Refresh()
'
' Refresh Macro
' Macro recorded 8/12/2011 by joao-oliveira
'
Dim oBar As CommandBar
Set oBar = Application.CommandBars("Worksheet Menu Bar")
oBar.Controls("Hyperion").Controls("Refresh").Execute
End Sub
This worked for me. You'll be able to assign this macro to any button. Instead of using the refresh all function, I am using the HypMenuVRefresh function within each worksheet.
Sub refreshWS()
Dim Count, i As Integer
i = 1
Count = Worksheets.Count
Do While i < Count
Sheets(i).Select
Call HypMenuVRefresh
i = i + 1
Loop
MsgBox "done"
End Sub
Create a button and assign it a new subroutine. Use the call command to call the public function.
Sub RefreshHFM()
'
' RefreshHFM Macro
'
Call HypMenuVRefreshAll
'
End Sub
Related
I have a workbook which I use to value my investment portfolio. It includes UDFs which scrape data from some websites where Excel's stocks data type is not available. The UDFs work well but they take a little time to calculate. I would like for the UDFs to only run when I hit F9 but not when I open the workbook but I can't work out how to achieve this. Is there something like "If running as part of loading up the workbook then do this..."?
I have Calculation=Automatic and Application.Volatile(False).
Thank you for any suggestions.
I'm not sure it's necessary, here is one of the UDFs:
`
Function GetLSEPrice(ticker As String) As Double
Application.Volatile (False)
Dim driver As New ChromeDriver
Dim url As String
Dim y As Selenium.WebElement
url = "https://www.londonstockexchange.com/stock/" & _
ticker & _
"/united-kingdom/company-page"
driver.AddArgument "--headless"
driver.Get url
Set y = driver.FindElementByClass("price-tag")
GetLSEPrice = CDbl(y.Text)
End Function
`
The following should do it;
Step 1) - Create a New Property in your Workbook - to count how many times the various UDFs are called
Step 2) - Add Code in the UDF's to Test that Counter
I've Added Code to the SheetSelectionChange Event (Just to help trigger the UDF's)
AS follows;
Public UDFCallCtr As Long
Private Sub Workbook_Open()
ThisWorkbook.UDFCallCtr = 1 ' Not Really Reqd
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Application.CalculateFull
End Sub
This is the UDF I've tested it with
Public Function UDFTester() As String
If ThisWorkbook.UDFCallCtr > 5 Then ' Change 5 to any value that works for you
' Put you Code here
UDFTester = "Time is now " & Now()
' Done
Else
UDFTester = "NOT READY YET"
ThisWorkbook.UDFCallCtr = ThisWorkbook.UDFCallCtr + 1
End If
End Function
The following may help show where the code goes
I encounter a weird problem that I believe is related to Excel behavior, rather than to my code.
I have a global variable named "numEtape", which is an integer. My code consists in several steps where the user has to type data on a sheet, then press a button which saves the data in an array and increments the "numEtape", before going to the next step.
The code (simplified) looks like this :
Dim numEtape As Integer
Sub AjoutEssai()
numEtape = 2
UFPreAjoutInfos.Show 'Unrelated Userform that asks user for more informations, but doesn't modify "numEtape" or call any other macro
Call InterfaceFiller
End Sub
Sub InterfaceFiller()
Dim rangedubtn As Range
Dim btnPrecedent As Button
Select Case numEtape
Case 2
'Change value of some cells
Case 3
'Change value of some cells
Case 4
'Change value of some cells
Case Is >= 5
'Change value of some cells
Case Else
Debug.Print "Error"
End Select
Set rangedubtn = Sheets("Interface").Range("M3")
Set btnPrecedent = Sheets("Interface").Buttons.Add(rangedubtn.Left, rangedubtn.Top,rangedubtn.Width, rangedubtn.Height)
With btnPrecedent
.OnAction = "mSuivant"
.Caption = "Suivant"
.Name = "btnSuivant"
End With
End Sub
Sub mSuivant()
numEtape = numEtape + 1
Call InterfaceFiller
End Sub
I don't think the code itself is important, what I can expect from it, since I first call AjoutEssai(), is for numEtape to always be greater than 2.
However, when during the steps the user opens and close other excel/office files (that don't have any vba code/macros in it), excel seems to empty numEtape, which makes the Select Case go to the Case Else.
When does excel remove global variables from memory, and is there a way to prevent this behavior from happening?
Public numEtape As Long
A viable option is to use the word public like public numEtape As Long.
Then the variable will be saving its value for as long as the Excel workbook is opened. In older versions of VBA the word was Global (What is the difference between Dim, Global, Public, and Private as Modular Field Access Modifiers?)
Dim numEtape As Long
For using Dim outside of Sub or Function, the variable will be emptied, after the code is over. Take this snippet only:
Dim numEtape As Long
Sub MainTest()
numEtape = 23
End Sub
Once you run it and you hit End Sub the variable would be emptied as well. Check after running the MainTest():
Sub PrintingVariable()
Debug.Print numEtape
End Sub
If you want to save the value, there are 2 basic ways that work:
Write the value in an excel cell
Write the value in a database
I have a macro running sheets in excel where the data being shown is connected to an external database. I am trying to have the data that is being shown refreshed as the data source is updated, all while the macro is running. To be clear, by "running" I mean the macro is displaying each sheet in the workbook for a number of seconds and just looping.
Here is the code:
Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As
Long) As Integer
Public Sub Switch()
Dim ws As Worksheet
Do
For Each ws In ThisWorkbook.Worksheets
ws.Activate
Application.Wait Now() + TimeValue("00:00:05")
If GetAsyncKeyState(vbKeyShift) Then Exit Sub
DoEvents
Next ws
Loop
End Sub
I have tried to insert ActiveWorkbook.RefreshAll just before 'Next ws' and I have also tried ThisWorkbook.RefreshAll in the same location.
As of now, when I am told the data has been updated, I stop the macro from running, which lets the data refresh, then I run the macro again. This is what I am trying to avoid having to do.
Thank you in advance for your help.
Thanks,
Derek
You can turn screen updating on or off during execution of your macro. The macro will run slower with it on.
Application.ScreenUpdating = True
I am trying to create a piece of code that links to a certain sheet after a certain amount of time of inactivity, what I mean by inactivity is not switching through sheets, so when somebody is clicking on sheets that counts as activity but as soon as its been on the same sheet for an amount of time I want it to switch to sheet 1 (sheet 1 is linked to a presentation and will act much like a screensaver would)
Here is my code in ThisWorkbook
Private nTime As Date
Const proc As String = "SelectIndex"
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Source As Range)
Call SetTimer
End Sub
Private Sub SetTimer()
If nTime <> 0 Then
Call Application.OnTime(EarliestTime:=nTime, Procedure:=proc, Schedule:=False)
End If
nTime = Now + TimeValue("00:00:05")
Application.OnTime nTime, Procedure:=proc
End Sub
This works for entering data, when somebody doesn’t enter data for so long it goes to my sheet, but I want it to do it if somebody isn’t switching sheets because nobody has access to enter data anyway, just view the sheets.
It also only works once, when you cancel the presentation and try it again I get the error
"Run time error '1004' Method 'OnTime' of object '_ Application'
Failed "
Just these two problems to overcome and I would really appreciate it if anyone could help J
For information, the procedure SelectIndex is just a macro that switches to sheet 1
If I understand the question correctly, you could trigger the timer within the Sheet_Activate event:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call SetTimer
End Sub
I have a worksheet that automatically gets updated with live stock price data. At the moment we have a very messy solution of copying periodically to the clipboard and manipulating the data from there.
Is it possible to instead automatically export data to CSV every time a price change is detected? I'm guessing it would involve VBA.
You can treat excel file as a data source and you may query it.
See google results: http://www.google.ro/#sclient=psy&hl=ro&q=excel+data+source+sql+query&aq=0&aqi=g1&aql=&oq=&pbx=1&fp=b0efac6ab816e29b
I will try to find a specific article for you.
I'd suggest the following strategy:
Fire up your worksheet and switch into "design mode"
Right-click the button which updates the stock info and try to find out to which macro the button is bound to
Open the VBA editor (ALT+F11)
Choose the "Workbook"-Section
From there select the "Open" Event/Method
Write a simple loop with a delay which calls the macro mentioned above periodically and programmatically save the excel-sheet as CSV
The code would be somthing like this (can't check it as I don't have access to excel right now):
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Sub Workbook_open()
Do While True
Call name_of_macro()
ActiveWorkbook.SaveAs Filename:= _
"c:\path/to/file.csv", FileFormat:=xlCSV _
, CreateBackup:=False
Sleep 10000 'Sleep 10 seconds
Loop
End Sub
This example is just intended to show a rough solution. As Jean-Francois pointed out, this piece of code will NOT update everytime a change is detected, it will update every 10 seconds, even if the data is still the same.
You can use an Application.OnTime to set up a function to get called on a regular basis.
The following function gets called by Excel every 30 seconds. Either call it once to kick off the schedule or just set Application.OnTime once when your worksheet opens to get it running.
Public Sub DoExport()
' do your export to CSV logic here
Application.OnTime Now + TimeValue("00:00:30"), "DoExport"
End Sub
This will do the trick:
Sub LoadNewValuesAndCheckForChange()
Dim rngMyValues As Range
Dim varBefore As Variant
Dim varAfter As Variant
Dim iRow As Long
Dim iCol As Long
Dim booValuesHaveChanged As Boolean
Set rngMyValues = Range("B4:D9") ' Or wherever your data is
varBefore = rngMyValues ' Save old values in an array
' Call the function that loads your new stock prices here...
varAfter = rngMyValues ' Get new values
' Loop through all cells to see if anything has changed.
booValuesHaveChanged = False
For iRow = LBound(varBefore, 1) To UBound(varBefore, 1)
For iCol = LBound(varBefore, 21) To UBound(varBefore, 21)
If Not varAfter(iRow, iCol) = varBefore(iRow, iCol) Then
' Change detected!
booValuesHaveChanged = True
End If
Next iCol
Next iRow
If booValuesHaveChanged Then
' Save .csv file with timestamp in filename
ActiveWorksheet.SaveAs _
Filename:="c:\myfile" & Format(Now, "yyyymmddhhnnss") & ".csv", _
FileFormat:=xlCSV
End If
End Sub