I recently started programming with .NET visual basic using visual basic studio. I am also using excel VBA to make some macros. I would be very appreciative if someone could answer a question I have, apologies if the answer is obvious, I'm just getting started:
Basically, if I have set a variable in excel VBA, for example:
dim text as string
text = "hello world"
Would it be possible for me to use that variable when programming in visual basic and have it retain its value from when it was set in the excel VBA macro.
Please comment if you need clarification.
Many thanks.
SOLUTION:
Okay I managed to figure it out with the help of the solutions, the code that works in VB is as follows:
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Core
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim oxl As excel.application
Dim owb As excel.workbook
Dim osheet As Excel.worksheet
Dim orng As excel.Range
Dim strtext As String
oxl = CreateObject("Excel.application")
owb = oxl.Workbooks.Open(Filename:="C:\Users\USERNAME\Documents\Variable Passing Test.xlsm")
oxl.Run("dosomethingtostrtext")
strtext = oxl.Run("getstrtext")
MsgBox(strtext)
End Sub
End Class
One way to access variables in another workbook's VBA code is to create functions that return those values to you. Then call those functions from your other app.
For example, let this be code in a module in your Excel file with the macro:
Option Explicit
Private strText As String
' Say you have a routine that manipulates strText (or not, even!)
Public Sub doSomethingToSTRTEXT()
strText = "Hello World!"
End Sub
' This is the function to call to retrieve strText
Public Function getSTRTEXT() As String
getSTRTEXT = strText
End Function
And this is code in a VBA project elsewhere (not running .Net on this machine, just microsoft office sad) where you have this:
Option Explicit
Sub Test()
' Declare
Dim WBK As Workbook
' Open the workbook in question
Set WBK = Workbooks.Open(Filename:="C:\Path\To\File\With\VBA.xls")
' This code's own variable
Dim strText As String
' Call the routine (or not) that does something to that workbook's vba's strText
Application.Run (WBK.Name & "!doSomethingToSTRTEXT")
' Now let's retrieve that value via function!
strText = Application.Run(WBK.Name & "!getSTRTEXT")
' Show it to me
MsgBox strText
End Sub
I would like to leave the conversion of the code right above ^ into VB.Net to you (or do a search here on SO for .Net code to handle Excel objects) and try it out
Related
I'm trying to create a macro (in PERSONAL.XLSB) that every time a workbook is opened, it checks a condition and in if it's true (this means the workbook opened contains an specific Sub), it calls this Sub.
Option Explicit
Private WithEvents App As Application
Private Sub Workbook_Open()
Set App = Application
End Sub
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
If condition Then Call Specific_Sub
End Sub
It runs fine when I open a file that contains that Sub, however, if the Sub is not in the file, the compiler returns the error “Sub or Function not defined”, naturally.
I’m trying very hard to find a way to do this and deal with the error, but On error GoTo doesn’t work because the compiler error is before the run time, so it’s not executed.
I guess I have to do this in a different way but I can’t picture how to do it, any help or ideas?
Thanks a lot!
Thanks to the answers I've discovered that the best way is to use Application.Run. To keep the code as simple as possible, I just changed the last part to look like this:
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
On Error Resume Next
If condition Then
Application.Run ("'" & ActiveWorkbook.FullName & "'!" & "Specific_Sub")
End If
End Sub
Thank you all.
I cobbled this together from a few web sites. The key is that your sub routines name is in a variable and application. run uses the variable. This gets past the compiler error you are running into
Sub SubExists()
Dim ByModule As Object
Dim ByModuleName As String
Dim BySub As String
Dim ByLine As Long
'
'Module and sub names
ByModuleName = "Module1"
BySub = "Specific_Sub"
On Error Resume Next
Set ByModule = ActiveWorkbook.VBProject.vbComponents(ByModuleName).CodeModule
ByLine = ByModule.ProcStartLine(BySub, vbext_pk_Proc)
If Err.Number = 0 Then
Application.Run BySub
End If
End Sub
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
SubExists
End Sub
I'm trying to read/write an .xlsx file with vb.net, but I have some problems. I'm using the following code:
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fileTest As String = "C:\testFile.xlsx"
Dim oExcel As Object
oExcel = CreateObject("Excel.Application")
oExcel.Workbooks.Open(fileTest)
Dim oBook As Excel.Workbook
Dim oSheet As Excel.Worksheet
oBook = oExcel.ActiveWorkbook
oSheet = oExcel.Worksheets(1)
oSheet.Range("C2").Value = "testing c2"
oExcel.DisplayAlerts = False
oBook.SaveAs(fileTest, 51)
oBook.Close()
oBook = Nothing
End Sub
End Class
What I get is this dialog:
And when I open the testFile.xlsx I get just a bunch of some awkward symbols.
What might be the issue (that I suspect) is the thing that there are two versions of Excel application on my computer: Excel 2007 and Excel 2003, in order of installation. When I go to Task Manager, Excel applicaton which is running is 2003 version (which can't handle .xlsx files).
Maybe the solution could be to force vb.net application to use 2007 version of Excel, but I don't know how to do that (if it's even possible).
Any help would be appreciated.
And I have tried number of codes found on internet for reading .xlsx files, but with no success.
you need to update your Interop dll to point to your 2007 excel assembly. Try this for reference:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/87e65b6a-f211-4b4a-9d42-a264dcf2a6f4/microsoftofficeinteropexceldll?forum=csharpgeneral
So it's obviously easy to write code that will call a sub/function that is in an add-in library via VBA code, simply by doing
call myFunctionOrSub
However, is there a way to allow users to directly call public subs in an add-in? For example, when the user goes to Tools -> Macros and pulls up this screen:
I would like to add to the list of macros in that box all Subs which are included in add-ins that are linked to for the file. That is, I have a library (library.xlam) that is referenced by this current workbook. In this library.xlam file, I have Subs (such as copyToResults). I want copyToResults to appear as a runnable macro in this list. Is there a way to do that?
The only solution I could come up with was to create a Sub in my test file for each Sub in library.xlam. This Sub in the test file would do nothing by call library's Sub. However, this is terrible for the purpose of having external libraries and terrible for scalability, so we definitely don't want to go this route.
Make a form in your xlam with a list box.
Use the script from this post to populate your form. You will have to change some excel settings.
Get a list of the macros of a module in excel, and then call all those macros
Here is my code from my form:
Private Sub btnCancel_Click()
Unload Me
End Sub
Private Sub btnExecute_Click()
Application.Run "macros.xlam!" & lstMacros.Value
Unload Me
End Sub
Private Sub UserForm_Initialize()
Dim pj As VBProject
Dim vbcomp As VBComponent
Dim curMacro As String, newMacro As String
Dim x As String
Dim y As String
Dim macros As String
On Error Resume Next
curMacro = ""
Documents.Add
For Each pj In Application.VBE.VBProjects
For Each vbcomp In pj.VBComponents
If Not vbcomp Is Nothing Then
If Not vbcomp.CodeModule = "Utilities" Then
For i = 1 To vbcomp.CodeModule.CountOfLines
newMacro = vbcomp.CodeModule.ProcOfLine(Line:=i, _
prockind:=vbext_pk_Proc)
If curMacro <> newMacro Then
curMacro = newMacro
If curMacro <> "" And curMacro <> "app_NewDocument" Then
frmMacros.lstMacros.AddItem curMacro
End If
End If
Next
End If
End If
Next
Next
End Sub
In the end mine looked like this:
Macros Form
I want to select the Cell A3 using VB.net..
I tried doing this by:
sheet.Range("A3:A3").Select()
But this gives an exception = Select method of Range Class Failed !
What is the problem and how to do it ?
Please help.. I am waiting for the reply !
Assuming you meant Excel VBA try this:
sheet.Range("A3").Select
You can just specify the cell if all you want is one cell.
This program works for me in VB.NET, I agree with rajah9, check the other aspects.
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
oExcel = CreateObject("Excel.Application")
oBook = oExcel.Workbooks.Add()
oSheet = oBook.Worksheets(1)
oSheet.Range("A3").Select()
oExcel.ActiveCell.Value = "Put text here"
oBook.SaveAs("C:\Path\testinterop.xlsx")
oExcel.Quit()
End Sub
End Class
(based on, and drawn in part from, examples here)
How to pass arguments to Excel VBA code called from Outlook?
By using Application.Run:
objExcel.Run "MacroName", param1, param2
You can execute a macro via the Application.Run method. This method takes the macro name as the first argument and then up to 30 parameters that are passed as arguments to the macro.
In Outlook use the following code:
Public Sub RunExcelMacro()
Dim excelApp As Object
Set excelApp = CreateObject("Excel.Application")
excelApp.Visible = True
' open the workbook that contains the macro
' or place the macro in a workbook in your XLSTARTUP folder
excelApp.Workbooks.Open "C:\tmp\book.xls"
' run the macro
excelApp.Run "ThisWorkbook.SayHello", "Hello World!"
excelApp.Quit
Set excelApp = Nothing
End Sub
In Excel, add the following method to the ThisWorkbook element of a spreadsheet document:
Option Explicit
Public Sub SayHello(message As String)
MsgBox message
End Sub