Skip to content

Google Sheets y Apps Scripts

ArrayFormula

Para combinar múltiples condiciones en un IF o IFS, AND/OR no funcionan bien.

En vez de AND/OR se puede "multiplicar":

=ARRAYFORMULA(IFS(FILA(M:M)=1,"Estado", (L:L="Aprobado")*(K:K="PRESENTE")*(M:M="APROBADO"), 1, VERDADERO, 0))

Cast y Melt

Hay funciones hechas y publicadas en el GitHub de rgertenbach.

Para mis usos, fue un poco lenta, y me hice una más rápida (pero que hace menos cosas y no es tan fácil de usar). Hay dos versiones, una para castear variables numéricas y otra para strings.

La parte "difícil" de usar es que la funcion toma como argumentos cosas como SORT(UNIQUE(A2:A)).

Cast para números

=castearNota(filter(B2:J,B2:B<>""), 1, sort(unique(filter(B2:B,B2:B<>""))), 5, sort(unique(filter(F2:F,F2:F<>""))), 9)

function castearNota(values, id_col, unique_ids, value_col, unique_values, return_col){
  var sheet = SpreadsheetApp.getActiveSheet();
  //var values = sheet.getRange(rango).getValues(); // Retrieve values "A1:D4" Returns a two-dimensional array of values, indexed by row, then by column.

  var active_cell = sheet.getActiveCell()
  var range = sheet.getRange(active_cell.getRow(), active_cell.getColumn(), unique_ids.length, unique_values.length + 1)
  var active_range = range.getValues()

  var result = []

  var empty = []
  for(var i = 0; i <= unique_values.length; i++){
    empty.push(0)
  }

  var values_dict = {};
  for(var i = 0; i < unique_values.length; i++){
    //  0,   1,   2
    //  TP1, TP2, TP3
    values_dict[unique_values[i]] = i;
  }

  var ids_dict = {};
  for(var i = 0; i < unique_ids.length; i++){
    //  0,   1,   2
    var dni = unique_ids[i]
    ids_dict[dni] = i

    active_range[i] = empty.slice(0);
  }

  for(var i = 0; i < values.length; i++){
    var row = values[i];
    var dni = row[id_col -1];
    var tp = row[value_col -1];
    var nota = row[return_col -1];

    var dni_row = ids_dict[dni]
    active_range[dni_row][0] = dni * 1

    var tp_col = values_dict[tp] + 1
    active_range[dni_row][tp_col] = nota * 1

  }

  return(active_range)
}

Cast para strings

=castearString(filter(B2:K,B2:B<>""), 1, sort(unique(filter(B2:B,B2:B<>""))), 5, sort(unique(filter(F2:F,F2:F<>""))), 10, "Ausente")

function castearString(values, id_col, unique_ids, value_col, unique_values, return_col, stringMalo){
  var sheet = SpreadsheetApp.getActiveSheet();
  //var values = sheet.getRange(rango).getValues(); // Retrieve values "A1:D4" Returns a two-dimensional array of values, indexed by row, then by column.

  var active_cell = sheet.getActiveCell()
  var range = sheet.getRange(active_cell.getRow(), active_cell.getColumn(), unique_ids.length, unique_values.length + 1)
  var active_range = range.getValues()

  var result = []

  var empty = []
  for(var i = 0; i <= unique_values.length; i++){
    empty.push(stringMalo)
  }

  var values_dict = {};
  for(var i = 0; i < unique_values.length; i++){
    //  0,   1,   2
    //  TP1, TP2, TP3
    values_dict[unique_values[i]] = i;
  }

  var ids_dict = {};
  for(var i = 0; i < unique_ids.length; i++){
    //  0,   1,   2
    var dni = unique_ids[i]
    ids_dict[dni] = i

    active_range[i] = empty.slice(0);
  }

  for(var i = 0; i < values.length; i++){
    var row = values[i];
    var dni = row[id_col -1];
    var tp = row[value_col -1];
    var nota = row[return_col -1];

    var dni_row = ids_dict[dni]
    active_range[dni_row][0] = dni * 1

    var tp_col = values_dict[tp] + 1
    active_range[dni_row][tp_col] = nota + ""

  }

  return(active_range)
}