This example shows you how to use J-Integra® to invoke existing VBA (Visual Basic for Application) objects in a Microsoft Excel workbook with pure Java.
You will use J-Integra® to interact with the objects, properties and methods exposed by Microsoft Excel either locally or remotely.
VBA (Visual Basic For Applications) is a macro language that is identical to the Visual Basic programming language. By using VBA you can easily handle objects and collections exposed by Microsoft Office. Since VBA can be embedded inside Excel workbook, you can use J-Integra® to trigger a VBA macro by emulating the end user’s interaction.
You can run the Java client on a Windows machine to access its local Microsoft Excel, or run the Java client on a non-Windows machine (such as Linux) to access Microsoft Excel installed on a remote Windows machine.
Install Microsoft Office (Microsoft Office 2003 is recommended)
Download and install the Java™ Developers Kit
Download and install J-Integra®
Ensure that you have you have installed the J-Integra® license.
Create an empty Excel workbook in C:\Java-VBA\ and name it JInvokeVBA.xls.
In Excel, click Tools > Macro > Visual Basic Editor
Private Sub Worksheet_Activate() Range("B2:B14").Value = 10000 Range("B15").Formula = "=Sum(B2:B14)" Range("B15").Font.Bold = True Range("B15").Font.Color = RGB (0, 255, 0) End Sub Public Function method1(ByVal p1 As String, ByVal p2 As Date) As Double Range("C2").Value = p1 & " " & p2 method1 = 1234.5678 End Functions |
Public Sub test() MsgBox "Sub test() in Module1 is invoked" End Sub |
Compile the VBA code and save the file.
Run J-Integra®'s com2java tool on the Windows machine, and select C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE as the type library, choose an empty directory named excel (e.g. C:\excel) as output directly, and use excel as Java package name. Click the Generate Proxies button to generate Java proxies from Excel type library.
This example is for Microsoft Office Excel 2003. If you use a different version of Excel, you need to look at the generated Java proxies (Workbooks.java) and call the methods accordingly.
Create a .java file named JInvokeVBA.java. Then copy and paste the Java code below:
import excel.*; import java.io.*; import java.util.*; public class JInvokeVBA { public JInvokeVBA() { } public static void main(String[] args) { try { JInvokeVBA myInstance = new JInvokeVBA(); // DCOM authentication: Make sure NT Domain, NT User, NT Password are valid credentials. // Uncomment this line if JInvokeVBA.java remotely accesses Excel: // com.linar.jintegra.AuthInfo.setDefault("NT DOMAIN", "NT USER", "NT PASSWORD"); String strExcelFilename = "C:\\Java-VBA"; try { File f = new File(""); strExcelFilename = f.getAbsolutePath(); } catch (Exception ex) { ex.printStackTrace(); } strExcelFilename += "\\JInvokeVBA.xls"; myInstance.testVBA( strExcelFilename, "Sheet1", true, false ); } catch(Exception e) { e.printStackTrace(); } finally { // Release all remote objects that haven't already been garbage collected. com.linar.jintegra.Cleaner.releaseAll(); } } public void testVBA( String strWorkbookFilePath, String strWorksheetName, boolean bExcelAppVisible, boolean bExcelAppDisplayAlerts) { try { Application app = null; Workbooks workbooks = null; Workbook wb = null; int iTemp = 0; Integer iTemp2 = null; Sheets worksheets = null; Worksheet ws = null; String strTemp = null; Range rg = null; // Specify host name or IP address of Excel machine as parameter if // JInvokeVBA.java remotely accesses Excel. // app = new Application("123.456.789.0"); app = new Application(); app.setVisible( bExcelAppVisible ); app.setDisplayAlerts( bExcelAppDisplayAlerts ); // open existing workbook workbooks = app.getWorkbooks(); // Open the excel file // For Excel XP or 2003, use: wb = workbooks.open( strWorkbookFilePath, new Boolean(true), new Boolean(true), null, null, null, null, null, null, null, null, null, null, null, null ); // For Excel 2000, use: // wb = workbooks.open( // strWorkbookFilePath, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null, // null // ); // Operating Worksheets and Worksheet objects worksheets = wb.getWorksheets(); iTemp = worksheets.getCount(); while(iTemp > 0) { ws = new Worksheet(worksheets.getItem(new Integer(iTemp))); strTemp = ws.getName(); if( strWorksheetName.equals(strTemp) ) { break; } iTemp--; } // Invoke the method "method1" Object[] params = { "hello", new java.util.Date() }; Double retVal = (Double) ws.invokeMethodByName("method1", params); System.out.println("VBA method1 returns: " + retVal); app.run( "test", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null ); Thread.sleep(5000); wb.close(new Boolean(true), null, null); workbooks.close(); app.quit(); } catch( Exception e ) { e.printStackTrace(); } } } |
On the Java client machine, make sure your CLASSPATH and PATH environment variables are set up according to J-Integra® installation instructions. Compile and run the example in J-Integra®'s native mode (you need to use DCOM mode if remotely accessing Excel):
The -J parameters make more memory available to the compiler than it would normally have, since there are a lot of generated files in this example.
javac -J-mx32m -J-ms32m JInvokeVBA.java
java -DJINTEGRA_NATIVE_MODE JInvokeVBA
JInvokeVBA will open JInvokeVBA.xls, activate Sheet2, and run the VBA macro.
You can also run the Java client on a remote machine, such as Linux, Solaris, UNIX and AIX. For instance, if you run it on a Linux machine, then you must do the following.:
To access OLE Programmatic Identifier (ProgID) from Java, you'll need to generated Java proxies from C:\WINDOWS\system32\FM20.DLL using com2java and put them in a Java package named "FM20". For example, open JInvokeVBA.xls, click View -> Toolbars -> Control Toolbox, and draw a Command Button named "CommandButton1" on the Sheet1. To control this Command Button from Java, you'll need to use this code snippet below.
Worksheet ws = new Worksheet(worksheets.getItem("Sheet1"); FM20.CommandButton commandButton = new FM20.CommandButton(ws.getPropertyByName("CommandButton1")); commandButton.setValue(true); |
J-Integra® is a generic bi-directional bridge between any Java objects and any COM components. We do not provide the documentation of the generated Java proxies since the Java proxies are just mapped from the programming API of the COM component. For more information about Microsoft Excel programming, please refer to the Microsoft Excel VBA Language Reference. It's also easier to find a VB example first, and then convert the VB example to Java program using the reference Mapping VB Code to Java Code.