Ayuda: ¿Como puedo transponer las columnas de una tabla?

131 views
Skip to first unread message

Alejandro Garcia G.

unread,
Nov 23, 2016, 4:12:31 PM11/23/16
to Comunidad de Visual Foxpro en Español
Saludos, voy a tratar de explicarme, por un lado tengo una tabla con los clientes; id, numeros de credtios y otros datos En otra tengo los recaudos de cada cliente y su correspondiente numero de credito, tambien tiene el año y mes del pago.

Se necesita hacer una consulta que me muestre, id, numero de credito y los valores que me ha abonado, pero de manera horizontal. Me explico con la imgen para ver si comprenden mi dilema (no se como hacerlo y me piden no usar Pivots de Excel) ver imagen adjunta.


Ayuda.png

Jorge Bernardo Morales Hernandez

unread,
Nov 23, 2016, 4:50:10 PM11/23/16
to Comunidad de Visual Foxpro en Español
Select ;
   id, ;
   nombre, ;
   numero, ;
   Sum(Iif(Month(fecha) = 1, abono, 000000000.00)) As mes01, ;
   Sum(Iif(Month(fecha) = 2, abono, 000000000.00)) As mes02, ;
   Sum(Iif(Month(fecha) = 3, abono, 000000000.00)) As mes03, ;
   Sum(Iif(Month(fecha) = 4, abono, 000000000.00)) As mes04, ;
   Sum(Iif(Month(fecha) = 5, abono, 000000000.00)) As mes05, ;
   Sum(Iif(Month(fecha) = 6, abono, 000000000.00)) As mes06, ;
   Sum(Iif(Month(fecha) = 7, abono, 000000000.00)) As mes07, ;
   Sum(Iif(Month(fecha) = 8, abono, 000000000.00)) As mes08, ;
   Sum(Iif(Month(fecha) = 9, abono, 000000000.00)) As mes09, ;
   Sum(Iif(Month(fecha) = 10, abono, 000000000.00)) As mes10, ;
   Sum(Iif(Month(fecha) = 11, abono, 000000000.00)) As mes11, ;
   Sum(Iif(Month(fecha) = 12, abono, 000000000.00)) As mes12 ;
From nombredetabla ;
Group By id, numero ;
Order By id, numero ;
Where Between(fecha, fechainicio, fechafinal) ;
Into Cursor nombredecursor

fechainicio y fechafinal serían las variables que contienen el inicio y final del periódo que se desea consultar.

Espero haber sido de ayuda, saludos,

Fidel Charny

unread,
Nov 23, 2016, 4:54:41 PM11/23/16
to Comunidad de Visual Foxpro en Español
Mirá si te sirve
En el ejempo no se informan los períodos sin datos, pero eso se puede hacer construyendo una cadena de períodos.
LOCAL ARRAY aId(7),aNombre(7),aNUmero(7),aAbono(7),afecha(7)

aId
[1]=26876414
aId
[2]=26876414
aId
[3]=26876414
aId
[4]=49691995
aId
[5]=49691995
aId
[6]=49691995
aId
[7]=77175549

anombre
[1]=[asdfg]
anombre
[2]=[asdfg]
anombre
[3]=[asdfg]
anombre
[4]=[qwer]
anombre
[5]=[qwer]
anombre
[6]=[qwer]
anombre
[7]=[zxcv]

anumero
[1]=123
anumero
[2]=123
anumero
[3]=123
anumero
[4]=124
anumero
[5]=124
anumero
[6]=124
anumero
[7]=321


aabono
[1]=100
aabono
[2]=100
aabono
[3]=150
aabono
[4]=285
aabono
[5]=285
aabono
[6]=285
aabono
[7]=576

afecha
[1]=[2013-01]
afecha
[2]=[2013-02]
afecha
[3]=[2013-06]
afecha
[4]=[2014-01]
afecha
[5]=[2014-02]
afecha
[6]=[2014-03]
afecha
[7]=[2014-02]

CREATE CURSOR curDatos
("id" i,"nombre" c(40),"numero" i,"abono" n(12,2),"fecha" c(7))
FOR i
= 1 TO ALEN(aId)
    INSERT INTO curDatos
(id,nombre,numero,abono,fecha) ;
        VALUES
(aid[i],aNombre[i],anumero[i],aAbono[i],afecha[i])
NEXT

SELECT curDatos

SELECT distinct fecha FROM curDatos INTO ARRAY laFecha
lnTally
= _tally

LOCAL ARRAY laCursor
(3,4)
laCursor
[1,1]="Id"
laCursor
[1,2]="I"
laCursor
[1,3]=0
laCursor
[1,4]=0

laCursor
[2,1]="Nombre"
laCursor
[2,2]="C"
laCursor
[2,3]=40
laCursor
[2,4]=0

laCursor
[3,1]="Numero"
laCursor
[3,2]="I"
laCursor
[3,3]=0
laCursor
[3,4]=0

lnDim
= ALEN(laCursor,1)
FOR i
= 1 TO m.lnTally
    lnDim
= lnDim + 1
    DIMENSION laCursor
(lnDim,4)
    laCursor
[lnDim,1] = "P_"+CHRTRAN(laFecha[i,1],"-","")
    laCursor
[lnDim,2] = "N"
    laCursor
[lnDim,3] = 12
    laCursor
[lnDim,4]= 2
NEXT

CREATE CURSOR curPivot FROM ARRAY laCursor
SELECT curPivot
INDEX on id TAG id_tag

SELECT curDatos
SCAN
    lnId
= Id
    lcPer
= "P_"+TRIM(CHRTRAN(FECHA,"-",""))
    IF
!INDEXSEEK(m.lnId,.f.,"curPivot","id_tag")
        INSERT INTO curPivot
(id,nombre,numero) ;
            VALUES
(lnId,curDatos.Nombre,curDatos.numero)
    ENDIF
    SELECT curPivot
    INDEXSEEK
(m.lnId,.t.,"curPivot","id_tag")
    replace
(m.lcPer) WITH EVALUATE("curPivot."+m.lcPer) + curDatos.Abono
   
ENDSCAN
SELECT curPivot
GO top
BROWSE


USE IN curpivot
USE IN curDatos

Alejandro Garcia G.

unread,
Nov 23, 2016, 5:39:25 PM11/23/16
to Comunidad de Visual Foxpro en Español
Gracias a todos por sus respuestas, voy a ver como lo implemento/pruebo para saber con cual me va mejor.

Saludos.

Gregori Arjona Toledo

unread,
Nov 24, 2016, 4:15:52 AM11/24/16
to Comunidad de Visual Foxpro en Español
Creo que esta clase es lo que buscas, descarga y pruebala.


Yo la he utilizado y funciona perfectamente, lo bueno que tiene es que te servira para cualquier consulta que quieras hacer.

Saludos.

Alejandro Garcia G.

unread,
Nov 24, 2016, 9:45:14 AM11/24/16
to Comunidad de Visual Foxpro en Español
Retroalimento:

Analice, adapte y utilice la rutina dada por Fidel Charny para mis necesidades y me resulto lo que deseaba hacer, le estoy muy agradecido por el dato.

De todas formas voy a seguir mirando con la opción dada por Gregori a ver como me va, creo que una vez intente usarla pero no di cmo hacerlo. Gracias.

Gregori Arjona Toledo

unread,
Nov 24, 2016, 10:26:23 AM11/24/16
to Comunidad de Visual Foxpro en Español
Hola, es mu sencillo utilizarlo, si sabes como.

La unica cosa a tener en cuenta es como te has dereferir a los campos del cursor, en ves de utilizar su nombre has de utilizar su posicion numerica.

Por ejemplo:

IF USED("prueba")
 USE IN prueba
endif


CREATE TABLE prueba
(id n(10),nombre c(20),numero n(10),abono n(10),fecha c(7))


INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (26876414,"asdfg",123,100,"2013-2")
INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (26876414,"asdfg",123,100,"2013-6")
INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-1")
INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-2")
INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-3")
INSERT INTO prueba
(id,nombre,numero,abono,fecha) VALUES (77175549,"zxcv",321,576,"2014-2")


Select prueba


oXtab
= NewObject("FastXtab", "FastXtab.prg")


oXtab
.nPageField = 1 && id
oXtab
.nRowField = 2 && nombre
oXtab
.nColField = 5 && fecha
oXtab
.nDataField = 4 && abono
oXtab
.lCursorOnly = .t.
oXtab
.lDisplayNulls = .f.
oXtab
.lBrowseAfter = .t.




oXtab
.lCloseTable = .F.
If oXtab.RunXtab() = .T.
 
MessageBox("Corecto")
EndIf



Alejandro Garcia G.

unread,
Nov 24, 2016, 1:06:28 PM11/24/16
to Comunidad de Visual Foxpro en Español
Muy amable Gregori, voy a darle un vistazo ahora que tengo algo de tiempo....

Saludos.

Alejandro Garcia G.

unread,
Nov 24, 2016, 1:46:54 PM11/24/16
to Comunidad de Visual Foxpro en Español
Una pregunta, ya que tratando de hacer una prueba (que me da como lo envias), ¿como se hace para incluir ademas del id y nombre, el numero en el cursor?


oXtab.nPageField = 1 && id
oXtab
.nRowField = 2 && nombre


¿Como agreguego a demas de estas dos columnas, la columna numero?

Gregori Arjona Toledo

unread,
Nov 25, 2016, 2:50:18 AM11/25/16
to Comunidad de Visual Foxpro en Español
Buenas, directamente no puedes ya que la clase solo admite dos columnas, pero puedes probar lo siguiente relacionando el resultado obtenido con ta tabla inicial.

Saludos.

IF USED("prueba")
USE IN prueba
endif

CREATE TABLE prueba (id n(10),nombre c(20),numero n(10),abono n(10),fecha c(7))

INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (26876414,"asdfg",123,100,"2013-2")
INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (26876414,"asdfg",123,100,"2013-6")
INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-1")
INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-2")
INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (49691995,"qwer",124,285,"2014-3")
INSERT INTO prueba (id,nombre,numero,abono,fecha) VALUES (77175549,"zxcv",321,576,"2014-2")

Select prueba

oXtab = NewObject("FastXtab", "FastXtab.prg")

oXtab.nPageField = 1
oXtab.nRowField = 2
oXtab.nColField = 5
oXtab.nDataField = 4
oXtab.lCursorOnly = .t.
oXtab.lDisplayNulls = .f.
oXtab.lBrowseAfter = .f.


oXtab.lCloseTable = .F.
If oXtab.RunXtab() = .T.
SELECT a.numero,b.* ;
FROM  xtabquery b ;
left join prueba a ON(a.id=b.id) ;
into cursor result
SELECT result
brow
MessageBox("Corecto")
EndIf

Alejandro Garcia G.

unread,
Nov 25, 2016, 11:32:42 AM11/25/16
to Comunidad de Visual Foxpro en Español

Bien viejo, gracias por el dato. Voy a probar para armarlo con lo requiero y ver cual es mas fácil de manejar. El archvo finalizado sin incluir las columnas de los años, contiene cerca de 27 datos, pero me puede servir para hacer algo.

Gracias y saludos.
Reply all
Reply to author
Forward
0 new messages