VBA to trigger Market Data Engine restart - vba

I have PPP.xla, DDE.xla, PPPInit.xla Add-in installed.
But I don't know the Protected Password for those Add-in.
If I want to trigger [Market Data Engine Restart], which function i should call?
Call Application.Run("???")
The reason I want this is becoz sometimes when I use RtHistory("IDN", ,,,), it does not work (return "#N/A N/A") unless I restart PowerPlusPro.exe or when i clicked [Restart Data Engine] in the Reuters ToolBar. And I want to automate this RtHistory job by calling Excel using VBScript. Therefore I must have this function name to trigger the restart before fetching data.
Any experts have idea on this? Many thanks.

I had the same problem. I solved it by re activating the powerplus pro addin.
sub yourSub()
Dim wbName As String
wbName = ActiveWorkbook.Name
Call activateAddIn("PowerPlus Pro Excel v5.1")
Workbooks(wbName).Activate
end sub
'/**
' ReActivate AddIn
'**/
Public Function activateAddIn(AddinName As String) As Boolean
AddIns(AddinName).Installed = False
AddIns(AddinName).Installed = True
Sleep 5000
End Function
cheers
stephan

Related

Run a MakeTable query in Access from Excel

I have an Excel file that I need to automate. When the user opens the Excel Report, it will prompt if they would like to refresh the data. If they say yes, then I need it to run a MakeTable query that is in an Access database to refresh all the underlying numbers for the report.
I have searched and haven't been able to find anything that actually works.
I tried to even create VBA code inside of Access that I could run that would handle the query, but I can't even get that to run from Excel VBA.
Here is the current code I have along with some of what I have tried that didn't work:
Sub RunAccessMTQuery(ByVal DBLocation As String)
Dim db As Object
Set db = CreateObject("Access.Application")
With db
.OpenCurrentDatabase DBLocation
.Visible = True
' .Run "Main.RunMTJobBond"
' .docmd.runmacro "Main.RunMTJobBond" '<---Module.Proc Name
' .docmd.runmacro "mMTJobBond" '<---Macro name that calls the Proc
.Application.Run "mMTJobBond"
.CloseCurrentDatabase
.Quit
End With
'Below was found on https://support.microsoft.com/en-us/help/131921/running-a-microsoft-access-macro-from-microsoft-excel
' Dim Chan as Long
'Opens Microsoft Access and the file nwind.mdb
' Shell("""C:\Program Files (x86)\Microsoft Office\Office12\MSACCESS.EXE"" """ & DBLocation & """")
'Initiates a DDE channel to Microsoft Access
' Chan = DDEInitiate("MSACCESS", "system")
'Activates Microsoft Access
' Application.ActivateMicrosoftApp xlMicrosoftAccess
'Runs the macro
' Application.DDEExecute Chan, "RunMTJobBond"
'Terminates the DDE channel
' Application.DDETerminate Chan
End Sub
Either I need to be able to run the MakeTable query from Excel, or launch Access and have it run the query. Nothing I have tried has worked...I have gotten numerous errors such as:
Runtime error 5 - Invalid procedure call or arguement
Runtime error 2517 - Application-defined or object-defined error
Others as well, but I don't recall them as I was able to work through those, and these are some of the ones I'm stuck on. Any help would be great, thanks.
The Application.Run() command runs a function or sub procedure, not a macro. That's why the attempts to run the macro do not work.
As for running the function or sub directly, the expected parameter format for Run() is "projectname.procedurename", NOT "modulename.procedurename". Unless you have multiple VBA projects within your database (which I assume you do not), then you don't even need projectname. See documentation here.
Try
Set dbApp = CreateObject("Access.Application")
With dbApp
...
.Run "RunMTJobBond"
This assume that RunMTJobBond is a public function or sub in a standard module.

Issues accessing the user desktop using VBA

I am trying to use VBA in order to save a file on a user's desktop. I have found people requesting similar things on this site and others and the answers usually recommend using the following function to get the file path of the user's desktop
Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
However, I tried this and all I get is a 424 Object required error. The spreadsheet I am trying to add this to is long and complex so I created a new sheet with just the section of code I was interested in.
Sub TestMacro()
Dim Testy As String
Testy = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
MsgBox Testy
End Sub
When I run this macro I still get a 424 object required error. Am I doing something wrong? Or is there something locked down in my office environment preventing me from using this command?
Any help appreciated.
Try with below code
Sub TestMacro()
Set oWSHShell = CreateObject("WScript.Shell")
MsgBox (oWSHShell.SpecialFolders("Desktop"))
End Sub

Writing VBA procedure/function to an .xlam addin

I have created a VBA project in Excel and within said project is a module that writes code to another module. I eventually password protected the project so as to keep the code hidden (not realizing right away that this would pose some pretty obvious issues).
When the user interacts with the file, the module attempts to run the code but, encounters an error (a password protected project can't modify itself! Hey we all have our duh moments :p).
So, as a way around this, I figured 'why not make the portion that is edited unprotected', whilst keeping the remainder of the file locked. So I figured I would create an unprotected .xlam add-in, then write said code to this portion. I am having some difficulty figuring how to do this though however. Below is the code I have written that writes code to another module:
Public Sub errorWrite()
Dim VBComp As VBIDE.VBComponent
Dim CodeMod As VBIDE.CodeModule
Dim s As String
Dim d As String
Dim lineNumb As Long
With ThisWorkbook.VBProject.VBComponents.item("NewModule")
.CodeModule.InsertLines j, "Public sub newModule()"
j = j + 1
With ThisWorkbook.VBProject.VBComponents.item("NewModule")
.CodeModule.InsertLines j, "(my code etc..)"
j = j + 1
With ThisWorkbook.VBProject.VBComponents.item("NewModule")
.CodeModule.InsertLines j, "end sub"
end sub
While I have found some info on Stack and elsewhere regarding .xlam add-ins (Updating an xlam add-in using VBA) for example, I'd rather just keep it as simple as possible. Suggestions and hints are much appreciated. Thanks!
Using an unprotected Addin seems like a reasonable approach. But the code you have posted writes to another Module within the Protected addin. You need to reference the other AddIn as a VBProject
Change the name of your Unprotected AddIn to a unique Name (it defaults to VBAProject and does not have to be unique)
Then create a reference to it like this
Dim VBP As VBProject
Set VBP = ThisWorkbook.VBProject.VBE.VBProjects("NameOfYourUnprotectedAddin")
Then all your code uses this reference instead of ThisWorkbook.VBProject
Eg
With VBP.VBComponents.item("NewModule")
.CodeModule.InsertLines j, "Public sub newModule()"
' etc
End With
so I was able to find a way that seems to work, I wrote the code using FSO, then save the file as a .bas module. From there I used the below to have the module imported directly into the .xlam addin as a module:
Public Sub importBas()
Dim VBP As VBProject
Set VBP = Workbooks("example.xlam").VBProject
VBP.VBComponents.Import ("C:\Users\...example.bas")
VBP.VBComponents.Remove
End Sub
Then, in the original module, I deleted procedure within the xlam after execution was finished. Therefore no code can be seen (assuming I remember to use error-handling and disable break mode :p)
I am still curious how to write it 'directly', so I will play around with it more and see if I get it, although this way works
Thank you :)

VBA function error when other users try to use it

I've made this short function to find whether a name is "given name surname" or "surname, given name", however when this is run by another user (on another PC), the result function In error #NAME? :
Function FindName_Function(NameCell As String) As String
Dim FindComma As Long
Dim FindName As String
FindComma = InStr(1, NameCell, ",")
If FindComma <> 0 Then
FindName = VBA.Right(NameCell, Len(NameCell) - FindComma)
Else
FindName = VBA.Left(NameCell, InStr(1, NameCell, " ") - 1)
End If
FindName_Function = FindName
End Function
This is how the function is called:
This is the formula:
="Hello "&FindName_Function(INDEX(Table_HP_Effective_contact_list;MATCH(SiteID;Table_HP_Effective_contact_list[Site];0);4))&","
I believe you use the function as a UDF (User Defined Function) and the #NAME error indicates that the function can't be found or executed. Make sure you store the UDF on a discoverable location and has permission to run. It is not clear from your question -where- you stored the UDF and what the security settings are on the client machines.
What I did is create a new Workbook, added a new Module to the Workbook, copied the UDF in the Module, used it in a cell on the new Workbook and worked without problems. So my guess from the limited information provided is that you stored the UDF in a different location outside the Workbook, inaccessible for the other users to find.
On a side note:
- the VBA. prefix is not necessarily needed
- test if the name is empty, InStr will fail if the name is empty
If you want a better answer, please elaborate on the location of the UDF (where did you create/store the UDF) and what are the macro security settings currently in place on the machines you see the error on.
if u save the function in the same workbook and saved the workbook in *.xlsm format, then the possible cause is user did not enable macro when opening the file.
if u save the function in the same workbook and saved the workbook in *.xlsx format, then u saved it in the wrong format.
if u save the function in another workbook, then that workbook should be saved in Excel Add-In format (*.xlam) and the Add-in must be loaded in Excel.
hope this helps
+
Try use the insert function window to find the function. Select category = "User Defined".
If the function is listed, then try call it from there.
If the function is not listed, then for sure macro for that workbook is not enabled.

Enabled Add-In Does Not Persist beyond Session

I have a PowerPoint Add-In ("Chart Builder") which when enabled manually (Developer | Add-Ins | Add New) the add-in persists in the Application beyond the session expiration. I.e., I can close PowerPoint, reopen it later, and then the Add-In is still "installed" and available to use.
For ease of distributing updates, I have created another Add-In ("Controller") which checks the version for updates, and installs the most recent version if necessary on user machines.
The Controller calls this from the ribbon onLoad callback:
Option Private Module
Option Explicit
Private rib As IRibbonUI
''Callback for customUI.onLoad
Sub RibbonOnLoad(ribbon As IRibbonUI)
Set rib = ribbon
Call UPDATE(rib)
End Sub
Private Sub UPDATE(rib)
'Debug.Print ObjPtr(rib)
'1 Check for valid network connection:
If NetworkConnected Then
'2 Check the add-in already exists:
If Not AddInExists Then
If Not DoUpdate Then Exit Sub
End If
'3 Call procedure to update the PPAM if needed
If CheckUpdate Then
Application.Run "ChartBuilder_PPT!AddIn_RibbonExtensibility.RibbonOnLoad", rib
Else:
MsgBox "unable to enable the CB ribbon!", vbCritical
End If
Else
'4 The user is not connected to the network
Debug.Print "Not connected to JDPA network."
End If
End Sub
So we check if connected to network (pass) then we check if the Add In already exists, if not then we prompt for update. Then if yes, then Controller downloads the current version from a shared directory path and activates/installs on the user machine.
The problem is that when this add-in is installed, it is always taking me to the DoUpdate function (which prompts the user vbYesNo to update the version).
That function is reproduced below, and ShortName is a public Const representing the ShortName of the Chart Builder add-in.
Function AddInExists() As Boolean
Dim a As AddIn
For Each a In Application.AddIns
If a.Name = ShortName Then
AddInExists = True
Exit For
End If
Next
End Function
QUESTION
Is there some property of the Add-In that I need to set when activating it (I do .Loaded = msoCTrue?
Or are the Add-Ins loaded sequentially, such that when Controller is loaded, Chart Builder is not (yet) and this triggers false negative on the AddInExists() function? And if this is the case, is there anything I can do to change the order of load, or otherwise prevent this discrepancy?
OK, well that didn't take long to figure out during my normal troubleshooting/debugging. Posting the answer in case it is helpful to others.
Is there some property of the Add-In that I need to set when activating it (I do .Loaded = msoCTrue?
Yes. Ensure the .AutoLoad = msoCTrue.