Often enough, INOSIM models are maintained by several people. One challenge is to provide everyone involved with the most up-to-date version and to keep them consistent. With linked-files features introduced with INOSIM 13 and common tools from software development, a workflow can be created to overcome this challenge.
Often enough, INOSIM models are created and maintained by several people. The main challenge is to provide everyone involved with the most up-to-date version and to keep it consistent. While model elements like units or recipes cannot be synchronized automatically (yet), it is possible for the VBA code with a feature introduced with INOSIM 13. Using this feature and common tools from software development, a workflow can be created to allow efficient collaboration. This Tip & Trick showcases this feature and an efficient workflow to eliminate divergent model versions and avoid undocumented changes.
Overview
This Tip & Trick assumes no prior experience in version control. Therefore, in the first section, we will introduce the basics of distributed version control, and will explain additional concepts and features in the subsequent sections. The second section introduces the LinkedFiles feature for VBA files and section three shows how it can be used together with version control in three use cases:
- Use Case 1: Code History as a personal backup
- Use Case 2: Code Library for internal standard functions or custom classes
- Use Case 3: Code Management within a project team with multiple users
The fourth section of this Tip & Trick provides a number of bonus tips that can be applied to reduce the collaborative effort.
Introduction to distributed version control systems
This Tip & Trick builds on existing solutions for distributed version control system (DVCS), widely used in software development. Distributed version control mirrors the complete codebase, including its full history on every developer’s computer. A DVCS automatically manages branching and merging, allows working offline (temporarily) and provides a form of backup of previous versions.
A DVCS usually consists of a Remote Repository on a server, a Local Repository (LR), and a Working Directory (WD). Initially, all are identical, i.e., cloned from the Remote Repository. Users only change files in their Working Directory. Changes are committed to (i.e., recorded in) the Local Repository and can then be pushed to a Remote Repository. Foreign changesets are pulled from the Remote into the Local Repository. The software compares LR and WD and allows users to update their WD and to merge diverging branches if necessary.
A DVCS solution typically consists of two components: user software and a hosting platform. (A platform is only necessary for collaborative work. In case you are working alone and are only interested in versioning and documenting changes, the software and a local repository are sufficient.)
Typical software to manage DVCS
The most used software is git, which we will use throughout this Tip & Trick. Many sophisticated third-party user interfaces are available for Git. To ensure compatibility with all setups, this Tip & Trick will rely only on the interfaces which are included in the Git installation: the command line interface and the basic graphical user interface (Git GUI in the windows start menu).
For hosting, common platforms are Github, Gitlab and Bitbucket. Most hosting platforms can be used either on-premise or by online service providers.
For this Tip & Trick, we will omit the use of an external hosting platform and create the Remote and Local Repositories on the same machine, in different folders, to showcase the basic functions.

INOSIM’s Linked Files Feature
The Link feature allows synchronizing VBA Macros in INOSIM with files on the hard drive, with a single button press. The link can be established by right-clicking the target macro and selecting Add File Link (see figure 2). In the file selection, you can either select an existing file or just define the name of the target file. If it does not exist, it will be created upon synchronization. The linked file will be shown in the macro properties. To write or read from the linked file, go to Tools/Synchronize Linked Files and synchronize in your desired direction. Here, you can also specify a base path if you prefer to define relative paths. We will handle the specifics of linking in the later sections. (See INOSIM Help for detailed explanations of the link-feature: Basic: Editor::How to use the editor::Linking and synchronizing macros with external files).


Use Cases
We will introduce three use cases, which build upon each other. Therefore, they are meant to be read in sequence:
- The first use case shows how to initialize and use version control for a single user who manages VBA code only.
- The second use case shows how to introduce a new colleague to the project from the first use case for collaborative work.
- The third use case extends the workflow to an entire INOSIM model.
Use Case 1: Personal ‘Backup’ for VBA code
While this Tip & Trick focuses on collaboration with other people, the benefit of using version control for a single user cannot be understated. To quote the mathematician Karl Weierstraß:
When I wrote this, only God and I understood what I was doing. Now, God only knows.
Version control does not replace a good documentation but serves as a commented history of all changes which can be freely accessed to reduce the burden of code maintenance. With the full history available, it is also possible to generously remove unused code from the current version, as it can be restored easily. Additionally, it is possible to branch off of any point in history and use this as the basis for further development – with each branch being easily identifiable. Diverging branches can later be merged as a new point in the code’s history. For example, multiple larger changes can be developed isolated from each other or from a main version, which must be deployable without errors at any time.
We will start by creating a version-controlled collection of useful VBA Macros in the folder C:\VBA-Collection. As described above, we will show the command line interface, as well as the basic graphical user interface (GUI). For the command line commands, either the native windows prompts can be used or the installed Git Bash. The latter will be used for the screenshots provided in this Tip & Trick.

Press Create New Repository in the GUI and enter the corresponding directory (C:\VBA-Collection) in the following dialog, or enter the following commands in the command line:
cmd
cd C://
git init VBA-Collection
cd VBA-Collection
The GUI will automatically open the repository, the command line should display the newly created directory and show the current Git branch name (here: main). Branches can be used to split single developments from the main history (the trunk), before merging them back together later, e.g., to ensure that work in progress does not influence production code. While not part of this Tip & Trick, we recommend teams that want to adopt Git into their workflow and deployment procedure to dive deeper into this topic.

These steps will create a new folder, preconfigured for version control. We will store macros from our other Tips & Tricks in this folder. For demonstration purpose we also display the hidden folder .git, which was automatically created during initialization of the repository. This is the local repository as depicted in Figure 1. Every other file and folder are part of the working directory.

The files are now part of the working directory, but not part of the version control mechanism.
Typing git status in the command line will confirm this. For the GUI, press F5 or click Rescan (under Toolbar>Commit).

The following commands will change this:
cmd
git add Sorting.bas TableTools.bas TimerClass.bas
git commit -m "Add macros to repository"
The git add command submits the specified files to be put into the next commit, whereas the git commit command creates a commit.
A commit can be roughly interpreted as a snapshot of the files. The string, that follows the -m-specifier will serve as the description and will be saved together with the snapshot.
The same can be achieved in the GUI by selecting the desired file/s and pressing Ctrl + T (or click: Toolbar>Commit>Stage to Commit). The files will now be displayed under Staged Changes (Will Commit). Enter the commit message in the textbox and press the commit button. The window should look like Figure 8 (left side).

For new files, git add also has a second effect: after they have been committed, Git is able to detect changes in these files. While these changes are not saved until the next commit, it is possible to see what changes have been done since the last commit.
We will do two things to highlight this behaviour (and to prepare the next steps): First, create a new INOSIM database inside the Working Directory; Second, open TableTools.bas with any text editor (we will cover changes from within INOSIM shortly) and add a new comment line at the top of the file:
'#Language "WWB-NET"
'Hello World!
Option Explicit
[…]
Enter git status into the command line (or press F5 in the GUI) and check the output.

Git now shows that the TableTools macro has changed and that a new file was added into the folder. The GUI shows this info on a per-file basis in the yellow banner when clicking each file. (Along with the file content and the changes, if possible).
We will not add the new file, nor commit the change at this point. In fact, we never want to commit entire database files, because their size can slow down the work with Git. (We will instead use exports in Use Case 3).
It is possible to tell Git to ignore certain files by creating a file aptly named .gitignore” (mind the dot at the beginning and ensure that the file has no file extension!). On the first line of this file write *.imdf, on the second write *.ldf.
Entering git status once more (GUI: F5), we can see that the database file is no longer visible to Git, instead we see the gitignore file. To make the decision to ignore database files part of the project – (in preparation for collaboration and to keep the output of git status clean) – we add and commit the gitignore file to the local repository, same procedure as before.
As mentioned, we don’t want to commit the change to TableTools. Using git restore TableTools.bas, we can undo the change and reset the file to the state of the last commit. GUI: Select the file and either press Ctrl + J or click Toolbar>Commit>Revert Changes. Again, the GUI will show a clean state.

To combine these foundations in version control and the previously described link-feature, open the INOSIM database, create a new project in the database, and import the macros:

With the macros both available as files and in the model, we can use the link feature to connect them. For this, right click each macro and select Add file link. A file dialog box will open and ask for the file. Select the corresponding macro file and confirm. (Note: If you enter a non-existent filename, you can still confirm and later sync from INOSIM to the file; the file will then be created.)
The absolute path to the linked file will now be displayed in the properties window. While the absolute path is fine for a single user, use case 2 will cover the use of relative paths and the benefit of doing so.

At this point, after importing them, the external files and the code in the model are identical. Before syncing, let us introduce a small change: We will extend the TableTools macro with a simplified function to read tables. The function Read_Full_Vertical_Table will call the well-known Read_Table function, but with predefined arguments. In this case, the function assumes we are interested in the entire sheet and that only the first row contains header/index data, thus the sheet represents a vertical table.
VBA
Function Read_Full_Vertical_Table(XLS_Sheet As String) As Table
' Reads an entire excel sheet that is formatted vertically (only uses row index)
Read_Full_Vertical_Table = Read_Table(XLS_Sheet, 0, 0, 0, 0, True, False)
End Function
Now, the macro TableTools inside INOSIM contains changes, which are not yet contained in the corresponding external file. Consequently, Git is also not aware of any changes yet. (Feel free to test this using the command git status or by pressing F5 in the Git GUI).
To synchronize a file from INOSIM, open the Tools menu in the VBA Editor and click Synchronize Linked Files, which will open the synchronization dialog.

In this dialog, you can select the synchronization direction, configure the base path for relative paths (Note: INOSIM 14, shown in Figure 13, offers a finer control for global and project specific paths, while INOSIM 13 offers one base path) and configure which macros you wish to select for synchronization. The list of macros also indicates the direction of the synchronization by specifying source and target dynamically. Before synchronization, double-check the direction; accidentally syncing from file to INOSIM can overwrite your changes and lead to data loss!
To sync the change made to the TableTools Macro, select Update linked files and press Synchronize. This will overwrite the file with the new content.
Calling git status will confirm this.
Additionally, git diff TableTools.bas will show the exact changes inside the file. If the change exceeds the window size, you can progress inside the file by pressing Enter and you can end the diff command by pressing the Q-key (Quit). For the GUI, pressing F5 will refresh the list of unstaged changes. Selecting TableTools.bas will show the file content, with all changes highlighted.

Now, using git add TableTools.bas and git commit -m Add function to read vertical tables from excel sheet (or the GUI equivalences) records this change in the history of your project.
Because covering all possibilities to move through the history of commits would exceed the scope of this already lengthy Tip & Trick, we will limit this consideration to the most basic case: reverting a commit. Here, we will revert the latest commit, but the command allows to revert any commit in history by applying the inverse of the change. Approaching changes and commits tactically and making clear commit messages supports this. (See Bonus Section.)
Inside INOSIM, open the TimerClass Macro. Select the entire macro content (Ctrl + A) and delete everything (Del). Using the steps above, sync from INOSIM -> File and create a new commit with this rather drastic change.
To revert this (or any) change, we need to specify which exact commit we want to revert. The logs are the easiest method to get the unique identifier of each commit. Enter git log into the console. Your commit history will be displayed. In the GUI, you’ll find the history under: Toolbar> Repository>Visualize main’s history. This will open a new window with a detailed overview of the history.

Besides the commit message, the date, time, and author of each commit is displayed. Furthermore, each commit is uniquely identified with an alphanumerical string (a SHA-1 checksum). When using this identifier in any command, it is enough to use the first few characters, if the commit can be identified without ambiguity (i.e., no other commit starts with the same characters).
We can identify our undesired commit by the commit message and note down the identifier. For long outputs of the log command, press the Q key to exit the command.
Now we can revert the commit by entering git revert –-no-commit <ID>. When following this Tip & Trick, you will most likely see a different identifier, so replace <ID> with the corresponding value.
After git revert –no-commit, your Working Directory will have been modified, which can be verified by a quick execution of git status. To finalize the revert-action, use git commit -m “Revert deletion”. For larger or consecutive reverts, the state between revert and commit should be used to check for errors in the reversal. If you wish to directly commit the reversal, omit –no-commit; in this case, a text editor will open and request a commit message. In the GUI, you can right-click the commit you want to revert and select Revert this commit, this will automatically revert the commit and create a new commit with a predefined commit message.

Now the file has changed inside the working directory, but INOSIM is not aware of the change yet. To synchronize from File ->INOSIM, go to INOSIM and open the Synchronize Linked Files dialog again. Select Update macros. Before clicking Synchronize ensure that only the desired macro is selected and that no uncommitted code will be overwritten. Now, press Synchronize – the file content will be visible in the macro now and the change was successfully reverted.

For a single user, this use case covered all basic Git commands and concepts to productively utilize version control, although many useful commands couldn’t be covered in this scope. (Honourable mention: git bisect, which uses binary search to semi-automatically find the commit that introduced a bug). Based on this use case, it’s straightforward to extend the repository from single-user use to a collaborative work environment between colleagues. It is also possible to add the export of an INOSIM model to the version history, although not without caveat. Both will be covered in Use Case 2 and Use Case 3, respectively.
Use case 2: Using a common VBA library
Note: For brevity, synchronization steps will not be explicitly shown or mentioned in this section. It’s assumed that changes are directly synchronized between files and INOSIM. Unless new commands are introduced, no screenshots of the interfaces are added. Refer to Use Case 1 for the basic commands.
Important: To prevent data loss, follow the following procedure:
Before pulling new versions from the remote repository, first sync from INOSIM -> Files and commit (or discard) any changes. Only then pull the changes and sync from Files -> INOSIM.
After pulling the latest changes, you can also safely push your own changes to the Remote Repository.
Instead of using a hosting platform, we will generate a Remote Repository on the local hard drive. When using a hosting platform, it is not uncommon to first create a local repository and then upload this to the platform, but the details of this would exceed the scope of this article.
Open Git Bash in C:\\ and enter the following command:
git clone –-bare VBA-Collection Remote-VBA
Afterwards, you can delete the folder VBA-Collection. (It is possible to connect VBA-Collection to the Remote Repository now, but this is omitted here).
Cloning the existing repository
To work with a remote repository, we first need a local copy. This is generally called cloning and is done by using the command git clone.
For demonstration purposes, we will create two local repositories to check if the history is as expected. After the following commands, the last commit of use case 1 should be displayed (Revert deletion..).
git
cd c:\\
git clone Remote-VBA LocalOne
git clone Remote-VBA LocalTwo
cd LocalOne
git log -1
For the graphical interface, open a new Git GUI window and click Clone Existing Repository. In the cloning dialog, use the folder Remote-VBA as the source and enter the path of a new folder as target. Confirm with the button Clone.

Now, as shown in Use Case 1, create any change within repository LocalOne in the VBA-Code and commit it. This can be as small as a new comment in the macro Sorting.bas. This change exists only in the Local Repository LocalOne currently, as can be checked by using git log in both Local Repositories.
Push and Pull
Local Repositories of collaborators are synchronized via the Remote Repository. The process of updating the remote repository with new changes is called push, the process of downloading changes from the remote is called pull (compare Figure 1).
To push the new change from LocalOne to Remote-VBA, enter git push in the command line interface, or click Toolbar>Remote>Push in the GUI (and then confirm with the Push button).

To pull the changes, move inside the LocalTwo repository and use the command git pull. In Figure 20, you can also see the optional command git remote update which will download references to commits available on the remote repository. This enables git status to see how far behind your current version is (see console output in the Figure 20).
For Git GUI, further explanation is necessary: git pull is a combination of downloading all remote changes and automatically merging them into your local repository, running the command git fetch followed by git merge. In Git GUI, both steps must be performed manually by first using Toolbar>Remote>Fetch from origin, followed by Toolbar>Merge>LocalMerge. In this dialog, you can select the remote version of the main branch and merge it with your local version.

Merging Git branches
Merging is generally automatically performed by Git, even if multiple users work on the same file. Keeping your commits small makes merging more robust. Sometimes it can happen that Git is not able to automatically merge a file, for example, when two users change the same line in a file. In this case, Git will issue a warning and request that the conflict will be resolved manually by changing the files within the working directory and creating a subsequent commit for the merge.
This covers the basic commands to work together on a collection of VBA-code, although much more is possible.
A shared Remote Repository like this can easily be extended to hold entire libraries of company or project specific templates and general-purpose code. Multiple teams can then access the latest version any time, while being able to trace back all changes.
Project specific relative path in INOSIM 14
This is especially facilitated in INOSIM 14 by using a general base path for all projects and a relative project-specific path. Hint for implementation: The general base path could point to C:\VBA-Code\General, which is a repository for company-wide macros, while the project path is set to ..\TheProject, which, as a relative path, would point to C:\VBA-Code\TheProject, which can be a different repository with project specific macros.
In Use Case 3, we will take a different route and use this repository as the single point of truth for the development of a single model.
Use Case 3: Model Versioning / Project Code Management
In general, versioning is recommended for modeling projects in which changes are mainly made to the VBA code. These changes can be easily visualized by the software, e.g., by highlighting specific code sections. Versioning for changes to the model and parameter workbook is also possible, but without visualization.
The following subsections will guide you through the initial setup, how to apply foreign changesets and how to commit your changes.
Initial setup
In this use case, we modify the repository structure slightly, based on the LocalOne repository and the Remote Repository from Use Case 2, or the repository VBA-Collections from Use Case 1. For the latter case, the interactions with the Remote Repository can be ignored.
First, all VBA code is moved into a separate folder, here VBA-Code.
If you followed the Tip & Trick so far, manually create that folder, move the VBA files and commit this as a separate change. (Alternatively, it is slightly better to use the git mv command and then commit).

While the INOSIM database in the previous use case was only used to edit the code, we now will use a model we want to work with. For this Tip & Trick, we will use the Recycling example, which you can find in the Download Area, contained in the sample projects for INOSIM 13.
If you save the database inside the working directory folder, ensure that it will be ignored by Git, via the .gitignore file (see Use Case 1).
Next, open the model and export all macros into the folder VBA-Code. Additionally, we will add the macros from the previous step to the model as well.
Link the external files and INOSIM macros as described in Use Case 1 and ensure that all paths are relative to your repository folder, and that the base path is correctly set – as shown in the screenshot below:

After setting up all file-links, export the project into the Local Repository directory. Add and commit both the two additional macros and the project export file (.IXML). Push the changes from the Local Repository LocalOne to the Remote Repository with git push.
With all files in place, we can now use the Git commands from the previous use cases to track changes in each file, with the model export being a special case: Because it is a binary file and not a text file, Git will not be able to differentiate between individual changes within the file and will not be able to merge two diverging files; every commit of an updated model export is like saving a full copy, while updates in the VBA code files only require the minimum information (i.e., the difference) between two files.
After this setup, the repository is ready for further development and for sharing with collaborators.
Setup steps for collaborators
Clone the Remote Repository as described in Use Case 2 (or pull the new changes into the previously created Local Repository LocalTwo if you are working through this Tip & Trick). Your working directory will contain the VBA-Code folder, the model export and the gitignore file.
Import the model export into an (new) INOSIM database file. Important: With this workflow, there is no guarantee that the model export contains the latest VBA code! Therefore, go to the INOSIM Basic Editor, Tools, and open the Synchronize linked files menu. After the initial setup, all paths should be relative and point to the VBA-Code folder inside the repository. If the base path differs between collaborators, each collaborator must configure the base path individually and ensure that the path is correct after every model update. For example, after following the previous instructions, it is necessary to change the folder to C:\LocalTwo. If the local repositories had the same name and path on different machines, no change would be necessary.
If all paths are correct, sync from Files -> INOSIM. With this, your database is ready for further development.
Commit own changes
The steps for adding and committing changes is the same as previously described, with a slightly modified workflow:
If the model or parameter sheet has changed, export the entire model and override the existing .IXML file. Important: If the model did not change and only the VBA code was updated, do not export the project! Exporting an unchanged model might be wrongly recognized as a change by Git and lead to confusion!
To save further disk space, ensure that you remove result data from the project before exporting (INOSIM Main Window > Project > Purge, then mark all results for deletion).
If VBA code has been changed, use the sync-feature to save the changes to the external files:
- Menu Tools > Synchronize Linked Files and select Update linked files.
- Pay attention to the direction, risk of data loss! When choosing Update macros, the macros in the VBA Editor will be overwritten with the content of the linked files. This cannot be undone.
- Commit your changes and push them to the remote repository if necessary.
Pull and Merge foreign changes
For changes in VBA code, the same principles as in use case 2 hold. Changes in the model require communication with your collaborators; it’s recommended that only one person works on the model/parameter sheet at one time (others can continue work on the code). The reason for this is the inability to automatically merge changes in models and the inability to track individual changes within the models. Advanced users might want to use the branching features of Git and later merge the two diverging versions manually.
To recap the steps for pulling changes:
- Sync your code from INOSIM -> File.
- If you changed the model, export and overwrite the .IXML file. Mind the warning above!
- Add and commit the local changes that you want to keep.
- Pull new changes from Remote Repository. Skipping the previous steps can lead to loss of data!
- Resolve possible conflicts in VBA code (Model changes: The latest version will be adopted without comment).
- If the model changed: Re-import the model export into the database and delete the old project.
- Import VBA files into the model database.
Bonus Tips
In the following subsections, you will find some bonus tips for consistent and productive collaboration with a shared code base and model versioning.
VBA Comments
Understanding the code someone else has written can be challenging. (Even understanding your own code after some time has passed…). Adding descriptive and precise comments to complex algorithms, subs, or functions can immensely help the next person that needs to add a change. So does cleanly written code.
Ad hoc notes may seem clear in the moment but can be very confusing six months later; Use common keywords in VBA code comments to clarify their purpose:
- Asynchronous communication can be facilitated by common keywords, such as NOTE, QUESTION, HACK, TODO, FIXME, e.g.,
- Example: ‘TODO Add counter to for-loop’
- Code lines highlighted with these keywords need attention but cannot be solved by the current user, e.g., because something is unclear.
Tactical Commits and Good Commit messages
Create commits tactically in small steps, from one stable change to the next.
- Tactical: Create the prerequisites for the desired change first and commit individual, small changes continuously. For Example: Write and commit a new function first, then change the existing code to use the new function and commit this separately.
- Non-tactical: Insert desired change and then retrospectively change everything else to match the change. (Bad practice!)
Write good commit messages: Start them with prefixes, for example: [FIX], [DOCS], [INTERNAL], [FEATURE] and add a short but meaningful summary.
Examples:
- [FIX] error, where wrong unit was allocated, when custom attribute Test was null.
- [DOC] Update function description of WriteTable.
- [FEATURE] Calculate utility demand for centrifuges.
An online search can reveal many more tips and guidelines regarding commit messages. The key is to develop a consistent method for the entire team.
Model Version Numbers
Communication across models can be simplified by unique version numbers. Here is one possible tactic to implement a consistent versioning pattern. The version numbers follow the scheme: MAJOR.MINOR.REVISION̂̂̂̂̂, e.g., 3.0.1 or 1.3.2. New models start at 0.1.0.
The revision is increased when the VBA code is changed for troubleshooting. For example, if an error is detected and corrected in a macro, the version number is increased from 1.3.2 to 1.3.3.
The minor is incremented when the VBA code changes, as new functions are added, or existing functions change functionally. The revision is set to 0. For example, when integration a new allocation control in VBA, the version number changes from 1.3.3 to 1.4.0.
The major is incremented if something changes outside of VBA (parameter workbook, new model elements like recipes or units). Revision and minor are set to 0. For example, when adding a new recipe, the version number changes from 1.4.0 to 2.0.0.
To avoid too many major increments, it’s recommended (but not mandatory!) to use a model where development of recipes and parameters are nearly completed.
The version can be tagged in the version control software and/or documented in a VERSION.TXT file. The number makes it easy for colleagues to assess what to expect when new updates arrive:
- Revision: VBA files must be synchronized/updated. If they are not affected by the error, no noticeable change.
- Minor: VBA files must be synchronized/updated. Model probably behaves differently, or at least can be reconfigured.
- Major: Updated IXML file needs to be imported & VBA files need to be synced. Model might have changed more drastically.
How many changes are bundled in a revision, a minor or major change is best discussed within the working group. It is recommended to commit small changes to allow reverting to a former status easily.
More Questions?
Want to know more about this topic or have another question? Please contact us!
More Tips & Tricks
The Reporting Object
The Reporting Object With INOSIM 12, the Reporting object was added to the INOSIM object library. The Reporting object provides extensive options to create and…
Custom Gantt Colors
The INOSIM Gantt chart provides the option to color allocation bars on the basis of various predefined attributes. In the order view, it is possible…
Event Call Sequence
As an experienced INOSIM user, you are aware that you are working with a discrete-event simulation software. For most events, VBA controls can be called…