modificar nome de campo em dbf
Moderador: Moderadores
-
Glauco Cruz Costa
- Usuário Nível 3

- Mensagens: 102
- Registrado em: 15 Dez 2005 22:02
- Localização: Brasília/DF
- Contato:
modificar nome de campo em dbf
Procurei muito, mas não encontrei.
Alguém sabe de algum comando ou função que altera o nome de um campo em um dbf?
Exemplo: Meu dbf tem os campos PRONTUARIO, CLINICA, MEDICO, DATA, LOCAL, COD
Gostaria de mudar o nome do campo COD para ATIVIDADE, mas tem que ser na execução.
É que eu quero mandar os campos para um outro dbf. E neste outro dbf o campo COD se chama ATIVIDADE.
E eu to apanhando muito pra passar. De repente se eu alterasse o campo durante o processo, facilitaria. Depois, eu renomearia novamente.
Nossa!!!! Eu ainda sou iniciante nisso. O pior é que desde 1997 eu ainda sou iniciante em Clipper.
Mas, ainda bem que existe esse fórum.
Alguém sabe de algum comando ou função que altera o nome de um campo em um dbf?
Exemplo: Meu dbf tem os campos PRONTUARIO, CLINICA, MEDICO, DATA, LOCAL, COD
Gostaria de mudar o nome do campo COD para ATIVIDADE, mas tem que ser na execução.
É que eu quero mandar os campos para um outro dbf. E neste outro dbf o campo COD se chama ATIVIDADE.
E eu to apanhando muito pra passar. De repente se eu alterasse o campo durante o processo, facilitaria. Depois, eu renomearia novamente.
Nossa!!!! Eu ainda sou iniciante nisso. O pior é que desde 1997 eu ainda sou iniciante em Clipper.
Mas, ainda bem que existe esse fórum.
-
alxsts
- Colaborador

- Mensagens: 3092
- Registrado em: 12 Ago 2008 15:50
- Localização: São Paulo-SP-Brasil
Re: modificar nome de campo em dbf
Olá Glauco,
ficou meio nebulosa a tua intenção.
Não existe nenhum comando ou função do próprio Clipper que altere a estrutura em tempo de execução. Se voce precisar fazer isto, terá que montar a estrutura desejada num array e criar uma tabela nova, utilizando este array criado, via função DBCreate().
Parece que voce já tem as duas tabelas, total de campos e tipos de campos iguais, sendo que na segunda o campo COD é chamado de ATIVIDADE. Neste caso, não vejo necessidade de alteração de estrutura. É só ler a primeira tabela e gravar os dados na segunda.
De qualquer forma, preparei um exemplo que contempla os dois cenários. Segue abaixo:
Por favor, poste informando se serviu ou se tiver dúvidas adicionais.
[]´s
AlxSts
ficou meio nebulosa a tua intenção.
Não existe nenhum comando ou função do próprio Clipper que altere a estrutura em tempo de execução. Se voce precisar fazer isto, terá que montar a estrutura desejada num array e criar uma tabela nova, utilizando este array criado, via função DBCreate().
Parece que voce já tem as duas tabelas, total de campos e tipos de campos iguais, sendo que na segunda o campo COD é chamado de ATIVIDADE. Neste caso, não vejo necessidade de alteração de estrutura. É só ler a primeira tabela e gravar os dados na segunda.
De qualquer forma, preparei um exemplo que contempla os dois cenários. Segue abaixo:
Código: Selecionar todos
// PRONTUARIO, CLINICA, MEDICO, DATA, LOCAL, COD
#Include "Dbstruct.ch"
FUNCTION AltStru()
LOCAL aStru, nPos
BEGIN SEQUENCE
// Abrir o Arquivo com a estrutura original
Use "Tabela1" SHARED New
// obtem a estrutura da Tabela1
aStru := Tabela1->( DbStruct() )
// sei que o campo COD, que desejo alterar,
// é o sexto campo na estrutura da tabela...
// então altero o nome de COD para ATIVIDADE:
// Note que aStru é um Array de Arrays. Estou
// alterando a sexta linha, coluna 1 (DBS_NAME),
// onde é armazenado o nome do campo.
aStru[ 6, DBS_NAME ] := "Atividade"
// Se eu não soubesse que a coluna COD é a sexta
// e soubesse apenas o nome da coluna (COD), teria
// que procurar em aStru qual a linha referente à
// coluna COD. Neste caso faria assim:
// procura em aStru:
// nPos := AScan( aStru, { |e| e[ DBS_NAME ] == "COD" } )
// se encontrou,
// IF nPos > 0
// aStru[ nPos, DBS_NAME ] := "Atividade"
// ELSE
// Alert( "Erro ao gravar alterar estrutura...;Programa cancelado." )
// Break
// ENDIF
// Cria uma tabela com a nova estrutura:
DBCreate( "Tabela2", aStru )
// abre a nova tabela para uso...
Use "Tabela2" EXCLUSIVE New
// Ler os registros originais e gravar na tabela com a estrutura nova
Tabela1->( DbGoTop() )
WHILE Tabela1->( ! Eof() )
Tabela2->( DbAppend() )
IF ! NetErr()
Tabela2->PRONTUARIO := Tabela1->PRONTUARIO
Tabela2->CLINICA := Tabela1->CLINICA
Tabela2->MEDICO := Tabela1->MEDICO
Tabela2->DATA := Tabela1->DATA
Tabela2->LOCAL := Tabela1->LOCAL
Tabela2->ATIVIDADE := Tabela1->COD
ELSE
Alert( "Erro ao gravar tabela destino...;Programa cancelado." )
Break
ENDIF
Tabela1->( DbSkip() )
ENDDO
END SEQUENCE
DbCloseAll()
RETURN NIL
//------------------------------------------------------------------------------
// Cópia do arquivo DBStruuct.Ch presente na instalação padrão do Clipper5 em
// C:\Clipper5\Include:
/***
*
* Dbstruct.ch
*
* DBSTRUCT() function definitions
*
* Copyright (c) 1990-1993, Computer Associates International, Inc.
* All rights reserved.
*
*/
/*
// Subscripts for field structure array
#define DBS_NAME 1
#define DBS_TYPE 2
#define DBS_LEN 3
#define DBS_DEC 4
// Length of array
#define DBS_ALEN 4
#define _DBSTRUCT_CH
*/
//------------------------------------------------------------------------------
[]´s
AlxSts
[]´s
Alexandre Santos (AlxSts)
Alexandre Santos (AlxSts)
Re: modificar nome de campo em dbf
Não existe função nativa do Clipper para alterar o nome de um campo. Mas esse nome consta no cabeçalho do DBF. Com uma função de baixo nível, que o Clipper tem, e conhecendo a estrutura de um DBF, você pode criar uma função dessas. Ou, sendo um único DBF (acredito que não seja o caso), você pode usar um editor hexa pra fazer isso.
Mas quando são vários arquivos, a técnica mais comumente utilizada é a criação de um novo DBF com a nova estrutura e seu povoamento a partir do DBF antigo.
Mas quando são vários arquivos, a técnica mais comumente utilizada é a criação de um novo DBF com a nova estrutura e seu povoamento a partir do DBF antigo.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
-
Glauco Cruz Costa
- Usuário Nível 3

- Mensagens: 102
- Registrado em: 15 Dez 2005 22:02
- Localização: Brasília/DF
- Contato:
Re: modificar nome de campo em dbf
Eu quero fazer isso somente uma vez. Mas não é em execução com o programa sendo trabalhado.
Eu apenas quero transportar os dados para o outro dbf com a estrutura diferente. E mais, na tabela destino, já há outros dados, portanto não se tratará de dar append, mas apenas de se fazer alteração.
E tb na tabela de origem há campos que a tabela de destino não possui:
DBF origem - campos: prontuario, clinica, medico, crm, paciente, data, atividade, turno, prof.
DBF destino - campos: prontuario, data, local, cod.
Eu quero atualizar o DBF destino com os dados do DBF origem:
prontuario, data, clinica (local), atividade (cod).
Ou seja, no dbf origem um campo é clinica; no destino é local.
No dbf origem um campo é atividade; no de destino é local.
Eu apenas quero transportar os dados para o outro dbf com a estrutura diferente. E mais, na tabela destino, já há outros dados, portanto não se tratará de dar append, mas apenas de se fazer alteração.
E tb na tabela de origem há campos que a tabela de destino não possui:
DBF origem - campos: prontuario, clinica, medico, crm, paciente, data, atividade, turno, prof.
DBF destino - campos: prontuario, data, local, cod.
Eu quero atualizar o DBF destino com os dados do DBF origem:
prontuario, data, clinica (local), atividade (cod).
Ou seja, no dbf origem um campo é clinica; no destino é local.
No dbf origem um campo é atividade; no de destino é local.
-
alxsts
- Colaborador

- Mensagens: 3092
- Registrado em: 12 Ago 2008 15:50
- Localização: São Paulo-SP-Brasil
Re: modificar nome de campo em dbf
Olá Glauco.
Foi por isso que escrevi "ficou meio nebulosa a tua intenção".
Talvez soe esquisito mas, programação de computadores é uma arte exata...Se não soubermos o que temos que programar, o resultado certamente será aquele que não esperamos. Assim, quanto mais informação voce passar. melhor.
- O que quer dizer com "Eu quero fazer isso somente uma vez. Mas não é em execução com o programa sendo trabalhado. "?
- Considerando a frase "...Eu apenas quero transportar os dados para o outro dbf com a estrutura diferente. E mais, na tabela destino, já há outros dados, portanto não se tratará de dar append, mas apenas de se fazer alteração...." suponho:
1 - o DBF destino é indexado pelo campo Prontuário
2 - Voce quer ler o DBF origem, pesquisar o prontuário deste no DBF destino.
3 - Se o prontuário for encontrado no DBF destino, gravar neste os campos data, clinica (local), atividade (cod) do DBF origem. O que fazer se não encontrar? Ignorar?
Estou certo? Poste suas observações e ou correções. Depois te ajudo. É fácil alterar o código que postei para fazer isto. Insisto: só é preciso saber o que temos que programar.
[]´s
AlxSts
Foi por isso que escrevi "ficou meio nebulosa a tua intenção".
Talvez soe esquisito mas, programação de computadores é uma arte exata...Se não soubermos o que temos que programar, o resultado certamente será aquele que não esperamos. Assim, quanto mais informação voce passar. melhor.
- O que quer dizer com "Eu quero fazer isso somente uma vez. Mas não é em execução com o programa sendo trabalhado. "?
- Considerando a frase "...Eu apenas quero transportar os dados para o outro dbf com a estrutura diferente. E mais, na tabela destino, já há outros dados, portanto não se tratará de dar append, mas apenas de se fazer alteração...." suponho:
1 - o DBF destino é indexado pelo campo Prontuário
2 - Voce quer ler o DBF origem, pesquisar o prontuário deste no DBF destino.
3 - Se o prontuário for encontrado no DBF destino, gravar neste os campos data, clinica (local), atividade (cod) do DBF origem. O que fazer se não encontrar? Ignorar?
Estou certo? Poste suas observações e ou correções. Depois te ajudo. É fácil alterar o código que postei para fazer isto. Insisto: só é preciso saber o que temos que programar.
[]´s
AlxSts
[]´s
Alexandre Santos (AlxSts)
Alexandre Santos (AlxSts)
-
Glauco Cruz Costa
- Usuário Nível 3

- Mensagens: 102
- Registrado em: 15 Dez 2005 22:02
- Localização: Brasília/DF
- Contato:
Re: modificar nome de campo em dbf
Eu só quero copiar de um dbf para outro, atualizando campos.
Ninguém trabalhando é ninguém usando o sistema. Assim, eu o abrirei exclusive sem problemas.
O problema é que eu quero copiar somente os campos que possuem uma data específica. E tenho que encaixá-los em dois dos campos de nomes diferentes.
Não é todos, conforme coloquei antes.
Se fosse todos, eu abria o DBU e só renomeava os campos. Deu para entender?
E um outro problema que me está enculcando agora é o seguinte:
Tenho um outro dbf em que as datas foram armazenadas sem o set epoch, ou seja, os campos foram armazenados como 1900, mas, no formato "xx/xx/xx"
Quando eu uso set epoch 2000 em uma pesquisa, os dados armazenados com a época anterior não aparecem na pesquisa. Parece lógico.
Mas, eu gostaria de poder copiá-los (atualizar os dados dele) para o outro dbf, porém eles vindo com a data e set epoch 2000. Isso pq o sistema que usa o 2º dbf, usa o set epoch 2000.
Será que se eu usar o set epoch para pesquisar, e depois usar o set epoch 2000 antes do replicate resolve?
Ninguém trabalhando é ninguém usando o sistema. Assim, eu o abrirei exclusive sem problemas.
O problema é que eu quero copiar somente os campos que possuem uma data específica. E tenho que encaixá-los em dois dos campos de nomes diferentes.
Não é todos, conforme coloquei antes.
Se fosse todos, eu abria o DBU e só renomeava os campos. Deu para entender?
E um outro problema que me está enculcando agora é o seguinte:
Tenho um outro dbf em que as datas foram armazenadas sem o set epoch, ou seja, os campos foram armazenados como 1900, mas, no formato "xx/xx/xx"
Quando eu uso set epoch 2000 em uma pesquisa, os dados armazenados com a época anterior não aparecem na pesquisa. Parece lógico.
Mas, eu gostaria de poder copiá-los (atualizar os dados dele) para o outro dbf, porém eles vindo com a data e set epoch 2000. Isso pq o sistema que usa o 2º dbf, usa o set epoch 2000.
Será que se eu usar o set epoch para pesquisar, e depois usar o set epoch 2000 antes do replicate resolve?
Re: modificar nome de campo em dbf
Para o primeiro problema, que deu origem a esta thread, como há o detalhe da filtragem, não há como escapar: você terá de fazer um programa de exportação de dados, que leve em conta o filtro que você precisa ativar.
Quanto ao segundo problema, o de data, no arquivo de dados a data sempre será armazenada no formato ANSI, que é AAAAMMDD. Ou seja, você tem a informação de século. O que foi gravado na informação do século do registro vai depender do valor de SET EPOCH no momento em que os dados foram inseridos no programa.
Quanto ao segundo problema, o de data, no arquivo de dados a data sempre será armazenada no formato ANSI, que é AAAAMMDD. Ou seja, você tem a informação de século. O que foi gravado na informação do século do registro vai depender do valor de SET EPOCH no momento em que os dados foram inseridos no programa.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.
---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
modificar nome de campo em dbf
Ou seja... muito provável que as datas em que foram gravadas ficaram no século passado. Isto é, datas com ano 2004 devem ter ficado 1904. Seria bom você abrir o bd e aplicar o SET CENTURY ON para ver como estão essas datas. Se você tiver certeza de que está tudo correto, então não se preocupe quanto ao tratamento desse campo data mas se contiver "alguns", você será obrigado a passar por uma função que transforme essa data corretamente. Se quiser utilizar veja como eu usei num caso semelhante:O que foi gravado na informação do século do registro vai depender do valor de SET EPOCH no momento em que os dados foram inseridos no programa.
Código: Selecionar todos
nova_data:=MUDATA(DATA) // chama a função
FUNCTION MUDATA(XDT)
XYD:=(RIGHT(ALLTRIM(STR(YEAR(XDT))),2))
XYA:=(RIGHT(ALLTRIM(STR(YEAR(DATE()))),2))
IF VAL(XYD)>VAL(XYA)
IF (VAL(XYD))-(VAL(XYA))<2
XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"20"+XYD )
ELSE
XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"19"+XYD )
ENDIF
ELSE
XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"20"+XYD )
ENDIF
RETURN XDTUm clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
-
Glauco Cruz Costa
- Usuário Nível 3

- Mensagens: 102
- Registrado em: 15 Dez 2005 22:02
- Localização: Brasília/DF
- Contato:
Re: modificar nome de campo em dbf
Obruigado.
Depois de muito quebra-cabeça, consegui bolar essa rotina que deu certo:
SET EPOCH TO 2000
SET DATE BRITISH
USE RETORNO
GO TOP
DO WHILE .NOT. EOF()
IF DATA <> CTOD(" / / ")
A = DATA
B = DTOC(DATA)
REPLACE DATA WITH CTOD(B)
ENDIF
SKIP
ENDDO
Aqui eu modifiquei os campos datas para caracteres em cada registro. Depois, eu os transformei novamente em data. E como o set epoch estaava 2000, as datas foram gravadas no formato de 2000. Aí ficou mais fácil, pois eu faço uma cópia do dbf, para não atrapalhar o outro sistema, e nessa cópia eu uso a rotina acima para transformar as datas, e, após, eu posso atualizar o outro dbf, adaptando uma rotina que um outro amigo postou em uma outra dúvida minha aqui no forum, a que se segue:
use arquiv01.dbf new excl
inde on prontuario to temp
set inde to temp
use arqui01.dbf new excl
go top
do whil !eof()
sele arquiv01
seek arqui01->prontuario
if !found()
?"Erro - Prontuário não localizado"
?prontuario
else
repl data with arqui01->data
repl cod with arqui01->cod
repl local with arqui01->local
endi
sele arqui01
skip
endd
Vlw!
)
Depois de muito quebra-cabeça, consegui bolar essa rotina que deu certo:
SET EPOCH TO 2000
SET DATE BRITISH
USE RETORNO
GO TOP
DO WHILE .NOT. EOF()
IF DATA <> CTOD(" / / ")
A = DATA
B = DTOC(DATA)
REPLACE DATA WITH CTOD(B)
ENDIF
SKIP
ENDDO
Aqui eu modifiquei os campos datas para caracteres em cada registro. Depois, eu os transformei novamente em data. E como o set epoch estaava 2000, as datas foram gravadas no formato de 2000. Aí ficou mais fácil, pois eu faço uma cópia do dbf, para não atrapalhar o outro sistema, e nessa cópia eu uso a rotina acima para transformar as datas, e, após, eu posso atualizar o outro dbf, adaptando uma rotina que um outro amigo postou em uma outra dúvida minha aqui no forum, a que se segue:
use arquiv01.dbf new excl
inde on prontuario to temp
set inde to temp
use arqui01.dbf new excl
go top
do whil !eof()
sele arquiv01
seek arqui01->prontuario
if !found()
?"Erro - Prontuário não localizado"
?prontuario
else
repl data with arqui01->data
repl cod with arqui01->cod
repl local with arqui01->local
endi
sele arqui01
skip
endd
Vlw!
-
Glauco Cruz Costa
- Usuário Nível 3

- Mensagens: 102
- Registrado em: 15 Dez 2005 22:02
- Localização: Brasília/DF
- Contato:
Re: modificar nome de campo em dbf
Na verdade, ainda não deu certo.
Em um dbf, as datas foram gravadas sem set epoch, ou seja, ficaram no padrão 1900.
Mesmo eu tendo transformado elas com dtoc, depois, voltado elas para o normal com ctod, estando o set epoch to 2000, não ficou gravado como 2000.
Será que há outra solução?
Vejam como fiz:
set date british
set epoch to 2000
use retorn
go top
DO WHILE .NOT. EOF()
IF DATA <> CTOD(" / / ")
A = DATA
B = DTOC(DATA)
REPLACE DATA WITH CTOD(B)
ENDIF
SKIP
ENDDO
close
// essa rotina abaixo deu certo com um um outro dbf que estava já gravado em set epoch to 2000.
// o problema mesmo está sendo transformar essas datas para seculo XXI.
use arqui01.dbf new excl // este possui seu executavel em set epoch 2000
inde on prontuario to temp
set inde to temp
use retorn.dbf new excl // este possui seu executavel sem set epoch, ou seja, set epoch to 1900, padrão do clipper. Por isso, ele gravou as datas nela como séc. XX.
go top
do whil !eof()
sele arqui01
seek retorn->prontuario
if !found()
?"Prontuário não localizado"
? prontuario
else
repl data with retorn->data
repl cod with retorn->clin // o cod em arquiv01, em retorn eh clin
repl local with retorn->CLINICA // o local em arquiv01, em retorn eh clinica
endi
sele retorn
skip
endd
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
modificar nome de campo em dbf
Glauco, Glauco... você não leu com atenção o que eu postei e nem o que colega Maligno falou sobre a questão datas. Esse código seu não iria dar certo sem fazer alterações que tratem as datas que foram gravadas no SET EPOCH 1900 no passado. Por isso você vai ter que tratar na marra e por isso postei aquele código. Pois a data foi gravada com o ano errado e que no seu sistema passou desapercebido em virtude de não exibir os quatro dígitos do ano, mas na realidade estão lá... então ja que você viu que existem registros com ano errados, faça uso da rotina que postei. E se precisar de ajuda: poste suas dúvidas que iremos lhe atender.Na verdade, ainda não deu certo.
Em um dbf, as datas foram gravadas sem set epoch, ou seja, ficaram no padrão 1900.
Mesmo eu tendo transformado elas com dtoc, depois, voltado elas para o normal com ctod, estando o set epoch to 2000, não ficou gravado como 2000.
Será que há outra solução?
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
