pyOpenVBA 6.1.3__tar.gz → 6.2.0__tar.gz
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-6.1.3 → pyopenvba-6.2.0}/PKG-INFO +4 -2
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/README.md +3 -1
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/excel_checklist.csv +72 -7
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/host_completeness.md +3 -3
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/vba_runtime.md +182 -8
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/pyproject.toml +1 -1
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/__init__.py +1 -1
- pyopenvba-6.2.0/src/pyopenvba/_relationships.py +90 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_autofill.py +1 -0
- pyopenvba-6.2.0/src/pyopenvba/apps/excel/_cell_styles.py +1120 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_clipboard.py +25 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_dimensions.py +2 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_editing.py +4 -1
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_formats.py +73 -23
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_formula_format.py +18 -0
- pyopenvba-6.2.0/src/pyopenvba/apps/excel/_hyperlinks.py +553 -0
- pyopenvba-6.2.0/src/pyopenvba/apps/excel/_hyperlinks_file.py +280 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_io.py +58 -27
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_model.py +113 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_protection.py +7 -1
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_row_formats.py +4 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_sheet_copy.py +5 -1
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_sort.py +5 -0
- pyopenvba-6.2.0/src/pyopenvba/apps/excel/_styles.py +1404 -0
- pyopenvba-6.2.0/src/pyopenvba/apps/excel/_text_columns.py +428 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_typing.py +233 -69
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_runtime.py +3 -0
- pyopenvba-6.1.3/src/pyopenvba/apps/excel/_styles.py +0 -862
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/.gitignore +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/LICENSE.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/architecture.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/ms-ovba-implementation-guide_v2.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/power_query.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/research/access_complex/README.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/research/access_designs/README.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/research/access_macros/README.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/research/access_write/README.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/research/pcode/README.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/docs/roadmap.md +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/__main__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_a1.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_deflate.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_host.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_new_project.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_oforms_pages.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_oforms_records.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_package_signature.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_ppt_container.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_references.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_database.accdb +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_database_module.accdb +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_document.docm +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_excel_addin.xlam +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_presentation.pptm +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_workbook.xlsb +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_workbook.xlsm +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/blank_workbook.xlsx +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/engine_skeleton.accdb +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/blank_files/engine_skeleton.mdb +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/form.blob +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/form.lvprop +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/form.propdata +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/form.prototypes +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/form.typeinfo +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/report.blob +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/report.lvprop +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/report.propdata +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/report.prototypes +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_templates/designs/report.typeinfo +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/_xml.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_alloc.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_btree.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_collation.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_collation_general_legacy.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_compact.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_complex.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_datapage.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_ddl.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_designs.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_facade.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_format.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_index.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_lval.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_macros.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_pages.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_props.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_queries.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_rows.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_schema.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_sql.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_storage.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_tdef.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_validate.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/_vba.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access/database.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/access_read.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_arrays.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_autofilter.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_bridge.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_calc.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_control_refs.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_controls.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_copy_names.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_duplicates.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_dynamic_file.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_engine_book.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_evaluate.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_events.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_find.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_font_rows.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_merges.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_named_api.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_names.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_notes.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_notes_file.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_number_format.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_radios.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_refresh.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_region.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_shape_api.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_shapes.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_shared.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_sheet_move.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_special_cells.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_spills.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_table_edits.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_tables.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_validation.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_visible.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_windows.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/excel/_worksheet_functions.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/powerpoint/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/powerpoint/_bridge.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/powerpoint/_io.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/powerpoint/_model.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/word/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/word/_bridge.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/word/_io.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/apps/word/_model.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/cfb.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/excel.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/exceptions.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/forms.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_arity.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/catalog.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/cells.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/collate.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/dates.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/evaluator.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/aggregate.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/arithmetic.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/arrays.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/common.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/conditional.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/database.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/dates.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/distributions.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/engineering.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/financial.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/information.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/lambdas.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/logical.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/lookup.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/matrix.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/statistics.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/subtotal.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/functions/text.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/host.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/lexer.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/nodes.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/numbers.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/parser.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/precise.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/reference.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/registry.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/special.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_calc/values.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_deep.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_display.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_formula2.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_inventory.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_parse.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_prefixes.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_r1c1.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_spell.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_structured.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/formula/_values.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_ast.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_constants_data.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_intrinsics.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_inventory.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_inventory_data.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_lex.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_objects.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_parse.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_preprocess.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_scripting.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/interpreter/_values.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_eval.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_inventory.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_inventory_data.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_library.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_parse.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/mlang/_values.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerpoint.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_binary.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_files.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_mashup.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_metadata.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_opc.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_package.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_refresh.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_section.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/_sheets.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/powerquery/workbook.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/__init__.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_docx.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_docx_text.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_drawingml.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_pptx.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_values.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/shapes/_xlsx.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/vba.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/vba_pcode.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/src/pyopenvba/word.py +0 -0
- {pyopenvba-6.1.3 → pyopenvba-6.2.0}/tests/fuzz_corpus/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pyOpenVBA
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.2.0
|
|
4
4
|
Summary: Read and write VBA macros and Excel Power Query in pure Python, no dependencies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyOpenVBA
|
|
6
6
|
Project-URL: Repository, https://github.com/WilliamSmithEdward/pyOpenVBA
|
|
@@ -746,7 +746,9 @@ it, and a save adds only the stylesheet entries the file lacks, spelled
|
|
|
746
746
|
as Excel spells them. Formatting whole rows, whole columns or the whole
|
|
747
747
|
sheet keeps the row, column and sheet formats Excel keeps, with the
|
|
748
748
|
cells Excel makes where they cross, and saves them as Excel does. Named
|
|
749
|
-
cell styles
|
|
749
|
+
cell styles (`Range.Style`, `Workbook.Styles` and the `Style` object)
|
|
750
|
+
and hyperlinks (`Hyperlinks.Add` and the `Hyperlink` object) behave and
|
|
751
|
+
save as Excel's do. Conditional formats are not implemented yet.
|
|
750
752
|
|
|
751
753
|
Row heights, column widths and hidden rows and columns behave as they do
|
|
752
754
|
in Excel on a 96-DPI display, the one the model emulates: `RowHeight = 20`
|
|
@@ -709,7 +709,9 @@ it, and a save adds only the stylesheet entries the file lacks, spelled
|
|
|
709
709
|
as Excel spells them. Formatting whole rows, whole columns or the whole
|
|
710
710
|
sheet keeps the row, column and sheet formats Excel keeps, with the
|
|
711
711
|
cells Excel makes where they cross, and saves them as Excel does. Named
|
|
712
|
-
cell styles
|
|
712
|
+
cell styles (`Range.Style`, `Workbook.Styles` and the `Style` object)
|
|
713
|
+
and hyperlinks (`Hyperlinks.Add` and the `Hyperlink` object) behave and
|
|
714
|
+
save as Excel's do. Conditional formats are not implemented yet.
|
|
713
715
|
|
|
714
716
|
Row heights, column widths and hidden rows and columns behave as they do
|
|
715
717
|
in Excel on a 96-DPI display, the one the model emulates: `RowHeight = 20`
|
|
@@ -432,7 +432,7 @@ Font,Strikethrough,property,As Variant,,VERIFIED,tests/fixtures/range_format.jso
|
|
|
432
432
|
Font,Subscript,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
433
433
|
Font,Superscript,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
434
434
|
Font,ThemeColor,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
435
|
-
Font,ThemeFont,property,As XlThemeFont,,
|
|
435
|
+
Font,ThemeFont,property,As XlThemeFont,,PARTIAL,tests/fixtures/cell_styles/style_changes.json,Read; setting it on a range reports unsupported.
|
|
436
436
|
Font,TintAndShade,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
437
437
|
Font,Underline,property,As Variant,,PARTIAL,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,"Values other than the five styles, True, False and 3 report unsupported."
|
|
438
438
|
GroupShapes,_Default,method,_Default(Index As Variant) As Shape,,MISSING,,
|
|
@@ -443,6 +443,31 @@ GroupShapes,Creator,"property, read-only",As XlCreator,,MISSING,,
|
|
|
443
443
|
GroupShapes,Item,method,Item(Index As Variant) As Shape,,UNASSESSED,,
|
|
444
444
|
GroupShapes,Parent,"property, read-only",As Object,,MISSING,,
|
|
445
445
|
GroupShapes,Range,"property, read-only",As ShapeRange,,MISSING,,
|
|
446
|
+
Hyperlink,Address,property,As String,,PARTIAL,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,"Kept as Excel tidies it -- an http, https or ftp address's scheme and host in lower case, its path resolved, a # splitting off the subaddress -- for the kinds of address measured; saved with a DOS path relative to the workbook's folder. Setting it keeps the subaddress unless the new address has a # of its own."
|
|
447
|
+
Hyperlink,AddToFavorites,method,AddToFavorites(),,EXCLUDED,,Adds the address to the browser's favourites.
|
|
448
|
+
Hyperlink,Application,"property, read-only",As Application,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
449
|
+
Hyperlink,CreateNewDocument,method,"CreateNewDocument(Filename As String, EditNow As Boolean, Overwrite As Boolean)",,EXCLUDED,,Creates and opens a document of another application.
|
|
450
|
+
Hyperlink,Creator,"property, read-only",As XlCreator,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
451
|
+
Hyperlink,Delete,method,Delete(),,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"Its cells go back to the default format, merges kept. On a protected sheet a locked cell keeps its link, error 1004."
|
|
452
|
+
Hyperlink,EmailSubject,property,As String,,PARTIAL,tests/fixtures/hyperlinks/hyperlinks.json,"The subject of a mailto address, which setting it writes in, in place of one it names, or takes out; """" for no address; another address fails. Set on a link with no address, which leaves Excel refusing every change after it, it reports unsupported."
|
|
453
|
+
Hyperlink,Follow,method,"Follow([NewWindow As Variant], [AddHistory As Variant], [ExtraInfo As Variant], [Method As Variant], [HeaderInfo As Variant])",,EXCLUDED,,Opens the address in another application.
|
|
454
|
+
Hyperlink,Name,"property, read-only",As String,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"The text to show it was given, or ""address - subaddress"", which follows a new address; read from a file without a display, its cell's text. Setting it is error 450."
|
|
455
|
+
Hyperlink,Parent,"property, read-only",As Object,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,Its cells.
|
|
456
|
+
Hyperlink,Range,"property, read-only",As Range,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
457
|
+
Hyperlink,ScreenTip,property,As String,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,
|
|
458
|
+
Hyperlink,Shape,"property, read-only",As Shape,,PARTIAL,tests/fixtures/hyperlinks/hyperlinks.json,Error 1004 for a link on cells; a link on a shape is not implemented.
|
|
459
|
+
Hyperlink,SubAddress,property,As String,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,Setting it takes the address away.
|
|
460
|
+
Hyperlink,TextToDisplay,property,As String,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,"The text the first cell holds, """" for a number or a formula; setting it writes the first cell and names the link, """" doing nothing."
|
|
461
|
+
Hyperlink,Type,"property, read-only",As Long,,PARTIAL,tests/fixtures/hyperlinks/hyperlinks.json,0 for a link on cells; a link on a shape is not implemented.
|
|
462
|
+
Hyperlinks,_Default,"property, read-only",As Hyperlink,,MISSING,,
|
|
463
|
+
Hyperlinks,_NewEnum,"property, read-only",As IUnknown,,MISSING,,
|
|
464
|
+
Hyperlinks,Add,method,"Add(Anchor As Object, Address As String, [SubAddress As Variant], [ScreenTip As Variant], [TextToDisplay As Variant]) As Object",,PARTIAL,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,"A link on each area of the anchor, the last answered; over the very cells of a link it takes that link's place. The cells take the Hyperlink style, and the first the text to show or, when empty, the address. SubAddress, ScreenTip and TextToDisplay not strings are error 5. A protected sheet needs AllowInsertingHyperlinks and unlocked cells. A shape anchor reports unsupported."
|
|
465
|
+
Hyperlinks,Application,"property, read-only",As Application,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
466
|
+
Hyperlinks,Count,"property, read-only",As Long,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
467
|
+
Hyperlinks,Creator,"property, read-only",As XlCreator,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,
|
|
468
|
+
Hyperlinks,Delete,method,Delete(),,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"Every link the collection holds goes, its cells back to the default format."
|
|
469
|
+
Hyperlinks,Item,"property, read-only",As Hyperlink,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"By place in the sheet's order or by name; 0, past the last and an unknown name are error 9."
|
|
470
|
+
Hyperlinks,Parent,"property, read-only",As Object,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"The worksheet, a range's collection's too."
|
|
446
471
|
Interior,Application,"property, read-only",As Application,,UNASSESSED,,
|
|
447
472
|
Interior,Color,property,As Variant,,PARTIAL,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,A gradient fill reports unsupported.
|
|
448
473
|
Interior,ColorIndex,property,As Variant,,PARTIAL,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,A gradient fill reports unsupported.
|
|
@@ -631,7 +656,7 @@ Range,Clear,method,Clear() As Variant,,PARTIAL,tests/fixtures/excel_model/probes
|
|
|
631
656
|
Range,ClearComments,method,ClearComments(),,VERIFIED,tests/fixtures/excel_model/probes.txt,
|
|
632
657
|
Range,ClearContents,method,ClearContents([RemoveControls As Variant]) As Variant,no RemoveControls,PARTIAL,tests/fixtures/excel_model/probes.txt; tests/fixtures/row_formats/row_formats.json; tests/fixtures/autofilter_edits.json,"An emptied cell in the format its row or column gives it goes. On a filtered sheet only the visible cells clear, and clearing a filter's whole header row turns the filter off."
|
|
633
658
|
Range,ClearFormats,method,ClearFormats() As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py; tests/fixtures/row_formats/row_formats.json; tests/fixtures/autofilter_edits.json,"Whole rows and columns lose their own formats, and positions a column's or row's format still reaches get a cell in the default format. On a filtered sheet only the visible cells, and clearing a filter's whole header row turns the filter off."
|
|
634
|
-
Range,ClearHyperlinks,method,ClearHyperlinks(),,
|
|
659
|
+
Range,ClearHyperlinks,method,ClearHyperlinks(),,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,The links the range holds go; their cells keep their formats.
|
|
635
660
|
Range,ClearNotes,method,ClearNotes() As Variant,,VERIFIED,tests/fixtures/excel_model/probes.txt,The same as ClearComments.
|
|
636
661
|
Range,ClearOutline,method,ClearOutline() As Variant,,MISSING,,
|
|
637
662
|
Range,Column,"property, read-only",As Long,,PARTIAL,tests/fixtures/excel_model/probes.txt,
|
|
@@ -697,7 +722,7 @@ Range,HasSpill,"property, read-only",As Variant,,VERIFIED,tests/fixtures/dynamic
|
|
|
697
722
|
Range,Height,"property, read-only",As Variant,,PARTIAL,tests/fixtures/dimensions.json; tests/fixtures/dimensions/dimensions_answers.json; tests/fixtures/font_rows.json,"A row grows with its fonts from a measured table of eleven families; one resting on another font, a mix of tables, super- or subscript, or wrapped or turned text keeps its file's height until it changes, then reports unsupported."
|
|
698
723
|
Range,Hidden,property,As Variant,,PARTIAL,tests/fixtures/dimensions.json; tests/fixtures/dimensions/dimensions_answers.json; tests/fixtures/autofilter_edits.json,"Hiding every row, or rows down to the last one, makes hidden the sheet's default as Excel does; a block that stops short of the last row is hidden row by row, and whether Excel switches over for a large one was not measured. On a filtered sheet a block with shown rows reaches only those, so showing it does nothing; showing columns there over hidden ones reports itself unsupported."
|
|
699
724
|
Range,HorizontalAlignment,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
700
|
-
Range,Hyperlinks,"property, read-only",As Hyperlinks,,
|
|
725
|
+
Range,Hyperlinks,"property, read-only",As Hyperlinks,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json,"The links inside one of its areas, and for one area the link it lies in."
|
|
701
726
|
Range,ID,property,As String,,MISSING,,
|
|
702
727
|
Range,IndentLevel,property,As Variant,,VERIFIED,tests/fixtures/range_format.json; tests/fixtures/format/formats_answers.json; tests/test_live_excel_model_gate.py,
|
|
703
728
|
Range,Insert,method,"Insert([Shift As Variant], [CopyOrigin As Variant]) As Variant",,PARTIAL,tests/fixtures/range_edit.json; tests/fixtures/excel_model/probes.txt; tests/fixtures/row_formats/row_formats.json; tests/fixtures/autofilter_edits.json; tests/fixtures/cell_shifts.json,"Whole rows and columns rewrite references, and a new row or column takes the formats beside it. Cells shifted down or right rewrite references as Excel does and take the formats above or to the left; with no Shift a range taller than it is wide shifts right. Sheets with merges or shapes and several areas of cells report unsupported. Shifting cells on a sheet whose rows or columns carry formats, and CopyOrigin:=xlFormatFromRightOrBelow, report unsupported. On a filtered sheet whole rows go in as many as the range shows, at its top, and inserting cells is error 1004."
|
|
@@ -778,13 +803,13 @@ Range,Speak,method,"Speak([SpeakDirection As Variant], [SpeakFormulas As Variant
|
|
|
778
803
|
Range,SpecialCells,method,"SpecialCells(Type As XlCellType, [Value As Variant]) As Range",,PARTIAL,tests/fixtures/special_cells.json; tests/fixtures/excel_model/probes.txt,"Constants and formulas by kind, blanks, the last cell, visible cells and the cells with notes, split into areas as Excel splits them; validation and conditional formats report themselves unsupported."
|
|
779
804
|
Range,SpillingToRange,"property, read-only",As Range,,VERIFIED,tests/fixtures/dynamic_arrays.json,The block a dynamic-array formula in the first cell spilled into; Nothing for any other cell.
|
|
780
805
|
Range,SpillParent,"property, read-only",As Range,,VERIFIED,tests/fixtures/dynamic_arrays.json,The cell of the dynamic-array formula whose answer spilled over the first cell; Nothing where none did.
|
|
781
|
-
Range,Style,property,As Variant,,
|
|
806
|
+
Range,Style,property,As Variant,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,"The cells' style, Nothing where they differ; set by name in any case or by Style object, the parts the style includes replaced and the rest kept. Error 450 for any other name or value, and on a protected sheet unless AllowFormattingCells."
|
|
782
807
|
Range,SubscribeTo,method,"SubscribeTo(Edition As String, [Format As XlSubscribeToFormat]) As Variant",,MISSING,,
|
|
783
808
|
Range,Subtotal,method,"Subtotal(GroupBy As Long, Function As XlConsolidationFunction, TotalList As Variant, [Replace As Variant], [PageBreaks As Variant], [SummaryBelowData As XlSummaryRow]) As Variant",,MISSING,,
|
|
784
809
|
Range,Summary,"property, read-only",As Variant,,MISSING,,
|
|
785
810
|
Range,Table,method,"Table([RowInput As Variant], [ColumnInput As Variant]) As Variant",,MISSING,,
|
|
786
811
|
Range,Text,"property, read-only",As Variant,,PARTIAL,tests/fixtures/excel_model/probes.txt; tests/fixtures/number_formats.json; tests/fixtures/number_spelling.json; tests/fixtures/value_typing.json,"Excel's number formats on a US English system, in a column wide enough for the value; a value a format cannot show fills the column with #. A * fill reports itself unsupported, and a value too wide for its column, which Excel cuts to # or fewer digits, is not modelled."
|
|
787
|
-
Range,TextToColumns,method,"TextToColumns([Destination As Variant], [DataType As XlTextParsingType], [TextQualifier As XlTextQualifier], [ConsecutiveDelimiter As Variant], [Tab As Variant], [Semicolon As Variant], [Comma As Variant], [Space As Variant], [Other As Variant], [OtherChar As Variant], [FieldInfo As Variant], [DecimalSeparator As Variant], [ThousandsSeparator As Variant], [TrailingMinusNumbers As Variant]) As Variant",,
|
|
812
|
+
Range,TextToColumns,method,"TextToColumns([Destination As Variant], [DataType As XlTextParsingType], [TextQualifier As XlTextQualifier], [ConsecutiveDelimiter As Variant], [Tab As Variant], [Semicolon As Variant], [Comma As Variant], [Space As Variant], [Other As Variant], [OtherChar As Variant], [FieldInfo As Variant], [DecimalSeparator As Variant], [ThousandsSeparator As Variant], [TrailingMinusNumbers As Variant]) As Variant",,PARTIAL,tests/fixtures/text_to_columns.json,"Delimited and fixed width, every delimiter, runs of them, qualifiers, typing, FieldInfo's kinds and how each date order reads a field, separators, a trailing minus and a destination as Excel does them. FieldInfo pairs that do not number the columns 1, 2, 3 in order, a column of formulas and a sheet with merged cells report themselves unsupported; an omitted argument takes its default, whether Excel carries one over from an earlier call not being measured."
|
|
788
813
|
Range,TogglePythonMarshalMode,method,TogglePythonMarshalMode([MarshalMode As Variant]),,MISSING,,
|
|
789
814
|
Range,Top,"property, read-only",As Variant,,PARTIAL,tests/fixtures/dimensions.json; tests/fixtures/dimensions/dimensions_answers.json; tests/fixtures/font_rows.json,"A row grows with its fonts from a measured table of eleven families; one resting on another font, a mix of tables, super- or subscript, or wrapped or turned text keeps its file's height until it changes, then reports unsupported."
|
|
790
815
|
Range,Ungroup,method,Ungroup() As Variant,,MISSING,,
|
|
@@ -1031,6 +1056,46 @@ SortFields,Count,"property, read-only",As Long,,VERIFIED,tests/fixtures/sort.jso
|
|
|
1031
1056
|
SortFields,Creator,"property, read-only",As XlCreator,,MISSING,,
|
|
1032
1057
|
SortFields,Item,"property, read-only",As SortField,,UNASSESSED,,
|
|
1033
1058
|
SortFields,Parent,"property, read-only",As Object,,MISSING,,
|
|
1059
|
+
Style,_Default,"property, read-only",As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1060
|
+
Style,AddIndent,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1061
|
+
Style,Application,"property, read-only",As Application,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1062
|
+
Style,Borders,"property, read-only",As Borders,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"xlLeft, xlRight, xlTop and xlBottom, and 1 to 4, are its edges and 5 and 6 its diagonals, set as a range's are; Borders(7) to Borders(12) read -4142 and 2 where edge 1 to 6 has a line in the automatic colour, else Null, and setting one does nothing. A property set on the collection sets all six; one read reports unsupported."
|
|
1063
|
+
Style,BuiltIn,"property, read-only",As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Setting it is error 450, as in Excel."
|
|
1064
|
+
Style,Creator,"property, read-only",As XlCreator,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1065
|
+
Style,Delete,method,Delete() As Variant,,PARTIAL,tests/fixtures/cell_styles/style_changes.json,"Its cells go to Normal, every part they did not set themselves following Normal from then on; a built-in style stays in the file, hidden. Normal is error 1004, as is a workbook with a protected sheet."
|
|
1066
|
+
Style,Font,"property, read-only",As Font,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Read and set as a range's are; Superscript and Subscript read False while the style leaves its font out. Normal's font takes colours and strikethrough; its size, face, bold, italic and underline, which the sheets' geometry rests on, report unsupported."
|
|
1067
|
+
Style,FormulaHidden,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1068
|
+
Style,HorizontalAlignment,property,As XlHAlign,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1069
|
+
Style,IncludeAlignment,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1070
|
+
Style,IncludeBorder,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1071
|
+
Style,IncludeFont,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1072
|
+
Style,IncludeNumber,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1073
|
+
Style,IncludePatterns,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1074
|
+
Style,IncludeProtection,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set: a part included again reaches the cells that took it from the style; one left out stays with them as it is.
|
|
1075
|
+
Style,IndentLevel,property,As Long,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Null unless aligned left, right or distributed and not turned. Read and set; each cell that follows the style follows it while the style includes the part."
|
|
1076
|
+
Style,Interior,"property, read-only",As Interior,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Read and set as a range's are, but its automatic pattern colour stays white or black, as it is, where a cell's turns black."
|
|
1077
|
+
Style,Locked,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1078
|
+
Style,MergeCells,property,As Variant,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,"Error 1004, as Excel's is."
|
|
1079
|
+
Style,Name,"property, read-only",As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Setting it is error 450, as in Excel."
|
|
1080
|
+
Style,NameLocal,"property, read-only",As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Setting it is error 1004, as in Excel."
|
|
1081
|
+
Style,NumberFormat,property,As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1082
|
+
Style,NumberFormatLocal,property,As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1083
|
+
Style,Orientation,property,As XlOrientation,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1084
|
+
Style,Parent,"property, read-only",As Object,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1085
|
+
Style,ReadingOrder,property,As Long,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1086
|
+
Style,ShrinkToFit,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1087
|
+
Style,Value,"property, read-only",As String,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"Setting it is error 450, as in Excel."
|
|
1088
|
+
Style,VerticalAlignment,property,As XlVAlign,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1089
|
+
Style,WrapText,property,As Boolean,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,Read and set; each cell that follows the style follows it while the style includes the part.
|
|
1090
|
+
Styles,_Default,"property, read-only",As Style,,MISSING,,
|
|
1091
|
+
Styles,_NewEnum,"property, read-only",As IUnknown,,MISSING,,
|
|
1092
|
+
Styles,Add,method,"Add(Name As String, [BasedOn As Variant]) As Style",,PARTIAL,tests/fixtures/cell_styles/cell_styles.json; tests/fixtures/cell_styles/style_changes.json,"A copy of Normal, or of the first cell of BasedOn without the parts its cells do not share. A name with no characters (Excel's Style 1) reports unsupported."
|
|
1093
|
+
Styles,Application,"property, read-only",As Application,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1094
|
+
Styles,Count,"property, read-only",As Long,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1095
|
+
Styles,Creator,"property, read-only",As XlCreator,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1096
|
+
Styles,Item,"property, read-only",As Style,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,By name in any case or by place in the sorted list.
|
|
1097
|
+
Styles,Merge,method,Merge(Workbook As Variant) As Variant,,PARTIAL,tests/fixtures/cell_styles/style_changes.json,"A style named as one here takes its place, keeping this workbook's spelling, and reaches the cells that follow it; the rest come in the order their names sort. A workbook with another theme, a Normal that differs and a built-in style this workbook deleted report unsupported."
|
|
1098
|
+
Styles,Parent,"property, read-only",As Object,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,
|
|
1034
1099
|
TextFrame,Application,"property, read-only",As Application,,MISSING,,
|
|
1035
1100
|
TextFrame,AutoMargins,property,As Boolean,,MISSING,,
|
|
1036
1101
|
TextFrame,AutoSize,property,As Boolean,no setter,UNASSESSED,,
|
|
@@ -1366,7 +1431,7 @@ Workbook,ShowPivotTableFieldList,property,As Boolean,,MISSING,,
|
|
|
1366
1431
|
Workbook,Signatures,"property, read-only",As SignatureSet,,MISSING,,
|
|
1367
1432
|
Workbook,SlicerCaches,"property, read-only",As SlicerCaches,,MISSING,,
|
|
1368
1433
|
Workbook,SmartDocument,"property, read-only",As SmartDocument,,MISSING,,
|
|
1369
|
-
Workbook,Styles,"property, read-only",As Styles,,
|
|
1434
|
+
Workbook,Styles,"property, read-only",As Styles,,PARTIAL,tests/fixtures/cell_styles/cell_styles.json,"Excel's 47 built-in styles and every one the file or a macro adds, in the order Windows word sort puts their names."
|
|
1370
1435
|
Workbook,Sync,event,Sync(SyncEventType As MsoSyncEventType),,MISSING,,
|
|
1371
1436
|
Workbook,TableStyles,"property, read-only",As TableStyles,,MISSING,,
|
|
1372
1437
|
Workbook,TemplateRemoveExtData,property,As Boolean,,MISSING,,
|
|
@@ -1466,7 +1531,7 @@ Worksheet,ExportAsFixedFormat,method,"ExportAsFixedFormat(Type As XlFixedFormatT
|
|
|
1466
1531
|
Worksheet,FilterMode,"property, read-only",As Boolean,,PARTIAL,tests/fixtures/autofilter.json; tests/fixtures/autofilter_file/autofilter_file.json; tests/test_live_excel_model_gate.py,
|
|
1467
1532
|
Worksheet,FollowHyperlink,event,FollowHyperlink(Target As Hyperlink),,MISSING,,
|
|
1468
1533
|
Worksheet,HPageBreaks,"property, read-only",As HPageBreaks,,MISSING,,
|
|
1469
|
-
Worksheet,Hyperlinks,"property, read-only",As Hyperlinks,,
|
|
1534
|
+
Worksheet,Hyperlinks,"property, read-only",As Hyperlinks,,VERIFIED,tests/fixtures/hyperlinks/hyperlinks.json; tests/test_live_excel_model_gate.py,"In the order they were added, a link replaced keeping its place."
|
|
1470
1535
|
Worksheet,Index,"property, read-only",As Long,,PARTIAL,tests/fixtures/excel_model/probes.txt,
|
|
1471
1536
|
Worksheet,LensGalleryRenderComplete,event,LensGalleryRenderComplete(),,MISSING,,
|
|
1472
1537
|
Worksheet,ListObjects,"property, read-only",As ListObjects,,PARTIAL,tests/fixtures/tables/tables.json,"The sheet's tables, read from a file or made by ListObjects.Add."
|
|
@@ -138,12 +138,12 @@ entry tracked explicitly.
|
|
|
138
138
|
| VBA projects and forms | In-scope MS-OVBA gates, designer round trips and live file gates exist; shared library-reference add/remove operations pass native Excel/Word/PowerPoint checks and Access persistence tests | Reconcile every operation with its format and protection/signing limits; distinguish form design from form runtime; linked VBA-project creation and arbitrary library runtime resolution remain separate gaps |
|
|
139
139
|
| VBA language and runtime | Measured semantics, classes, errors and control flow exist; every constant of VBA's own type library, the colour, key-code and system-colour modules included, typed as declared; Scripting.Dictionary in memory, its key matching measured | Audit complete syntax, type system, lifetime, references and intrinsics; track file I/O, external calls and known typing gaps explicitly |
|
|
140
140
|
| Application, workbooks and sheets | Core collections, cells, names and queries exist; sheet protection -- Protect, Unprotect, the Protection object and every edit a protected sheet refuses a macro, with Excel's own errors -- follows 168 live cases, and is saved and read as Excel saves and reads it, SHA-512 and legacy passwords included, over 13 files and a live gate; workbook protection -- Protect, Unprotect and the sheet changes a protected structure refuses -- follows 41 cases and 5 files, with a live gate; windows -- ActiveWindow, Windows, Goto, each sheet's zoom, view, display settings, scrolling, frozen panes and selection, the tabs and the window order -- follow 113 live workbooks, saved and read as Excel saves and reads them | Map all reference members; identify stubs, missing collections and incomplete arguments; allowed edit ranges and copying or moving sheets between workbooks while one is protected; a split that is not frozen, which Excel keeps in twips of the window; NewWindow, hidden windows and a window's size and state |
|
|
141
|
-
| Ranges and editing | Values, formulas, areas and basic movement exist; written values are typed as Excel types them, with the formats typing brings, prefix characters, Text cells and Value/Value2 types, pinned by
|
|
141
|
+
| Ranges and editing | Values, formulas, areas and basic movement exist; written values are typed as Excel types them, with the formats typing brings, prefix characters, Text cells and Value/Value2 types, pinned by 4,902 live writes and a saved workbook; formulas a macro writes are spelled as Excel spells them over 120 live formulas; NumberFormat codes round-trip Excel's spelling on both sides; Range.Text, TEXT and WorksheetFunction.Text follow Excel's number-format engine over 156 live codes and 28 values, and round times as Excel does over 152 times on the half second; CurrentRegion and End pass 34 live layouts, FillDown/Up/Right/Left 16 and SpecialCells 18; single-area Find/FindNext/FindPrevious pass 48 native cases; Replace passes 80 live layouts and the formula-bar text of 20 numbers in 26 formats; the clipboard's Copy, Cut, Paste and PasteSpecial pass 49; Range.Sort and the Sort object pass 58, in Excel's order for ASCII text over 583 values; AutoFill passes 208 layouts and 520 columns, its series of numbers, dates, times, text and names to the last digit; RemoveDuplicates passes 98; TextToColumns passes 54 of 57 live cases of delimiters, qualifiers, typing, FieldInfo and its six date orders, separators and fixed widths, the other 3, FieldInfo pairs out of order, reporting themselves unsupported; Range.Range passes 29 live probes and a space-separated intersection 5; AutoFilter passes 113 layouts, reads and writes 41 filters as Excel saves them, and passes a live gate; edits on a filtered sheet -- writes, formats, clears, fills, copies, sorts, deletes and inserts, and the filter following rows and columns -- match 190 of 195 live layouts, the other 5 reporting themselves unsupported (two-dimensional arrays over several areas); SUBTOTAL passes 31 live layouts over hidden, filtered and nested rows and references that functions and operators give; every edit above meets sheet protection as Excel's does; Cut moves the references that overlap it as Excel does over 24 live layouts; cell shifts -- Insert and Delete with a Shift or none -- move references, names, the filter's range and formats as Excel does over 47 live layouts; merged-range geometry/value operations pass 21 native cases and four persistence gates; FormulaR1C1 scalar and array writes/reads pass 27 native cases and five persistence gates; A1 Formula array writes share the implementation and pass 15 native cases plus four persistence gates | Complete multi-area/comment/format/MatchByte searches, complex across/multi-area merges and merge formatting; Range.Text with a `*` fill and in columns too narrow for a value (both need text widths in pixels); typing a space before a month's name and a time, or digits after AM or PM and a point, which Excel misreads into numbers; audit insertion, deletion, copying, sorting and filtering |
|
|
142
142
|
| Named ranges | Workbook/worksheet CRUD, validation, scope precedence, rename/retarget/delete, visibility/comments and Python snapshots share one implementation; 19 native cases and three persistence gates | Active-cell-relative name semantics, locale translation, Excel 4 macro metadata and arbitrary named-formula evaluation remain incomplete |
|
|
143
143
|
| Multiple workbooks and sheet copying | Add/open/activate/close; VBA sheet Copy/Move before/after or into a new book, matching native held-object invalidation on cross-book moves; inter-book range copies import used names and aliases with reuse/rename/error policies, backed by native probes and persistence gates | External workbook links, independent VBA projects, sheet-copy/move name conflicts, relative/other-sheet name imports, transferred drawings/controls, sheet modules and advanced worksheet metadata remain incomplete |
|
|
144
144
|
| Structural edits | Whole-row/column insertion/deletion and formula/name reference updates pass 12 native cases and four persistence gates; occupied-edge insertion is atomic | Partial-cell reference rewriting, relative name context, merges/shapes, formatting inheritance/CopyOrigin and table/validation/chart metadata updates remain incomplete |
|
|
145
145
|
| Range copying | Explicit-destination copies pass 17 native cases and five persistence gates: overlap, blanks, repeated blocks, formulas, cross-sheet copying and measured formatting | Merged-cell and multi-area copies, destinations larger than 1,048,576 cells, clipboard/paste behavior and full formatting fidelity remain incomplete |
|
|
146
|
-
| Formatting and layout | Cell formats are complete for Font, Interior, Borders, alignment, protection, NumberFormat and ClearFormats: 161 live probes, an Excel-authored workbook read back value for value, the border storage rules, a live gate for model-written formats, and
|
|
146
|
+
| Formatting and layout | Cell formats are complete for Font, Interior, Borders, alignment, protection, NumberFormat and ClearFormats: 161 live probes, an Excel-authored workbook read back value for value, the border storage rules, a live gate for model-written formats, and the stylesheet Excel writes for the same edits, entry for entry. Row heights, column widths and hidden rows and columns follow Excel on a 96-DPI display: 185 live probes, Excel-authored and foreign files read back, the saved XML Excel's, and a live gate. Rows grow with their fonts from a 25,662-row table measured for eleven font families in four styles, beside the Normal font and alone on a row. Row, column and sheet-wide formats follow Excel: 149 live probes, Excel's saved workbook read back, 16 foreign files read and written back as Excel does, the model's saved XML Excel's, and a live gate. Medium, thick and double borders make rows taller as Excel's do, 39 more probes in the same fixture. Data validation reads, adds, changes, deletes and checks rules as Excel does, each rule moving with inserts and deletes, splitting round a delete or a Clear and carried by a copy, over 39 live workbooks and the dataValidations element Excel saves. Named cell styles -- `Range.Style`, `Styles` with `Add` and `Merge`, and the `Style` object's properties, read, set and deleted -- answer as Excel's do over 11,147 live reads and 6,459 more of styles a macro changes, deletes and merges: the 47 built-in styles given to cells in both orders, styles over formats and formats over styles, which cells follow a changed style, Normal's font, protected sheets; the stylesheet Excel writes for them, in the order its tables hold what a session made, under two themes and after a reopen, over 45 saved workbooks, files holding entries nothing uses, entries twice and custom formats out of order among them, and a live gate opens ten of the model's in Excel, which reads them as its own; an edge two cells' styles both draw reads as Excel reads it over 415 pairs | Normal's font size, face, bold, italic and underline, which the sheets' geometry rests on; a style of a workbook that is not the active one, which Excel changes in the active workbook; conditional formatting and page setup; a validation list read from another sheet, which Excel keeps in the worksheet's x14 extension; cell shifts (`Insert`/`Delete` with `Shift`) on sheets with row or column formats; rows mixing fonts from different tables, unmeasured fonts, super/subscript and wrapped or turned text; a thick border along a hidden row; column AutoFit; Normal fonts other than Aptos Narrow 11 and Calibri 11 |
|
|
147
147
|
| Tables and structured references | Power Query reads workbook tables and writes load targets; ListObjects reads a file's tables and makes new ones as Excel does -- headers, generated column names, the header row put in, the name and style -- with ListObject, ListColumns and ListRows answering, and saves them in the parts Excel writes, over 8 live workbooks and 15 live questions; a table read from a file keeps its part until it changes, and whole rows inserted or deleted through it carry it. Structured references are read, spelled, saved and worked out as Excel does over 80 live formulas and a 50-name character sweep: this row, special items, spans, escapes, the table's name left out inside it, a column read as this row's cell where one value is wanted, Range and Evaluate, AutoFill along the columns, and renaming a table or its columns through every formula. The totals row shows and hides as Excel does over 20 live workbooks, with its default label and function, every TotalsCalculation, and labels, SUBTOTALs and formulas written into it. ListRows.Add and Delete, ListColumns.Add and Delete, Resize and Delete, calculated columns, and a table growing over what a macro writes beside it, with the references it stretches, match 28 live workbooks and 21 live writes | Unlist, which turns the table style into cell formats; a copy or fill beside a table, which puts a table row in first; whole columns inserted or deleted through a table; the dxf a calculated column made from one cell brings; and a header holding a carriage return, which VBA reads as a line feed |
|
|
148
148
|
| Formulas and calculation | Cells are worked out by pyOfficeEditor's engine, 493 of Excel's 525 functions, which comes to what Excel cached for all 10,958 formulas of its corpus over the model's workbook; formula parser, dependency invalidation and manual mode exist; a formula's last sum set to zero when it cancels, comparisons to fifteen digits and lookups to the bit follow Excel over 1,788 live pairs of doubles; defined names that stand for a formula work out where they are used, as array formulas; a range or array where one value is wanted is cut to the formula's row or column or run item by item, SUMPRODUCT, INDEX, ROWS and COLUMNS work their arguments out as arrays, and a value where a function reads cells is refused, as 232 live formulas show and as each of the engine's 493 functions measured there does, 15 of them taken; a call with too few or too many arguments, a LET's or a LAMBDA's name that is none, and a formula past Excel's limits on text, brackets, calls, signs and length are refused, over 14,377 live formulas, every function with 25 counts of arguments; a running total 3000 rows down and the deepest formulas Excel takes work out as Excel does; a formula written in the other notation, `Formula = "=R[-1]C+1"` or `FormulaR1C1 = "=A1"`, reads as Excel reads it, over 79 live formulas; LET's and LAMBDA's names, those looking like cells among them, and LAMBDA's optional parameters read, work out and save as Excel's do, over 24 live formulas; a formula written to a General cell takes the number format Excel gives it, over 111 live cases; `FormulaArray`, `HasArray` and `CurrentArray` follow Excel over 78 live cases, array formulas saved and read as Excel does; the range operator, intersections, unions and INDEX, OFFSET, INDIRECT, CHOOSE, IF, IFS, SWITCH and XLOOKUP as references follow Excel over 45 live formulas, and INDEX with one index into rows and columns and a `+` before a reference over 26 more; `Formula2` and `Formula2R1C1` read a legacy formula with Excel's `@` over 2100 live formulas, every function in every way it takes an argument; an `@` or a call of SINGLE written through `Formula`, `Formula2`, `FormulaR1C1` or `Value` is kept, left out, read back and saved as Excel does, over 274 live writes and a saved workbook; dynamic arrays spill, grow, shrink and are #SPILL! where something is in the way, with `HasSpill`, `SpillParent`, `SpillingToRange`, `A1#` and their file format, over 42 live cases, 18 expressions and two saved workbooks | Complete function and argument coverage, spills and structural edits (sort, insert and delete through a spill), copying part of an array formula, relative R1C1 in INDIRECT and unions for functions beyond the aggregates, errors, circular/iterative calculation, cached-value persistence and names with relative references |
|
|
149
149
|
| VBA WorksheetFunction and Evaluate | WorksheetFunction.X and the late-bound Application.X call the cell formula engine for the 388 WorksheetFunction members it has, with arguments, answers and errors converted as 160 live calls made both ways show; Evaluate, `[...]` and Worksheet.Evaluate work out expressions through the same engine as Excel does over 91 live cases: a Range for cells, blocks whole, error values, ROW() as an array of one | The WorksheetFunction members the engine lacks: the cube functions, WEBSERVICE, STOCKHISTORY and the like; the members registered with the engine checked through VBA one by one |
|
|
@@ -152,7 +152,7 @@ entry tracked explicitly.
|
|
|
152
152
|
| Charts | Existing chart parts can be preserved and shapes identified | Audit chart objects, creation, series, axes, formatting, data links and round trips |
|
|
153
153
|
| Pivots, caches and data model | Unmodelled content is preserved in existing files | Inventory and implement headless operations; preservation alone is not runtime support |
|
|
154
154
|
| Power Query | Packaging, M evaluation, local refresh and sheet load targets exist | Complete language/library conformance, data types, errors, query dependency behavior, connectors and refresh settings |
|
|
155
|
-
| Other workbook features | Coverage varies and needs classification; notes, which VBA calls comments, are added, read, edited, moved with their cells, copied and saved as Excel does, over 89 live probes and a saved workbook of every kind of note, its parts written byte for byte | Inventory names, links, threaded comments,
|
|
155
|
+
| Other workbook features | Coverage varies and needs classification; notes, which VBA calls comments, are added, read, edited, moved with their cells, copied and saved as Excel does, over 89 live probes and a saved workbook of every kind of note, its parts written byte for byte. Hyperlinks are added, read, set, taken away, moved, copied, pasted, cut, sorted and saved as Excel does, with the Hyperlink style and the HYPERLINK function's, over 26 sections of live Excel and 21 workbooks it saved, their links, relationships, cell styles and stylesheets matched, and a live gate opens the model's in Excel, which reads them as its own; a part's relationships come in Excel's order, from the hash Office places their ids by, over every count to 160 and 17 larger ones up to 65,530 | Inventory names, links, threaded comments, protection, metadata, embedded objects, connections and remaining reference/file features; a note's box a macro moves or resizes, and notes under Sort and RemoveDuplicates; a hyperlink on a shape, EmailSubject on a link with no address, Follow, a paste of links turned or from several areas, and the relationship order of a part with more than 65,536 |
|
|
156
156
|
| Fidelity and release verification | Offline tests, live gates, language matrix and cross-platform CI exist | Add real-world mixed-feature cases, malformed/foreign-author packages and scale tests; require live evidence for new persisted behavior |
|
|
157
157
|
|
|
158
158
|
## Execution order within Excel
|
|
@@ -572,6 +572,49 @@ does (`tests/fixtures/remove_duplicates.json`, 98 layouts).
|
|
|
572
572
|
merged cells, row and column formats, and a destination that runs on
|
|
573
573
|
in two directions at once report themselves unsupported.
|
|
574
574
|
|
|
575
|
+
**Text to columns.** `Range.TextToColumns` splits a column of text as
|
|
576
|
+
Excel does (`tests/fixtures/text_to_columns.json`, 57 cases).
|
|
577
|
+
|
|
578
|
+
* Only a range of one column splits; more is error 1004. Each line splits
|
|
579
|
+
at any of the delimiters asked for, OtherChar giving only its first
|
|
580
|
+
character, and with none asked for it stays whole. ConsecutiveDelimiter
|
|
581
|
+
reads a run of them as one, though a field in quotes, `""` included, is
|
|
582
|
+
a field of its own. A field in the text qualifier, a double quote
|
|
583
|
+
unless TextQualifier asks for a single one or none, keeps the
|
|
584
|
+
delimiters in it and reads a doubled qualifier as one.
|
|
585
|
+
* Every row of the block is written across the widest line: a field that
|
|
586
|
+
is empty, or that a shorter line lacks, clears its cell and leaves its
|
|
587
|
+
format. A number or a blank in the source column stays as it is. A
|
|
588
|
+
Destination moves the block's corner, on the source's sheet whichever
|
|
589
|
+
sheet it names.
|
|
590
|
+
* A field is typed as typing a cell types it, into a number, a date, a
|
|
591
|
+
time, TRUE or an error, with the format typing brings where the cell's
|
|
592
|
+
own is General. A format of the cell's own stays, and a cell formatted
|
|
593
|
+
Text still takes the number. A field starting with `=` is a formula.
|
|
594
|
+
`5-` is text unless TrailingMinusNumbers is True, `-0` is 0, and a
|
|
595
|
+
number past Excel's largest stays text. DecimalSeparator and
|
|
596
|
+
ThousandsSeparator read numbers written with other separators.
|
|
597
|
+
* FieldInfo gives the columns, in order, a kind: xlTextFormat keeps the
|
|
598
|
+
field as it is and formats the cell Text, a date order reads the field
|
|
599
|
+
as that order's date, and xlSkipColumn drops the column. With DataType
|
|
600
|
+
xlFixedWidth each line is cut where the pairs start, counted from 0.
|
|
601
|
+
* A date column fills its day, month and year in its order from runs of
|
|
602
|
+
digits split at `/`, `-`, `.` or a space, a run of separators counting
|
|
603
|
+
as one: two digits to a day or a month and four to a year, the rest
|
|
604
|
+
spilling into the next part, so `5/2020` in an MDY column is 20 May
|
|
605
|
+
2020. A month's name fills a month. A run of digits with no separator
|
|
606
|
+
is cut by its length: four digits two and two, five with one for the
|
|
607
|
+
month, six two each, eight at the parts' widths. Three parts make an
|
|
608
|
+
m/d/yyyy date if they are one. Two go by a fixed table, not the
|
|
609
|
+
letters' order: DMY, YMD and YDM read a day and its month, else a year
|
|
610
|
+
and its month; MDY, MYD and DYM a month and its day, else a month and
|
|
611
|
+
its year; a day read so falls in the current year. A field the column
|
|
612
|
+
reads no date in is typed as a General column types it.
|
|
613
|
+
* FieldInfo pairs that do not number the columns 1, 2, 3 in order, a
|
|
614
|
+
column holding formulas and a sheet with merged cells report
|
|
615
|
+
themselves unsupported. An omitted argument takes its default; whether
|
|
616
|
+
Excel carries one over from an earlier call is not measured.
|
|
617
|
+
|
|
575
618
|
**The clipboard.** `Range.Copy` and `Range.Cut` with no destination put
|
|
576
619
|
the range on the clipboard, and `Application.CutCopyMode` reads 1 after
|
|
577
620
|
a copy, 2 after a cut and 0 once it is cleared; setting it to False
|
|
@@ -740,10 +783,9 @@ protection properties, `NumberFormat` and `ClearFormats` read and write a
|
|
|
740
783
|
cell's format the way Excel does; 161 probes of live Excel pin the
|
|
741
784
|
answers (`tests/fixtures/range_format.json`). A workbook's `styles.xml`
|
|
742
785
|
is read into one format per cell, so a file Excel formatted reads back
|
|
743
|
-
exactly as Excel reads it, and a save
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
first whenever one is used.
|
|
786
|
+
exactly as Excel reads it, and a save writes the stylesheet the way Excel
|
|
787
|
+
writes it (see **The stylesheet** below): for the same edits it comes out
|
|
788
|
+
byte for byte as Excel's (`tests/fixtures/format/formats.xlsx`).
|
|
747
789
|
|
|
748
790
|
* A property read over several cells answers the shared value or Null.
|
|
749
791
|
Colours compare as colours, and a mixed `Interior.Color` or
|
|
@@ -763,6 +805,12 @@ first whenever one is used.
|
|
|
763
805
|
neighbour's copy. An inside border is written on both cells, and one
|
|
764
806
|
that only one of them stored comes out in the automatic colour, which
|
|
765
807
|
the file writes `auto="1"`.
|
|
808
|
+
* Cell styles can leave both cells drawing the edge between them, and
|
|
809
|
+
then the stronger line style shows -- double, thick, medium, the
|
|
810
|
+
medium dashes, slanted dash-dot, thin, dashed, dotted, dash-dot,
|
|
811
|
+
dash-dot-dot, hair -- and between two of one style the darker colour,
|
|
812
|
+
by 2R + 5G + B, as 415 pairs of cells in live Excel show
|
|
813
|
+
(`tests/fixtures/cell_styles/shared_edges.json`).
|
|
766
814
|
* `LineStyle` and `Weight` pair into the thirteen line styles the file
|
|
767
815
|
has; a style keeps the current weight when the pair exists and takes
|
|
768
816
|
its own default otherwise.
|
|
@@ -770,22 +818,103 @@ first whenever one is used.
|
|
|
770
818
|
left-aligned, and choosing an alignment that cannot be indented drops
|
|
771
819
|
the indent. `ClearFormats` unmerges.
|
|
772
820
|
|
|
773
|
-
`Range.Style`, the `Styles` collection and
|
|
774
|
-
|
|
775
|
-
|
|
821
|
+
**Cell styles.** `Range.Style`, the `Styles` collection and the `Style`
|
|
822
|
+
object answer as Excel's do over 11,147 reads in live Excel
|
|
823
|
+
(`tests/fixtures/cell_styles/cell_styles.json`), and styles a macro
|
|
824
|
+
changes, deletes and merges over 6,459 more (`style_changes.json`, made
|
|
825
|
+
by `scripts/measure_style_changes.py`). The 45 workbooks Excel saved on
|
|
826
|
+
the way are written the same by the model, entry for entry.
|
|
827
|
+
|
|
828
|
+
* A new workbook lists Excel's 47 built-in styles, and its file holds
|
|
829
|
+
only Normal until a cell uses another. Styles are listed in the order
|
|
830
|
+
Windows word sort puts their names, and a name finds its style in any
|
|
831
|
+
case.
|
|
832
|
+
* Giving a range a style replaces the parts of its cells' formats the
|
|
833
|
+
style includes -- `IncludeNumber`, `IncludeFont`, `IncludeAlignment`,
|
|
834
|
+
`IncludeBorder`, `IncludePatterns`, `IncludeProtection` -- and keeps
|
|
835
|
+
the rest; a border the style includes replaces all four sides. A range
|
|
836
|
+
whose cells have different styles answers Nothing. Anything but the
|
|
837
|
+
name of a style or a `Style` is error 450, and so is a protected sheet
|
|
838
|
+
that does not allow formatting cells.
|
|
839
|
+
* `Styles.Add` copies Normal, or the first cell of `BasedOn`, leaving out
|
|
840
|
+
the parts the range's cells do not share.
|
|
841
|
+
* A style's properties set as a range's do. The style changes, and each
|
|
842
|
+
cell, row and column format that did not set the part itself follows,
|
|
843
|
+
while the style includes the part; including a part again brings the
|
|
844
|
+
style's part back to them. A built-in style a macro touches, even to
|
|
845
|
+
set what it was, is written `customBuiltin`.
|
|
846
|
+
* Normal's font is the file's first font, which every format in it points
|
|
847
|
+
at, so a change to it reaches cells of any style that did not set their
|
|
848
|
+
font. The model takes its colours and strikethrough, and reports its
|
|
849
|
+
size, face, bold, italic and underline unsupported: the sheets' column
|
|
850
|
+
widths and row heights rest on them.
|
|
851
|
+
* A style's `Borders` are its edges by `xlLeft`, `xlRight`, `xlTop` and
|
|
852
|
+
`xlBottom` and its diagonals by 5 and 6; `Borders(7)` to `Borders(12)`
|
|
853
|
+
read -4142 and 2 where the edge in that turn has a line in the
|
|
854
|
+
automatic colour, else Null, and setting one does nothing. A style's
|
|
855
|
+
automatic pattern colour stays white or black, where a cell's turns
|
|
856
|
+
black. `Superscript` and `Subscript` read False while the style leaves
|
|
857
|
+
its font out, and `IndentLevel` is Null unless the style aligns left,
|
|
858
|
+
right or distributed and does not turn its text.
|
|
859
|
+
* `Style.Delete` moves its cells to Normal, each part they did not set
|
|
860
|
+
themselves following Normal from then on; a built-in style stays in
|
|
861
|
+
the file, hidden, a held `Style` of it is error 424, and Normal is
|
|
862
|
+
error 1004. `Styles.Merge` brings another workbook's styles in: one
|
|
863
|
+
named as one here takes its place and reaches the cells that follow
|
|
864
|
+
it, keeping this workbook's spelling, and the rest come in the order
|
|
865
|
+
their names sort.
|
|
866
|
+
* A protected sheet in the workbook makes a change or a delete error
|
|
867
|
+
1004, whatever the protection allows. A macro that changes a style of
|
|
868
|
+
a workbook that is not the active one changes the active workbook's
|
|
869
|
+
style of that name in Excel; the model reports that unsupported.
|
|
870
|
+
* A save writes a built-in style while a cell uses it, a macro changed
|
|
871
|
+
it or deleted it, and every style a macro added: after the file's own,
|
|
872
|
+
the built-in ones in Excel's order and then the rest in the order they
|
|
873
|
+
were made, each in the theme's fonts.
|
|
874
|
+
|
|
875
|
+
**The stylesheet.** Excel keeps a workbook's number formats, fonts,
|
|
876
|
+
fills, borders, cell styles and cell xfs as tables in the order they
|
|
877
|
+
came -- the file's own, then the parts of its built-in styles, then what
|
|
878
|
+
the session made -- and a save writes the ones in use in that order and
|
|
879
|
+
leaves the rest out. The model keeps the same tables
|
|
880
|
+
(`tests/fixtures/cell_styles/order.xlsx`).
|
|
881
|
+
|
|
882
|
+
* A new part equal to a built-in style's takes that style's place: a red
|
|
883
|
+
font, which Warning Text has, comes ahead of the fonts a macro made
|
|
884
|
+
before it.
|
|
885
|
+
* A custom number format takes its id when it is made, and a save leaves
|
|
886
|
+
a gap where one was made and then dropped. Opening a file numbers its
|
|
887
|
+
custom formats from 164 in the order it lists them.
|
|
888
|
+
* A cell xf changes in place when its style changes, and two that come
|
|
889
|
+
to say the same stay apart. Opening a file, Excel works each xf's apply
|
|
890
|
+
flags out afresh and takes an xf that then points at what an earlier
|
|
891
|
+
one points at as that one; a font the file holds twice stays two.
|
|
892
|
+
* A save that follows no change to a format leaves the stylesheet as the
|
|
893
|
+
file had it, as it leaves a sheet no macro wrote to.
|
|
894
|
+
|
|
895
|
+
Conditional formats are not implemented yet; the operation checklist,
|
|
896
|
+
`docs/excel_checklist.csv`, records each member's status.
|
|
776
897
|
|
|
777
898
|
**Typing.** A string written through `Value`, `Value2`, `Formula` or an
|
|
778
899
|
array is typed the way Excel types what someone enters in a cell, and a
|
|
779
900
|
Date or Currency a macro computes brings a format of its own. 3,723
|
|
780
901
|
writes in live Excel pin the rules (`tests/fixtures/value_typing.json`,
|
|
781
902
|
`tests/fixtures/typing_formats.json`), with 49 more in a workbook Excel
|
|
782
|
-
saved (`tests/fixtures/typing/`)
|
|
903
|
+
saved (`tests/fixtures/typing/`) and 911 dates and times in
|
|
904
|
+
`tests/fixtures/typed_dates.json`.
|
|
783
905
|
|
|
784
906
|
* `"5%"` is 0.05 in the 0% format, `"$1,000.50"` a dollar amount,
|
|
785
907
|
`"1e3"` scientific, `"1 3/16"` a fraction, `"12:30:45.5"` a time to the
|
|
786
908
|
tenth of a second, and `"1/2"` the second of January this year. Dates
|
|
787
909
|
run month first on Excel's own calendar, which has a 29 February 1900,
|
|
788
910
|
from 1900 to 9999; a date that does not exist stays text.
|
|
911
|
+
* A month's name may stand before or after its day, parted from it by a
|
|
912
|
+
slash, a dash, a space or nothing, and a date and a time may come
|
|
913
|
+
either way round, with numbers after them read past. A space before a
|
|
914
|
+
date or a time keeps it text, except before a day and a month's name.
|
|
915
|
+
Excel misreads a space before a month's name and a time, and digits
|
|
916
|
+
after AM or PM and a point, into numbers; those report themselves
|
|
917
|
+
unsupported.
|
|
789
918
|
* A cell keeps its own format unless it is General, or one of Excel's
|
|
790
919
|
built-in currency, accounting, percent, scientific, fraction, date and
|
|
791
920
|
time formats and the typed value is of another kind; a number with
|
|
@@ -1209,6 +1338,48 @@ a workbook Excel saved opens with its notes and saves them back as they
|
|
|
1209
1338
|
came. Sorting or removing duplicates over a note, and threaded comments,
|
|
1210
1339
|
report themselves unsupported.
|
|
1211
1340
|
|
|
1341
|
+
**Hyperlinks.** `Worksheet.Hyperlinks`, `Range.Hyperlinks`,
|
|
1342
|
+
`Range.ClearHyperlinks` and the `Hyperlink` object answer as Excel's do
|
|
1343
|
+
(`tests/fixtures/hyperlinks/`, 26 sections of live Excel and the 21
|
|
1344
|
+
workbooks it saved along the way; `_hyperlinks`, `_hyperlinks_file`).
|
|
1345
|
+
`Hyperlinks.Add` puts a link on each area of its anchor and answers the
|
|
1346
|
+
last; one over the very cells of a link takes that link's place in the
|
|
1347
|
+
list, one over any other cells goes at the end, overlapping or not. The
|
|
1348
|
+
anchor's cells take the style named Hyperlink, the built-in one made the
|
|
1349
|
+
first time among the styles a session makes, and the first cell the
|
|
1350
|
+
text to show or, when it is empty, the address, a number staying a
|
|
1351
|
+
number. An address is kept as Excel tidies it: spaces round it and tabs
|
|
1352
|
+
in it dropped, a `#` splitting off the subaddress, an http, https or ftp
|
|
1353
|
+
address's scheme and host in lower case, its path's `.` and `..`
|
|
1354
|
+
resolved and its escapes of letters, digits and spaces undone; `file:///C:/x`
|
|
1355
|
+
becomes `C:\x`. A link is named by the text to show it was given, or by
|
|
1356
|
+
"address - subaddress", which follows a new address; one read from a
|
|
1357
|
+
file without a display is named by its cell's text until a new address
|
|
1358
|
+
names it. `TextToDisplay` reads the first cell's text, "" for a number or
|
|
1359
|
+
a formula. Setting `SubAddress` takes the address away, and `Address`
|
|
1360
|
+
keeps the subaddress unless the new one has a `#` of its own.
|
|
1361
|
+
`EmailSubject` is a mailto address's subject, which setting it writes in.
|
|
1362
|
+
A range's collection holds the links inside one of its areas, and for a
|
|
1363
|
+
range of one area the link it lies in; `Clear`, `ClearContents`, an empty
|
|
1364
|
+
value, `ClearHyperlinks` and a copy landing on them take those links
|
|
1365
|
+
away, and `Delete` takes them with their cells' formats, merges kept. A
|
|
1366
|
+
copy or a paste of everything brings the links it meets over the cells it
|
|
1367
|
+
copies, a cut moves them in place, inserts and deletes move them as they
|
|
1368
|
+
move a reference, a sort moves a link one line high with its line, and a
|
|
1369
|
+
copy of the sheet has them all. On a protected sheet a link needs
|
|
1370
|
+
AllowInsertingHyperlinks and unlocked cells. A formula whose first
|
|
1371
|
+
function is HYPERLINK gives its cells the Hyperlink style. A save writes
|
|
1372
|
+
the hyperlinks element as Excel does, with a display where the name is
|
|
1373
|
+
not the text the cell holds, and each address as a relationship's
|
|
1374
|
+
target, escaped as Excel escapes it, a DOS path relative to the
|
|
1375
|
+
workbook's folder; the relationships number the links first, and a
|
|
1376
|
+
part's relationships come in the order Office lists them, a table
|
|
1377
|
+
placing each id by its characters in base 101 through a step of C's
|
|
1378
|
+
`rand()` (`pyopenvba._relationships`, measured to 65,530). A link on a shape,
|
|
1379
|
+
`EmailSubject` set on a link with no address -- which leaves Excel
|
|
1380
|
+
refusing every change after it -- and `Follow` report themselves
|
|
1381
|
+
unsupported.
|
|
1382
|
+
|
|
1212
1383
|
**Windows and sheet views.** `ActiveWindow`, `Windows`,
|
|
1213
1384
|
`Workbook.Windows` and `Goto` behave as Excel does with its window shown
|
|
1214
1385
|
(`tests/fixtures/windows/`, 113 workbooks). Each sheet has its own view,
|
|
@@ -1418,6 +1589,9 @@ macros, which the model does not write.
|
|
|
1418
1589
|
| `apps/excel/_dimensions.py` | Row heights, column widths and hidden rows and columns, on a 96-DPI display |
|
|
1419
1590
|
| `apps/excel/_row_formats.py` | Formats a whole row, a whole column or the whole sheet carries, and how a change spreads |
|
|
1420
1591
|
| `apps/excel/_font_rows.py` | How tall each measured font makes a row, baked from `tests/fixtures/font_rows.json` |
|
|
1592
|
+
| `apps/excel/_hyperlinks.py` | A sheet's hyperlinks, as a macro reaches them, and what edits do to them |
|
|
1593
|
+
| `apps/excel/_hyperlinks_file.py` | Hyperlink addresses as Excel keeps and saves them, and the sheet's hyperlinks element |
|
|
1594
|
+
| `_relationships.py` | The order Office writes a part's relationships in |
|
|
1421
1595
|
| `apps/word/` | Word's object model, its bridge and its file |
|
|
1422
1596
|
| `apps/powerpoint/` | PowerPoint's, the same three |
|
|
1423
1597
|
| `shapes/_values.py` | What a shape is, in all three hosts' words |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""The order Office writes a part's relationships in.
|
|
2
|
+
|
|
3
|
+
Excel, and PowerPoint with it, writes each ``.rels`` part in the order a
|
|
4
|
+
linear-hashing table keyed by the relationship ids iterates. Measured by
|
|
5
|
+
saving sheets holding every count of hyperlinks from 1 to 160 and larger
|
|
6
|
+
counts up to 65,530, the most a sheet holds, one relationship each
|
|
7
|
+
(scripts/measure_relationship_order.py):
|
|
8
|
+
|
|
9
|
+
- An id's hash is its characters read as a number in base 101, the
|
|
10
|
+
textbook string hash, put through one step of C's rand() generator:
|
|
11
|
+
(h * 1103515245 + 12345) >> 16, in 32 bits.
|
|
12
|
+
- The table starts with 8 buckets. Before an insert that would put more
|
|
13
|
+
than 4 ids per bucket it splits one bucket, p, the next in turn, into p
|
|
14
|
+
and p + L (L the buckets before this round of splits began), the ids
|
|
15
|
+
whose next hash bit is set moving to the new bucket, in their order. An
|
|
16
|
+
id's bucket is its hash mod L, or mod 2L while that is below the split
|
|
17
|
+
pointer.
|
|
18
|
+
- It is read bucket by bucket, each bucket's ids in the order they went
|
|
19
|
+
in; Office puts them in as rId1, rId2 and so on.
|
|
20
|
+
|
|
21
|
+
This reproduces all 177 measured orders, and each part Office wrote in the
|
|
22
|
+
tests' fixtures. They reach 16,384 buckets, the hash's low 14 bits; a
|
|
23
|
+
part of more than 65,536 relationships, whose order they cannot vouch
|
|
24
|
+
for, keeps the order it has, as does one whose ids are not all rId and a
|
|
25
|
+
number.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import math
|
|
31
|
+
import re
|
|
32
|
+
from typing import Final
|
|
33
|
+
|
|
34
|
+
#: The buckets the table starts with, and the ids per bucket past which it splits one.
|
|
35
|
+
_START: Final = 8
|
|
36
|
+
_LOAD: Final = 4
|
|
37
|
+
#: The most relationships a part can hold for the order to be the measured one: 16,384 buckets.
|
|
38
|
+
_MOST: Final = 65536
|
|
39
|
+
_RELATIONSHIP = re.compile(r"<Relationship\b[^>]*?(?:/>|>\s*</Relationship>)")
|
|
40
|
+
#: An id Office numbers: rId and a number, written as a number is, with no leading zero.
|
|
41
|
+
_ID = re.compile(r'\bId="rId(0|[1-9]\d*)"')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def id_hash(identifier: str) -> int:
|
|
45
|
+
"""The hash Office's table places a relationship id by: base 101, then a step of C's rand() generator."""
|
|
46
|
+
h = 0
|
|
47
|
+
for character in identifier:
|
|
48
|
+
h = (h * 101 + ord(character)) & 0xFFFFFFFF
|
|
49
|
+
return ((h * 1103515245 + 12345) & 0xFFFFFFFF) >> 16
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def bucket_order(numbers: list[int]) -> list[int] | None:
|
|
53
|
+
"""The ids rId<number>, by their numbers, in the order Office writes them; None where the order is not
|
|
54
|
+
known."""
|
|
55
|
+
if not numbers or len(numbers) > _MOST or any(number < 0 for number in numbers):
|
|
56
|
+
return None
|
|
57
|
+
buckets = max(_START, math.ceil(len(numbers) / _LOAD))
|
|
58
|
+
level = _START
|
|
59
|
+
while level * 2 <= buckets:
|
|
60
|
+
level *= 2
|
|
61
|
+
split = buckets - level
|
|
62
|
+
|
|
63
|
+
def bucket(number: int) -> int:
|
|
64
|
+
hashed = id_hash(f"rId{number}")
|
|
65
|
+
home = hashed % level
|
|
66
|
+
return hashed % (2 * level) if home < split else home
|
|
67
|
+
|
|
68
|
+
return sorted(numbers, key=lambda number: (bucket(number), number))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def in_office_order(text: str) -> str:
|
|
72
|
+
"""A ``.rels`` part with its relationships in the order Office writes them, where the order is known."""
|
|
73
|
+
elements = _RELATIONSHIP.findall(text)
|
|
74
|
+
numbers: list[int] = []
|
|
75
|
+
for element in elements:
|
|
76
|
+
found = _ID.search(element)
|
|
77
|
+
if found is None:
|
|
78
|
+
return text
|
|
79
|
+
numbers.append(int(found.group(1)))
|
|
80
|
+
if len(set(numbers)) != len(numbers):
|
|
81
|
+
return text
|
|
82
|
+
order = bucket_order(numbers)
|
|
83
|
+
if order is None:
|
|
84
|
+
return text
|
|
85
|
+
by_number = dict(zip(numbers, elements, strict=True))
|
|
86
|
+
start = text.find(elements[0])
|
|
87
|
+
end = text.rfind(elements[-1]) + len(elements[-1])
|
|
88
|
+
if start < 0 or "".join(elements) != text[start:end]:
|
|
89
|
+
return text
|
|
90
|
+
return text[:start] + "".join(by_number[number] for number in order) + text[end:]
|