Thursday, 26 June 2014

Get List Of Running MBXs

This example demonstrates how to use DDE to retrieve a topic string which contains the list of running mbx's within a mapinfo session. The function  GetMBXFromTopicString(strTopics As StringAs String  extracts the mbx name from the topic string. I have used similar code in other applications to determine if an mbx was running in the current instance of mapinfo. If it was not found, I issued a Run Application statement to fire off the mbx


Include "Mapbasic.def"

Declare Sub Main
Declare Sub
PrintListOfRunningMBXs

Declare Function GetMBXFromTopicString(strTopics As String) As String

'---------------------------------------------------------------------------------------
Sub Main
Print Chr$(12)
Set Window Message Position(1,1) Width 3 Height 5 Title "List of Running MBXs"

Call PrintListOfRunningMBXs
End Sub
'---------------------------------------------------------------------------------------
Sub PrintListOfRunningMBXs
OnError Goto CatchEx
   
   Dim nChan, i As Integer
   Dim sTopics, strMBX As String

   nChan = DDEInitiate("MapInfo", "System")
   sTopics = DDERequest$(nChan, "Topics")
   DDETerminate nChan
   strMBX = GetMBXFromTopicString(sTopics)
   i = 1
   
   Do While sTopics <> ""
      Print PathToFileName$(GetMBXFromTopicString(sTopics))
      i = i + 1
   Loop

Done:
   Exit Sub
CatchEx:
   Resume Done
End Sub
'---------------------------------------------------------------------------------------
Function GetMBXFromTopicString(strTopics As String) As String
OnError Goto CatchEx

   Dim iDelimPos As SmallInt
   strTopics = RTrim$(LTrim$(strTopics))
   iDelimPos = InStr(1, strTopics, Chr$(9))

   If iDelimPos Then
      GetMBXFromTopicString = Left$(strTopics, iDelimPos-1)
      strTopics = Right$(strTopics, Len(strTopics)-iDelimPos)
   Else
      GetMBXFromTopicString = strTopics
      strTopics = ""
   End If

Done:
   Exit Sub
CatchEx:
   Resume Done
End Function
'---------------------------------------------------------------------------------------

Thursday, 19 June 2014

MapBasic Progress Bar Example 2: How to step progress bar for multiple tasks

Following on from Example 1, in this example I will demonstrate how I use a progress step sub routine as a way of calling many functions and sub routines to show progress through my mbx. The code uses a case statement to see what step count it is up to. It also demonstrates how to track if the progress bar cancel button was clicked, or if the code was ended prematurely because of user intervention. 

This example enables you to show the progress bar, and set up a sequence of routines / scripts / functions and update the progress bar with a progress percentage when each task is complete.


Include "Mapbasic.def"

Declare Sub Main
Declare Sub
StepProgress

Declare Sub Wait3Seconds
Declare Function ReturnTrue() as Logical

Dim iProgress as Integer
Dim iProgressRange as Integer

Sub Main
   Print Chr$(12)
   Set Window Message Position(1, 1) Width 3 Height 1
   Print "*** Started Progress Bar Example ***"

   iProgress = 1
   iProgressRange = 5

   ProgressBar "Processing...."
      Calling StepProgress
      Range iProgressRange


   If CommandInfo(CMD_INFO_STATUS) then
      If iProgress <= iProgressRange then
         Note "You ended the Progress early because you only got to step " & iProgress
      Else
         Note "Progress Bar Example Complete!"
      End If
   Else
      Note "You clicked the cancel button on the Progress Bar!"
   End If

End Sub
'----------------------------------------------------------------
Sub StepProgress
   Print "Progress is @ step " & iProgress

   Do Case iProgress
      Case 1
         Note "Progress is @ step " & iProgress 'This is just an example process
      Case 2
          Note "Progress is @ step " & iProgress & ". Now going to wait 3 secs!"
          Call Wait3Seconds 'This is just an example process
      Case 3
          Note "Progress is @ step " & iProgress 'This is just an example process
      Case 4
          If NOT ReturnTrue() then 'This is just an example process
             Print "You eneded Progress"
             ProgressBar = -1 'Now the progress bar will stop and hide
             Exit Sub
         End If
      Case 5
         Note "Progress is @ step " & iProgress 'This is just an example process
   End Case

   iProgress = iProgress + 1
   
   If iProgress <= iProgressRange Then
      ProgressBar = iProgress
   Else
      ProgressBar = -1
   End If

End Sub
'----------------------------------------------------------------
Sub Wait3Seconds

   Print "Waiting for 3 seconds"

   Dim iCurrentTime, iElapsedTime, iWaitTime as Float

   iCurrentTime = Timer()
   iWaitTime= 3

   Do While iElapsedTime <= iCurrentTime + iWaitTime
      iElapsedTime = Timer()
   Loop

End Sub
'----------------------------------------------------------------
Function ReturnTrue() as Logical

   Dim bResult as Logical
   bResult = Ask("Progress is @ step " & iProgress & ". Do you want the progress bar to Contiue or End?", "Continue", "End")
   Print "Return True = " & bResult
   
   ReturnTrue = bResult

End Function

Mapbasic Progress Bar Example 1: How to step progress bar for each row in a table

The progress bar that is provided within Mapbasic is not very flexible. It is limited to calling sub routines and is designed in a way that it continues to call a the specified sub routine until you end it (ProgressBar = -1). This means you can't parse a variable and you can't just show the progress bar and update it's progress and any point in your code. 

It took me a while to harness it, and this example and Example 2 demonstrates how I use the Mapbasic progress bar in my mbx's. 

In this example I will demonstrate how to iterate through a table fetching each row. I use global variables to track progress and range and I create a selection table that I step through each row and print out the column 1 value. I would suggest you open a table with more than 1000 rows when you run this example mbx.



Include "Mapbasic.def"

Declare Sub Main
Declare Sub
StepProgress 


Dim iProgress as Integer
Dim iProgressRange as Integer

'----------------------------------------------------------------
Sub Main
   Print Chr$(12)

   Set Window Message Position(1, 1) Width 3 Height 1
   Print "*** Started Progress Bar Example ***"

   If NumTables() < 1 then
      Note "This Progress Bar Example needs a table open to demonstrate"
      Exit Sub
   End If

   Select * from TableInfo(1,TAB_INFO_NAME) Where str$(Col1) <> "" Into Temp
   iProgressRange = TableInfo("Temp",TAB_INFO_NROWS)

   Fetch First From Temp
   iProgress = 1

   ProgressBar "Processing...."
      Calling StepProgress
      Range iProgressRange

   Close Table Temp

   If CommandInfo(CMD_INFO_STATUS) Then
      Note "Progress Bar Example Complete!"
   Else
      Note "You clicked the cancel button on the Progress Bar!"
   End If
End Sub
'----------------------------------------------------------------
Sub StepProgress

   Print "Row " & iProgress & " Value " & Temp.Col1
   'Do Something here
   'EG: Update Temp Set Col1 = "A New Vaule" Where RowID = iProgress

   iProgress = iProgress + 1
   Fetch Rec iProgress From Temp

   If iProgress <= iProgressRange Then
      ProgressBar = iProgress
   Else
      ProgressBar = -1
   End If
End Sub
'----------------------------------------------------------------