如何从Java运行Excel VBA宏?[duplicate]

yc0p9oo0  于 2022-11-18  发布在  Java
关注(0)|答案(2)|浏览(419)

此问题在此处已有答案

How to call an Excel VBA Macro from Java Code?(5个答案)
6天前关闭。
我需要从Java运行Excel VBA宏。我已经将模块导出为vbs文件:module1.vbs
现在我只需要从java代码运行它。
我试着从Java运行它,如下所示:

Runtime.getRuntime().exec("C://Users//pk//OneDrive - pk//Documents//Module1.vbs");

这是我从它得到的错误:
java.io.IOException:无法运行程序“C:\用户\pk\OneDrive -pk\文档\模块. vbs”:CreateProcess错误=193,%1不是有效的Win32应用程序

gblwokeq

gblwokeq1#

如果要执行VBA宏,需要打开宿主应用程序(在您的情况下,宿主应用程序是Excel)。简单地将宏代码存储为VBS文件是行不通的- VBS和VBA相似,但不完全相同,而且VBS对Excel一无所知。
打开Excel并执行宏的最简单方法是编写一个VBS脚本作为从Java代码启动的 Package 程序。该脚本启动Excel应用程序,打开特定的Excel文件并启动要运行的宏。请注意,Sub应存储在常规模块中,而不是工作簿或工作表模块中。
Windows上的VBScript以CScript(或WScript)启动-在将其添加到Java代码中之前,请在Windows命令行中尝试。确保它能成功执行。
我不熟悉Java Exec语句,但我假设它看起来像这样

Runtime.getRuntime().exec("CScript \"C://Users//pk//OneDrive - pk//Documents//startExcelWithMacro.vbs\"");

有关示例代码,请查看Run Excel Macro from Outside Excel Using VBScript From Command Line

4xy9mtcn

4xy9mtcn2#

我能想到的两个选项:
1.安装可以运行VBA文件的VB运行时
1.使用Jacob(Java COM桥)连接到Excel(或任何其他MS Office应用程序),然后在其中运行VBAProject
关于第一个我没有任何具体的建议。
第二个步骤包括:
获取新的Excel示例

ActiveXComponent excel = new ActiveXComponent(ApplicationIdentifiers.EXCEL.OleAddress);

获取所有加载的工作簿(类 Workbook 是我的一个自定义类,只是简单地 Package 创建的Dispatch):

public ArrayList<Workbook> getWorkbooks() {
    final ArrayList<Workbook> ret = new ArrayList<>();
    final Dispatch workbooks = excel.getProperty("Workbooks").getDispatch();
    final int count = Dispatch.get(workbooks, "Count").getInt();
    for (int i = 1; i <= count; ++i) {
        final Dispatch oneworkbook = Dispatch.invoke(workbooks, "Item", Dispatch.Get, new Object[] { Integer.valueOf(i) }, new int[0]).getDispatch();
        final Workbook wb = new Workbook(this, oneworkbook);
        ret.add(wb);
    }
    return ret;
}

...或手动打开文件,我只是没有相应的代码,可能是沿着于以下内容的代码

final Dispatch newworkbook = Dispatch.invoke(workbooks, "Open", Dispatch.Get, new Object[] { filename }, moreparams).getDispatch();

然后,获取包含的VBProject:

final Dispatch vbp = Dispatch.get(oneworkbook, "VBProject").toDispatch();

在那里,您可以得到VBComponents:

final Dispatch components = Dispatch.get(vbp, "VBComponents").toDispatch();

按如下方式获取组件计数:

return Dispatch.get(components, "Count").getInt();

在这里,iterate to count(pIndex),你可以通过以下方式得到模块/窗体/类:

final Dispatch item = Dispatch.call(components, "Item", Integer.valueOf(pIndex)).toDispatch();

各自的代码模块如此:

final Dispatch d = Dispatch.get(item, "CodeModule").toDispatch();

从那里你必须做一些自己的研究,得到正确的方法,然后运行它。
访问/创建Office应用程序的标识符我在这里编译:

public enum ApplicationIdentifiers {
    ACCESS("Access.Application", "Access.CodeData", "Access.CurrentData", "Access.CodeProject", "Access.CurrentProject", "Access.DefaultWebOptions"), //
    EXCEL("Excel.Application", "Excel.AddIn", "Excel.Chart", "Excel.Sheet"), //
    FILE_EXPLORER("Shell.Explorer.1"), //
    GRAPH("MSGraph.Application", "MSGraph.Chart"), //
    OUTLOOK("Outlook.Application", "Outlook.OlkBusinessCardControl", "Outlook.OlkCategoryStrip", "Outlook.OlkCheckBox", "Outlook.OlkComboBox", "Outlook.OlkCommandButton", "Outlook.OlkContactPhoto", "Outlook.OlkDateControl", "Outlook.OlkFrameHeader", "Outlook.OlkInfoBar", "Outlook.OlkLabel", "Outlook.OlkListBox", "Outlook.OlkOptionButton", "Outlook.OlkPageControl", "Outlook.OlkSenderPhoto", "Outlook.OlkTextBox", "Outlook.OlkTimeControl", "Outlook.OlkTimeZone"), //
    POWERPOINT("PowerPoint.Application"), //
    WORD("Word.Application", "Word.Document", "Word.Template", "Word.Global"), //
    ;


    public final String     OleAddress;
    public final String[]   Components;
    
    private ApplicationIdentifiers(final String pOleAddress, final String... pComponents) {
        OleAddress = pOleAddress;
        Components = pComponents;
    }

    @Override public String toString() {
        return "Application: " + OleAddress + ", Components: " + Components;
    }
}

相关问题