martes, 18 de enero de 2022

Office Scripts: Operadores

Tras repasar de manera introductoria los tipos de datos y las formas de declarar variables en Office Scripts para Excel, llega el momento de ver algunos de los operadores más frecuentes...
Sabiendo que habitualmente podemos trabajar con dos tipologías de operadores: UNARIA y BINARIA
Un operador binario requiere dos operandos, uno antes del operando y otro después del operador:
operando1 operador operando2
Por ejemplo, 21-13 o a*b

Mientras que un operador unario solo necesita un operando, antes o después del operador:
operador operando1 o operando1 operador
Por ejemplo, x++ o ++x.

Si navegas un poco por internet encontraras diferentes clasificaciones de estos operadores, y una lista larga de todos ellos... pero al final todo se resume en:
1-operadores de asignación: donde se asigna un valor a su operando izquierdo basándose en el valor de su operando derecho. Ejemplo Y = X
NombreForma…Significado
Asignaciónx = yx = y
Asignación de adiciónx += yx = x + y
Asignación de restax -= yx = x - y
Asignación de multiplicaciónx *= yx = x * y
Asignación de divisiónx /= yx = x / y
Asignación de residuox %= yx = x % y
Asignación de exponenciaciónx **= yx = x ** y

2-operadores de comparación: donde se comparan dos operadores, recuperando un verdadero o falso.
OperadorForma…Significado
Igual (==)x == yDevuelve true si los operandos son iguales.
No es igual (!=)x != yDevuelve true si los operandos no son iguales.
Estrictamente igual (===)x === yDevuelve true si los operandos son iguales y del mismo tipo.
Desigualdad estricta (!==)x !== yDevuelve true si los operandos son del mismo tipo pero no iguales, o son de diferente tipo.
Mayor que (>)x > yDevuelve true si el operando izquierdo es mayor que el operando derecho.
Mayor o igual que (>=)x >= yDevuelve true si el operando izquierdo es mayor o igual que el operando derecho.
Menor que (<)x < yDevuelve true si el operando izquierdo es menor que el operando derecho.
Menor o igual (<=)x <= yDevuelve true si el operando izquierdo es menor o igual que el operando derecho.

3-operadores aritméticos: que toma valores numéricos (ya sean literales o variables) como sus operandos y devuelve un solo valor numérico como resultado.
OperadorForma...Significado
Residuo (%)x % y // 20 % 3 = 2Operador binario. Devuelve el resto entero de dividir los dos operandos.
Incremento (++)x=3 // ++x = 4 Operador unario. Agrega uno a su operando. Si se usa como operador prefijo (++x), devuelve el valor de su operando después de agregar uno; si se usa como operador sufijo (x++), devuelve el valor de su operando antes de agregar uno.
Decremento (--)x=9 // --x = 8Operador unario. Resta uno de su operando. El valor de retorno es análogo al del operador de incremento.
Negación unaria (-)x=5 // -x = -5Operador unario. Devuelve la negación de su operando.
Positivo unario (+)x='13' // +x = 13Operador unario. Intenta convertir el operando en un número, si aún no lo es.
Operador de exponenciación (**)3 ** 3 = 27Calcula la base a la potencia de exponente, es decir, baseexponente

4-operadores lógicos: se utilizan normalmente con valores booleanos (true o false).
OperadorForma…Significado
AND Lógico (&&)expr1 && expr2Devuelve expr1 si se puede convertir a false; de lo contrario, devuelve expr2. Por lo tanto, cuando se usa con valores booleanos, && devuelve true si ambos operandos son true; de lo contrario, devuelve false.
OR lógico (||)expr1 || expr2Devuelve expr1 si se puede convertir a true; de lo contrario, devuelve expr2. Por lo tanto, cuando se usa con valores booleanos, || devuelve true si alguno de los operandos es true; si ambos son falsos, devuelve false.
NOT lógico (!)!exprDevuelve false si su único operando se puede convertir a true; de lo contrario, devuelve true.

5-operador de cadena: el operador de concatenación (+) concatena dos valores de cadena, devolviendo otra cadena que es la unión de los dos operandos dados.
OperadorForma…Significado
más (+)expr1 + expr2 // expr1 += expr2Concatena ambas expresiones

Por supuesto existen más categorías, pero he optado por detallar los principales o más habituales.

Algunos ejemplos de estos operadores...
function main(workbook: ExcelScript.Workbook)
{
  let v1: string ='1';
  let v2: number = 1;
  let txt3: string='Romero';
  let txt4='año ';
  let anyo=2022;
  let mes=1;
  let dia1=31;
  let dia2=10;
//
console.log(v1 == v2);
console.log(v1 === v2);
console.log(+v1 === v1);
console.log(dia2 % dia1);
console.log( txt4 += anyo);
}

Office Scripts: Operadores

El primer ejemplo v1 == v2 compara el '1' (texto) con 1 (número), retornando true, ya que el valor es el mismo.
Sin embargo v1 === v2 compara y verifica valor y tipo de dato, por lo que devuelve false.
Otro ejemplo curios es el operador de cadena +=, donde sobre la variable txt4 añadimos otra subcadena 'anyo', obteniendo ahora una cadena completa asociada a txt4...

NOTA FINAL: OJO con los operadores, ya que nos son iguales, ni en forma ni en comportamiento, a los de otros lenguajes (como VBA) en todos los casos!!!

jueves, 13 de enero de 2022

Office Scripts: Declaración de variables

En la entrada anterior del blog vimos cuáles eran los tipos de datos más frecuentes en nuestros Scripts... pero ¿qué formas existen de asignar a nuestras constantes y variables esos tipos de datos?.
Pues disponemos de tres formas de declarar variables. Que veremos de forma introductoria:
var: nos permite declarar una variable 'local' y 'global' dependiendo del contexto de ejecución, donde opcionalmente le asignaremos un valor.
let: declaramos una variable local con 'ámbito de bloque', e igual que var, opcionalmente asignamos un valor de inicio.
const: nombre de constante local de solo lectura y ámbito de bloque.
Como curiosidad, la sintaxis de un identificador de constante es la misma que la de cualquier identificador de variable: debe comenzar con una letra, un subrayado o un signo de dólar ($).
Como podemos entrever let es similar a var en muchos aspectos; y const incrementa las posibilidades de let evitando, además, la reasignación a una variable.
Es recomendable, en general, emplear 'let' y 'const' frente a 'var'.

Mencionar brevemente algo respecto al ámbito de las variables.
Cuando declaramos una variable fuera de cualquier función, se denomina variable global, ya que está disponible para cualquier otro código en el documento actual.
Por contra, cuando declaramos una variable dentro de una función, se llama variable local, porque solo está disponible dentro de esa función.

Veamos algunos ejemplos sencillos de declaración de variables:
function main(workbook: ExcelScript.Workbook)
{
  var a = 1313;
  var mensaje = "algo de texto";
  console.log(a + mensaje);
////
  let b = 1234;
  let texto = "algo más de texto";
  console.log(b + texto);
////
  const n=1;
  const nombre_completo = {nombre:'Ismael', apellido: "Romero"}; 
  console.log(nombre_completo.nombre + ' ' + nombre_completo.apellido);

}

Office Scripts: Declaración de variables


Como se observa todo depende de dónde declaremos nuestras variables para determinar su tipo (global o local) e incluso su ámbito.

martes, 11 de enero de 2022

Office Scripts: Tipos de datos

Un aspecto básico al programar en cualquier lenguaje es aplicar correctamente a constantes y/o variables el tipo de dato asociado a ésta... y por supuesto, Office Scripts no es la excepción.
Hoy repasaremos los distintos tipos de datos que nos podemos encontrar al programar con Office Script.

En la distinta documentación existente al respecto dividen los tipos de datos en dos grandes categorías:
i) primitivos,
ii) objetos.

Si bien nos centraremos en los tipos de datos primitivos, esto es, lo más esenciales que serían: Number, Boolean, String, Symbol, Void, Null y Undefined... además de los definidos por el usuario: enum.
Finalmente, para emplear en nuestra programación alguna de estas categorías deberemos emplear una clave de tipo de datos concreta: number, boolean, string, symbol, void, null y undefined respectivamente...

Por comentar los más frecuentes:
Tipo de datos boolean: el más simple... permite valores true y false.
Tipo de datos number: un número entero o un número con coma flotante.
Tipo de datos string: secuencia de caracteres que representan un valor de texto. NOTA. Se asigna valor entre comillas simples o dobles !!!.
Tipo de datos null: en minúscula... representa el valor vacío, sin dato.
Tipo de datos undefined: valores sin tipo de datos asignado.
Tipo de datos personalizado enum: empleado para asignar nombres, más sencillos de recordar, a los conjuntos de valores (numéricos o de texto).
Por comentar brevemente los objetos, diré que este tipo de dato se usa habitualmente para guardar una colección de datos definidos o entidades más complejas.

Un comentario general es que en Office Scripts, igual que en otros lenguajes, NO es necesario especificar el tipo de dato de una variable cuando la declaramos!!.
Otra ventaja es que los tipos de datos se convierten automáticamente según sea necesario durante la ejecución de nuestros Scripts, pasando si fuera necesario de un tipo de datos a otro.

Veamos en la práctica cómo definir y asignar tipos de datos a variables o constantes.
Por suerte no hay una sola manera ;-)
Una estructura o sintáxis general es:
let/var/const 'nombre variable': tipo de dato = valor dado a la variable
let/var/const 'nombre variable' = valor dado a la variable

Ejemplos:
function main(workbook: ExcelScript.Workbook)
{
  let texto: string = "Excel";
  let num: number = 1234;
  let t_f: boolean = true;
  let sin_dato: null = null;
  enum apps { Excel, Word, Access, Outlook };
  let w: apps = apps.Word;
///
// otra forma de trabajar, sin asignar tipos de datos
let texto2 = 'Excel';
let num2 = 1234;
let verdadero = true;
/// Conversiones...
  let y = num.toFixed(2);
  let t = texto.charAt(2);
  let p_i=parseInt('123.45',0);
  let p_f = parseFloat('123.45');
  let mas= +'3.14'+ +'3.14';

  console.log(num2 + 2);
  console.log(texto2 + 2);
  console.log(w + 2);
  // conversiones
  console.log(y);
  console.log(t);
  console.log(p_i);
  console.log(p_f);
  // más
  console.log(mas);
}

Office Scripts: Tipos de datos

Mencionar algunas funciones que nos permitirán tratar o pasar de un tipo de datos a otro:
Numero.toFixed(num_decimales): devuelve el valor numérico como un TEXTO, con las posiciones decimales indicadas.
Texto.CharAt(posción-en base cero): devuelve la posición indicada (en base cero), obviamente como un TEXTO
.parseInt: convierte un número almacenado como texto a número ENTERO!!.
.parseFloat: convierte un número almacenado como texto a número DECIMAL!!.
Uso del operador +: convierte un número almacenado como texto a número!!. (let mas= +'3.14'+ +'3.14';)

martes, 4 de enero de 2022

Office Scripts: IF ELSE y SWITCH Condicionales

En las entradas del blog previas hemos repasado como construir nuestros bucles (FOR o WHILE), lo que nos permite recorrer partes o elementos de nuestros objetos...
Eso está muy bien, pero sin aplicar condiciones que segmenten los valores recorridos, poco podremos hacer.
Y aquí es, entre otras muchas y distintas casuísticas, donde entran en juego los condicionales:
IF ELSE y SWITCH
.

La instrucción IF ELSE normalmente se emplea para verficiar ciertas condiciones... y en otros casos cuando necesitamos ejecutar otras rutinas cuando se den las condiciones especificadas.
La sintaxis de la sentencia de control sería, en su forma simple:
if (Condición_Prueba Lógica)
{
// nuestro código a procesar si cumple la condición
}

O bien en su forma más completa, donde indicamos la acción en caso de no cumplir la condición dada:
if (Condición_Prueba Lógica)
{
// nuestro código a procesar si cumple la condición
else
// nuestro código a procesar si NO cumple la condición
}

Veamos un ejemplo donde evaluaremos el valor de cada celda de un rango dado, verificando si el valor es mayor o menor a 18:
function main(workbook: ExcelScript.Workbook)
{
  let Hoja = workbook.getActiveWorksheet();
  let Edades = Hoja.getRange("A1:A10").getValues(); 
  let texto: string;
  
  Edades.forEach(edad => 
    {
      if (+edad < 18)
        texto = 'Menor de edad';
      else
        texto = 'Mayor de edad';

      console.log( texto );
    });
}

Office Scripts: IF ELSE y SWITCH Condicionales

Por supuesto podemos incorporar tantas respuestas 'else' como sean necesarias (sujetas a otras tantas condiciones)...:
if (condición1)
//código a procesar si cumple la condición1
else if(condición2)
//código a procesar si cumple la condición2
else if(condición3)
//código a procesar si cumple la condición
....
else
//código a procesar si NO cumple ninguna de las condiciones anteriores


La otra instrucción condicional es SWITCH CASE (equivalente al SELECT CASE de VBA), con sintaxis:
switch (expresión a evaluar) {
case case1:
statements1
[break;]
case case2:
statements2
[break;]
...
default
: default statements
[break;]
}

Un 'pequeño problema' (hasta donde he podido analizar) de SWITCH es que no admite operadores de comparación como < o > :'(
En estos casos mejor emplear IF ELSE
... o bien aplicar un truco 'booleano'.
Veamoslo en el siguiente ejemplo:
function main(workbook: ExcelScript.Workbook) {
  let Hoja = workbook.getActiveWorksheet();
  let Edades = Hoja.getRange("A1:A10").getValues() ;
  let texto: string;

  Edades.forEach(edad  => {
    switch (true) {
        case (edad < 18) : 
          texto ="Menor de edad";
          break; 
        case (edad < 30 ): 
          texto = "Joven";
          break;
        case (edad < 60): 
          texto = "Maduro" ;
          break;
        default :
          texto="Senior";
          break;     }
    console.log(texto);
  });
}

La lógica inicial hubiera sido:
Edades.forEach(edad => {
switch (edad) {
case ( < 18) :
texto ="Menor de edad";
break;
case ( < 30 ):
texto = "Joven";
break;
case ( < 60):
texto = "Maduro" ;
break;
default :
texto="Senior";
break; }
console.log(texto);
});

pero esta construcción genera error y no ejecuta correctamente el proceso.

Continuaremos con Office Scripts en siguientes artículos...

jueves, 30 de diciembre de 2021

Office Scripts: Bucles WHILE y DO ... WHILE

Vamos con la segunda entrada de sentencias de control fundamentales para trabajar con Office Scripts, y hablamos de los bucles WHILE y DO ... WHILE.
El primer bucle WHILE ejecuta un bloque de código mientras una condición determinada sea verdadera, i.e., se detendrá cuando la condición sea falsa.
Su sintáxis es sencilla:
while (Condición_Prueba Lógica)
{
// nuestro código a procesar
}


El segundo bucle DO ... WHILE ejecutará un bloque de código una vez, y luego repetirá el ciclo mientras la condición se mantenga verdadera.:
do
{
// nuestro código a procesar
} while (Condición_Prueba Lógica);


Y podrías decirme... no veo la diferencia.
Bueno, la diferencia entre uno y otro es que en el bucle DO...WHILE, el bloque a procesar siempre se ejecuta, al menos, una vez. Sin embargo con WHILE podría ocurrir que si el primer paso del bucle nis siquiera cumpliera la condición dada, NO se ejecutara nada...
Interesante...

Veamos un par de ejemplos...
En el primer ejemplo recorremos valores impares mientras que el valor devuelto sea inferior a 10:
function main(workbook: ExcelScript.Workbook) {
  // mostramos impares de 1 al 10
  // definimos variables
  let i = 1, limite = 10;

  // bucle while de 1 a 10
  while (i <= limite) 
  {
    console.log(i);
    i +=2;
  }
}

El bucle empieza en 1, y va incrementando el valor de 2 en 2, mientras/while el valor devuelto sea inferior a 10.
Office Scripts: Bucles WHILE y DO ... WHILE


Un segundo ejemplo con el bucle DO ... WHILE
function main(workbook: ExcelScript.Workbook)
{
  let i=1, limite=10;
  do 
  {
    console.log(i);
    i ++
  } while (i<=limite);
}

El bucle empieza en 1, y va incrementando el valor de 1 en 1, mientras el valor devuelto sea inferior a 10.

Veamos un ejemplo donde lanzamos un primer bucle WHILE y a continuación uno DO..WHILE similar (con igual condición) pero con resultados algo distintos...
 function main(workbook: ExcelScript.Workbook)
{
// diferencias entre WHILE y DO .. WHILE
let i=1, limite=4;
//1ro WHILE
while (i>2 && i<=limite)
  {
  console.log("bucle while " + i);
    i ++
  }

let j = 1, limite2 = 4;
//2do DO...WHILE
do 
{
  console.log("bucle do...while " + j);
  j++
} while (j > 2 && j<=limite2);
}

Al lanzar este Script vemos como solo se ejecuta el primer intento del bucle DO..WHILE!!.
El motivo, lo ya comentado.
WHILE escapa del bucle en el momento que no se cumple la condición; por tanto, en el ejemplo previo, al asignar i=1 como primer intento y NO cumplir con la condición dada (valor entre 2 y 4) sale del bucle...
Sin emabrgo, DO...WHILE si ejecuta el primer bloque... y solo después evalúa la condición, y al no cumplirla escapa del bucle.

En realidad este comportamiento es el habitual en todos los lenguajes de programación ;-)

Veamos un último ejemplo donde obtendremos un acumulado de celdas hasta cumplir que sobrepasamos el total de 250:
function main(workbook: ExcelScript.Workbook)
{
  let Acum =0;
  let fila =0; 
  let Hoja = workbook.getActiveWorksheet();
  let numero = Hoja.getCell(0,fila).getValues();
  
  do
  {
    Acum += +numero;
    fila ++;
    numero= (Hoja.getCell(fila,0).getValues());
  } while (Acum <= 250 && fila<=9) 

  // mostramos el acumulado
  console.log(`El acumulado es ${Acum}.`);
}

Office Scripts: Bucles WHILE y DO ... WHILE

Comprobamos como con nuestro bucle vamos recorriendo celdas de nuestra hoja, y acumulando valores, mientras que el total sea inferior a 250.