Página 1 de 1

Copy to na Memoria, é possível?

Enviado: 26 Jul 2021 18:22
por Adalberto
Amigos e professores, boa tarde.

Mais uma vez venho pedir ajuda.

É possível fazer com que o comando COPY TO copie o conteúdo, ou parte do conteúdo, de um .DBF para um arquivo na memória?

se possível ... por favor me diga qual o comando apropriado ou as cláusulas necessárias.

Muito grato a cada um de vocês, desejo-lhes muita prosperidade.

Adalberto

Copy to na Memoria, é possível?

Enviado: 26 Jul 2021 20:32
por Itamar M. Lins Jr.
Olá!
Onde o arquivo está não importa.
Se na memória ou HD/SSD/TCP/FTP...
Como vc acessa o arquivo na memória ?
Qual programa foi que jogou/criou esse arquivo na memória ?

Saudações,
Itamar M. Lins Jr.

Copy to na Memoria, é possível?

Enviado: 26 Jul 2021 20:44
por Itamar M. Lins Jr.
Olá!
Criando um DBF na memoria.

Código: Selecionar todos

REQUEST HB_MEMIO

PROCEDURE Main()

   LOCAL tmp

   dbCreate( "mem:test", { { "F1", "N", 9, 0 } }, , .T., "memarea" )
   FOR tmp := 1 TO 1000
      dbAppend()
      FIELD->F1 := hb_Random() * 1000000
   NEXT
   INDEX ON FIELD->F1 TAG f1
   dbEval( {|| QOut( FIELD->F1 ) } )
   dbCloseArea()
   dbDrop( "mem:test" )  /* Free memory resource */

   RETURN
Agora, se o arquivo já está lá na memória e não foi a sua aplicação que criou(XLS/MDB...), vai precisar conversar com ele via ADO por exemplo.

Saudações,
Itamar M. Lins Jr.

Copy to na Memoria, é possível?

Enviado: 27 Jul 2021 02:23
por alxsts
Olá!
Adalberto escreveu:É possível fazer com que o comando COPY TO copie o conteúdo, ou parte do conteúdo, de um .DBF para um arquivo na memória?
Usando apenas recursos do Harbour, não é possível fazer isto com COPY TO.
COPY TO <targetFile> ;
[FIELDS <fieldNames,...> ;]
[<Scope> ; ]
[WHILE <lWhileCondition> ;]
[FOR <lForCondition> ;]
[VIA <rddName>]
[SDF | DELIMITED [WITH BLANK | TAB | PIPE | <xDelimiter> ]

TO <targetFile>
This is the name of the target file as a literal character string or a character expression enclosed in parentheses. When the file name is specified without a file extension, .dbf is assumed as default extension, unless the SDF or DELIMITED option is specified. In this case, the default file extension is .txt.

The file in the current work area can be opened in SHARED mode. COPY TO creates the target file and opens it in EXCLUSIVE mode while data is being exported.
COPY TO cria o arquivo destino no sistema de arquivos. Não cria em memória. A única forma de fazer COPY TO copiar para a memória, seria criar um drive em memória. Veja How to Set up and Use a Ram Drive in Windows 10

É possível fazer a cópia criando uma rotina escrita em Harbour, sem utilizar COPY TO.
Basta:
1 - criar a tabela em memória, com o layout desejado, conforme o exemplo acima, do Itamar
2 - abrir a tua tabela destino (em memória)
3 - abrir a tua tabela origem (em disco)
4 - ler a tabela origem, selecionando os registros e colunas desejados
5 - fazer append na tabela destino, gravando os registros e colunas desejados

Copy to na Memoria, é possível?

Enviado: 27 Jul 2021 09:25
por Adalberto
Bom dia a todos, amigos e professores.

Meu agradecimento especial a Itamar e alxsts pela ajuda.

Alxsts, como você me disse, así é que estou trabalhando, mas pensei em acelerar um pouco com o comando COPY TO.

Eu continuo a agradecer sua ajuda.

Deus os abençoe e dê prosperidade.

Abraços Adalberto

Copy to na Memoria, é possível?

Enviado: 27 Jul 2021 10:32
por Itamar M. Lins Jr.
Olá!
Quando eu migro uma estrutura de DBF para outra, por exemplo quando eu crio mais um campo na estrutura do DBF, eu uso esse recurso para PUXAR os dados.

Código: Selecionar todos

   MyAppendFrom("old","new",cTempDBF) 

***************************************
FUNCTION MyAppendFrom(cAO,cAD,cTempDBF) //cAO = Alias Origem, cAD Alias Destino
***************************************
*
*
LOCAL nCount, nCampos := (cAD)->(FCount()), x:=1, nRec:=1, nTotRec := (cAO)->(LastRec())

oBar := HProgressBar():NewBox("Importando " + cTempDBF + ", " + (cAO)->(Dbf()) + ": "+lTrim(str(1,9))+" De "+lTrim(Str(nTotRec,9))+" Registro(s)" ,,0,400,, nTotRec, nTotRec,,.f. )

DO WHILE (cAO)->(!Eof())
   (cAD)->(dbAppend())

   FOR nCount := 1 TO nCampos
      cField := (cAD)->(Field(nCount))      
      IF ( (cAO)->(fieldpos( cField )) != 0 )
         (cAD)->&cField := (cAO)->&cField
      ENDIF
   NEXT
   (cAO)->(dbSkip())
   iif(x++==100,(nRec+=x,x:=1,ShowGrafico(oBar,nRec,nTotRec)),.t.)
EndDO

oBar : Close()   
FechaDb(cAD)
FechaDb(cAO)

RETURN .T.
Saudações,
Itamar M. Lins Jr.

Copy to na Memoria, é possível?

Enviado: 28 Jul 2021 09:17
por Adalberto
Itamar, bom dia, Deus te abençoe muito.

Agradeço a função MyAppendFrom que você compartilhou.

Tenho uma função que faz esse trabalho, mas a sua função é mais prática.
Vou ver a melhor maneira de fazer as mudanças que preciso.

Mais uma vez agradeço sua boa vontade.

Um grande abraço, Adalberto.

Copy to na Memoria, é possível?

Enviado: 31 Jul 2021 17:15
por alxsts
Olá!

Revisitando este tópico:

Testei o comando COPY TO copiando para um DBF em memória. Ele até cria o arquivo destino mas não copia os registros.

Criei um exemplo usando as funções hb_vf*, sugeridas no tópico mapeamento, e verifiquei que estas funções tem suporte para DBF em memória. Funciona perfeitamente no Harbour que usei (Harbour 3.2.0dev (r1612161005) ) Nightly.
Capturar.JPG
Capturar.JPG (18.85 KiB) Exibido 1640 vezes

Código: Selecionar todos

/*
   Compilação: hbmk2 teste hbmemio.hbc -w3 -es2
   Alexandre Santos - Fórum Clipper On Line
*/
REQUEST HB_MEMIO
REQUEST DBFCDX

#define   lNewArea   .T.
#define   lShared    .T.

PROCEDURE Main()
  
   LOCAL tmp, oErr, cColor
 
   cls

   BEGIN SEQUENCE

      // seleciona o RDD "DBFCDX"
      RddSetDefault( "DBFCDX" )
      // abertura automática do índice CDX
      SET AUTOPEN ON
      // abertura automática da tag 1
      SET AUTORDER TO 1

      cColor := Setcolor( "B/W/W+/B" )

      // Cria um DBF no disco e o deixa aberto...
      dbCreate( "test", { { "F1", "N", 9, 0 } }, , .T., "test" )

      // popula com 1000 registros...
      FOR tmp := 1 TO 1000
         dbAppend()
         FIELD->F1 := hb_Random() * 1000000
      NEXT

      // cria um índice...
      OrdCreate( "Test", "F1", "F1"  )
   
      // fecha o arquivo do disco...
      dbCloseArea()
   
      // copia o DBF e o CDX para a memória...
      hb_vfCopyFile( "test.dbf", "mem:test.dbf" )
      hb_vfCopyFile( "test.cdx", "mem:test.cdx" )

      // deleta o DBF e o CDX do disco...
      hb_vfErase( "test.dbf" )
      hb_vfErase( "test.cdx" )

      // abre o DBF e o CDX na memória...
      DbUseArea( lNewArea, "DBFCDX" , "mem:test", "Test", lShared )

      DbGoTop()

      // exibe os registros...
      Browse( 05, 25, 20, 55 )

      // fecha  os arquivos da memória
      dbCloseArea()
      
      // deleta os arquivos da memória - Free memory resource
      dbDrop( "mem:test.dbf" )
      dbDrop( "mem:test.cdx" )

      Setcolor( cColor ) ; SetPos( 0, 0 ) ; Scroll( 0, 0, MaxRow(), MaxCol() )
   RECOVER USING oErr 
      hb_Alert(  { PadC( "*** Uma exceção não tratada foi encontrada ***", 50 ), ;
      Replicate( "_", 50 ), "", ;
      PadR( " Erro       : " + oErr:description, 50 ), ;
      PadR( " Operação   : " + oErr:operation, 50 ), ;
      PadR( " Subsistema : " + oErr:subsystem, 50 ), ;
      PadR( " Subcódigo  : " + LTrim( Str( oErr:subcode ) ), 50 ), ;
      PadR( " Programa   : " + procfile(), 50 ), ;
      PadR( " Procedure  : " + procName(), 50 ), ;
      PadR( " Linha      : " + LTrim( Str( ProcLine() ) ), 50 ), "", "", ;
      Replicate( "_", 50 ), "" },, "W+/N" )
   END SEQUENCE
RETURN