MapInfo Pro Developers User Group

Expand all | Collapse all

That old Chestnut -- The Alias Variable

  • 1.  That old Chestnut -- The Alias Variable

    Posted 8 days ago
    Dear all,
    quite new to mapBasic. Using Mapinfo/Discover v16 (64bit) build 26. Windows 10 OS.

    Can you help with the following code – it errors on the select statement:

     

    Sub GetmyVidFiles

    Dim sQuery As String

    Dim pQuery As String

    Dim nCol As Integer

    Dim nNumCols As Integer

    Dim arrColNames() As String

    Dim arrColValues() As String

    Dim LeftCamera As Alias

    Dim RightCamera As Alias

    Dim myTrackName As Alias

    Dim myInterval As Alias

     

    '**Getting the name of the query (instead of Selection)

    sQuery = SelectionInfo(SEL_INFO_SELNAME)

    Print "my sQuery = " +  sQuery

    LeftCamera = sQuery & ".Link"

    RightCamera = sQuery & ".GoProLink"

    myTrackName = sQuery & ".Trackname"

     

    Open Table "G:\GPS_Tracks\All_VideoTrackPts.TAB" Interactive

    Add Map Auto Layer All_VideoTrackPts

    Select * from All_VideoTrackPts where myTrackName = "myTrackname" into myQuery

    Browse * From myQuery

    'pQuery = SelectionInfo(SEL_INFO_SELNAME)

    'myInterval = pQuery & ".Seg_Interval_s"

    'Fetch First From pQuery

     

    Print "my LeftCamera = " + LeftCamera

    Print "my RightCamera = " + RightCamera

    Print "my TrackName = " + myTrackName

    'Print "my pQuery = " +  pQuery

    'Print "my Segment = " +  myInterval

     

    End Sub



    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------


  • 2.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago
    Hi Peter,

    There are two errors I noticed in your code.

    1.  sQuery needs to be defined as an Alias

    2. In the select statement, I think you want to query from the sQuery  temp table rather than "All_VideoTrackPts".  Change the code to:

    Select * from sQuery  where myTrackName = "myTrackname" into myQuery

    Other points:
    - Obviously sQuery should be renamed now that it is no longer a string.
    - Since you are querying from a single table you don't need the "sQuery." prefixes for the column names.
    - You might like to try Run Command if you want to avoid Alias variables.


    ------------------------------
    James Nolet
    Dooley Mitchell & Morrison Pty Ltd
    ------------------------------



  • 3.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago

    Why does sQuery need to be defined as an alias? It's just the name of the selection table as a string and is later used to build aliases. It doesn't need to be an alias itself as far as I know.

     

    I think there's a lot of confusion and overuse of aliases. They're only needed when you don't know table and field names at compile-time. An alias essential defers this until run-time.

     

    Regards,

    Warren Vick

     






  • 4.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago

    Hello Peter,

     

    Doing a bit of 360degree photography are we? ��

     

    I think the key problem area in your code is one of precedence. In the following statement:

    Select * from All_VideoTrackPts where myTrackName = "myTrackname" into myQuery

    If you're expecting this query to run on a field called myTrackName in the table All_VideoTrackPts, I'm afraid it doesn't. That alias you defined earlier, with the same name, will take precedence. If you want to guarantee that it's a field from the database, prefix it with the table name. e.g. All_VideoTrackPts.myTrackName

     

    Secondly, your query is searching for a literal string "myTrackname" every time, which might not be what you're expecting. If you're trying to look-up from All_VideoTrackPts based on the current selection, you need to evaluate the alias and then search based on the result.

     

    For example:

     

    Dim myTrackName as string

    TrackNameAlias = sQuery & ".Trackname"               ' This will evaluate to something like "Query1.Trackname"

    myTrackName = TrackNameAlias                              ' Evaluate this at run-time. myTrackName now contains the contents of Query1.Trackname

    Select * from All_VideoTrackPts where All_VideoTrackPts.myTrackName = myTrackname into myQuery  ' Look-up that track name

    It's quote common to prefix variable with something to make them working variable in MapBasic. In you example, you've used "my"... I often use "work", but it's odd to have myTrackName in the database? I would have assume TrackName would be more likely, so check that this isn't a bug in your code.

     

    There are a few other things that you could look at to tidy your code. For example, check that there is something selected before proceeding.

     

    Hope that helps.

     

    Regards,

    Warren Vick

     






  • 5.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago
    Hi Warren,

    I think you're on the right track.  I was assuming that the Select statement was intending to select from the current selection, but see now that the value retrieved from the "TrackName" field of the current selection will be used to select from the "All_VideoTrackPts" table.

    ------------------------------
    James Nolet
    Dooley Mitchell & Morrison Pty Ltd
    Mentone, VIC, Australia
    ------------------------------



  • 6.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago

    Thanks. I think the original question demonstrates how people can get themselves into trouble with aliases.

     

    One of the most common uses, where it's not necessary, is in table names. For example:

     

    Select * from tableName into WORK noselect

     

    tableName could be a string variable containing the actual table name to be queried. It doesn't need to be an alias. Otherwise, tableName is taken literally as the table name.

     

    Although I'm an old school software engineer, I've never been a huge fan of Hungarian notation for variable names. This is when one would prefix the variable with its type. For example: dim iCount as integer  There are, however, some exceptions to my rule. In languages like C/C++, I've always prefixes pointers with a "p" and in MapBasic, some indication that a variable is an alias is quite useful. This is because a=b is not a straight value copy when b is an alias... it's a run-time evaluation of b. So, poor variable names aside, an "alias" prefix/suffix makes codes much easier to understand:

     

    a = bAlias

     

    Regards,

    Warren Vick

     






  • 7.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago
    The main issue is that you're trying to get the query result name before you've actually run the query/selection.

    Select * From All_VideoTrackPts Where Trackname = "myTrackName"
    sQuery = SelectionInfo(SEL_INFO_SELNAME)
    LeftCamera = sQuery + ".Link"
    Print "my LeftCamera = " + LeftCamera
    etc...

    However since you are naming the query result, and you know the column names, you can reference these directly and avoid aliases

    Select * From All_VideoTrackPts Where Trackname = "myTrackName" Into myQuery
    Print "my LeftCamera = " + myQuery.Link
    etc...

    ------------------------------
    Timothy Mashford
    Melbourne, Australia
    ------------------------------



  • 8.  RE: That old Chestnut -- The Alias Variable

    Posted 7 days ago
    Timothy - Yes, I think quite a bit of tidying up is required.
    Peter - More details might help us (such as what tables you are working with and the structure of these tables).
    Warren - I tend to use Run Command and avoid aliases altogether!

    ------------------------------
    James Nolet
    Dooley Mitchell & Morrison Pty Ltd
    Mentone, VIC, Australia
    ------------------------------



  • 9.  RE: That old Chestnut -- The Alias Variable

    Posted 6 days ago
    Remember always to use a Fetch statement to make sure the table cursor is pointing at the record you want it to point it:

    Select * From All_VideoTrackPts Where Trackname = "myTrackName" Into myQuery
    Fetch First From myQuery

    Print "my LeftCamera = " + myQuery.Link

    Having said that, I often try to select my dataset into a new named query and sometimes I also renamed my columns through the query.

    I use Hungarian Notation throughout my application. This helps me to identify the variable types with a single look. Alias variables I always prefix with an a: aTrackName.

    ------------------------------
    Peter Horsbøll Møller
    Pitney Bowes
    ------------------------------



  • 10.  RE: That old Chestnut -- The Alias Variable

    Posted 6 days ago
    Sorry for taking so long to rejoin the conversation I got redoployed to another project.
    What I am trying to do is simulate a GPS feed.
    I have a table called "AllGPSTracks" this file contains many polylines that represent roads traveled and the location of video shot along this road.
    The user selects a track (only one at time) "sQuery" From this selection I obtain the name of the track, and the files containing Video of the left and right side of the track.

    The second select pQuery is from a file call AllGPSTrackPts which contains the points that were used to construct the selected GPSTrack this table has the time interval taken to traverse each segment of track.
    The end result is a point moving along the polyline (GPSTrack) at the same velosityas the vehicle that the video was captured while the video is being playback;.
    Iwastrying to identified the trackname, the videofiles, and the time Intervals in the same Procedure; Can to only run instance of  "SelectionInfo(SEL_INFO_SELNAME)" function in a procedure?

    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------



  • 11.  RE: That old Chestnut -- The Alias Variable

    Posted 6 days ago
    Ah OK so the user has manually selected a polyline when the sub is run, this is the 'selection' you're referring to.

    Also your Select statement doesn't look correct, ' ....where myTrackName = "myTrackname" ....'. myTrackName is an alias pointing to a different table, and you're searching for a literal string "myTrackname" which doesn't seem right.

    The code could look something like:

    Dim sQuery, sTrackName, sLeftCamera, sRightCamera, sInterval As String
    Dim aTrackName, aLeftCamera, aRightCamera As Alias

    'Create the column aliases, since we don't know the query result name at runtime

    sQuery = SelectionInfo(SEL_INFO_SELNAME)
    aTrackName = sQuery + ".Trackname"
    aLeftCamera = sQuery + ".Link"
    aRightCamera = sQuery + ".GoProLink"

    'Copy the column values from the first row into string variables
    Fetch First From sQuery
    sTrackName = aTrackName
    sLeftCamera = aLeftCamera
    sRightCamera = aRightCamera

    Open Table "G:\GPS_Tracks\All_VideoTrackPts.TAB" Interactive

    'assume the track column is called 'TrackName'...?
    Select * from All_VideoTrackPts where TrackName = sTrackname into myQuery
    Browse * From myQuery

    Fetch First From myQuery
    'no need to use aliases here since we have named the query result and know the column names
    sInterval = myQuery.Seg_Interval_s


    etc.... 



    ------------------------------
    Timothy Mashford
    Melbourne, Australia
    ------------------------------



  • 12.  RE: That old Chestnut -- The Alias Variable

    Posted 5 days ago
    The First selection "sQuery" is the polyline is selected From the I get the trackname "myTrackname" which is used to select the nodes for the selected track form the table AllGPSTrackPts "pQuery" which will in turn give me the time interval of each segment "Seg_interval_s".

    The first selection work ok bt the procedure stall on the second selection.

    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------



  • 13.  RE: That old Chestnut -- The Alias Variable

    Posted 5 days ago
    Did you try the solution by @Timothy Mashford?  If that didn't work, you might need to supply a sample of your data.

    Do you have a field in All_VideoTrackPts called "myTrackName"?

    ​​

    ------------------------------
    James Nolet
    Dooley Mitchell & Morrison Pty Ltd
    Mentone, VIC, Australia
    ------------------------------



  • 14.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    My understanding of the role  of alias variables is that if the table name or the field name are not known  an alias variable is required. Since  the track table has many tracks when one is selected the query name produced from that selection will be dynamic . Hence the need for an alias variable.

    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------



  • 15.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    Hi Peter,

    I think it would be good if you could show the exact code that doesn't work. Sometimes it's a small thing that breaks it. It can be a variable that has the same name as a table, a String variable that should be an Alias variable.

    You don't need an Alias variable for a query unless the query name is dynamic. If you use Select ...Into SomeName then you know that your query will always be named SomeName.

    ------------------------------
    Peter Horsbøll Møller
    Pitney Bowes
    ------------------------------



  • 16.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    Global LeftCamera As Alias
    Global RightCamera As Alias
    Global myTrackName As Alias
    Global myInterval As Integer
    Global Poly as Object
    Sub GetmyVidFiles
    Dim sQuery As Alias
    Dim nCol As Integer
    Dim nNumCols As Integer
    Dim arrColNames() As String
    Dim arrColValues() As String


    '**Getting the name of the query (instead of Selection)
    sQuery = SelectionInfo(SEL_INFO_SELNAME)

    Fetch First From sQuery 'ERRORS HERE "EXPRESSION DOES NOT EVALUATE TO A COLUMN OR TABLE NAME" This was working but now is broken -- See further down

    LeftCamera = sQuery & ".Link"
    RightCamera = sQuery & ".GoProLink"
    myTrackName = sQuery & ".Trackname"



    Print "my LeftCamera = " + LeftCamera
    Print "my RightCamera = " + RightCamera
    Print "my TrackName = " + myTrackName
    'Print "my pQuery = " + pQuery
    'Print "my Segment = " + myInterval

    End Sub

    Sub GetmyTrackFiles
    Dim pQuery As String
    Dim nCol As Integer
    Dim nNumCols As Integer
    Dim arrColNames() As String



    Print "my LeftCamera = " + LeftCamera
    Print "my RightCamera = " + RightCamera
    Print "my TrackName = " + myTrackName


    Open Table "G:\GPS_Tracks\All_VideoTrackPts.TAB" Interactive
    Add Map Auto Layer All_VideoTrackPts
    Select * from All_VideoTrackPts where TrackName = "myTrackname" into myQuery
    Browse * From myQuery  'Errors here :Tbale not open

    '**Getting the name of the query (instead of Selection)
    'pQuery = SelectionInfo(SEL_INFO_SELNAME)

    Fetch First From myQuery
    myInterval = myQuery.Seg_Interval_s


    Print "my LeftCamera = " + LeftCamera
    Print "my RightCamera = " + RightCamera
    Print "my TrackName = " + myTrackName
    Print "my pQuery = " + pQuery
    Print "my Segment = " + myInterval
    End Sub

    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------



  • 17.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    Edited by Peter Horsbøll Møller 4 days ago
    I have made some minor adjustments and also added some comments to your code below

    Global aLeftCamera As Alias
    Global maRightCamera As Alias 'PHM: Renamed these to include m for modular and a for Alias type
    Global maTrackName As Alias 'PHM: Renamed these to include m for modular and a for Alias type
    Global mnInterval As Integer 'PHM: Renamed these to include m for modular and i for Integer type
    Global moPoly as Object 'PHM: Renamed these to include m for modular and o for Object type

    Sub GetmyVidFiles

    Dim sQuery As String 'PHM: should be a string
    Dim nCol As Integer
    Dim nNumCols As Integer
    Dim arrColNames() As String
    Dim arrColValues() As String


    '**Getting the name of the query (instead of Selection)
    sQuery = SelectionInfo(SEL_INFO_SELNAME)

    'ERRORS HERE "EXPRESSION DOES NOT EVALUATE TO A COLUMN OR TABLE NAME" This was working but now is broken -- See further down
    'Should be fixed now that sQuery is a String variable and not an Alias variable
    Fetch First From sQuery 

    aLeftCamera = sQuery & ".Link"
    maRightCamera = sQuery & ".GoProLink"
    maTrackName = sQuery & ".Trackname"

    Print "my LeftCamera = " + aLeftCamera
    Print "my RightCamera = " + maRightCamera
    Print "my TrackName = " + maTrackName
    'Print "my pQuery = " + pQuery
    'Print "my Segment = " + mnInterval


    End Sub


    Sub GetmyTrackFiles
    Dim pQuery As String
    Dim nCol As Integer
    Dim nNumCols As Integer
    Dim arrColNames() As String
    Dim sTrack As String 'You need a string to hold the current track name


    '**This might be a bit unsafe as you don't know which record you are pointing at
    '**nor do you know if the query exists or even which query your alias refers to

    Print "my LeftCamera = " + aLeftCamera
    Print "my RightCamera = " + maRightCamera
    Print "my TrackName = " + maTrackName

    sTrack = maTrackName

    Open Table "G:\GPS_Tracks\All_VideoTrackPts.TAB" InteractiveAdd Map Auto Layer All_VideoTrackPts
    Select *  from All_VideoTrackPts
       where TrackName = sTrack '**now we refer to the current value stored in the string variable
       into myQuery

    'Errors here :Tbale not open
    'I assume that has been fixed too as you now should select with a value that exists
    Browse * From myQuery  

    '**Getting the name of the query (instead of Selection)
    'pQuery = SelectionInfo(SEL_INFO_SELNAME)

    Fetch First From myQuery
    mnInterval = myQuery.Seg_Interval_s

    'PHM: These Alias variables still point back at the earlier query
    'PHM I have given an alternative way to get to the values using the named query.named column
    Print "my LeftCamera = " + aLeftCamera 'You can refer to myQuery.Link
    Print "my RightCamera = " + maRightCamera 'You can refer to myQuery.GoProLink
    Print "my TrackName = " + maTrackName 'You can refer to myQuery.Trackname
    Print "my pQuery = " + pQueryPrint "my Segment = " + mnInterval


    End Sub

    ------------------------------
    Peter Horsbøll Møller
    Pitney Bowes
    ------------------------------



  • 18.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    Thanks Peter,

    It works better but still fails at (see Below):

    Sub GetmyVidFiles
    Dim sQuery As String 'PHM: should be a string
    Dim nCol As Integer
    Dim nNumCols As Integer
    Dim arrColNames() As String
    Dim arrColValues() As String

    '**Getting the name of the query (instead of Selection)sQuery = SelectionInfo(SEL_INFO_SELNAME)
    'ERRORS HERE "EXPRESSION DOES NOT EVALUATE TO A COLUMN OR TABLE NAME" This was working but now is broken -- See further down
    'Should be fixed now that sQuery is a String variable and not an Alias variable 'Expression Does not evaluate to a column or table name
    Fetch First From sQuery
    aLeftCamera = sQuery & ".Link"
    maRightCamera = sQuery & ".GoProLink"
    maTrackName = sQuery & ".Trackname"
    Print "my LeftCamera = " + aLeftCamera
    Print "my RightCamera = " + maRightCamera
    Print "my TrackName = " + maTrackName
    'Print "my pQuery = " + pQuery
    'Print "my Segment = " + mnInterval

    End Sub

    from a previous sub a track is selected by a user:
    moPoly = Selection.obj
    Now I want to extract the filenames of video and the tracknamefrom this selected record
    to populate
    aLeftCamera = sQuery & ".Link"
    maRightCamera = sQuery & ".GoProLink"
    maTrackName = sQuery & ".Trackname"
    What value do I us for sQuery when I don't want the whole table just the selected record?



    ------------------------------
    Peter Taylor
    Ellesmere Geological services
    Kalgoorlie WA
    ------------------------------



  • 19.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago
    Yeah, sorry, look at my code again in the previous answer. When I copied it, a lot of line breaks were missing so a number of lines where all in one.

    You still need this to get to the query name:
    sQuery = SelectionInfo(SEL_INFO_SELNAME)

    I have modified the code in my earlier answer and added the missing line breaks

    ------------------------------
    Peter Horsbøll Møller
    Pitney Bowes
    ------------------------------



  • 20.  RE: That old Chestnut -- The Alias Variable

    Posted 4 days ago

    Hello Peter,

     

    True for fields but not tables names. For example, the following is fine:

     

    dim tableName as string

    tableName = "MyTable"

    select * from tableName into FOO noselect   ' this will select from a table called MyTable

     

    Someone earlier said use "run command". The only time that's necessary with a select statement is when there's a variable number of fields (unknown until run-time) you want to select.

     

    Regards,

    Warren Vick