Happy #MapInfoMonday and #MapBasicMonday!
Until now we have used a single MapBasic source file to create our MapBasic application. I would however like to introduce you to the concept of MapBasic Projects. This allows you to split your source code across multiple source files and link these together using a MapBasic Project file (.MBP) to create the final MapBasic executable to run inside MapInfo Pro.
The benefit of doing this is that you can start reusing your functions across multiple applications without having to copy and paste these. You simply include a module with additional functions and procedures, and then you can take advantage of these functions. You will only have to compile the file you make changes to, and then use the MapBasic Project file to link it with the additional modules that already have been compiled.
Another benefit is that you can take advantage of the existing modules built by other MapBasic developers. In our example, we will use the Common MapBasic Library from GitHub. Other examples could be the ComFunctions module from RW Toolbox.
Downloading Common MapBasic Libraries
In this example, we will take advantage of a function in the TABLELib module from the Common MapBasic Library above. This function allows us to check if a table is already open. We will use this to extend the capability of our tool to close the table if it's already open when you click on the matching button.
Let's start by downloading the entire set of modules. GitHub allows you to do this in multiple ways. I'll explain the very simple way. Go to the site for the mbLibrary on GitHub. Now click on the green <> Code button and select Download ZIP. This will download the file to your computer. Unzip the file into the folder where you have your source code. It will create a new folder called mbLibrary-Master. I would recommend renaming the folder to Library. This is where the additional modules that we will use exist.
Open the file TABLELib.def in your MapBasic Editor. This file holds the declarations of the functions and procedures that this module allows you to take advantage of. I have in the image below highlighted the function that we will use: TABIsOpen
.
Notice how all functions and procedures start with the upper case word TAB
. That's to help you identify what module the function originates from. As you start adding more and more modules, it can be beneficial to have named your functions in a way that makes it easier to see what module they come from.
You can see the function that one parameter: sTab
, the table to check for. That is the name of the table to check if it is open or not.
Before you can use a function from another module, you need to include the declaration for that function in the module. Here we can include the TABLELib.def in our source file as it contains the declarations of all the functions of that module.
At the top of our module, I will write this line:
Include "Library\TABLELib.def"
Notice that I add the name of the folder where the def file exists. If the file is in the same folder as your source code file, you should not write the folder name.
Now I can modify my two procedures that check if the table is open, and deal with this in the appropriate way.
'******************************************************************
'Sub OpenTableCustomers: Open a specific table
'******************************************************************
Sub OpenTableCustomers
Dim nMID As Integer,
sTab, sTabFile As String
sTabFile = "C:\3. Demo\2. Maps\2023\Site Selection\Customers\Customers.TAB"
sTab = PathToTableName$(sTabFile)
If TABIsOpen(sTab) Then
'**Table is open, let's close it
Close Table sTab
Else
'**Table isn't open, let's open it
nMID = OpenTableIntoMap(sTabFile)
Call ConfigureLayer(nMID, sTabFile)
End If
End Sub
'******************************************************************
'Sub OpenTableCatchmentArea: Open a specific table
'******************************************************************
Sub OpenTableCatchmentAreas
Dim nMID As Integer,
sTab, sTabFile As String
sTabFile = "C:\3. Demo\2. Maps\2023\Site Selection\Customers\Catchment Areas.TAB"
sTab = PathToTableName$(sTabFile)
If TABIsOpen(sTab) Then
'**Table is open, let's close it
Close Table sTab
Else
'**Table isn't open, let's open it
nMID = OpenTableIntoMap(sTabFile)
Call ConfigureLayer(nMID, sTabFile)
End If
End Sub
I can now save the changes and compile my source file. You will notice that the result of the compilation isn't an MBX but an MBO.
This will happen if the file you compile doesn't hold a Main
procedure. Remember that the Main
procedure is where MapInfo Pro will start when you load the MapBasic application. If the source file doesn't have a Main
procedure, the Mapbasic compiler assumes this source file is to be used in combination with at least one other compiled source file - the one that holds the Main
procedure.
You will also get an MBO file if you compile a source file that uses a function that isn't found in the current source file. That's what happened here. Our source file now used the function TABIsOpen
. And because the functionality of this function isn't found in our source file, the compiler assumes that the source file will be used in combination with at least one other compiled source file - the one that holds the functionality of this function.
Create the MapBasic Project File
Now it's time to combine the compiled source files into a MapBasic executable. This is where the MapBasic Project file comes into play. A MapBasic Project file is a text file structured in a specific way to tell the MapBasic compiler what compiled MBO files to include in the final MBX.
Here's the structure of a MapBasic Project file:
[LINK]
Application=EasyOpenTables.mbx
Module=Library\TABLELib.mbo
Module=Session 05.mbo
I have specified the name of the final MBX file using the Application
key, and after this, I list the compiled source file to include as well using the Module
keys. You can add as many modules as needed.
Save this file as an MBP file. I name it EasyOpenTable.mbp.
From the Project menu in the MapBasic editor, you can now use Select Project File... to specify the project file that you currently are working on. Once done, use Link Current Project from the Project menu or Ctrl+L to link the project.
The compiler will check if all the used functions and procedures are found in the modules listed. If not, it will tell you which is missing. In our example, I get this error: Unresolved Sub or Function ERRCreate
.
You will often get these errors if you forget that you started using a function from another module. But it may also be because the module you added is using additional modules. That's the case here. The TABLELib module is using some functions from the ERRORLib module. Notice the ERR
prefix which gives me a clue about what module I'm missing.
I add that module to my MapBasic Project file and try to link it again.
[LINK]
Application=EasyOpenTables.mbx
Module=Library\ERRORLib.mbo
Module=Library\TABLELib.mbo
Module=Session 05.mbo
And when I now test my application it allows me to easily open and close the two tables with a single click on the two buttons.
We will be using more of these additional libraries in the coming articles as this really is an easy way to add capabilities to your applications without having to write it all yourself.
Stay tuned for more.
------------------------------
Peter Horsbøll Møller
Principal Presales Consultant | Distinguished Engineer
Precisely | Trust in Data
------------------------------