﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	severity	resolution	keywords	cc
1171	TableColumns()	Javier Gallardo	Víctor de Buen Remiro	"La función ahora permite más de tres campos por fila.


{{{
#!java
//////////////////////////////////////////////////////////////////////////////
Set TableColumns(Anything qry_OR_cto){
//////////////////////////////////////////////////////////////////////////////
  Real enOtroCaso = 1;

  Text qry_OR_cto.gram = Grammar(qry_OR_cto);

  Set ctoDatos = Case(
  // ------------
    qry_OR_cto.gram==""Text"", 
    DBTable(qry_OR_cto),
  // ------------
    qry_OR_cto.gram==""Set"", 
    qry_OR_cto,
  // ------------
    enOtroCaso,
  {
    WriteLn(""<E>ERROR TableColumns: gramática de qry_OR_cto, '""+
            qry_OR_cto.gram +
            ""' no contemplada</E>"");
    Empty
  });

  // ---------------------------
  Text toText(Anything algo){
  // ---------------------------
     """"<< algo
  };
  // ---------------------------

  // ---------------------------
  Real posicion(Set cto, Text elto){
  // ---------------------------
    Real card = Card(cto);
    Real cont = Copy(1);
    Text elto_i = Copy(cto[cont]);
    Real condicion = And(elto_i!=elto, LT(cont, card));

    Real While(condicion,
    {
      Real (cont := cont+1);
      Text (elto_i := Copy(cto[cont]));
      Real (condicion := And(elto_i!=elto, LT(cont, card)));
      1
    });
    If(elto_i==elto, Copy(cont), 0)
  };
  // ---------------------------

  Real card = Card(ctoDatos);

  Set indices = {
    Set c01 = Extract(ctoDatos, 2);
    Set c02 = For(1, card, Text(Real i){
       toText(c01[i][1])
    });
    Set c03 = Unique(c02);
    Sort(c03, Real(Text t1, Text t2){ Compare(t1, t2) })
  };

  Set prefijos = {
    Set c01 = Extract(ctoDatos, 1);
    Set c02 = For(1, card, Text(Real i){
       toText(c01[i][1])
    });
    Set c03 = Unique(c02);
    Sort(c03, Real(Text t1, Text t2){ Compare(t1, t2) })
  };

  Set prefijos_indices = For(1, Card(indices), Set(Real i){
    Set cto = For(1, Card(prefijos), Text(Real j){ Copy("""") });
    cto
  });

  Set EvalSet(ctoDatos, Real(Set reg){
    Text reg_pre = toText(reg[1]);
    Text reg_ind = toText(reg[2]);
    Text reg_dat = {
      Set subCto = ExtractByIndex(reg, Range(3, Card(reg), 1));
      If(Eq(Card(subCto), 1),
        toText(subCto[1]),
        toText(subCto)
      )
    };

    Real pos_i = posicion(indices, reg_ind);
    Real pos_j = posicion(prefijos, reg_pre);
    Text elto  = reg_dat;
    Text (prefijos_indices[pos_i][pos_j] := Copy(elto));

    1
  });

  Set ctoIndices = EvalSet(indices, Set(Text t){ SetOfText(t) });

  Set ctoPrefijos = SetOfSet(SetOfText(""indices / prefijos"") << prefijos);

   ctoPrefijos << (ctoIndices | prefijos_indices)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(""
Dada una consulta que devuelve al menos tres campos, crea un conjunto-tabla
donde las columnas serán el primer campo (prefijo), y las filas serán el 
segundo (índice).
La primera fila del Set resultante tendrá los nombres de los prefijos.
La primera columna del Set resultante tendrá los nombres de los índices.
¡¡¡ TODO lo que se devuelve dentro del conjunto es de tipo Text !!!, por lo 
tanto, el orden que se sigue tanto en los prefijos como en los índices es el 
lexicográfico.
Las máscaras utilizadas en FormatReal() y en FormatDate() son las que usa Tol 
por defecto.
"", TableColumns);
//////////////////////////////////////////////////////////////////////////////
}}}"	enhancement	closed	lowest	Mantainance	Various	head	trivial	fixed		
