How to access a constant defined in another Excel workbook? - vba

Question
How do I access a public constant defined in another Excel workbook?
Setup
Workbook.xls
My VBA code runs in the current Excel workbook called "MyWorkbook.xls".
It has some VBA code in it which reads a file name --"OtherWorkbook.xls in this case-- from cell "A1". Then, the code should read a constant defined in that other workbook and write it to cell "A2". Here is what my code looks like:
Sub GetValueFromOtherWorkbook()
otherWorkbook = Range("A1").Value ' Value = "OtherWorkbook.xls"
Dim returnedValue As String
' Idea 1: Doesn't work
Set returnedValue = OtherWorkbook.xls!Module1.MY_CONSTANT
' Idea 2: Doesn't work either
Set returnedValue = Application.Run(otherWorkbook & "!Module1.MY_CONSTANT")
Range("A2").Value = returnedValue ' MY_CONSTANT = "testValue"
End Sub
OtherWorkbook.xls
The second Excel workbook is called "OtherWorkbook.xls" as mentioned above.
It has a VBA module called Module1.
Module1 defines a public constant. The code looks like this:
Public Const MY_CONSTANT As String = "testValue"
Problem
The code from MyWorkbook.xls does not run, it returns the following error
Run-time error '424'
Object required
I don't quite know what to do with it even after reading the help documentation. In another context, I managed to call a routine in another workbook with this code:
otherWorkbookName = "OtherWorkbook.xls"
Application.Run (otherWorkbookName & "!Module1.SomeRoutine")
So, calling a routine works, but accessing a public constant does not.
Any ideas what I could try next?

A code module is not an object that can be accessed like a worksheet.
You can access and manipulate it, but in order to do that you need to reference the Microsoft Visual Basic for Applications Extensibility library and allow access to the VBA project (Tools - Options - Security - Macro security - Trusted publishers - Trust access to VBA project), after which you can use the Workbook.VBProject property of the second workbook.
You don't need to do this. Instead you can create a reference to the other workbook: in VBA IDE, go Tools - References, click Browse and locate your workbook with the constant.
If that's no good, you can create a method in that workbook that only returns the value of the constant, and call it as you have demonstrated.

Related

How To Call a Subroutine From Another Object

I am not entirely sure if this is possible, but assuming with us being able to set object references I don't see why not.
To start off, the object that contains the subroutine in question is Excel itself. I am wanting to call one of Excel's VBA subroutines using a different program's VB6 script editor.
I have tried the following without success, but hopefully you can see what I am trying to accomplish here:
Sub Excel_Test()
Dim appXL As Object
Set appXL = GetObject(, "Excel.Application")
Call appXL.Project1.Module1.Test()
End Sub
Obviously this code is not working - but what would be the proper Syntax (if one exists) to call the Macro Test, located in Module1 contained in Excel's object?
You can automate other instances of excel if you identify them by some criteria like the workbook name,
try like
Code:
set otherinstance = getobject(,"fullpath\filename.xls")
otherinstance.application.run "macroname"

Global worksheet variable for userform in excel

I am building a userform that adds data to a worksheet. I have a bunch of sub-routines for my userform, but I'm having issues accessing the variable I set to my worksheet. It's currently a local variable (in a sub) and have tried placing it in a module as discussed here: Can a worksheet object be declared globally in Excel VBA. I've done some further searching but didn't quite get the results I wanted.
I'm quite new to VBA and new to programming in general. I've used Excel quite a bit and want to do more by creating macros and such using VBA. Here's the code I'm currently using:
sub savebutton_click()
Dim trees As Worksheet
Set trees = ThisWorkbook.Sheets("Sheet1")
trees.Cells(1, 1) = Me.TextTreeName
trees.Cells(1, 2) = Me.TextTreeType
End sub
Obviously I cannot access local variables from another subroutine, so I have to make 'trees' global. I created a module and replaced Dim with Public, placed the second line of code in Workbook_Open(), and then tried accessing the 'trees' variable. I get an "Invalid outside procedure" and highlights the code in Workbook_Open() when I hit 'Debug'.
Essentially I just want to be able to access, say, trees.Cells(5,6) from any sub and I'm not sure what else to do with it. Any ideas? Thank you!
It must be a matter of placement ... if you open the VBA IDE and select the ThisWorkbook item in your VBAProject. Double click that item to open it, Select Workbook in the top left dropdown, Select Open in the top right dropdown. This will create your Workbook_Open Sub in the ThisWorkbook object:
Private Sub Workbook_Open()
Set trees = ThisWorkbook.Sheets("Sheet1")
End Sub
Right click your VBAProject and Add Module. In that module you put the global variable:
Public trees As Worksheet
Next you create your form, put the button on that and double click the button. This will generate the button event:
In my case:
Private Sub CommandButton1_Click()
trees.Cells(1, 1) = Me.TextTreeName
trees.Cells(1, 2) = Me.TextTreeType
End Sub
Now if you close the Excel Workbook (save the code and the workbook first) and reopen the Workbook the Workbook_Open() will kick in and set the Worksheet. Now call your Form, and click the button. This will fill the two cells on the given sheet....

transferring variable form one workbook to another workbook vba

I am creating a userform (userform1) in workbookA and in the userform, I'll be needing a module(module1) created in other workbook (workbookB) to made some calculation. In order to launch the calculation, the module need some info (TTAA, tolerance). I would really love to know the easiest way to transfer some variable from userform1(workbookA.userform1) to module1(workbookB.module1) and re-transfer the results to userform1.
below, you can find a small part of the programm which I've coded to call the module.
TTAA = CDbl(Me.TTAA_textbox.Value)
tolerance = CDbl(Me.tolerance_textbox.Value)
application.Run ("'Workbooks.xls'!module1")
I've declared as public, the variable TTAA and tolerance in the module1
The easiest way (which I know to work) is to temporarily "save" the variable on a sheet in one of either file and then reference it as
Worksheets.Add.Name = "tmp"
Workbooks(WorkbookA.Name).Worksheets("tmp").Range("A1").Value2
'And remove it later on
Application.DisplayAlerts = False
Workbooks(WorkbookA.Name).Worksheets("tmp").Delete
Application.DisplayAlerts = True
An alternative might be to declare the subs in WorkbookB as functions. Apart from public variables this is the only way to get return values (in a native format) from independent VBA code segments. Yet, if you had no luck with public variables I doubt this will work.
But why don't you import the module into WorkbookA instead? The following SO answer might be able to help you with that.
Writing a macro that writes a macro to another Excel-file

Open new workbook, and run macro, using button

I have a workbook that runs a large multitude of macros, all based on which button is clicked.
I need one of the macro to open a new workbook, and import two files into the workbook (that part I can do).
The second part is that I need it to run a particular macro, in the new workbook. The macro would be stored in the original workbook.
I've seen some suggestions that I need to use APPLICATION.RUN, which has the parameters of having to choose a workbook and name of the routine.
Does this method work?
Assuming it does:
For the workbook, do I need to specify the file path, or just the workbook name?
For the macro, do I need to make the macro public?
Do I need to specify the module it is in?
Are there any other parameters I need to specify to get this method to work?
Is there another method that might work, if APPLICATION.RUN does not work?
What you need to use is :
Application.Run "'FileName.xlsm'!MacroName", "Parameters"
You don't need to specify the path if your workbook is already open, you don't need to specify the module as you can't have doubloons names for different procedures, and there are no other parameters needed.
The procedure doesn't need to be public (let me know if it does), and for alternative methods in VBA, there is none (as the Call method only work in the same workbook), but there are some in VB if this doesn't work out.
Here is a very short example that you can adapt:
Sub demo()
Dim Original As Workbook
Dim Created As Workbook
Set Original = ThisWorkbook
' create a new workbook
Workbooks.Add
Set Created = ActiveWorkbook
' go back
Original.Activate
'make a change in the newly created workbook
Created.Sheets("Sheet1").Range("A1").Value = "whatever"
' save the newly created workbook
Created.Save
Created.Close
End Sub

Excel VBA, Get the value of a private worksheet constant

I want to retrieve the value of a worksheet-code-level private constant via VBA. I'm trying to do something similar to having "tags" on my worksheets that are accessible via VBA. I'd like to use the CodeModule in the VBAProject so that I can have a number of "tags", not just one. I just can't figure out how to grab the constant, even after reviewing much code and forums on-line. Does anyone have any insight on this? I am running Excel 2013 on a Windows 8.1 machine.
Maybe the easiest way to do this is to have a function that can the value of a private constant with a public accessor method. For instance, if you have the following code in your worksheet Sheet1:
Private Const myValue = "the answer is 42"
Public Function getSecret()
getSecret = myValue
End Function
Then you can access it from another module with
Sub test()
Dim sheetName = "Sheet1"
MsgBox "The sheet says that " & Sheets(sheetName).getSecret()
End Sub
You can make this fancier - you could create a collection of tags and index them… but I think that goes beyond the question you had. Note that you have to "fully qualify" the name of the accessor macro when it is in a worksheet; the advantage is that you can use the same function to examine the tag of different worksheets just by changing the sheetName.
I would export the code to a .BAS file. You can then read the material back in as a text file and retrieve the constant