A development toolkit for Excel VBA projects that provides module/form import/export with encoding conversion and sheet map export.
Designed to support xlsm development workflows that combine the VBE (Visual Basic Editor) with external editors such as VS Code.
Import xlsm_devkit.bas alone to get the following macros:
| Macro | Description |
|---|---|
ExportAllModulesFormsSheetMaps |
Exports all VBA modules and forms to src/, and all sheet maps to sheet/ |
ImportAllModulesFormsSheetMaps |
Imports all VBA modules and forms from src/, and all sheet maps from sheet/ |
CallExportAllComponents |
Exports all VBA modules and forms to src/ |
CallImportAllComponents |
Imports all VBA modules and forms from src/ |
CallExportAllSheetMapsToMD |
Exports cell values, shapes, formulas, and styles of all sheets to sheet/*.md |
CallImportAllSheetMapsFromMD |
Restores cell values, formulas, styles, named ranges, data-validation lists, and merged regions from sheet/*.md |
CallInitDevMode |
Creates DEV_<name>.xlsm from the current workbook and imports all devkit_* files from src/ into it. If the source workbook is .xlsx, the DEV_ copy is automatically created as .xlsm. |
CallSaveAsRelease |
Saves a production copy (strips DEV_ prefix, removes all devkit modules); call from a DEV_ workbook |
Modules (.bas) and forms (.frm/.frx) are handled together by the same export/import operation.
xlsm_devkit itself is never imported — a running module cannot overwrite itself.
These features require additional files to be imported alongside xlsm_devkit.bas.
Inserts or deletes rows/columns, saves before/after sheet maps as Markdown files, and generates an AI prompt for updating affected VBA references.
Required files (all must be imported into the same VBA project):
| File | Role |
|---|---|
devkit_InsertDelete.bas |
Feature logic |
devkit_frmInsertDelete.frm + devkit_frmInsertDelete.frx |
Setup dialog |
devkit_frmInstruction.frm + devkit_frmInstruction.frx |
Result/import dialog (shared with Move) |
Entry point: ShowInsertDeleteForm
Records a cell-range cut-and-paste operation via Excel's macro recorder, captures before/after sheet maps, and generates an AI prompt for updating affected VBA references.
Required files (all must be imported into the same VBA project):
| File | Role |
|---|---|
devkit_Move.bas |
Feature logic |
devkit_frmMoveSetup.frm + devkit_frmMoveSetup.frx |
Setup dialog |
devkit_frmMoveWait.frm + devkit_frmMoveWait.frx |
Recording dialog |
devkit_frmInstruction.frm + devkit_frmInstruction.frx |
Result/import dialog (shared with InsertDelete) |
Entry point: ShowMoveSetupForm
A central dialog that exposes all import/export operations in one place and lets users switch the UI language. Buttons for InsertDelete and Move also appear when those modules are loaded.
Required files (all must be imported into the same VBA project):
| File | Role |
|---|---|
devkit_Launch.bas |
Feature logic |
devkit_frmLauncher.frm + devkit_frmLauncher.frx |
Launcher dialog |
Entry point: ShowLauncherForm
UI text in all optional-feature dialogs is localized via INI-based language files. The i18n functions (t(), Fmt(), SetLang(), GetLangCode()) are built into xlsm_devkit.bas — no additional VBA module is required. Place the lang/ folder next to the workbook to enable localization.
27 languages are bundled: Arabic, Bengali, English, Spanish, Persian, French, German, Hindi, Indonesian, Japanese, Javanese, Korean, Malay, Marathi, Portuguese, Punjabi, Russian, Swahili, Tamil, Telugu, Thai, Turkish, Ukrainian, Urdu, Vietnamese, Simplified Chinese, and Traditional Chinese.
The active language is auto-detected from Windows. It can be overridden via the Launcher's language selector or programmatically:
SetLang "ja" ' switch to Japanese
SetLang "" ' revert to system auto-detection- Open your target
.xlsmworkbook and pressAlt + F11to open the VBE. - In Project Explorer, right-click the target VBA project and import
xlsm_devkit.bas. - Enable "Trust access to the VBA project object model" in Excel settings.
- Run
ExportAllModulesFormsSheetMapsonce and confirm thatsrc/andsheet/are created next to the workbook. - Edit files in
src/with VS Code, then runImportAllModulesFormsSheetMaps.
When you want to keep the user-facing workbook free from devkit modules, use the DEV_ naming convention:
Start development (CallInitDevMode)
- Open the production workbook (e.g.
MyTool.xlsm) and importxlsm_devkit.basmanually (same as the initial setup step above). - Place the optional
devkit_*.bas,devkit_*.frm, anddevkit_*.frxfiles from the xlsm_devkit release intosrc/next to the workbook (only the ones you need). - Run
CallInitDevModefrom the Macro dialog (Alt+F8). It createsDEV_MyTool.xlsmin the same folder and imports alldevkit_*files fromsrc/into the copy. - Close
MyTool.xlsmwithout saving — this keeps the production file free from devkit modules. - Open
DEV_MyTool.xlsmand develop there.
Working with
.xlsxsource files:CallInitDevModealso supports.xlsxworkbooks. The DEV_ copy is always created as.xlsm(macro-enabled format), so all devkit functionality is available regardless of the source format. After development,CallSaveAsReleaseproduces aMyTool.xlsmrelease file; use File → Save As if you need a.xlsxoutput instead.
Release (CallSaveAsRelease)
When you are ready to ship:
- From
DEV_MyTool.xlsm, runCallSaveAsReleasefrom the Macro dialog (Alt+F8), or use the Save as Release button in the Launcher (enabled only when the workbook name starts withDEV_). - It saves a copy named
MyTool.xlsm(stripsDEV_prefix) and removes allxlsm_devkitanddevkit_*modules from that copy. - The
DEV_MyTool.xlsmworkbook is unchanged — continue developing from it.
Run ExportAllModulesFormsSheetMaps to export all modules, forms, and sheet maps at once.
- Each module →
src/*.bas(UTF-8, BOM-less), each form →src/*.frm(UTF-8, BOM-less), binary resources →src/*.frx. - Each sheet →
sheet/*.md(UTF-8, BOM-less).
To export only modules and forms (without sheet maps), run CallExportAllComponents.
To export only sheet maps, run CallExportAllSheetMapsToMD.
Run ImportAllModulesFormsSheetMaps to import all modules, forms, and sheet maps at once.
- Files from
src/are loaded into the project. Existing modules/forms are updated; new ones are added. Companion*.frxfiles are picked up automatically. - Each
sheet/*.mdis applied to the corresponding sheet: cell values, formulas, background/foreground colors, font sizes, number formats, alignment, cell protection, data-validation lists, named ranges, and merged regions are all restored. - Sheet maps whose Markdown file has not changed since the last export or import are skipped automatically. File size and modification time are compared against a sync cache (
sheet/xlsm_devkit_sync.tsv); only changed files are processed, so a full re-import of an unmodified workbook completes in near-instant time.
To import only modules and forms (without sheet maps), run CallImportAllComponents.
To import only sheet maps, run CallImportAllSheetMapsFromMD.
By default every token in a sheet map is applied on import. To disable specific categories, place an xlsm_devkit.ini file next to the workbook with an [import] section:
[import]
; 1 = apply on import (default if key or file is absent), 0 = skip
; Exception: unlocked defaults to 0 (opt-in) -- applying Locked=False to unintended
; cells can weaken sheet protection; enable explicitly to restore lock state.
; Works with both merge=0 and merge=1 (lazy-unmerge handles slave cells).
value=1
formula=1
numfmt=1
unlocked=0
list=1
bg=0
fg=0
font_size=0
bold=0
italic=0
strike=0
wrap=0
halign=0
valign=0
merge=0
hidden_rows=0
hidden_cols=0
shapes=0The most impactful setting is merge=0: it skips ws.Cells.UnMerge, a blocking COM call that can take 8--15 minutes on sheets with thousands of merged regions. With merge=0 the merged-cell structure is left intact and only cell values/formulas are updated.
Each sheet is exported to sheet/<CodeName>.md. The file begins with a metadata
header, followed by a Markdown table, and optionally a Shapes section.
# Sheet Configuration
- VBA CodeName: Sheet1
- Excel UI Name: Summary
- Hidden Rows: 3, 5-7
- Hidden Columns: B, D-F
Hidden Rows and Hidden Columns appear only when the sheet contains hidden rows or columns.
| Address | Name | Value / Label | Formula | Style |
| :--- | :--- | :--- | :--- | :--- |
| A1 | - | Hello | - | Bold |
| B2 | rate | 0.05 | `=A1*0.05` | FontSize:14; NumFmt:0.00% |
| C3 | - | !merged_left | - | - || Column | Content |
|---|---|
Address |
Cell address (e.g. A1, B12) |
Name |
Named range bound to this cell; - if none. Sheet-scoped names include the worksheet prefix (Sheet1!myRange). |
Value / Label |
Display value (formula result when a formula is present). For merge-slave cells, a merge marker (see below). |
Formula |
The formula wrapped in backticks (`=A1*B1`); - if not a formula cell. |
Style |
Semicolon-separated style tokens; - if none. |
Cells with no value, no formula, and no background color are omitted from the export.
| Token | Format | Exported when | Import flag | When absent |
|---|---|---|---|---|
BG:#rrggbb |
6-digit hex | background color set | bg=1 |
unchanged |
FG:#rrggbb |
6-digit hex | font color set | fg=1 |
unchanged |
FontSize:<n> |
integer pt | differs from standard font size | font_size=1 |
unchanged |
Bold |
flag | Font.Bold = True |
bold=1 |
reset to False |
Italic |
flag | Font.Italic = True |
italic=1 |
reset to False |
Strike |
flag | Font.Strikethrough = True |
strike=1 |
reset to False |
Wrap |
flag | WrapText = True |
wrap=1 |
reset to False |
Unlocked |
flag | Locked = False |
unlocked=1 |
reset to True (Locked) |
NumFmt:<format> |
Excel format string | not "General" |
numfmt=1 |
unchanged |
List:<formula> |
e.g. =$A$1:$A$10 |
validation list present | list=1 |
unchanged |
HAlign:<value> |
see below | never (import-only) | halign=1 |
unchanged |
VAlign:<value> |
see below | never (import-only) | valign=1 |
unchanged |
HAlign values: General, Left, Center, Right, Fill, Justify, CenterAcrossSelection, Distributed (case-insensitive).
VAlign values: Top, Center, Bottom, Justify, Distributed (case-insensitive).
Boolean-token reset behaviour: When a boolean import flag is enabled (bold=1, etc.) and the token is absent from a cell's style string, the attribute is reset to its default value on import. This mirrors export semantics -- only non-default values are written.
Slave cells of a merged region appear in the cell table with a marker in the Value / Label column:
| Marker | Meaning |
|---|---|
!merged_left |
slave cell in the same row as the master (extends right) |
!merged_up |
slave cell in the same column as the master (extends down) |
!merged_ul |
slave cell right of and below the master |
Slave rows are skipped during import; merge geometry is rebuilt in a separate pass (merge=1 required).
The following characters are escaped in cell values and style token values:
| Escape | Character |
|---|---|
\\ |
literal backslash |
\n |
newline (CR, LF, or CRLF) |
\v |
vertical tab (Chr 11) |
| |
pipe (Markdown table delimiter) |
\; |
semicolon (style token delimiter -- style values only) |
In Shapes fields the literal string - (the sentinel for "empty") is written as \-.
When the sheet contains shapes (text boxes, buttons, etc.) a ## Shapes section is appended after the cell table:
## Shapes
| Address | Name | Label | Formula | OnAction | Style |
| :--- | :--- | :--- | :--- | :--- | :--- |
| A1 | Button 1 | Click me | - | Module1.DoAction | BG:#4472C4; FG:#FFFFFF || Column | Content |
|---|---|
Address |
Top-left cell under the shape |
Name |
Shape's internal name |
Label |
Visible text (- if none; \- if the text is literally -) |
Formula |
Linked cell formula in backticks; - if none |
OnAction |
Assigned macro name; - if none |
Style |
BG:, FG:, and FontSize: tokens for the shape |
Import flag: shapes=1.
Enable the following setting in Excel:
File → Options → Trust Center → Trust Center Settings
→ Macro Settings → Check "Trust access to the VBA project object model"
Both export and import will fail if this setting is disabled.
VBA's VBComponents.Export / VBComponents.Import always use the system ANSI code page (e.g. Shift_JIS on Japanese Windows) when reading and writing files.
This module uses ADODB.Stream and the Win32 API GetACP() to keep files on disk in BOM-less UTF-8 while transparently converting to and from ANSI for the VBE.
<workbook folder>/
src/ # Exported .bas and .frm files (UTF-8, BOM-less) + companion .frx binaries
sheet/ # Exported sheet map .md files (UTF-8, BOM-less)
xlsm_devkit.ini # Optional: selective import settings (see Selective import)
When you replace xlsm_devkit.bas with a newer version, re-export all sheet maps before importing them again:
- Import the new
xlsm_devkit.basinto the VBE. - Run
CallExportAllSheetMapsToMDto re-generatesheet/*.mdin the current format. - Commit the refreshed
sheet/*.mdfiles.
Sheet map files generated by an older version may not import correctly with a newer version because the sheet map format can change between releases.
xlsm_devkititself is never imported byImportAllModulesFormsSheetMapsorCallImportAllComponents— a running module cannot delete or overwrite itself. To updatexlsm_devkit, paste the new code manually in the VBE.- When
SKIP_DEVKIT_MODULES = True(the default):devkit_*optional modules and forms are skipped during both import and export, andxlsm_devkititself is also skipped during export. SetSKIP_DEVKIT_MODULES = Falseinsidexlsm_devkit.baswhen developing the optional devkit modules. - While a Move capture is in progress,
devkit_Movecannot be reimported — it is on the active call stack, and reimporting would reset the VBA runtime and crash Excel. - Requires Windows and Microsoft Excel with VBA.
- Windows
- Verified: Microsoft Excel 2010 or later (32-bit and 64-bit)
- 32-bit Excel: Intended to work on Excel 2007 or later (VBA6 branch included; not yet tested)
- 64-bit Excel: Excel 2010 or later (
VBA7/PtrSaferequired) - This project depends on Windows Excel because it uses
GetACPandVBProjectautomation