sábado, 29 de julio de 2023

OOo Basic. Funciones.

Macro, subrutina y función

Para entender en qué consisten las funciones hay que tener en cuenta dos cuestiones: las instrucciones específicas que incorpora todo lenguaje para realizar determinadas tareas y el modo en que programamos los script.




La primera de estas cuestiones nos lleva a pensar en las funciones que incorpora todo lenguaje y que sirven para realizar "funciones" concretas y específicas. Un ejemplo son las funciones de conversión de tipos de variables, como CInt() que sirve para convertir una variable de cualquier tipo (string, por ejemplo) a numérica tipo Integer.

La segunda cuestión nos lleva a plantearnos los modos de programar, cuestión ésta de mayor complejidad conceptual y práctica que la anterior, pero ineludible a partir de cierto nivel de extensión y complejidad del código.

La forma de programar básica puede describirse como lineal: el conjunto de tareas que se definen en el algoritmo se convierten en líneas de código que se van sucediendo una tras otra hasta la conclusión del proceso.

Un ejemplo de ello es la forma de programar en el lenguaje Basic al inicio de la popularización  de los ordenadores. Otra, sin ir muy lejos, la que supone grabar una macro mediante Grabar macro.

Otra forma de plantearse la creación de programas se basa en reutilizar segmentos de código para simplificar el programa y hacerlo más legible y funcional. La forma más sencilla en que se manifiesta esta opción consiste en llamar a un script desde otro script, algo que también podemos hacer con macros. 

Sub EscribirMsgA
Dim sMsg As String
sMsg = "Hola Mundo 1"
MsgBox sMsg,64, "MENSAJE"
End Sub

 

Sub Receptor1
MsgBox "Mensaje desde script",64,"RECEPTOR 1"
Call  EscribirMsgA
End Sub

En este caso el script EscribirMsgA es funcional en si mismo,  pero también podemos reutilizarlo desde un segundo script (Receptor1llamándolo mediante la expresión Call, de la que podemos prescindir ya que se da por supuesta. Y lo dicho: también podemos hacerlo con una macro en sustitución del script EscribirMsgAaunque en este caso para escribir un texto directamente en el documento Writer.

A pesar de las ventajas de esta opción, también  tiene sus limitaciones; y la más importante es quizá, que es necesario modificar (en este ejemplo) el texto del mensaje en el script (o en la macro) subordinado, lo que en programas largos supone mucho trabajo e incrementa la probabilidad de cometer errores. 

Frente a estas opciones, funcionales pero limitadas, tenemos las subrutinas y las funciones. Empezaremos por aclarar en qué se diferencian ambas.

En OOo Basic las funciones se diferencian de las subrutinas claramente: mientras que las funciones devuelven  un valor (un  dato) y las subrutinas hacen algo, así que lo que "devuelven" es eso que hacen.

Veamos cómo crear una subrutina a partir del script anterior:

Sub EscribirMsgB (sMsg As String)
MsgBox sMsg,64, "MENSAJE"
End Sub

 

Sub Receptor2
MsgBox "Mensaje desde script",64,"RECEPTOR 2"
        EscribirMsgB ("Hola Mundo")
End Sub

Vamos a analizar ahora las diferencias entre EscribirMsgA (script) y EscribirMsgB (sMsg As String) (subrutina), aunque en cosa de denominación podrás comprobar que existe cierta confusión: en la documentación se suele emplear indistintamente el término macro, pero yo prefiero diferenciar entre macro, script (o rutina) y subrutina (1).

  • El script auxiliar (el primero) funciona con independencia del script principal (el segundo); la subrutina no.
  • La subrutina incorpora un identificador de variable en el paréntesis que lleva tras el nombre. En el script no existe dicho paréntesis y, en caso de identificarse una variable asimilable a la que declara la subrutina (es el caso de EscribirMsgA) se declara dentro del script y asigna contenido también dentro del script.
  • Mientras que en la llamada al script desde el principal (Receptor1) simplemente se llama al script auxiliar (Call  EscribirMsgA), al ser llamada la subrutina es necesario añadir un paréntesis tras el nombre y un contenido, en este caso un texto  (EscribirMsgB ("Hola Mundo")(2)

También podemos convertir las macros simples (algunas de ellas) en subrutinas, pero no en funciones, ya que las macros siempre hacen algo. Para ello, y en primer lugar, tenemos que diferenciar las que llamamos variables de sistema (que son de tipo objeto) de las que utilicemos para dar contenido concreto a la macro. A estas segundas son a las que daremos el tratamiento de subrutina, ya que las primeras, es posible darlas ese tratamiento, pero también otros, siendo preferible optar por uno más propio del trabajo con macros simples. Lo veremos a continuación en el ejemplo que vamos a desarrollar en base a la macro de escritura de texto.

Sub EscribirMsgC  (sTexto As String)
Dim document   as object
Dim dispatcher as object
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
Dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Text"
args2(0).Value = sTexto
dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args2())
End Sub

 

Sub Receptor3
MsgBox "Mensaje desde macro",64,"RECEPTOR 3"
EscribirMsgC ("Hola Mundo")
End Sub
  • Puedes observar que he formulado la macro del mismo modo que la subrutina. Gracias a ello, de hecho, he convertido la macro en una subrutina, aunque sería más correcto decir que esta formulación está a medio camino entre macro y subrutina, ya que mantiene componentes y formas propias de las macros, incorporando otras propias de la subrutinas. También sus "limitaciones": no funciona autónomamente, debiendo ser llamada desde un script "principal". 
  • El script "receptor" trata la macro como subrutina, tal y como podemos observar en la forma en que la llama (EscribirMsgC ("Hola Mundo"))

Frente a las subrutinas, en OOo Basic las funciones se diferencian claramente ya en su formulación: al denominarlas (apertura y cierre) se debe usar el identificador Function:

Function AreaCuadrado( iLado As Integer) As Double
    Dim dArea as Double
    AreaCuadrado = iLado * iLado
End Function

Esto es:
    • La función se declara con la expresión Function y finaliza con  End Function.
    • La función no funciona independientemente, necesita ser "llamada" desde un script principal.
    • Además del paréntesis donde se declaran las variables, también finaliza con una tipificación (As Double) que permite entender qué tipo de valor devuelve (numérico Double, en este caso) así como que la propia función es una variable, como de hecho lo es (o como tal se comporta), ya que devuelve un valor (el que contiene como variable)
    • El resultado del procesamiento interno de la función se asigna a la misma función a modo de variable (volvemos al punto anterior): AreaCuadrado = iLado * iLado. Otra formulación no provoca que la "función" dé error, pero tampoco devuelve nada.
Veamos cómo se formula el que llamamos script principal:

Sub Cuadrado
Dim sResultado As String
Dim iLong As Integer
Dim dArea
iLong = InputBox ("Dime el lado del cuadrado")
dArea = AreaCuadrado(iLong)
sResultado = "El cuadrado de lado " & iLong & " tiene un área de " & dArea
MsgBox (sResultado,64,"AREA DEL CUADRADO")
End sub

Puedes observar que la "llamada" a la función se diferencia de la llamada a la subrutina en que en la primera utilizamos la asignación a una variable, lo cual no hacemos en la llamada a subrutina puesto que la función es un valor (se comporta como una variable que tiene asignado un dato o valor), por lo que debe ser recogido por (y asignado a ) una variable. Después podrá ser tratado como dato, tal y como sucede en este ejemplo en su concatenación en la variable string sResultado (3)

NOTAS

(1) Las funciones se diferencian claramente, por lo que no existen estos problemas terminológicos.

(2) Podríamos sustituir el texto por una variable, pero en este ejemplo he optado por la formulación más sencilla. En ese caso, dicha variable es diferente de la que se declara en la subrutina, aunque termina cumpliendo la misma función que aquella. Esta equivalencia viene facilitada por la funcionalidad compartida de ambas: complementan la forma en que se escribe la subrutina.

(3) En la que contradigo lo que he considerado conveniente en otra entrada: no convierto las variables numéricas en string, como sería recomendable, por lo que una buena formulación de esta instrucción sería la siguiente: sResultado = "El cuadrado de lado " & CStr(iLong) & " tiene un área de " & CStr(dArea)

domingo, 23 de julio de 2023

OOo Basic. Datos

Colecciones de datos. Matrices

Cuando los datos individuales se presentan asociados por algún criterio y son relativamente numerosos, parece conveniente agruparlos para facilitar su manejo. Esta función la cumplen las matrices.

Precisamente la mayor utilidad de las matrices es ahorrar el trabajo de escribir largas series de variables, facilitando además procedimientos de acceso a su contenido, en cuanto que éste se define como colecciones de datos. Las matrices constituyen sistemas estructurados de almacenamiento.

La declaración de una matriz no es demasiado diferente de la declaración de una variable, salvo por el añadido del paréntesis (tras el nombre) que, además de identificarla como matriz, indica el número de contenidos con que se declara...

Dim mAlumnado(5) As String

... Bueno, más que el número, el límite superior de los elementos que la conforman, ya que, salvo instrucción específica en contra, las matrices se inician en OOo Basic con el índice 0, con lo que una matriz(4) contiene los elementos/índices 0 - 1 - 2 - 3 - 4 (total, 5 elementos) 

Para dotar de contenido a una matriz disponemos de varias opciones:

  • Introducirlo directamente, empleando el índice como referencia

mAlumando(0) = "Juana López Suárez"
  • Hacer que sean el resultado del procesamiento de datos preexistentes
mAlumnado(0) = sNombre & " " & sApellidos
  • Introducirlos externamente o capturarlos de una fuente de datos mediante algún procedimiento 
mAlumnado(0) = InputBox ("Nombre y apellidos del alumno :")

Pero también podemos introducirlos directamente como una lista mediante la función Array(), separando cada elemento con una coma.

mAlumnado = Array("Juana López Suárez", "Antonio Martínez Núñez", "Casimiro Rodríguez Fernandez", "Ana Martínez Sanz", "Susana García Méndez")

Esta función es de gran utilidad cuando deseamos introducir directamente los datos de la matriz, ya que evita tener que identificar uno a uno cada elemento, lo que supone un ahorro de tiempo. Otra ventaja de la función Array() es que nos permite introducir un número de elementos diferente del establecido en la declaración de la matriz, lo que la redimensiona de forma automática.

En relación con lo anterior, hasta el momento hemos hablado de matrices de dimensiones conocidas, lo que supone de sabemos dónde empiezan (mAlumnado(0)) y dónde terminan (mAlumnado(4)); pero es posible que, en script complejos si usamos la función Array(), o cuando capturamos datos externos, no sepamos a priori ni dónde empieza ni donde termina una matriz, especialmente dónde termina. Para estas situaciones son de gran utilidad las funciones LBound() y UBound():

  • LBound(mAlumnado()) nos devuelve el índice con el que inicia la matriz

  • UBound(mAlumnado()) nos devuelve su índice de finalización.

Esto significa que para mAlumnado()mAlumando(0) equivale a  LBound(mAlumnado()) mAlumando(5) equivale a UBound(mAlumando()). (1)

Un uso frecuente de las matrices es mediante un ciclo For que permite recorrerla. En este contexto, utilizar las funciones LBound() UBound() nos permite formalizar el bucle sin que sea necesario conocer sus dimensiones, evitándonos así una fuente común de error. Un ejemplo:

Sub EjemploMatriz

Dim mAlumnado(5) As String

Dim i As Integer

mAlumnado = Array("Juana López Suárez", "Antonio Martínez Núñez", "Casimiro Rodríguez Fernandez", "Ana Martínez Sanz", "Susana García Méndez")

For i = LBound(mAlumnado()) To UBound(mAlumnado())

MsgBox mAlumnado(i)

Next

End Sub

Dado que la variación del tamaño de una matriz es una maniobra relativamente frecuente, OOo Basic dispone de dos funciones que nos permiten realizar esta tarea de forma sencilla: mediante las palabras reservadas ReDim y Preserve. La primera redimensiona la matriz y la segunda permite mantener (si se desea) el contenido previo. Veamos un ejemplo tomado de [Mauricio Baeza, pg 54].

Sub Matriz
Dim misAmigos(2) As String
Dim co1 As Integer
misAmigos(0) = "Edgar": misAmigos(1) = "Gloria" : misAmigos(2) = "Toñito"
For co1 = LBound( misAmigos() ) To UBound( misAmigos() )
MsgBox Str( co1 ) & " - " & misAmigos( co1 ), 64, "Mis amigos"
Next
ReDim misAmigos(4)     -> Si usamos esta instrucción (1ReDim
Preserve misAmigos(4)   -> Si usamos esta otra (2)
  misAmigos(3) = "Lidia": misAmigos(4) = "Anita"
For co1 = LBound( misAmigos() ) To UBound( misAmigos() )
MsgBox Str( co1 ) & " - " & misAmigos( co1 ), 64, "Mis amigos"

Next

End Sub

En este script mostramos cómo emplear ReDim para aumentar el tamaño de la matriz misAmigos()que originalmente contiene 3 elementos (misAmigos(2) -> (0), (1) y (2)), pero que después de aplicado ReDim pasa a contener 5.

La diferencia entre usar la formulación (2)  que incluye la expresión Preserve o usar (1), que sólo contiene ReDim, es que los elementos (0), (1) y (2) no se conservan (sí cuando usamos Preserve)

La expresión ReDim también sirve para reducir el tamaño de la matriz, pero desgraciadamente no Preserve, por lo que en este caso se pierde el contenido de la matriz. Puedes comprobar lo que digo ejecutando este nuevo script en su dos formas alternativas (ver 3 y 4)

Sub Matriz
Dim misAmigos(4) As String
Dim co1 As Integer
misAmigos() = Array ("Edgar","Gloria","Toñito", "Lidia","Anita")
For co1 = LBound( misAmigos() ) To UBound( misAmigos() )
MsgBox Str( co1 ) & " - " & misAmigos( co1 ), 64, "Mis amigos"
Next
ReDim misAmigos(2)             -> (3)
ReDim Preserve misAmigos(2)     -> (4)
For co1 = LBound( misAmigos() ) To UBound( misAmigos() )
MsgBox Str( co1 ) & " - " & misAmigos( co1 ), 64, "Mis amigos"
Next
End Sub

Para  evitar este inconveniente hace falta crear una subrutina o una función, pero eso ya es tema de otra entrada.


NOTA

(1Si definimos el índice inicial de una matriz invariablemente con valor 0 (que es la opción por defecto), LBound no tiene mucho que aportar, pero sí es de interés si pensamos que podemos alterar los valores índices de una matriz y situar su inicio en un valor diferente de 0, como, por ejemplo, cuando definimos la matriz como sigue: Dim misNumeros(5 To 14) As Integer Dim misColores(-5 To 4) As String (ejemplo tomado de Mauricio Baeza, pg 51)

sábado, 22 de julio de 2023

OOo Basic. Estructuras

Bucle Do Loop

Mientras que el desarrollo de la iteración For se basa en la ejecución de un ciclo definido por los límites de una variable-contador, Do...Loop se basa en el cumplimiento (o no) de una determinada condición. 



Precisamente
 la diferencia entre ambos (For y Do) radica en que mientras que la primera implica necesariamente la ejecución de al menos una iteración, en Do
 puede darse el caso de que no se ejecute en ningún momento, dado que es posible que la condición necesaria no se cumpla nunca.


La sintaxis de Do es notablemente más compleja que For, como tendremos ocasión de comprobar en esta entrada por comparación con [la anterior], admitiendo Do dos variaciones básicas que, a su vez, presentan dos formas diferentes de plantear la condición de persistencia o finalización del bucle mediante dos instrucciones diferentes: While y Until. Veamos cada una de ellas (fuente de los gráficos libreoffice.org).

La primera de estas dos opciones es la que está representada en el gráfico siguiente: podemos advertir que las condiciones se plantean al inicio de la estructura, ubicándose las instrucciones While y Until asociadas a Do.


Este posicionamiento de la condición permite que no se ejecute el bucle ninguna vez si la condición que se establece no es verdadera (Do While)...

sub BucleA1

Dim iCondicion As Integer

iCondicion = 0

Do While iCondicion > 5

MsgBox iCondicion

iCondicion = iCondicion +1

Loop

End Sub

... como en este caso. Para que se ejecutar el bucle deberíamos cambiar el signo de la condición ( Do While iCondicion < 5) ...

... o mientras no lo sea (Do Until)...

sub BucleA2

Dim iCondicion As Integer

iCondicion = 0

Do Until iCondicion < 5

MsgBox iCondicion

iCondicion = iCondicion +1

Loop

End Sub

... no se ejecuta el bucle y para que se ejecute deberemos cambiar la condición en sentido contrario (Do Until iCondicion > 5) (1).

Contrariamente a la anterior, una segunda opción sitúa la condición asociada a Loop, motivo por el que While o Until se posicionan tomando a esta instrucción como referencia. El esquema siguiente representa esta segunda opción.


La consecuencia de este posicionamiento es que el bucle se ejecutará como mínimo al menos una vez, hasta que se comprueba que se cumple o no se cumple la condición que se establece. Por ejemplo...

sub BucleB1

Dim iCondicion As Integer

iCondicion = 0

Do

MsgBox iCondicion

iCondicion = iCondicion +1

Loop While iCondicion > 5

End Sub

... en este caso (Loop While) el bucle se ejecuta una vez MsgBox iCondicion -> 0, ya que la condición se comprueba asociada a la instrucción Loop. Para que se ejecute hasta que deja de cumplirse la condición debemos cambiar el signo de la comparación (Loop While iCondicion < 5): ahora se ejecutará hasta que iCondicion valga 5 (iCondicion=5), momento en que dejará de cumplirse.

Otra posibilidad es la que representa el siguiente script:

sub BucleB2

Dim iCondicion As Integer

iCondicion = 0

Do

MsgBox iCondicion

iCondicion = iCondicion +1

Loop  Until iCondicion < 5

End Sub

En él también se ejecuta el bucle una vez hasta que se comprueba que se cumple la condición para que no se ejecute, momento en el que finaliza en cumplimiento de la instrucción dada (Loop  Until iCondicion < 5), siendo necesario cambiar dicha condición (Loop  Until iCondicion > 5) para que persista ejecutándose hasta que se cumpla la condición se finalización que se establece.  

Las función específica y diferenciada de While y Until también resulta de interés, ya que optar por una o por otra implica priorizar el cumplimiento de la condición para que se ejecute el bucle (While), o establecer la condición que impida su cumplimiento (Until)

Como podemos observar, mientras que asociar la condición a Do vs. Loop modifica el funcionamiento del bucle...

  • Do (While|Until) Condición   -> Puede no ejecutarse nunca el bucle
  • Loo (While|Until) Condición   -> El bucle se ejecutará al menos en una ocasión.
... el uso de While vs Until invierte el sentido del cumplimiento de la condición:

  • While   -> Repite el bucle hasta que la condición sea falsa (deje de cumplirse)
  • Until    -> Repite el bucle mientras la condición es verdadera y finaliza cuando pasa a ser falsa.
Parece claro que el bucle Do presenta más dificultades de uso que el bucle For, por lo que éste es preferible siempre que lo que se pretenda ejecutar permita ser planteado de forma alternativa con una o con otra estructura; pero no es menos cierto que Do...Loop puede ser oportuno en determinadas circunstancias, como cuando queremos asegurar el cumplimiento de una condición y una forma determinada de funcionamiento del bucle, como en el uso de una clave de acceso por motivos de seguridad.

En cualquier caso es necesario tener mucho cuidado con cómo se planea el bucle ya que de hacerlo incorrectamente podemos generar un error de funcionamiento que derive en el bloqueo del programa. Y este peligro es mayor cuando usamos los bucles Do...Loop.

NOTA

(1) Queda claro en los ejemplos anteriores que de la inversión de la ejecución o no del bucle son responsables las instrucciones While vs. Until. De ellas hablaremos más abajo.

viernes, 21 de julio de 2023

OOo Basic. Estructuras

Bucle For Next

Junto con la bifurcación, la iteración constituye el segundo proceso básico de todo algoritmo. En resumen consiste en la repetición de un mismo procedimiento n-veces.



En esencia, un bucle consiste en la repetición de un procedimiento (un conjunto o bloque de sentencias) mientras se cumple una condición, y en su finalización una vez que se deja de cumplir dicha condición. 

El segundo tipo de bucle invierte el procedimiento: se repite la sentencia o el bloque de sentencias siempre que no se cumple la condiciones "x" y dejan de ejecutarse en el momento en que se cumplen.

En OOo Basic utilizamos dos estructuras para trabajar con bucles: For...Next y Do...Loop. En esta entrada trataremos el primero y habrá una segunda entrada para explicar el segundo.


La sintaxis de For...Next es la siguiente (lo que se sitúa entre corchetes es opcional):

For Variable = Inicio To (Variable) Fin [Step Salto]

 Bloque de código

[Exit For]

Next [Variable] 

Como puedes ver se utiliza una variable de control (normalmente identificada como contador por su función) que marca el inicio y el fin del bucle (Variable = Inicio To Fin) y también podemos indicar un salto ( o no, ya que este valor es opcional) que será útil si deseamos que la evolución del recorrido valor Inicio - valor Fin(nal) no sea lineal (+1). 

Una vez que se alcanza el valor Fin, entra en funcionamiento Next, dando por finalizado el ciclo. Mientras tanto (hasta ese momento) se ejecuta el bloque de código que se estableciera entre For y Next.

Al igual que Sept nos permite alterar el desarrollo de la secuencia, Exit For nos permite salir anticipadamente del bucle siempre que se cumpla una condición, lo que remite al uso de estructuras de bifurcación, dando lugar a estructuras complejas y mixtas.

Finalmente, el uso opcional de la identificación de variable tras Next (la misma que utilizamos en For como contador) es una buena práctica cuando se anidan dos bucles y cada uno tiene (obviamente) su propio contador: facilita delimitar ambos bucles, pero carece de valor cuando sólo desarrollamos un único bucle.

Ahora vamos a ejemplificar a continuación el uso simple de For...Next, que es la forma en que se utiliza esta estructura con mayor frecuencia. Para ello vamos a generar una tabla de multiplicar, ejemplo típico de este tipo de estructuras.

Sub TablaMultiplicar

Dim iNum As Integer, i As Integer

iNum = 5

For i = 0 To 10

MsgBox (iNum & " x " & i & " = " & iNum*i,64,"TABLA DE MULTIPLICAR DEL " & iNum)

Next

End Sub

Puedes mejorar este sencillo y poco atractivo script haciéndolo interactivo; para ello el valor iNum se establecerá mediante InputBox. También puedes transformarlo en un pequeño "juego" haciendo que sea el alumno quien deba indicar la solución, aunque en este caso te costará un poco más de trabajo, tendrás que crear una variable para contener el valor de la respuesta y el bloque de código será más complejo. En cualquier caso, lo importante y nuclear de qué es y cómo se construye un ciclo For...Next es lo expuesto en el ejemplo que tienes arriba expresado; el resto son "variaciones sobre el mismo tema".

lunes, 17 de julio de 2023

OOo Basic. Interface

InputBox

Aunque MsgBox() puede funcionar también como función como recurso para el input ([ver entrada]), es la función InputBox() el recurso especialmente pensado para este objetivo, definiéndose necesariamente como función, por lo que siempre se asocia a una variable, en este caso y en principio de tipo String.



InputBox permite al usuario interactuar con el script, aportando los datos que necesarios para (por ejemplo) personalizar el contenido del documento, así como para aportar la información necesaria para el correcto funcionamiento del script. Constituye, por ello, una forma sencilla de GUI en sentido estricto. Una interface sencilla y un tanto limitada, pero una forma básica de interface gráfica muy funcional.

Es además monótona ya que no presenta la variedad de opciones que tienen los controles de un formulario o de un cuadro de diálogo, pero lo compensa con la facilidad con que se implementa.

Lo de limitado es consecuencia de que todas las entradas son originariamente cadenas de caracteres (String) por lo que, en principio se debe asociar a una variable de tipo String. Pero dado que es posible realizar conversiones del tipo de variable mediante [las funciones que ya conocemos], podemos aplicar estas funciones previamente a InputBox()  para asociarlo a una variable no String.

La forma básica en la que se presenta InputBox()...

vNombre = InputBox("¿Cómo te llamas?")

... pasaría a ser para el caso de la edad (valor numérico)...

vEdad = CInt(InputBox("¿Cuántos años tienes?)) 

... para Dim vNombre As String y Dim vEdad As Integer.

Recuerda que las funciones de conversión en OOo Basic son las siguientes:

  • CStr() -> Conversión a string
  • CInt() -> Conversión a Integer
  • CVar() -> Conversión a Variant
  • CBool() -> Conversión a Boolean
La sintaxis completa de InputBox() es la siguiente...

InputBox (Prompt As String[, Title As String[, Default As String[, xpostwips As Integer, ypostwips As Integer]]]) As String

... aunque su uso más frecuente es más sencillo, omitiendo los parámetros de posicionamiento en pantalla, por ejemplo (1)

sNombre = InputBox("Dime tu nombre","NOMBRE DE USUARIO","Casimiro",6000,5000)

Primero asignamos a la variable sNombre (String) la respuesta dada (o confirmada) por el usuario. La sintaxis del InputBox() se describe como sigue:

  • Primer parámetro (Prompt) -> "Dime tu nombre", permite especificar la información o dato que se solicita al usuario.
  • Segundo parámetro (Title) -> "NOMBRE DE USUARIO", establece el título del InputBox().
  • A partir de aquí, el resto de los parámetros son opcionales
  • Tercer parámetro (Default) -> "Casimiro", establece una respuesta por defecto. Si se establece este parámetro opcional y el usuario no lo modifica, se considera que lo confirma. Este parámetro se usa para facilitar la entrada de datos cuando existe una respuesta predominante, pero también puede servir para ofrecer varias respuestas posibles y que sea el usuario quien elimine las que no corresponda.
  • Cuarto parámetro (xpostwips) -> 6000, posiciona el InputBox en el valor X 6000 de la pantalla (en pilxes)
  •  Quinto parámetro (ypostwips) -> 5000, posiciona el InputBox en el valor Y 5000 de la pantalla (en pilxes)

InputBox dispone de dos comandos (botones) invariables, Aceptar y Cancelar, el primero de ello seleccionado por defecto. Aceptar pasa el valor a la variable y Cancelar pasa una cadena vacía. En caso de pulsar Intro, el valor por defecto prevalece, por lo que equivale a pulsar Aceptar)(2).

sNombre = InputBox("Dime tu nombre","NOMBRE DE USUARIO","Casimiro",1200,1000)

print(sNombre) -> Devuelve Casimiro

Si lo que deseamos solicitar es un valor numérico (un Integer, por ejemplo), debemos utilizar la función de conversión CInt() aplicada bien a la variable string a la que asignamos el valor resultante de InputBox(), bien a la propia función, ya de que otro modo no se podrá operar con ese valor como numérico al ser éste se tipo String según la definición de InputBox() (InputBox() As String) (3)

Por si te interesa comprobar el funcionamiento de los script usados en esta entrada, en el IDE asociado a este documento tienes el código.

NOTAS

(1) Aunque lo más frecuente es omitir estos parámetros, puede ser interesante tenerlos en cuenta cuando ese posicionamiento sea de interés para el docap. Su principal inconveniente es que ese posicionamiento depende de la resolución del monitor y su tamaño, lo que afecta a la universalidad del código. Posiblemente esta sea la causa de su ausencia en la sintaxis de la función.

(2) Este comportamiento tiene su lógica (es el botón seleccionado por defecto) y sus ventajas: especialmente cuanto tenemos unos cuantos InputBox en el script, se agradece que la confirmación de los datos no dependa necesariamente de pulsar Aceptar; incluso ahorra unos cuanto posibles errores en la entrada de datos.

(3) En realidad el uso de la función de conversión CInt() sólo será imprescindible cuando insistimos en el tratamiento como String de las variables asociadas a InputBox(); en otro caso se realiza la conversión de forma implícita (y automática). No obstante, por claridad de escritura del algoritmo es conveniente respetar el procedimiento de conversión de tipología. Eso obliga a ser claros en lo que buscamos y evita posibles errores de funcionamiento del script. Este principio de actuación es válido para cualquier conversión de tipología de variables.