viernes, 29 de marzo de 2013

Mapbasic (Programación en MapInfo)

En este mes se verá un ejemplo de cómo usar el Mapbasic para obtener cierta información de unas capas en el MapInfo. Lo que haremos es primero seleccionar una capa o “table” que está en una vista en Mapinfo y luego mediante un programa en Mapbasic obtendremos:

El nombre de la capa / table seleccionada.
La ruta donde está la capa / table seleccionada.

La proyección que tiene la capa / table seleccionada.
Las columnas de la capa / table seleccionada.

Y al seleccionar una columna que nos visualice todas los valores de los registros de dicha columna.
Todos estos datos estarán en un formulario (cuadro de dialogo) para una mejor presentación.

Para ello, abrimos el Mapbasic y creamos un archivo, le ponemos un nombre que nos guste y por defecto tendrá la extensión mb. Luego si queremos ejecutarlo, hacemos doble clic en este archivo mbx.



El código es el siguiente:
 
include "Mapbasic.def"

Declare Sub Main
Declare Sub Dialogo (NombreTable as string)
Declare Sub SeleccionColumna

Declare Function NombreColumnas (NombreTable_Col as string,NumColumnas as integer) as string
Declare Function ValoresRegistros (NombreTable_Col as string,PosicionColumnas as integer) as string

Dim MiTableNombre as String

Sub Main()
 MiTableNombre = SelectionInfo(SEL_INFO_TABLENAME)
 if MiTableNombre <> "" then
  call Dialogo(MiTableNombre ) 
 else
  Note ("Seleccione una Capa / Table" ) 
 end if
end Sub

Sub Dialogo (NombreTable as string)
 Dim TableNumColumnas as integer
 TableNumColumnas = TableInfo(NombreTable ,TAB_INFO_NCOLS)

 Dialog
  Title "Ingeografos: Descripción de una Capa / Table"
   Width 300 Height 160
  Control StaticText
   Title "Capa / Table seleccionada: "& NombreTable
   Position 5,5
  Control StaticText
   Title "Ruta: "& TableInfo(NombreTable , TAB_INFO_TABFILE)
   Position 5,15
  Control StaticText
   Title "Proyección: "& TableInfo(NombreTable ,TAB_INFO_COORDSYS_NAME)
   Position 5,25
  Control GroupBox
   Title "Columnas" 
   Position 5, 35
   Width 145 Height 100
  Control StaticText
   Title "Numero de Columnas: "& TableInfo(NombreTable ,TAB_INFO_NCOLS)
   Position 7, 45
  Control ListBox
   Position 7, 55
   Width 135 Height 75
   Title NombreColumnas (NombreTable ,TableNumColumnas )
   Id 1
   Calling SeleccionColumna 
  Control GroupBox
   Title "Filas" 
   Position 150, 35
   Width 145 Height 100
  Control StaticText
   Title "Numero de Registros: "& TableInfo(NombreTable ,TAB_INFO_NROWS)
   Position 152, 45
  Control ListBox
   Position 152, 55
   Width 135 Height 75
   Id 2
   Control CancelButton
   Position 130, 140 
end sub

Function NombreColumnas (NombreTable_Col as string, NumColumnas as integer) as string
 Dim i as integer
 Dim TXT_AUX as string

 For i = 1 to NumColumnas 
  if TXT_AUX = "" then
   TXT_AUX = ColumnInfo(NombreTable_Col, "COL" & i, COL_INFO_NAME)
  else
   TXT_AUX = TXT_AUX & ";" & ColumnInfo(NombreTable_Col, "COL" & i, COL_INFO_NAME)
  end if
 next 
 
 NombreColumnas = TXT_AUX
end Function

Sub SeleccionColumna
 Dim VariableTXT as string
 Dim VariableALIAS as Alias
 Dim TXT_AUX as string
 
  If CommandInfo(CMD_INFO_DLG_DBL) = TRUE Then 
  VariableTXT = MiTableNombre & ".col"& ReadControlValue(1)
  VariableALIAS = VariableTXT
  
  Fetch First From MiTableNombre 
  Do While Not EOT (MiTableNombre)
   
   if TXT_AUX = "" then
    TXT_AUX = VariableALIAS
   else
    TXT_AUX = TXT_AUX & ";" & VariableALIAS
   end if
   Fetch Next From MiTableNombre 
  Loop
 end if

 Alter Control 2
  Title TXT_AUX
End Sub

Y esto nos creara un cuadro de dialogo como la siguiente:


Explicación:
PARTE 01:
1)include "Mapbasic.def"
2)Declare Sub Main
3)Declare Sub Dialogo (NombreTable as string)
4)Declare Sub SeleccionColumna
5)Declare Function NombreColumnas (NombreTable_Col as string,NumColumnas as integer) as string
6)Declare Function ValoresRegistros (NombreTable_Col as string,PosicionColumnas as integer) as string
7) Dim MiTableNombre as String

Donde:

1 )Se “agrega” o “incluye” el archivo "Mapbasic.def" donde están guardadas algunas referencias que utilizaremos en algunas funciones propias del Mapbasic
2) Declaramos un procedimiento Sub principal llamado Main.
3) Declaramos un procedimiento Sub llamado Dialogo donde se visualizara los datos de la capa / table. Tiene como referencia a una variable que contiene el nombre de la capa / table actualmente seleccionada.
4) Declaramos un procedimiento Sub llamado SeleccionColumna, y como su nombre indica, es donde seleccionaremos una columna.
5) Declaramos una Función llamadaNombreColumnas, donde obtendremos los nombres de las columnas. Tiene como variables el nombre de la capa / table seleccionada (NombreTable_Col), y la cantidad de columnas (NumColumnas).
6) Declaramos una Función llamadaValoresRegistros, donde obtendremos los valores de los registros de la columna seleccionada. Tiene como variables el nombre de la capa / table seleccionada (NombreTable_Col), y la posicion de columnas (PosicionColumnas).
7) Se declara una variable de tipo String (Texto) llamada MiTableNombre
, donde estará guardada el nombre de la capa / table seleccionada.

PARTE 02:
Sub Main()
 MiTableNombre = SelectionInfo(SEL_INFO_TABLENAME)
 if MiTableNombre <> "" then
  call Dialogo(MiTableNombre ) 
 else
  Note ("Seleccione una Capa / Table" ) 
 end if
end Sub
 
Donde:
En este procedimiento Sub, se obtiene el nombre de la capa / table seleccionada con la función SelectionInfo(SEL_INFO_TABLENAME) y se guarda en la variable MiTableNombre, luego se hace un procedimiento IF: si hay una capa / table seleccionada, es llamado el procedimiento
call Dialogo(MiTableNombre ) donde call hace llamar al procedimiento Dialogo junto con la variable MiTableNombre. Si no hay ninguna capa / table seleccionada, en el else aparecerá una alerta:
Note ("Seleccione una Capa / Table" ), donde todo lo que está encerrado entre paréntesis del note aparecerá en una ventana como la que se muestra en la imagen siguiente:
 
 
 
PARTE 03:
1)Sub Dialogo (NombreTable as string)
2)            Dim TableNumColumnas as integer
3)            TableNumColumnas = TableInfo(NombreTable ,TAB_INFO_NCOLS)
4)            Dialog
5)                            Title "Ingeografos: Descripción de una Capa / Table"
6)                                           Width 300 Height 160
7)                            Control StaticText
8)                                           Title "Capa / Table seleccionada: "& NombreTable
9)                                           Position 5,5
10)                         Control StaticText
11)                                         Title "Ruta: "& TableInfo(NombreTable , TAB_INFO_TABFILE)
12)                                         Position 5,15
13)                         Control StaticText
14)                                         Title "Proyección: "& TableInfo(NombreTable ,TAB_INFO_COORDSYS_NAME)
15)                                         Position 5,25
16)                         Control GroupBox
17)                                         Title "Columnas"
18)                                         Position 5, 35
19)                                         Width 145 Height 100
20)                         Control StaticText
21)                                         Title "Numero de Columnas: "& TableInfo(NombreTable ,TAB_INFO_NCOLS)
22)                                         Position 7, 45
23)                         Control ListBox
24)                                         Position 7, 55
25)                                         Width 135 Height 75
26)                                         Title NombreColumnas (NombreTable ,TableNumColumnas )
27)                                         Id 1
28)                                         Calling SeleccionColumna
29)                         Control GroupBox
30)                                         Title "Filas"
31)                                         Position 150, 35
32)                                         Width 145 Height 100
33)                         Control StaticText
34)                                         Title "Numero de Registros: "& TableInfo(NombreTable ,TAB_INFO_NROWS)
35)                                         Position 152, 45
36)                         Control ListBox
37)                                         Position 152, 55
38)                                         Width 135 Height 75
39)                                         Id 2
40)                        Control CancelButton
41)                                         Position 130, 140               
42)end sub
Donde:
En este procedimiento Sub, se construye el formulario donde aparecerán los datos de la capa / table seleccionada:
1) El procedimiento Dialago recibe el nombre de la capa / table en la variable NombreTable.
2) Se crea la variable TableNumColumnas de tipo entero.
3) Luego con la funcion TableInfo(NombreTable ,TAB_INFO_NCOLS) obtenemos el numero de columnas y la guardamos en la variable TableNumColumnas.
4) Abrimos el cuadro de dialogo con la sentencia Dialog.
5) Ponemos un titulo a nuestro cuadro de dialogo con la sentencia Title y un texto entre comillas ("mi texto" por ejemplo).
6) Fijamos un Ancho (Width) y una Altura (Height) al cuadro de dialogo.
7) Luego creamos un StaticText (viene ser como una etiqueta o Label) en donde pondremos el nombre de la capa / table seleccionada.
8) Para poner el nombre usamos la función Title y luego el nombre de la capa que está en la variable NombreTable, nótese que se usa el ampersand (&) para concatenar textos, números inclusive. Se usa las comillas para poner un texto que indica que información esta acá y luego el ampersand (&).
9) Luego para posicionarlo en el formulario, usamos la función Position X, Y (donde la X es un valor numérico que corresponde a la posición de la entidad en el eje X y lo mismo para el caso de la Y).
Se repite este procedimiento para los StaticText que están en los numerales 10 - 12, 13 - 15, 20 - 22 y 33 - 35 (se omitirá estos números por qué es lo mismo que lo explicado líneas arriba)
11) Se obtiene la ruta donde está la capa / table con la función TableInfo(NombreTable , TAB_INFO_TABFILE).
14) Se obtiene la proyección con la función TableInfo(NombreTable ,TAB_INFO_COORDSYS_NAME).
16) Se crea un GroupBox control donde estará la información de las columnas de la capa / table.
17) Se pone el titulo (con la función Title) entre comillas ("Columnas").
18) Y se ubica la posición Position 5,35.
19) Y luego un Ancho (Width) y una Altura (Height).
21) Se obtiene el numero de columnas con la función TableInfo(NombreTable ,TAB_INFO_NCOLS).
23) Se crea un ListBox control donde estarán los nombres de las columnas.
24) Se pone una posición (Position) y en 25) se fija el Ancho (Width) y la Altura (Height).
26) Con la función Title del ListBox se pondrán los nombres de las columnas, para hacerlo se usa la función NombreColumnas (esta función se verá más adelante). ListBox separa cada entidad de la lista con un punto y coma (;). Por ejemplo si queremos que en un ListBox estén las variables a, b y c, debemos separarlos así: a;b;c.
27) Se le asigna un Id al ListBox control con el numero 1 (el uso de este Id se verá en la función NombreColumnas), y sirve para llamar este control desde un lugar del programa y acceder a el.
28) Se le asigna también el procedimiento Sub SeleccionColumna (se verá más adelante).
29 - 32) Se crea un GroupBox control para el caso de los registros, se usa lo anteriormente hablado.
34) Se Obtiene el numero de registros con la función TableInfo(NombreTable ,TAB_INFO_NROWS).
40) Se crea un CancelButton que en 41) está en la posición (Position) 130, 140. Sirve para salir del formulario, y cumple la misma función de la cruz que está en la esquina superior derecha del mismo.
42) Fin del procedimiento Sub.
PARTE 04:
 
Function NombreColumnas (NombreTable_Col as string, NumColumnas as integer) as string
 Dim i as integer
 Dim TXT_AUX as string

 For i = 1 to NumColumnas 
  if TXT_AUX = "" then
   TXT_AUX = ColumnInfo(NombreTable_Col, "COL" & i, COL_INFO_NAME)
  else
   TXT_AUX = TXT_AUX & ";" & ColumnInfo(NombreTable_Col, "COL" & i, COL_INFO_NAME)
  end if
 next 
 
 NombreColumnas = TXT_AUX
end Function
 
Donde
En esta función se obtiene los nombres de la columna de la capa / table seleccionada y se requiere el nombre de la capa / table seleccionada (en la variable NombreTable y el numero de columnas en la variable NumColumnas) y devuelve una cadena de texto de la forma a;b;c;..;z donde las letras son los nombres de las columnas separadas por el punto y coma (;), esto es necesario para que el ListBox control los reconozca como entidades separadas. Usamos el For para mover el cursor i (definido como entero), para leer cada columna y obtener el nombre de la misma con la función ColumnInfo(NombreTable_Col, "COL" & i, COL_INFO_NAME), para guardarlo en la variable auxiliar (de tipo string) TXT_AUX. Luego al finalizar el For, se asigna el valor de TXT_AUX al de NombreColumnas para que sea devuelto fuera de la función y pueda llenar el ListBox con todos los nombres de las columnas.
PARTE 05:
1) Sub SeleccionColumna
2)            Dim VariableTXT as string
3)            Dim VariableALIAS as Alias
4)            Dim TXT_AUX as string
               
               
5)            If CommandInfo(CMD_INFO_DLG_DBL) = TRUE Then
6)                            VariableTXT = MiTableNombre & ".col"& ReadControlValue(1)
7)                            VariableALIAS = VariableTXT
 
8)                            Fetch First From MiTableNombre
9)                            Do While Not EOT (MiTableNombre)
                                              
10)                                          if TXT_AUX = "" then
11)                                                         TXT_AUX = VariableALIAS
12)                                          else
13)                                                         TXT_AUX = TXT_AUX & ";" & VariableALIAS
14)                                          end if
15)                                          Fetch Next From MiTableNombre
16)                          Loop
17)          end if
 
18)          Alter Control 2
19)                          Title TXT_AUX
20)End Sub
 
Donde:
1) Es la apertura del procedimiento Sub SeleccionColumna.
2) Se crea una variable de tipo string llamado VariableTXT.
3) Se crea una variable de tipo Alias llamado VariableALIAS.
4) Se crea una variable de tipo string llamado TXT_AUX.
5 ) Para que este procedimiento Sub se ejecute, primero se debe hacer un doble click a algún elemento del ListBox donde están los nombres de las columnas, esto se verifica con la condicional If CommandInfo(CMD_INFO_DLG_DBL) = TRUE Then .
6) Paralelamente se lee el valor seleccionado (por que al hacer el doble click a un elemento del ListBox ya está siendo seleccionado) con la función ReadControlValue(1), donde el 1 es el valor del Id 1 que colocamos al ListBox respectivo de las columnas, y se concatena, delante de este, el nombre de la capa / table seleccionado mas el texto “.col”, esto es para que lea específicamente la columna seleccionada, y es asignada a la variable VariableTXT, quedando de esta manera: VariableTXT = MiTableNombre & ".col"& ReadControlValue(1).
7) Es asignada el valor de la variable VariableTXT (de tipo string), a la variable VariableALIAS (de tipo alias), este tipo alias es muy usado cuando se quiere trabajar con nombres de columnas, es por eso que es usado aca.
8) Se posiciona un cursor al primer registro de la capa / table con la función Fetch First From MiTableNombre (MiTableNombre es el nombre de la capa / table seleccionada).
9) Se abre un Do While para leer todos los registros de la capa / table con Do While Not EOT (MiTableNombre).
10 – 14) Son comandos que son usados para crear un texto del tipo a;b;c;…;z, donde a, b, c, z son los registros de la columna seleccionada (en la variable VariableALIAS está la columna seleccionada), y que son guardados en la variable TXT_AUX.
15) Se mueve un cursor hacia delante con la función Fetch Next From MiTableNombre.
16) Fin del Do While , y en 17) fin del condicional If abierta en el punto 5.
18)  Ahora, el valor de TXT_AUX será guardado en el ListBox correspondiente de los Registros. Para eso usamos el comando Alter Control y ponemos el Id correspondiente a dicho ListBox que es el 2 para poder acceder a el: Alter Control 2.
19) luego con la función Title ponemos la variable TXT_AUX.
20) Fin del procedimiento.


Para ejecutar el programa, debemos compilarlo en el menú Project\Compile Current File  o haciendo ctrl. + k, esto nos creara un archivo con el mismo nombre del archivo mb creado anteriormente pero con la extencion mbx.


 

Esperando que este post sea de su utilidad, nos vemos el otro mes, hasta luego.
ª