Page 1 of 1

Pasar Registros de Dbf a Array.

Posted: Sat Nov 23, 2019 12:08 am
by remtec
Hola Amigos.

Nuevamente necesitando de su ayuda.

Derivado desde una pregunta anterior, no logro dar con la logica para pasar en orden datos de una Dbf a un Array.

Dentro de la DBF, tendre muchos profesionales, con la misma estructura de datos, solo variara los dias de la semana, que puede ir desde uno hasta toda la semana.

Donde Cod_Dia ---> 1=Lunes,2=Martes,3=Miercoles,4=Jueves,5=Viernes

BBF.
Cod_Pro - Cod_Dia - IHora_Ini - Hora_Fin

CONC 1 10:00 12:30
CONC 1 17:00 19:00
CONC 2 08:00 10:00
CONC 3 11:00 12:00
CONC 3 15:30 17:30
CONC 4 12:30 13:30
CONC 5 11:30 14:30
CONC 5 18:30 21:30

ARRAY Horario

Profe LUNES MARTES MIERCOLES JUEVES VIERNES

Estructura de Array

CONC 10:00 12:30 08:00 10:00 11:00 12:00 12:30 13:30 11:30 14:30
CONC 17:00 19:00 --------------- 05:30 17:30 -------------- 18:30 21:30


Existe alguna forma de Crear este Array?

En espera de su ayuda,les saluda muy atte.

Antonio

Re: Pasar Registros de Dbf a Array.

Posted: Sat Nov 23, 2019 4:52 am
by FranciscoA
Hola Antonio.
Mira si este codigo de ejemplo te sirve de guia.

Code: Select all

#include "fivewin.ch"
#include "xBrowse.ch"

//----------------------------------------------//
Function Main()
local oDlg, oBrw, aHoras:={}, aHorario, n, cCod, n1,n0

DbCreate("HORAS",{ {"COD_PRO",  "C", 4,0 } ,;
                   {"COD_DIA",  "N", 1,0 } ,;
                   {"HORA_INI", "C", 5,0 } ,;
                   {"HORA_FIN", "C", 5,0 } } )

DbUseArea(.t.,,"HORAS","HORAS",.f.)
DbSelectArea("HORAS")

  For n1 := 1 to 4
     cCod := strZero(n1,4)
     For n := 1 to 5
         dbAppend()
         Field->Cod_Pro  := cCod
         Field->Cod_Dia  := n
         Field->Hora_Ini := Time()
         Field->Hora_Fin := Time()
     Next
  Next

Index on field->Cod_Pro + str(Field->Cod_Dia,1) TO "UU" TEMPORARY ADDITIVE
DbGoTop()

While !Eof()
   cCod := Field->Cod_Pro
   aHorario := {,,,,,,,,,,}

   While Field->Cod_Pro == cCod
     aHorario[1] := field->Cod_Pro

     if field->Cod_Dia = 1             //Lunes
        aHorario[2] := Field->Hora_Ini 
        aHorario[3] := Field->Hora_Fin  
     elseif field->Cod_Dia = 2         //Martes
        aHorario[4] := Field->Hora_Ini  
        aHorario[5] := Field->Hora_Fin
     elseif field->Cod_Dia = 3         //Miercoles
        aHorario[6] := Field->Hora_Ini 
        aHorario[7] := Field->Hora_Fin
     elseif field->Cod_Dia = 4         //Jueves
        aHorario[8] := Field->Hora_Ini 
        aHorario[9] := Field->Hora_Fin
     elseif field->Cod_Dia = 5         //Viernes
        aHorario[10] := Field->Hora_Ini 
        aHorario[11] := Field->Hora_Fin
     endif
     dbskip()
   Enddo

     aadd(aHoras, aHorario)

Enddo
SysRefresh()

Horas->(DbCloseArea())

   DEFINE DIALOG oDlg TITLE "Prueba" SIZE 600,300 PIXEL
 
   @ 10, 10 XBROWSE oBrw SIZE -10,-10 PIXEL OF oDlg ;
   DATASOURCE aHoras ;
   COLUMNS 1,2,3,4,5,6,7,8,9,10,11 ;
   HEADERS "Profe", "Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza" ;
   CELL LINES NOBORDER

   oBrw:CreateFromCode()

   oBrw:SetGroupHeader( "LUNES",     2, 3) 
   oBrw:SetGroupHeader( "MARTES",    4, 5)  
   oBrw:SetGroupHeader( "MIERCOLES", 6, 7)
   oBrw:SetGroupHeader( "JUEVES",    8, 9)
   oBrw:SetGroupHeader( "VIERNES",  10,11)

  ACTIVATE DIALOG oDlg CENTERED
 
  Ferase("Horas.dbf")

return NIL
 
Saludos.

Re: Pasar Registros de Dbf a Array.

Posted: Sat Nov 23, 2019 3:58 pm
by remtec
Hola Francisco

Muchas gracias por tu ayuda.

Probé tu codigo, llego al mismo problema que he tenido.

Cuando un día tiene 2 o mas tramos de hora como el ejemplo de los datos, me crea una sola linea de datos y pierdo el primer registro de horas, solo guarda el ultimo.

Ejemplo: Martes 12:00 - 13:00 -----> 17:00 - 18:30

Resultado : Martes 17:00 - 18:30

Este problema es el que no he podido solucionar.

Muchos Saludos.
Antonio

Re: Pasar Registros de Dbf a Array.

Posted: Sat Nov 23, 2019 8:54 pm
by FranciscoA
ARRAY Horario
Profe LUNES MARTES MIERCOLES JUEVES VIERNES

Estructura de Array
CONC 10:00 12:30 08:00 10:00 11:00 12:00 12:30 13:30 11:30 14:30
CONC 17:00 19:00 --------------- 05:30 17:30 -------------- 18:30 21:30
Corrigeme si estoy equivocado.
Segun estos datos, implica que si un profesional labora varios tramos de tiempo el mismo dia, aparecerá tantas veces como tramos de tiempo laborados.
Por ejemplo, en esos datos, se indica que el prof CONC laboró de 10.00 a 12:30 y de 17.00 a 19:00 el dia Lunes?

Si es asi, intenta cambiando esta parte del codigo

Code: Select all

While !Eof()
   cCod := Field->Cod_Pro
   aHorario := {,,,,,,,,,,}

   While Field->Cod_Pro == cCod
     aHorario[1] := field->Cod_Pro

     if field->Cod_Dia = 1             //Lunes
        aHorario[2] := Field->Hora_Ini 
        aHorario[3] := Field->Hora_Fin  
     elseif field->Cod_Dia = 2         //Martes
        aHorario[4] := Field->Hora_Ini  
        aHorario[5] := Field->Hora_Fin
     elseif field->Cod_Dia = 3         //Miercoles
        aHorario[6] := Field->Hora_Ini 
        aHorario[7] := Field->Hora_Fin
     elseif field->Cod_Dia = 4         //Jueves
        aHorario[8] := Field->Hora_Ini 
        aHorario[9] := Field->Hora_Fin
     elseif field->Cod_Dia = 5         //Viernes
        aHorario[10] := Field->Hora_Ini 
        aHorario[11] := Field->Hora_Fin
     endif
     dbskip()
   Enddo
   aadd(aHoras, aHorario)
Enddo
SysRefresh()
por esta:

Code: Select all

While !Eof()
   aHorario := {,,,,,,,,,,}

     aHorario[1] := field->Cod_Pro

     if field->Cod_Dia = 1             //Lunes
        aHorario[2] := Field->Hora_Ini 
        aHorario[3] := Field->Hora_Fin  
     elseif field->Cod_Dia = 2         //Martes
        aHorario[4] := Field->Hora_Ini  
        aHorario[5] := Field->Hora_Fin
     elseif field->Cod_Dia = 3         //Miercoles
        aHorario[6] := Field->Hora_Ini 
        aHorario[7] := Field->Hora_Fin
     elseif field->Cod_Dia = 4         //Jueves
        aHorario[8] := Field->Hora_Ini 
        aHorario[9] := Field->Hora_Fin
     elseif field->Cod_Dia = 5         //Viernes
        aHorario[10] := Field->Hora_Ini 
        aHorario[11] := Field->Hora_Fin
     endif

     aadd(aHoras, aHorario)

     dbskip()
Enddo
SysRefresh()
 
Si no es asi, por favor sube una imagen de una hoja de excel con los datos finales que esperas obtener.
Saludos.

Re: Pasar Registros de Dbf a Array.

Posted: Sat Nov 23, 2019 9:52 pm
by remtec
Hola Francisco

Muchas gracias.

Exactamente lo que dices, un profesional en un dia, puede atender en 1, 2 o 3 tramos de horarios durante el dia.
Por ejemplo un profesional atiende el Lunes durante la mañana y luego volver en la tarde en otro horario, un dia a la semana o varios.

Esto es lo complejo que tengo, si Lunes atiende en 2 horarios, los debe mostrar y si Miercoles atiene solo en la mañana, ese dia tendra un solo horario.

EL Xbrowse debe mostrar la Linea con el Profesional, luego los dias de la semana, con los horarios que atiende, por lo que tendra una o 2 lineas, segun sea el caso, como podran haber profesionales que solo atiendan un solo horario.

No pude poner una imagen como pides, por no saber la forma de mostrar la imagen

Muchos Saludos

Antonio

Re: Pasar Registros de Dbf a Array.

Posted: Sun Nov 24, 2019 12:16 am
by FranciscoA
Antonio, prueba este codigo y nos dices.

Code: Select all

#include "fivewin.ch"
#include "xBrowse.ch"

//----------------------------------------------//
Function Main()
local oDlg, oBrw, aHoras:={}, aHorario, n, n1, cCod, cDia, cTur

DbCreate("HORAS",{ {"COD_PRO",  "C", 4,0 } ,;
                   {"COD_DIA",  "N", 1,0 } ,;
                   {"TURNO",    "N", 1,0 } ,;               //Nuevo campo... para identificar cada tramo horario.
                   {"HORA_INI", "C", 5,0 } ,;
                   {"HORA_FIN", "C", 5,0 } } )

DbUseArea(.t.,,"HORAS","HORAS",.f.)
DbSelectArea("HORAS")

  For n1 := 1 to 4
     cCod := strZero(n1,4)
     For n := 1 to 5
         dbAppend()
         Field->Cod_Pro  := cCod
         Field->Cod_Dia  := n
         Field->Turno    := 1
         Field->Hora_Ini := Time()
         Field->Hora_Fin := Time()
     Next
  Next

         dbAppend()
         Field->Cod_Pro  := "0001"
         Field->Cod_Dia  := 1
         Field->Turno    := 2
         Field->Hora_Ini := Time()
         Field->Hora_Fin := Time()
         dbAppend()
         Field->Cod_Pro  := "0001"
         Field->Cod_Dia  := 3
         Field->Turno    := 2
         Field->Hora_Ini := Time()
         Field->Hora_Fin := Time()
         dbAppend()
         Field->Cod_Pro  := "0003"
         Field->Cod_Dia  := 2
         Field->Turno    := 2
         Field->Hora_Ini := Time()
         Field->Hora_Fin := Time()


Index on field->Cod_Pro + Str(Field->Turno,1) + str(Field->Cod_Dia,1)  TO "UU" TEMPORARY ADDITIVE

DbGoTop()

While !Eof()
   cCod := Field->Cod_Pro
   cTur := Str(Field->Turno,1)   

   aHorario := {,,,,,,,,,,}

   While field->Cod_Pro + Str(Field->Turno,1) = cCod + cTur
      aHorario[1] := field->Cod_Pro
      if field->Cod_Dia = 1             //Lunes
         aHorario[2] := Field->Hora_Ini 
         aHorario[3] := Field->Hora_Fin  
      elseif field->Cod_Dia = 2         //Martes
         aHorario[4] := Field->Hora_Ini  
         aHorario[5] := Field->Hora_Fin
      elseif field->Cod_Dia = 3         //Miercoles
         aHorario[6] := Field->Hora_Ini 
         aHorario[7] := Field->Hora_Fin
      elseif field->Cod_Dia = 4         //Jueves
         aHorario[8] := Field->Hora_Ini 
         aHorario[9] := Field->Hora_Fin
      elseif field->Cod_Dia = 5         //Viernes
         aHorario[10] := Field->Hora_Ini 
         aHorario[11] := Field->Hora_Fin
      endif
      dbskip()
    
   Enddo

   aadd(aHoras, aHorario)
Enddo
SysRefresh()

Horas->(DbCloseArea())

   DEFINE DIALOG oDlg TITLE "Prueba" SIZE 600,300 PIXEL
 
   @ 10, 10 XBROWSE oBrw SIZE -10,-10 PIXEL OF oDlg ;
   DATASOURCE aHoras ;
   COLUMNS 1,2,3,4,5,6,7,8,9,10,11 ;
   HEADERS "Profe", "Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza","Inicia", "Finaliza" ;
   CELL LINES NOBORDER

   oBrw:CreateFromCode()

   oBrw:SetGroupHeader( "LUNES",     2, 3) 
   oBrw:SetGroupHeader( "MARTES",    4, 5)  
   oBrw:SetGroupHeader( "MIERCOLES", 6, 7)
   oBrw:SetGroupHeader( "JUEVES",    8, 9)
   oBrw:SetGroupHeader( "VIERNES",  10,11)

  ACTIVATE DIALOG oDlg CENTERED
 
  Ferase("Horas.dbf")

return NIL
 
 
Saludos.

Re: Pasar Registros de Dbf a Array.

Posted: Sun Nov 24, 2019 2:20 pm
by nageswaragunupudi

Code: Select all

#include "fivewin.ch"

REQUEST DBFCDX

field COD_PRO, COD_DIA, HORA_INI, HORA_FIN

//----------------------------------------------------------------------------//

function Main()

   local aTemp := { {}, {}, {}, {}, {} }
   local aData, i, j

   CreateTestDBF()
   XBROWSER "REMTEC1.DBF" // View DBF

   USE REMTEC1 NEW SHARED VIA "DBFCDX" READONLY
   SET FILTER TO COD_PRO = "CONC"
   GO TOP

   do while !Eof()
      AAdd( aTemp[ COD_DIA ], { HORA_INI, HORA_FIN } )
      SKIP
   enddo
   aTemp := ArrTranspose( aTemp )
   aData    := Array( Len( aTemp ) )
   for i := 1 to Len( aTemp )
      aData[ i ]  := { "CONC" }
      AEval( aTemp[ i ], { |a| If( a == nil, ( AAdd( aData[ i ], Space( 5 ) ), AAdd( aData[ i ], Space( 5 ) ) ), ;
                                             ( AAdd( aData[ i ], a[ 1 ] ), AAdd( aData[ i ], a[ 2 ] ) ) ) } )
   next

   XBROWSER aData TITLE "ARRAY" SETUP ( ;
      oBrw:cHeaders := { "PRO", "Ini", "Fin", "Ini", "Fin", "Ini", "Fin", "Ini", "Fin", "Ini", "Fin" }, ;
      oBrw:SetGroupHeader( "Lunes",    2, 3 ), ;
      oBrw:SetGroupHeader( "Martes",   4, 5 ), ;
      oBrw:SetGroupHeader( "Miercoles",6, 7 ), ;
      oBrw:SetGroupHeader( "Jueves",   8, 9 ), ;
      oBrw:SetGroupHeader( "Viernes", 10,11 )  ;
      )

return nil

//----------------------------------------------------------------------------//

static function CreateTestDBF()

   local aStruct  := ;
      {  {  "COD_PRO",  "C",  4, 0 } ;
      ,  {  "COD_DIA",  "N",  1, 0 } ;
      ,  {  "HORA_INI", "C",  5, 0 } ;
      ,  {  "HORA_FIN", "C",  5, 0 } ;
      }

   local aData := ;
      { { "CONC",  1, "10:00", "12:30" } ;
      , { "CONC",  1, "17:00", "19:00" } ;
      , { "CONC",  2, "08:00", "10:00" } ;
      , { "CONC",  3, "11:00", "12:00" } ;
      , { "CONC",  3, "15:30", "17:30" } ;
      , { "CONC",  4, "12:30", "13:30" } ;
      , { "CONC",  5, "11:30", "14:30" } ;
      , { "CONC",  5, "18:30", "21:30" } ;
      }

   DBCREATE( "REMTEC1", aStruct, "DBFCDX", .T., "RM" )
   FW_ArrayToDBF( aData )
   CLOSE RM

return nil

//----------------------------------------------------------------------------//

 
Original DBF
Image

Result Array:
Image

Re: Pasar Registros de Dbf a Array.

Posted: Sun Nov 24, 2019 5:26 pm
by remtec
Hola Francisco y Regards.

Muy agradecido por sus ayudas, y tiempo dedicado.

He probado ambos codigos.

Lo de Francisco Funciona Perfecto.

Pero en el codigo de Regards, me Acabo de dar cuenta que tiene un filtro para un solo profesional, debo agregar que tendre una lista de profesionales y cada uno con una definicion de hrs de atencion por dia.

Reitero mis agradecimiento por la bondad entregada.

Muchos Saludos

Antonio.