pyOpenVBA 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyopenvba/__init__.py +80 -0
- pyopenvba/__main__.py +68 -0
- pyopenvba/cfb.py +931 -0
- pyopenvba/excel.py +487 -0
- pyopenvba/exceptions.py +17 -0
- pyopenvba/vba.py +1543 -0
- pyopenvba-1.0.0.dist-info/METADATA +285 -0
- pyopenvba-1.0.0.dist-info/RECORD +11 -0
- pyopenvba-1.0.0.dist-info/WHEEL +4 -0
- pyopenvba-1.0.0.dist-info/entry_points.txt +2 -0
- pyopenvba-1.0.0.dist-info/licenses/LICENSE.md +21 -0
pyopenvba/__init__.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyOpenVBA
|
|
3
|
+
=========
|
|
4
|
+
Read and write VBA sections of xlsm / xlsb / xls Excel files
|
|
5
|
+
using pure Python — no external dependencies.
|
|
6
|
+
|
|
7
|
+
Public API
|
|
8
|
+
----------
|
|
9
|
+
from pyopenvba import ExcelFile, pull, push
|
|
10
|
+
|
|
11
|
+
# In-process module edit
|
|
12
|
+
with ExcelFile("workbook.xlsm") as wb:
|
|
13
|
+
modules = wb.vba_modules() # dict[name -> source]
|
|
14
|
+
wb.set_module("Module1", new_src)
|
|
15
|
+
wb.save("workbook_modified.xlsm")
|
|
16
|
+
|
|
17
|
+
# Disk-based workflow (.bas / .cls files)
|
|
18
|
+
pull("workbook.xlsm", "./vba_src") # extract modules
|
|
19
|
+
push("./vba_src", "workbook.xlsm") # write edits back in place
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Union
|
|
24
|
+
|
|
25
|
+
from pyopenvba.excel import ExcelFile
|
|
26
|
+
from pyopenvba.exceptions import (
|
|
27
|
+
PyOpenVBAError,
|
|
28
|
+
CFBError,
|
|
29
|
+
VBAProjectError,
|
|
30
|
+
UnsupportedFormatError,
|
|
31
|
+
)
|
|
32
|
+
from pyopenvba.vba import VBAModuleKind
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def pull(
|
|
36
|
+
workbook: Union[str, Path],
|
|
37
|
+
dest_dir: Union[str, Path],
|
|
38
|
+
*,
|
|
39
|
+
encoding: str = "utf-8",
|
|
40
|
+
overwrite: bool = True,
|
|
41
|
+
) -> list[Path]:
|
|
42
|
+
"""
|
|
43
|
+
Export every VBA module from ``workbook`` into ``dest_dir`` as
|
|
44
|
+
``.bas`` / ``.cls`` files. Returns the paths written.
|
|
45
|
+
"""
|
|
46
|
+
with ExcelFile(workbook) as wb:
|
|
47
|
+
return wb.pull_modules(dest_dir, encoding=encoding, overwrite=overwrite)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def push(
|
|
51
|
+
src_dir: Union[str, Path],
|
|
52
|
+
workbook: Union[str, Path],
|
|
53
|
+
*,
|
|
54
|
+
out: Union[str, Path, None] = None,
|
|
55
|
+
encoding: str = "utf-8",
|
|
56
|
+
strict: bool = False,
|
|
57
|
+
) -> list[str]:
|
|
58
|
+
"""
|
|
59
|
+
Update VBA modules in ``workbook`` from ``.bas`` / ``.cls`` files
|
|
60
|
+
in ``src_dir`` and save. Saves in place unless ``out`` is given.
|
|
61
|
+
Returns the list of updated module names.
|
|
62
|
+
"""
|
|
63
|
+
with ExcelFile(workbook) as wb:
|
|
64
|
+
updated = wb.push_modules(src_dir, encoding=encoding, strict=strict)
|
|
65
|
+
wb.save(out)
|
|
66
|
+
return updated
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
__all__ = [
|
|
70
|
+
"ExcelFile",
|
|
71
|
+
"VBAModuleKind",
|
|
72
|
+
"PyOpenVBAError",
|
|
73
|
+
"CFBError",
|
|
74
|
+
"VBAProjectError",
|
|
75
|
+
"UnsupportedFormatError",
|
|
76
|
+
"pull",
|
|
77
|
+
"push",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
__version__ = "1.0.0"
|
pyopenvba/__main__.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line entry point.
|
|
3
|
+
|
|
4
|
+
Usage::
|
|
5
|
+
|
|
6
|
+
python -m pyopenvba pull <workbook> <dest_dir>
|
|
7
|
+
python -m pyopenvba push <src_dir> <workbook> [--out <new_path>] [--strict]
|
|
8
|
+
python -m pyopenvba ls <workbook>
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from pyopenvba import ExcelFile, pull, push
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _cmd_pull(args: argparse.Namespace) -> int:
|
|
21
|
+
written = pull(args.workbook, args.dest, overwrite=not args.no_overwrite)
|
|
22
|
+
for p in written:
|
|
23
|
+
print(p)
|
|
24
|
+
return 0
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _cmd_push(args: argparse.Namespace) -> int:
|
|
28
|
+
updated = push(args.src, args.workbook, out=args.out, strict=args.strict)
|
|
29
|
+
for name in updated:
|
|
30
|
+
print(name)
|
|
31
|
+
return 0
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _cmd_ls(args: argparse.Namespace) -> int:
|
|
35
|
+
with ExcelFile(args.workbook) as wb:
|
|
36
|
+
for m in wb.vba_project().modules:
|
|
37
|
+
print(f"{m.kind.name:8s} {m.name}")
|
|
38
|
+
return 0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def main(argv: list[str] | None = None) -> int:
|
|
42
|
+
parser = argparse.ArgumentParser(prog="pyopenvba")
|
|
43
|
+
sub = parser.add_subparsers(dest="cmd", required=True)
|
|
44
|
+
|
|
45
|
+
p_pull = sub.add_parser("pull", help="Export VBA modules to a directory.")
|
|
46
|
+
p_pull.add_argument("workbook", type=Path)
|
|
47
|
+
p_pull.add_argument("dest", type=Path)
|
|
48
|
+
p_pull.add_argument("--no-overwrite", action="store_true")
|
|
49
|
+
p_pull.set_defaults(func=_cmd_pull)
|
|
50
|
+
|
|
51
|
+
p_push = sub.add_parser("push", help="Import VBA modules from a directory and save.")
|
|
52
|
+
p_push.add_argument("src", type=Path)
|
|
53
|
+
p_push.add_argument("workbook", type=Path)
|
|
54
|
+
p_push.add_argument("--out", type=Path, default=None)
|
|
55
|
+
p_push.add_argument("--strict", action="store_true",
|
|
56
|
+
help="Fail if any source file has no matching module.")
|
|
57
|
+
p_push.set_defaults(func=_cmd_push)
|
|
58
|
+
|
|
59
|
+
p_ls = sub.add_parser("ls", help="List VBA modules in a workbook.")
|
|
60
|
+
p_ls.add_argument("workbook", type=Path)
|
|
61
|
+
p_ls.set_defaults(func=_cmd_ls)
|
|
62
|
+
|
|
63
|
+
args = parser.parse_args(argv)
|
|
64
|
+
return int(args.func(args))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__": # pragma: no cover
|
|
68
|
+
sys.exit(main())
|