Some tips on how to get started with MapBasic, the scripting language for MapInfo Pro.
What is MapBasic? Where do I find support and what tools should I use? How do I work with the interface?
3. MapBasic – what is it?
MapBasic is
• A ”scripting language” for MapInfo Pro
• A text Editor
• A Compiler
MapBasic can be found and executed via
• Workspaces
• The MapBasic window in MapInfo Pro
HOME > Tool Windows > MapBasic
• MapBasic applications compiled with MapInfo MapBasic
• Executed using the IMapInfoPro application from .NET and Python
Same program!
5. Where do I start when I want to use MapBasic
Download MapBasic
• MapBasic can be downloaded for free here: https://support.precisely.com/product-downloads/for/mapbasic/
The MapBasic window
• Use MapInfo Pro with the MapBasic window open and notice that MapBasic statements will appear in this window
The MapBasic Editor
• Copy the statements from above and paste them into a new file in the MapBasic Editor
• Make some changes, if needed
• Compile your small application using MapBasic
• Run the application within MapInfo Pro
6. ... And where do I continue
• The MapBasic Editor
• Extend the application according to your needs
• Communities
• Follow the discussion on MapInfo-L and ask questions here: https://groups.google.com/forum/#!forum/mapinfo-l
• Follow the discussion via the #MapBasic topic on the Precisely Knowledge Community:
https://community.precisely.com/search?executeSearch=true&SearchTerm=mapbasic&l=1
• Follow the discussion in the MapInfo Developers group on the Precisely Knowledge Community:
https://community.precisely.com/communities/community-home?communitykey=3c2aca7a-c3ae-4602-a142-
9ee956769d55&tab=groupdetails
• Structuring your code
• Use Procedures (Sub’s) and Functions to structure your application
• Use separate modules and MapBasic projects to structure your project into separate files
• Use a third-party text editor to write your MapBasic code
7. The MapBasic Text Editor
• Works like a very basic Text Editor similar to NotePad for instanse
• Use File > New (Ctrl + N) to create a new file
• Use File > Open (Ctrl + O) to open an existing file
• Use File > Save (Ctrl + S) to save the currently active file
• You can have more than one file open at a time, in the Window menu you see a list of currently open files
8. The MapBasic Compiler
• The compiler functions can be found in the Project menu
• Compile the active file into a MapBasic application use Project > Compile Current File (Ctrl + K)
• Run the compiled MapBasic application using Project > Run (Ctrl + U)
9. The MapBasic Text Editor - Errors
• When you compile a MapBasic file, you might get a list of errors
• These will be shown at the bottom of the MapBasic Text Editor
• Double click the error to go to the place in the code where the error was found
• Always start from the top of the error list
• Recompile when you have fixed one or two errors
11. What tools do I use?
UEStudio:
• for writing MapBasic code
• You can also use Notepad++
MapBasic:
• for compiling my code. MapBasic is called from UEStudio. Errors show up in UEStudio, too
MapBasic IDE:
• for writing MapBasic code and designing MapBasic dialog – at least the bigger ones.
MS Visual Studio Express/MS Visual Studio Code:
• for writing assemblies. This is often used when I need to use a web service
• for writing integrated mapping applications
13. Basic structure
Include statements
• Constants, shared by multiple modules
• Declarations of shared procedures and functions
Define statements
• Constants used within this module only
Declare statements
• Declarations of internal procedures and functions
Dim statements
• Creation of modular variables
Procedures and functions
• The logic and functionality of the module/application
14. Show information to the user
You can easily show some values to the end user
This is very useful, for example for testing if the application works as expected
The Note statement shows a dialog on the screen and the user has to push the OK button to continue
Note "The table hasn’t been opened!"
The Print statement writes a text to the Message window without halting the application
Print "Now working with the chosen table…"
15. Sub Main
• This is the procedure that is called when the application is loaded into MapInfo Professional
• You often would use this to initialize the application, to create the user interface and read configurations files
• Sub Main must be declared at the top of the source code:
Declare Sub Main
Sub Main
Note "Now the application is running!"
End Sub
16. Procedures and functions
• Procedures contain code that can get called from other places in your application.
• It is suggested to split your code into smaller pieces to get a better overview of it and to better be able to reuse it
• Functions are procedures that return a value. Procedures don’t directly return a value, but can return value through
the parameters
• Procedures and functions must be declared before they can be used. You declare these at the top of the
file/module or in a separate definitions file
Declare Function GetPI() As Float
Function GetPI() As Float
GetPI = 3.14
End Function
17. Declare, Dim and Define
Declare is used to declare procedures and functions.
• Is used outside procedures and functions
Define is used to define constant values
• Is used outside procedures and functions
Dim is used to dimension/create variables that can be assigned new values during the session of the application
• Can be used inside as well as outside of procedures and functions depending of their scope
Declare Sub Main
Define FILE_INI "C:TempConfig.ini"
Dim i As Integer
18. Dim – data types
Dim var_name [, var_name ...] As var_type [, var_name [, var_name ...] As var_type...]
Dim sTab, sColumn As String,
nAntal As Integer
• SmallInt: Whole numbers from -32768 to 32767 (inclusive); stored in 2 bytes
• Integer: Whole numbers from -2,147,483,648 to +2,147,483,647 (inclusive); stored in 4 bytes
• LargeInt: Whole numbers from –9,223,372,036,854,775,808 to +9,223,372,036,854,775,807
(inclusive); stored in 8 bytes.
• Float: Floating point value; stored in eight-byte IEEE format
• String: Variable-length character string, up to 32768 bytes long
• String * length: Fixed-length character string (where length dictates the length of the string,
in bytes, up to 32768 bytes); fixed-length strings are padded with trailing blanks
• Logical: TRUE or FALSE, stored in 1 byte: zero=FALSE, non-zero=TRUE
• Date: Date, stored in four bytes: two bytes for the year, one byte for the month, one byte for
the day
• DateTime: DateTime is stored in nine bytes: 4 bytes for date, 5 bytes for time. 5 bytes for
time include: 2 for millisec, 1 for sec, 1 for min, 1 for hour
• Time: Time is stored in five bytes: 2 for millisec, 1 for sec, 1 for min, 1 for hour
• Object: Graphical object (Point, Region, Line, Polyline, Arc, Rectangle, Rounded Rectangle,
Ellipse, Text, or Frame)
• Alias: Column name
• Pen: Pen (line) style setting
• Brush: Brush (fill) style setting
• Font: Font (text) style setting
• Symbol: Symbol (point-marker) style setting
• IntPtr: A platform specific type that is used to represent a pointer or a handle. This helps to
write applications that will work with both the 32-bit and 64-bit versions of MapInfo Pro.
The 64-bit version of MapInfo Pro treats this like a LargeInt, and the 32-bit version of
MapInfo Pro treats this like an Integer.
• This: Represents a reference to a .NET object, You can use this to hold a .NET reference
type and call method/properties on it. Simple Integer value stored in 4 bytes.
• RefPtr: Represents a reference to a .NET object. You can use this to hold a .Net reference
type and pass to method in .NET code. Simple integer value stored in 4 bytes.
19. MapBasic.def
• You should always include MapBasic.def in your MapBasic applications
• The file MapBasic.def contains a number of constants that can be used in stead of unrecognisable numbers
• This is attributes for the MapBasic functions such as TableInfo(), ColumnInfo() and several others
• At the top of your MapBasic module you would write this line to include the file:
Include "MapBasic.def"
• From time till time you might need to include other files in your MapBasic project. Other relevant files could be
Menu.def, Icons.def, Enums.def, and IMapInfoPro.def
• Besides these common files you can also include your own definition files
21. If ... Then ... End If
• Braching like If ... Then ... End If can be used to control in what ”direction” the application should go depending on
one or more conditions
• You can also use this to investigate whether there are any tables open and if not ask the user to please open some
If NumTables() = 0 Then
Note "Please open one or more tables!"
Exit Sub
End If
• The If statement supports several braches/options:
If NumTables() = 0 Then
Note "Please open one or more tables!"
Exit Sub
ElseIf NumTables() = 1 Then
Note "There is only one table open!"
Else
Note "There is " & NumTables() & " tables open!
End If
22. Do Case ... Case ... End Case
• Another form of branching is Do Case.
• It is good for comparing a value with multiple possible options
Do Case TableInfo(sTab, TAB_INFO_TYPE)
Case TAB_TYPE_BASE
MENUTableTypeAsText = "Native"
Case TAB_TYPE_RESULT
MENUTableTypeAsText = "Query"
Case TAB_TYPE_VIEW
MENUTableTypeAsText = "View"
Case TAB_TYPE_IMAGE
MENUTableTypeAsText = "Raster"
Case TAB_TYPE_LINKED
MENUTableTypeAsText = "Linked, DBMS"
Case TAB_TYPE_WMS
MENUTableTypeAsText = "Web Map Service, WMS"
Case TAB_TYPE_WFS
MENUTableTypeAsText = "Web Feature Service, WFS"
End Case
24. Dialog and Control statements
• The Dialog statement begins the construction of a custom dialog
• The Dialog statement is always followed by one or more Control statements
• The Dialog as well as the Control statements can take a position.
• For the Dialog statement this is a position from the top left corner of the screen
• For the Control statement it is from the top left corner of the dialog
Dialog
Title "My dialog"
Control StaticText Position 5,5
Title "My text label"
Control ListBox Position 5,15 Width 100 Height 100
Control OKButton
26. Handlers
• Most of the controls on a dialog can have a handler assigned
• A handler is a procedure that is called when the user interacts with the control
• This is quite useful if you want to create a dynamic dialog that responds to the users choices, for example to update
the list of columns when the user picks a table
Dialog
Title "My dialog"
Control StaticText Position 5,5
Title "Tables"
Control ListBox
Position 5,15 Width 100 Height 100 ID 1
Calling MENUDialog_TableClick
Control OKButton
27. Reading from and altering Controls
• Inside the handler of a control, you can read values from all controls on the dialog
• For this purpose, you need the ID of the Control and the function ReadControlValue()
Sub MENUDialog_TableClick
Note "The user chose item " & ReadControlValue(1)
End Sub
• Inside the handler of a control you can also change the controls on the dialog, such as selecting from their list or
assign new values to them
• Again, you need the ID of the control and the statement Alter Control
Sub MENUDialog_TableClick
Note "The user chose item " & ReadControlValue(1)
Alter Control 2 Value 2
End Sub
29. Table Details
• You can get to the number of open tables thru the function NumTables()
Print "Number of open tables: " & NumTables()
• You can query the details of a given table thru the function TableInfo()
• The function takes these parameters:
• A table, either a number or a name
• An attribute: what detail are you looking for?
Print "Name of table: " & TableInfo(1, TAB_INFO_NAME)
Print "Number of records: " & TableInfo(1, TAB_INFO_NROWS)
Print "Number of columns: " & TableInfo(1, TAB_INFO_NCOLS)
30. Type of Tables
• The function TableInfo can also be used to figure out what type of table a given table is
• You need these attributes to figure out the type of table
• TAB_INFO_TYPE returns one of these types:
• TAB_TYPE_BASE
• TAB_TYPE_RESULT
• TAB_TYPE_VIEW
• TAB_TYPE_IMAGE
• TAB_TYPE_LINKED
• TAB_TYPE_WMS
• TAB_TYPE_WFS
• TAB_TYPE_FME
• TAB_TYPE_TILESERVER
• TAB_INFO_TEMP: is the table temporary?
• TAB_INFO_SEAMLESS: Is the table seamless?
31. Columns Details
• You can also query the number of columns in a table:
Print "Number of Columns: " & TableInfo(1, TAB_INFO_NCOLS)
Print "Number of Columns : " & NumCols(1)
• With the function ColumnInfo you can investigate the details about a given column in a table
• The function takes these parameters:
• Table, either a table number of a table name
• Column, either a column name or ”COL” + column number
• Attribute: what information do you watn to know about the column
Print "Name: " & ColumnInfo(sTab, "COL" & i, COL_INFO_NAME)
Print "Type: " & ColumnInfo(sTab, "COL" & i, COL_INFO_TYPE)
Print "Indexed: " & ColumnInfo(sTab, "COL" & i, COL_INFO_INDEXED)
32. Type of Columns
• When you are querying the type of column with COL_INFO_TYPE one of the following types are returned:
• COL_TYPE_CHAR
• COL_TYPE_DECIMAL
• COL_TYPE_LARGEINT
• COL_TYPE_INTEGER
• COL_TYPE_SMALLINT
• COL_TYPE_DATE
• COL_TYPE_LOGICAL
• COL_TYPE_GRAPHIC
• COL_TYPE_FLOAT
• COL_TYPE_TIME
• COL_TYPE_DATETIME
• Some of the types do require a closer inspection to for example figure out their width (char and decimal) and the
number of decimals (decimal).
34. Working with Arrays
• A variable normally only holds one value
• You can however create a variable that can hold several values – this is called an array
• The variable is either dimensioned as empty ”()”:
Dim arrTableNames() As String
• or with a given size ”(10)”:
Dim arrTableNames(10) As String
• You access the individual element in the array thru the index number. The index starts at 1.
Print "Table 1 is: " & arrTableNames(1)
• You can resize the array with the ReDim statement
ReDim arrTableNames((NumTables())
35. Looping: For ... Next
• You often need to be able to run thru a number of item, such of number of open tables, number of columns in a
table, number of open windows etc.
• For this purpose, there is a statement called For ... Next
• The For ... Next statement takes:
• An Integer variable to hold the current element (A)
• The initial Integer value to start from (B)
• The value to loop until (C)
For A = B To C
'**Do some work
Next
• For example looping over the number of open tables:
For nTab = 1 To NumTables()
'**Do some work with the table nTab
Next
37. Userdefined Functions
• You can create your own procedures as well as your own functions
• A function differs from a procedure by returning a value – this makes it very useful
• A function must be declared before it’s used
Declare Function MENULogical2YesNo(ByVal bValue As Logical) As String
• Then you must create it with its logic
Function MENULogical2YesNo(ByVal bValue As Logical) As String
If bValue = true Then
MENULogical2YesNo = "Yes"
Else
MENULogical2YesNo = "No"
End If
End Function
• When you set the function name equal to a value inside the function, this value will get returned by the function
39. Creating Spatial Objects
Create Statements
• Create Collection
• Create Ellipse
• Create Line
• Create Multipoint
• Create Pline
• Create Point
• Create Rect
• Create Region
• Create RoundRect
• Create Text
All the above support creating into Window or Variable
• [ Into { Window window_id | Variable var_name }]
Create Functions
• CreateCircle()
• CreateLine()
• CreatePoint()
• CreateText()
MapBasic supports the creation of any spatial object type used in MapInfo Pro
Commonly used statements and
functions are marked in red
40. Spatial Objects Details
• MapBasic has a number of functions for inspecting spatial objects. You can inspect their spatial elements, the
styling, their type and a number of other useful elements
• Object Type, styling, number of segments and nodes and text string:
ObjectInfo( object, attribute )
• Spatial information such as coordinates and extent:
ObjectGeography( object, attribute )
• Centroid coordinate of the object:
CentroidX( obj_expr )
• Returns coordinates from the individual nodes of polylines and polygons:
ObjectNodeX( object, polygon_num, node_num )
ObjectNodeY( object, polygon_num, node_num )
41. Performing Spatial Calculations
• MapBasic has support for doing spatial calculations
• Calculating the length of the object
ObjectLen( expr, unit_name )
• Calculates the area of the object
Area( obj_expr, unit_name )
• Calculates the perimeter of the object
Perimeter( obj_expr , unit_name )
• Calculates the distance between two coordinates
Distance( x1, y1, x2, y2, unit_name )
• Calculates the distance between two objects
ObjectDistance( object1, object2, unit_name )
• They all come in a Cartesian and a Spherical version:
CartesianObjectLen( obj_expr, unit_name )
SpericalObjectLen( obj_expr, unit_name )
42. Altering Spatial Objects
• You can modify the spatial elements as well as the styling of the spatial objects.
• The Alter Object statement can be used for this.
• Altering styling, text string and more:
Alter Object obj
Info object_info_code, new_info_value
• Altering geographical elements such as start and end coordinates for simple objects:
Alter Object obj
Geography object_geo_code , new_geo_value
• Alter individual nodes on complex object such as polylines and polygons
Alter Object obj
Node {
Add [ Position polygon_num, node_num ] ( x, y ) |
Set Position polygon_num, node_num ( x , y ) |
Remove Position polygon_num, node_num } }
43. Comparing spatial objects
• MapBasic comes with spatial operators that helps you to see their interaction
• Intersects
• Compares the individual elements
• Partly Within
• Compares the individual elements, Identical to Intersects
• Contains Part
• Compares the individual elements, Identical to Intersects
• Within
• Compares centroid from left side with right side
• Contains
• Compares left side with centroid from right side
• Entirely Within
• Compares the entire objects
• Contains Entire
• Compares the entire objects
45. MapInfo SQL – Select
• MapInfo Pro comes with support for SQL Select which also can be used directly from your MapBasic application.
• The basic syntax of the Select statement looks like this:
Select expression_list
From table_name [As "table_alias" ] [ , ... ]
[ Where expression_group ]
[ Into results_table [ Noselect ] [ Hide ] ]
[ Group By column_list ]
[ Order By column_list ]
[ Limit num_records ]
46. MapInfo SQL – Insert
• MapInfo Pro comes with support for SQL Insert which also can be used directly from your MapBasic application.
• The basic syntax of the Insert statement looks like this:
Insert Into table
[ ( columnlist ) ]
{ Values ( exprlist ) | Select columnlist
• You can insert individual values or records from another table.
47. MapInfo SQL – Update
• MapInfo Pro comes with support for SQL Update which also can be used directly from your MapBasic application.
• The basic syntax of the Update statement looks like this:
Update table Set column = expr [ , column = expr, ...]
[ Where RowID = id | expression ]]
[ DropIndex ( Auto | On | Off ) ]
• Notice that the Where part only can reference a single record using the RowID, or multiple records using the
expression. The expression part was added in v2019
• In MapBasic older than v2019, if you need to update a subset of a table, you need to first Select these records and
then update the resulting query.
48. Spatial Operators & Functions
• The SQL language of MapInfo Pro and so MapBasic supports a number of spatial operators and functions that
can be used with the SQL statements and in plain MapBasic statements
• Finding points within polygons:
Select *
From POINTS, REGIONS
Where POINTS.OBJ Within REGIONS.OBJ
Into __SPATIAL__JOIN__RESULT NoSelect
• Calculation overlapping area:
Select CartesianArea(Overlap(CADASTRE.OBJ, ZONES.OBJ), "sq m") "OverlapArea_sqm"
From CADASTRE, ZONES
Where CADASTRE.OBJ Intersects ZONES.OBJ
And CartesianArea(Overlap(CADASTRE.OBJ, ZONES.OBJ), "sq m") > 1
Into __OVERLAP__JOIN__RESULT NoSelect
49. SQL and Aggregations
• SQL can be used to generate statistics from the data in a column. For this purpose we are using aggregations.
• A couple of aggregations:
• Count(*) counts the number of records in a grouping
• Min( column ) calculates the minimum value of a column in a grouping
• Max( column ) calculates the maximum value of a column in a grouping
Select Count(*) "NUMRECORDS", Min(DATA) "MIN", Max(DATA) "MAX"
From MINTABLE
Into GROUPED__VALUES NoSelect
• With MapInfo Pro v2019, we added support for spatial aggregations such as:
• AggregateCombine( obj_expr ) merges the spatial objects
• AggreagteBuffer( obj_expr) merges the spatial objects and adds a buffer
• AggregateConvexHull( obj_expr ) creates a Convex Hull polygon around the spatial objects
• AggregateMBR( obj_expr ) merges the Minimum Bounding rectangle of the spatial objects
50. Run Command
• Run Command can be used to run a text containing one or more MapBasic statements
• This is useful for concatenating your string at runtime when all table names and column names are knows. The
might not be known at kompile time
• It works as if you were executing your statement thru the MapBasic window
Run Command "Select Min(" & sCol & ") ""MIN"", MAX(" & sCol & ") ""MAX"""
& " From " & sTab
& " Into GROUPED__VALUES NoSelect"
• Note that the two quotes ("") inside the string are translated into a single quote (”) when the statement is executed.
51. Looping thru Rows in a Table
• When you need to loop thru a table and read records from a table you have multiple options for doing so. I would
however recommend to do it like this:
Fetch First From GROUPED__VALUES
Do Until EOT(GROUPED__VALUES)
Print "Minimum value is: " & GROUPED__VALUES.MIN
Fetch Next From GROUPED__VALUES
Loop
• Fetch First and Fetch Next are used to position the cursor at the required record.
• Do Until EOT() … Loop is used the loop thru the table until the cursor no longer points at a record in the table (it’s at
End Of Table)
• Inside the loop you can read the necessary values and deal with them
• This practise automatically ignores deleted records and skips these in the loop
52. Using functions in SQL
• The MapBasic languages allows you to use any MapBasic functions in your Select, Update and Insert statements.
• You can also use custom defined functions with these statements.
54. Menus
• Menus are used to let the user decide when a specific part of the application should get used.
• Menus are often created in the Sub Main or in a procedure called from the Sub Main.
• When the user selects the menu item in the application, the associated procedure is called.
• Use comma (,) to separate menu items.
• The Help Message is not mandatory, but is shown in the lower left corner.
Create Menu "My Application" As
"Do task"
HelpMsg "Task is done when you click here"
Calling DoSomething,
"End Application"
Calling EndProgram
55. Adding a menu to the interface
• You can add a new menu to an existing menu, for instance to the Tools menu
Alter Menu M_TOOLS Add
"Table Analyse" As "Table Analyse"
• Or you can add a new menu to the Menu Bar
Alter Menu Bar
Add "Table Analyse"
• Or to add it in front of the Window and Help menu
Alter Menu Bar
Remove M_WINDOW, M_HELP
Alter Menu Bar
Add "Table Analyse“, M_WINDOW, M_HELP
57. MapInfo Pro 64-bit .NET API
• With MapBasic v2021, we introduced MapBasic support for building your ribbon user interface
• Earlier versions of MapBasic must rely on the .NET API and/or the RIBBONLib module
• MapInfo Pro 64-bit comes with a .NET API that can be used to integrate your tool into the Ribbon.
• That makes it easy to integrate your tool into the Ribbon if you are familiar with any .NET language, such as C# or
VB.NET.
• The .NET API also has a MapBasic declaration file that makes it possible to use the .NET API from MapBasic.
• But that’s quite cumbersome …
• Alternatively you can use the RIBBONLib for adding controls to the Ribbon using MapBasic
58. Using the MapBasic ribbon statement
• Adding a single button to an existing group on the Table tab
Set Ribbon Tab TAB_TABLE
Group TAB_TABLE_ADDEDIT_GRP
Controls( Add
Control "cmdPredominance2" Caption "Calculate Predominance"
Type CTRL_TYPE_BUTTON
Size Large
Properties( PROPERTY_CALLINGHANDLER : "MENUCalculatePredominance"
, PROPERTY_LARGEICON : PATH_IMAGES & "CalculatePredominance_32.png"
, PROPERTY_SMALLICON : PATH_IMAGES & "CalculatePredominance_32.png"
)
)
59. Using the IMapInfoPro interface
• Dim your variables
• You need to get the MapInfo Application
Global mapinfoApplication As This
Global RibbonTabColl As This
Global RibbonTab As This
Global thisApp As This
Global mapinfoEvents As This
'Get MiPro interface
mapinfoApplication = SystemInfo(SYS_INFO_IMAPINFOAPPLICATION)
'Get handle to current application
thisApp = MapBasicApplication(mapinfoApplication, ApplicationName$())
60. Using the IMapInfoPro interface
• Now you can get other elements through this, such as the Ribbon and add new UI elements to it
'Get Ribbon
Ribbon = GetRibbon(mapinfoApplication)
'Get RibbonTabs Collection
RibbonTabColl = GetTabsColl(Ribbon)
'Add a new Tab to RibbonTabs collection
RibbonTab = RbnTabCollAddStrStr (RibbonTabColl, "MBAddIn", "MB Tab")
61. Using the IMapInfoPro interface
• Next you can create new Ribbon Group and start adding controls/buttons to it.
'Get the ribbon group collection.
ribbonGroupsColl = GetRbnTabGrps(RibbonTab)
'Add a group to the newly added tab.
ribbonGroup = RbnCtrlGrpCollAddStrStr(ribbonGroupsColl, "MBGroup", "Addin")
'Get Group controls collection
Dim groupControlColl As This
groupControlColl = GetRbnCtrlGrpCtrls(ribbonGroup)
'Add a button to the ribbon group
Dim button1 As This
button1 = MICtrlCollAddStrStrInt(groupControlColl, "OpenBtn", "Open", 1)
Call SetRbnBtnCtrlIsLarge(button1, TRUE)
62. RIBBONLib
• Use a MapBasic library that wraps the .NET API into some more easy to use customer MapBasic functions
63. Get the Ribbon Library
You can get the Ribbon Library from:
Github.com: This link is for the updated mbLibrary repository
• https://github.com/PeterHorsbollMoller/mbLibrary