12

I have learnt to read and write an Excel file using a Java program with the help of Jxl and POI API. Is it possible to run a Java program with the help of macros?

Nimit_ZZ
  • 495
  • 4
  • 10
  • 21
  • 2
    Check this - [http://stackoverflow.com/questions/5297341/calling-java-library-jar-from-vba-vbscript-visual-basic-classic][1] [1]: http://stackoverflow.com/questions/5297341/calling-java-library-jar-from-vba-vbscript-visual-basic-classic – Sree Jul 05 '12 at 11:57
  • All those discussions tell that it is not possible. – Nimit_ZZ Jul 05 '12 at 12:13
  • How about this? http://stackoverflow.com/questions/10879757/vba-shell-java-call-errors – JimmyPena Jul 05 '12 at 17:44
  • Yes, it is with Jinx - https://exceljava.com. You can write Excel functions (UDFs), macros and menus all in Java. – Tony Roberts Nov 10 '18 at 10:18

4 Answers4

24

Yes, it is possible.

There are quite a few ways actually and I hope you like my examples.

To demonstrate this, I create a program where some text is send as arguments and program responds with an altered version of it. I made a runnable jar of it. First example reads the argument from args and other from standard input.

File Hello.java and H1.jar:

public class Hello {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        
        if (args.length > 0) 
            sb.append(' ').append(args[0]);
        System.out.println(sb.append('.').toString());
    }
}

File Hello2.java and H2.jar:

import java.util.Scanner;

public class Hello2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder("Hello");
        
        sb.append(' ').append(sc.nextLine());
        System.out.println(sb.append('.').toString());
    }
}

You can save them in a single jar, but then you need create and use a manifest (that's a bit overkill).

Now in Excel I add a module and a reference to Windows Script Host Object. If you do not like the sleep, then you can replace it with DoEvents:

'add a reference to Windows Script Host Object Model
'for example : Tools-References
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub RunSleep( _
    exec As WshExec, _
    Optional timeSegment As Long = 20 _
)
    Do While exec.Status = WshRunning
        Sleep timeSegment
    Loop
End Sub

Private Function RunProgram( _
    program As String, _
    Optional command As String = "" _
) As WshExec
    Dim wsh As New WshShell
    Dim exec As WshExec

    Set exec = wsh.exec(program)
    Call exec.StdIn.WriteLine(command)
    Call RunSleep(exec)
    Set RunProgram = exec
End Function

And to test it I saved the files to c:\ drive and used the code:

Public Sub Run()
    Dim program As WshExec
    Set program = RunProgram("java -jar ""C:\\H1.jar"" Margus")
    Debug.Print "STDOUT: " & program.StdOut.ReadAll

    Set program = RunProgram("java -jar ""C:\\H2.jar", "Margus")
    Debug.Print "STDOUT: " & program.StdOut.ReadAll
End Sub

In my case I get a responce of :

STDOUT: Hello Margus.

STDOUT: Hello Margus.

Sathiamoorthy
  • 8,831
  • 9
  • 65
  • 77
Margus
  • 19,694
  • 14
  • 55
  • 103
  • 1
    Note that variable **program** holds additional useful information like error stream and return code. – Margus Jul 05 '12 at 22:04
  • 1
    @sreehari My doubt is, I have written a program that read the data from the cells from an already existing Excel file and process it and put it back to the same file. I'm not new to Java but I certainly am new to Excel marcos. Do I need to write a macro? I have no clue about it and the tutorials don't give you any information. So how can it be done? – Nimit_ZZ Jul 06 '12 at 04:56
  • 1
    To open VBA environment in Excel, you can use "alt+f11". Alternative way would be to use developer ribbon Visual Basic button. Excel has code pages for each sheet, but Module is like a shared space. Note, that I can use command **java -jar "C:\H1.jar" Margus** to run the program in CMD - there is very little code that needs to be written. – Margus Jul 06 '12 at 06:38
  • Ok. I think I have not made my doubt clear. I write the java file and keep it at one particular place. I open the excel sheet and type in something in the cells and I want to take the content in those cells, process it and put it back to the same excel sheet and this data processing has to be done by the java program. Is that possible through excel macros? I went through __ikvm__ but it leads to a lot more dead ends. – Nimit_ZZ Jul 06 '12 at 06:46
3

Your VBA can write the output to a file and Java can poll for file modifications periodically and read from the file. And write the data back to VBA through another file. VBA - Java integration is next to impossible unless you just want to fire a Java program from the shell through System.execute(...).

Sree
  • 746
  • 6
  • 21
  • Not true. VBA-Java integration is far from impossible. A while ago there was even the good old Sun Java ActiveX Bridge, which unfortunately has been discontinued by Oracle (still available for Java 1.4: http://docs.oracle.com/javase/1.4.2/docs/guide/beans/axbridge/developerguide/ ). But there are still technologies available. Obba http://www.obba.info may be used from VBA. Also xlloop could be used. – Christian Fries Aug 16 '13 at 19:58
3

i've used it.. Attention, use javaw otherwise a black window is popping up

Dim result As String
Dim commandstr As String

commandstr = "javaw -jar somejar someparameter"


' try with or without cast to string
result = CStr( shellRun(commandstr) )


'somewhere from SO but forget.. sorry for missing credits

Public Function ShellRun(sCmd As String) As String

    'Run a shell command, returning the output as a string'

    Dim oShell As Object
    Set oShell = CreateObject("WScript.Shell")

    'run command'
    Dim oExec As Object
    Dim oOutput As Object
    Set oExec = oShell.exec(sCmd)
    Set oOutput = oExec.StdOut

    'handle the results as they are written to and read from the StdOut object'
    Dim s As String
    Dim sLine As String
    While Not oOutput.AtEndOfStream
        sLine = oOutput.ReadLine
        If sLine <> "" Then s = s & sLine & vbCrLf
    Wend

    ShellRun = s

End Function
mschwehl
  • 31
  • 2
  • The question was to write a Java program – Ori Marko Jul 06 '17 at 13:21
  • 1
    thank you for the comment but the question was 'Is it possible to run a Java program with the help of macros?' and this solution does it without the sleep-method as well as i pointed to javaw instead of java – mschwehl Jul 07 '17 at 07:53
0

Much better than the other suggested solutions is to create an Excel Add-In in Java using Jinx (https://exceljava.com).

See https://exceljava.com/docs/macros.html for details of how to write Excel macros in Java.

As well as macros, it is also possible to write user defined functions and menus.

In fact, you can use Java as a full replacement for VBA! See https://github.com/exceljava/jinx-com4j for how to call the Excel Object Model to allow you to do everything you can in VBA from Java.

Tony Roberts
  • 387
  • 1
  • 5
  • Two drawbacks with this tool - it's paid, and it does not support MacOS (only Windows is supported). – lagivan Oct 03 '19 at 06:58