#excel #xlsx #cli

app vba_extract

工具,用于从 Excel xlsm 宏文件中提取 vbaProject.bin 二进制文件,以便将其插入到 rust_xlsxwriter 文件中

2 个不稳定版本

新版本 0.2.0 2024 年 8 月 21 日
0.1.0 2024 年 7 月 15 日

#127过程宏

Download history 113/week @ 2024-07-12 14/week @ 2024-07-19 5/week @ 2024-07-26 1/week @ 2024-08-02 109/week @ 2024-08-16

115 每月下载量

MIT/Apache

14KB
72

vba_extract

vba_extract 命令行应用程序是一个简单的工具,用于从 Excel xlsm 文件中提取 vbaProject.bin 二进制文件,以便将其插入到 rust_xlsxwriter 文件中。

如果宏是数字签名的,则工具还会提取 vbaProjectSignature.bin 文件。

请参阅 rust_xlsxwriter 中使用 VBA 宏

用法

Usage: vba_extract [OPTIONS] <FILENAME_XLSM>

Arguments:
  <FILENAME_XLSM>
          Input Excel xlsm filename

Options:
  -o, --output-macro-filename <OUTPUT_MACRO_FILENAME>
          Output vba macro filename

          [default: vbaProject.bin]

  -s, --output-sig-filename <OUTPUT_SIG_FILENAME>
          Output vba signature filename (if present in the parent file)

          [default: vbaProjectSignature.bin]

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

安装

cargo install vba_extract

将 VBA 宏添加到 rust_xlsxwriter 文件

提取 vbaProject.bin 文件后,可以使用 Workbook::add_vba_project() 方法将其添加到 rust_xlsxwriter 工作簿中

use rust_xlsxwriter::{Workbook, XlsxError};

#[allow(unused_variables)]
fn main() -> Result<(), XlsxError> {
    let mut workbook = Workbook::new();

    workbook.add_vba_project("examples/vbaProject.bin")?;

    Ok(())
}

以下是一个完整示例,它添加了一个包含对话框的宏文件。它还使用按钮,通过 Worksheet::insert_button(),来触发宏

use rust_xlsxwriter::{Button, Workbook, XlsxError};

fn main() -> Result<(), XlsxError> {
    // Create a new Excel file object.
    let mut workbook = Workbook::new();

    // Add the VBA macro file.
    workbook.add_vba_project("examples/vbaProject.bin")?;

    // Add a worksheet and some text.
    let worksheet = workbook.add_worksheet();

    // Widen the first column for clarity.
    worksheet.set_column_width(0, 30)?;

    worksheet.write(2, 0, "Press the button to say hello:")?;

    // Add a button tied to a macro in the VBA project.
    let button = Button::new()
        .set_caption("Press Me")
        .set_macro("say_hello")
        .set_width(80)
        .set_height(30);

    worksheet.insert_button(2, 1, &button)?;

    // Save the file to disk. Note the `.xlsm` extension. This is required by
    // Excel or it raise a warning.
    workbook.save("macros.xlsm")?;

    Ok(())
}

此示例中的宏如下 VBA 代码

Sub say_hello()
    MsgBox ("Hello from Rust!")
End Sub

运行宏后的输出文件

如果 VBA 文件包含函数,则可以在计算中使用它们,例如 Worksheet::write_formula()

use rust_xlsxwriter::{Workbook, XlsxError};

fn main() -> Result<(), XlsxError> {
    let mut workbook = Workbook::new();

    workbook.add_vba_project("examples/vbaProject.bin")?;

    let worksheet = workbook.add_worksheet();

    worksheet.write_formula(0, 0, "=MyMortgageCalc(200000, 25)")?;

    // Note the `.xlsm` extension.
    workbook.save("macros.xlsm")?;

    Ok(())
}

注意:包含函数和宏的 Excel 文件必须使用 .xlsm 扩展名,否则 Excel 将会报错,并且可能无法打开文件。

use rust_xlsxwriter::{Workbook, XlsxError};

#[allow(unused_variables)]
fn main() -> Result<(), XlsxError> {
    let mut workbook = Workbook::new();

    workbook.add_vba_project("examples/vbaProject.bin")?;

    let worksheet = workbook.add_worksheet();

    // Note the `.xlsm` extension.
    workbook.save("macros.xlsm")?;

    Ok(())
}

以下是在将有效的 xlsm 文件错误地赋予 xlsx 扩展名时出现的对话框

设置 VBA 对象名称

VBA 宏通常通过 ThisWorkbookSheet1Sheet2 等名称来引用工作簿和工作表对象。

如果导入的宏使用其他名称,您可以使用以下方法和Workbook::set_vba_name()Worksheet::set_vba_name()方法进行设置。

use rust_xlsxwriter::{Workbook, XlsxError};

fn main() -> Result<(), XlsxError> {
    let mut workbook = Workbook::new();

    workbook.add_vba_project("examples/vbaProject.bin")?;
    workbook.set_vba_name("MyWorkbook")?;

    let worksheet = workbook.add_worksheet();
    worksheet.set_vba_name("MySheet1")?;

    // Note the `.xlsm` extension.
    workbook.save("macros.xlsm")?;

    Ok(())
}

注意:如果您使用的是非英文版本的Excel,您需要特别注意Excel版本使用的Workbook/Worksheet命名,并添加正确的VBA名称。您可以在VBA编辑器中找到这些名称。

您还可以通过解压xlsm文件并使用系统unzip和libxml的xmllint来格式化XML以提高清晰度来找到它们。

$ unzip myfile.xlsm -d myfile
$ xmllint --format `find myfile -name "*.xml" | xargs` | grep "Pr.*codeName"

    <workbookPr codeName="MyWorkbook" defaultThemeVersion="124226"/>
    <sheetPr codeName="MySheet"/>

将VBA宏签名文件添加到rust_xlsxwriter文件中

VBA宏可以在Excel中签名,以允许对执行进行进一步的控制。签名部分添加到另一个名为vbaProjectSignature.bin的二进制文件中。

vba_extract实用程序将提取带签名的宏的xlsm文件中的vbaProject.binvbaProjectSignature.bin文件。

您可以使用Workbook::add_vba_project_with_signature()方法将这些文件添加到rust_xlsxwriter文件中。

use rust_xlsxwriter::{Workbook, XlsxError};

#[allow(unused_variables)]
fn main() -> Result<(), XlsxError> {
    let mut workbook = Workbook::new();

    workbook.add_vba_project_with_signature(
        "examples/vbaProject.bin",
        "examples/vbaProjectSignature.bin",
    )?;

    let worksheet = workbook.add_worksheet();

    // Note the `.xlsm` extension.
    workbook.save("macros.xlsm")?;

    Ok(())
}

如果不起作用怎么办

rust_xlsxwriter测试套件包含多个测试以确保此功能正常工作,上面显示了一个有效示例。然而,并不能保证它在所有情况下都能工作。可能需要进行一些试错,并且了解一些VBA知识将非常有帮助。如果事情没有按照预期进行,以下是一些可以尝试的事情:

  1. 从简单的宏文件开始,确保它工作,然后再增加复杂性。

  2. 检查宏使用的代码名称,这些名称用于引用Workbook和Worksheets(请参阅上面的上一节)。通常VBA使用代码名称ThisWorkbook来引用当前Workbook,使用工作表名称(如Sheet1)来引用Worksheets。这些都是rust_xlsxwriter使用的默认值。如果宏使用其他名称,或者宏是从非英文版本的Excel中提取的,则可以使用Workbook和Worksheet的set_vba_name方法指定这些名称。

另请参阅

请参阅 rust_xlsxwriter 中使用 VBA 宏

依赖关系

~3–4MB
~70K SLoC