Página 1 de 2

Atenção: Campo incremental em DBF

Enviado: 11 Fev 2015 12:33
por JoséQuintas
2015-02-11 09:26 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* src/rdd/dbf1.c
+ finished support for AutoInc flag (+) for all numeric fields (N, F, I, B)
in DBF* RDDs. Now user can define field like:
{ "COUNTER", "I:+", 4, 0 }
and they will work like autoincrement fields but without any assign
restrictions.
Na primeira implementação de campo incremental havia um problema em determinadas situações, como cópia do DBF.
Quem adotou o estilo anterior, convém atualizar e testar, porque me parece que antes o tipo era apenas "+".

Nota: O tipo de campo/recurso não existia nem no dBASE nem no Clipper, então quem não usa campo incremental não precisa se preocupar.

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 16:53
por arcanjoebc
José, mas como eu crio um campo incremental, usando o harbour? Tenho a procedure abaixo que cria a base de dados, o campo COD, deveria ser o incremental, porém, já testei e não surtiu efeito com as modificações, podes me dar uma dica? Como disse, abaixo veja o meu código fonte:

Código: Selecionar todos

PROCEDURE Struc2
if .not. file("clientes.dbf")
 aDBF := {}
 //
 aAdd(aDBF, {"COD", "N",10,0})
 aAdd(aDBF, {"NOME", "C",30,0})
 aAdd(aDBF, {"NASC", "D",08,0})
 aAdd(aDBF, {"END", "C",35,0})
 aAdd(aDBF, {"CID", "C",35,0})
 aAdd(aDBF, {"CEP", "C",10,0})
 aAdd(aDBF, {"UF", "C",02,0})
 aAdd(aDBF, {"FONE", "C",14,0})
 aAdd(aDBF, {"CPF", "C",14,0})
 aAdd(aDBF, {"PROF", "C",20,0})
 aAdd(aDBF, {"SEXO", "C",01,0})
 aAdd(aDBF, {"EC", "C",01,0})
 aAdd(aDBF, {"OBS", "C",50,0})
 //
 dbCreate("clientes",aDBF)
endif
RETURN
Agradeço-lhe qualquer informação que puder me fornecer!

Everaldo

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 19:47
por JoséQuintas
Mas modificou e deixou de gravar o código, ou continuou gravando o código?

Nunca usei esse campo incremental.
Fiz um teste agora apenas usando o que postei, que diz que o tipo é "I:+"

Código: Selecionar todos

PROCEDURE Main

if .not. file("clientes.dbf")
 aDBF := {}
 aAdd(aDBF, {"COD", "I:+",10,0})
 aAdd(aDBF, {"NOME", "C",30,0})
 aAdd(aDBF, {"NASC", "D",08,0})
 aAdd(aDBF, {"END", "C",35,0})
 aAdd(aDBF, {"CID", "C",35,0})
 aAdd(aDBF, {"CEP", "C",10,0})
 aAdd(aDBF, {"UF", "C",02,0})
 aAdd(aDBF, {"FONE", "C",14,0})
 aAdd(aDBF, {"CPF", "C",14,0})
 aAdd(aDBF, {"PROF", "C",20,0})
 aAdd(aDBF, {"SEXO", "C",01,0})
 aAdd(aDBF, {"EC", "C",01,0})
 aAdd(aDBF, {"OBS", "C",50,0})
 dbCreate("clientes",aDBF)
endif
USE clientes
FOR nCont = 1 TO 10
   APPEND BLANK
NEXT
GOTO TOP
DO WHILE .NOT. Eof()
   ? Cod
   SKIP
ENDDO
RETURN

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 19:48
por JoséQuintas
Resultado

Código: Selecionar todos

d:\temp>test

         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
d:\temp>test

         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
d:\temp>
Ok. A cada execução inclui 10 registros em branco.
O campo COD está sendo incrementado a cada append blank.
Se o campo é incremental, o conteúdo se atualiza automaticamente, não é pra gravar o campo COD.

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 20:44
por asimoes
Campo incremental não existe no harbour, você tem que criar os controles para isso.

Esta função vai retornar um número incremental para qualquer tabela.

Se encontrar algum erro, nos fala.

Estamos aqui pra ajudar.

Código: Selecionar todos


cCodigo := StrZero(PsqControle( "DESPESAS"), 2)

DESPESAS->(DbAppend())
DESPESAS->Codigo := cCodigo
DESPESAS->(DbCommit(), DbUnClock())

FUNCTION PsqControle( cDataBase )
LOCAL nControle := IIF( (cDataBase)->(LastRec())=0, 1, (cDataBase)->(LastRec())+((cDataBase)->(LastRec())/2) ), cOldArea, aStru_Table
   IF Mod(nControle, 1000) == 0
      nControle ++
   ENDIF
   cOldArea := Select()
   IF !hb_FileExists("REGISTRO.DBF")
      // Cria a estrutura do controlador caso ainda não exista
      aStru_Table := { ;
                     { "DATABASE"  , "C", 12, 0 } , ;  // Guarda o nome do DBF/Alias
                     { "CONTADOR"  , "N",  9, 0 } }    // Armazena o contador

            DbCreate("REGISTRO", aStru_Table)
   ENDIF
   USE REGISTRO ALIAS REGISTRO SHARED NEW VIA "DBFCDX"
   // Verifica a existencia da chave( que pode ser também uma palavra )
   INDEX ON Upper(DataBase) TAG CHAVE TEMPORARY ADDITIVE
   IF REGISTRO->(DbSeek(Upper(cDataBase)))
      REGISTRO->(DbRLock()) // Usado no caso de rede
      nControle := REGISTRO->Contador + 1
      IF Mod(nControle, 1000) == 0
         nControle ++
      ENDIF
      REGISTRO->Contador := nControle
   ELSE
      // Caso a chave ainda não exista será criada
      REGISTRO->(DbAppend())
      REGISTRO->DataBase := cDataBase
      REGISTRO->Contador := nControle
   ENDIF
   REGISTRO->(DbCommit(), DbUnLock())
   REGISTRO->(DbCloseArea())
   // Volta a área antiga
   DbSelectArea(cOldArea)
   // Retorna o numero de controle
RETURN nControle 

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:24
por asimoes
A função que eu postei é de autoria do Mestre Rochinha, eu só fiz umas pequenas intervenções.

Tópico: Codigo Sequencial
https://pctoledo.org/forum/viewto ... ole#p96333

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:29
por JoséQuintas
Campo incremental não existe no harbour
Leu alguma coisa do tópico?

Postei a documentação sobre isso existir.

Postei um exemplo de uso.

Agora vém dizer que não existe!!!!!

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:30
por asimoes
Ops, Quintas,

Agora que eu vi a novidade do campo incremental.
Vou testar isso.

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:32
por JoséQuintas
O que postei inicialmente é de uma melhoria, há exatamente um ano..... rs

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:50
por asimoes
O recurso do campo incremental é uma novidade que deve ser usada com cuidado, desde que a tabela seja usada somente com programas compilados com harbour e a partir da implementação do recurso em (17-02-2015)

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 21:53
por asimoes
Nos casos em que ainda tem sistemas em clipper e harbour compartilhando as mesmas tabelas convém usar a função que o Rochinha postou.

Atenção: Campo incremental em DBF

Enviado: 27 Fev 2016 22:05
por asimoes
O CDBF for Windows informa que o tipo do campo é integer, fiz um teste adicionando um registro, o campo ficou com 0, eu esperava que isso fosse acontecer, quem faz o controle do campo é o harbour, então cuidado com isso.
Screen Shot 02-27-16 at 10.02 PM.PNG
Screen Shot 02-27-16 at 10.02 PM.PNG (7.39 KiB) Exibido 3129 vezes

Atenção: Campo incremental em DBF

Enviado: 21 Set 2021 22:53
por arcanjoebc
José Quintas, venho a ti me aconselhar novamente ... depois de tempos, voltei a programar e estou com o dilema do campo incremental. O exemplo que destes mais acima, eu o fiz e testei e realmente dá certo. Porém, no caso do cadastro de clientes, não é mostrado o campo em questão quando vou inserir um novo registro, voltando sempre para o 0 "zero". Tu podes me ajudar? Abaixo o fonte para inserir os dados:

Código: Selecionar todos

*----------------------------------------*
* PROGRAMA   : cli01.prg                 *
* DATA       : 15/04/2018                *
* FINALIDADE : CADASTRAR CLIENTES        *
*----------------------------------------*
use clientes
OrdSetFocus("indcod")

PUBLIC MEM_COD, MEM_NOME, MEM_NASC, MEM_SEXO, MEM_ENDE
PUBLIC MEM_NUM, MEM_BAIRRO, MEM_CID, MEM_CEP, MEM_FONE
PUBLIC MEM_CPF, MEM_PROF, MEM_EC, MEM_PROF, MEM_OBS
PUBLIC MEM_UF, CONFIRMA

DO WHILE .T.
  CLEAR
  @ 01,33 SAY "INCLUSAO DE NOVOS CLIENTES"
  @ 02,33 SAY "======== == ===== ========"
  @ 04,03 SAY "COD.:"
  @ 06,03 SAY "NOME:"
  @ 08,03 SAY "DATA NASC   /  /     SEXO:   ESTADO CIVIL:"
  @ 10,03 SAY "ENDERECO:                                          NUM.:"
  @ 12,03 SAY "BAIRRO:                               CEP:"
  @ 14,03 SAY "CIDADE:                                        UF:"
  @ 16,03 SAY "TELEFONE: (  )     -        CPF:    .   .   -  "
  @ 18,03 SAY "PROFISSAO:"
  @ 20,03 SAY "OBS.:"
  @ 22,03 SAY "CONFIRMA? (S/N) "
  MEM_COD = 0000
  MEM_NOME = SPACE(35)
  MEM_NASC = CTOD("  /  /    ")
  MEM_SEXO = SPACE(01)
  MEM_EC   = SPACE(01)
  MEM_ENDE = SPACE(35)
  MEM_NUM  = SPACE(10)
  MEM_BAIRRO = SPACE(20)
  MEM_CID  = SPACE(35)
  MEM_UF   = SPACE(02)
  MEM_CEP  = SPACE(10)
  MEM_FONE = SPACE(15)
  MEM_CPF  = SPACE(14)
  MEM_PROF = SPACE(20)
  MEM_OBS  = SPACE(50)
  CONFIRMA = SPACE(01)
  @ 04,13 SAY MEM_COD PICT "99999"
  @ 06,13 SAY MEM_NOME PICT "@!35"
  @ 08,13 SAY MEM_NASC PICT "  /  /    "
  @ 08,30 SAY MEM_SEXO PICT "!"
  @ 08,47 SAY MEM_EC PICT "!"
  @ 10,13 SAY MEM_ENDE PICT "@!35"
  @ 10,60 SAY MEM_NUM PICT "9999999999"
  @ 12,13 SAY MEM_BAIRRO PICT "@!20"
  @ 12,47 SAY MEM_CEP PICT "99.999-999"
  @ 14,13 SAY MEM_CID PICT "@!35"
  @ 14,56 SAY MEM_UF PICT "!!"
  @ 16,13 SAY MEM_FONE PICT "(99) 99999-9999"
  @ 16,36 SAY MEM_CPF PICT "999.999.999-99"
  @ 18,13 SAY MEM_PROF PICT "@!20"
  @ 20,13 SAY MEM_OBS  PICT "@!50"
  @ 22,19 SAY CONFIRMA PICT "!"
  @ 04,13 GET MEM_COD PICT "99999"
  READ
  IF MEM_COD = 0
    EXIT
  ENDIF
  LOCATE FOR COD = MEM_COD
  IF FOUND()
    ENTER=SPACE(01)
    @ 24,03 SAY "CLIENTE JAH CADASTRADO <ENTER> " GET ENTER
    READ
    @ 24,03 SAY "                               "
    LOOP
  ENDIF
  @ 04,13 GET MEM_COD PICT "99999"
  @ 06,13 GET MEM_NOME PICT "@!35"
  @ 08,13 GET MEM_NASC PICT "  /  /    "
  @ 08,30 GET MEM_SEXO PICT "!"
  @ 08,47 GET MEM_EC PICT "!"
  @ 10,13 GET MEM_ENDE PICT "@!35"
  @ 10,60 GET MEM_NUM PICT "9999999999"
  @ 12,13 GET MEM_BAIRRO PICT "@!20"
  @ 12,47 GET MEM_CEP PICT "99.999-999"
  @ 14,13 GET MEM_CID PICT "@!35"
  @ 14,56 GET MEM_UF PICT "!!"
  @ 16,13 GET MEM_FONE PICT "(99) 99999-9999"
  @ 16,36 GET MEM_CPF PICT "999.999.999-99"
  @ 18,13 GET MEM_PROF PICT "@!20"
  @ 20,13 GET MEM_OBS  PICT "@!50"
  @ 22,19 GET CONFIRMA PICT "!" 
  READ
  IF CONFIRMA = "S"
    APPEND BLANK
    REPLACE COD    WITH MEM_COD
    REPLACE NOME   WITH MEM_NOME
    REPLACE NASC   WITH MEM_NASC
    REPLACE SEXO   WITH MEM_SEXO
    REPLACE EC     WITH MEM_EC
    REPLACE ENDE   WITH MEM_ENDE
    REPLACE NUM    WITH MEM_NUM
    REPLACE BAIRRO WITH MEM_BAIRRO
    REPLACE CEP    WITH MEM_CEP
    REPLACE CID    WITH MEM_CID
    REPLACE UF     WITH MEM_UF
    REPLACE FONE   WITH MEM_FONE
    REPLACE CPF    WITH MEM_CPF
    REPLACE PROF   WITH MEM_PROF
    REPLACE OBS    WITH MEM_OBS
  ENDIF
ENDDO
CLOSE ALL
RETURN

Atenção: Campo incremental em DBF

Enviado: 22 Set 2021 07:09
por JoséQuintas
arcanjoebc escreveu:não é mostrado o campo em questão quando vou inserir um novo registro, voltando sempre para o 0 "zero"
Se está criando uma variável com conteúdo zero, se mostrar a variável o conteúdo vai ser zero.
E se gravar no campo um valor, o conteúdo vai ser esse valor.

O campo incremental no arquivo é gravado automaticamente.
Aonde está nesse fonte a parte de mostrar o conteúdo do campo incremental? Ao que parece não existe ou não está sendo usado pra isso.

Atenção: Campo incremental em DBF

Enviado: 22 Set 2021 17:16
por arcanjoebc
Olha, segui o teu conselho e ... funcionou!!! Abaixo como ficou meu código:

Código: Selecionar todos

*----------------------------------------*
* PROGRAMA   : cli01.prg                 *
* DATA       : 15/04/2018                *
* FINALIDADE : CADASTRAR CLIENTES        *
*----------------------------------------*
use clientes exclusive
OrdSetFocus("indcod")

PUBLIC MEM_COD, MEM_NOME, MEM_NASC, MEM_SEXO, MEM_ENDE
PUBLIC MEM_NUM, MEM_BAIRRO, MEM_CID, MEM_CEP, MEM_FONE
PUBLIC MEM_CPF, MEM_PROF, MEM_EC, MEM_PROF, MEM_OBS
PUBLIC MEM_UF, CONFIRMA

DO WHILE .T.
  CLEAR
  @ 01,33 SAY "INCLUSAO DE NOVOS CLIENTES"
  @ 02,33 SAY "======== == ===== ========"
  @ 04,03 SAY "COD.:"
  @ 06,03 SAY "NOME:"
  @ 08,03 SAY "DATA NASC   /  /     SEXO:   ESTADO CIVIL:"
  @ 10,03 SAY "ENDERECO:                                          NUM.:"
  @ 12,03 SAY "BAIRRO:                               CEP:"
  @ 14,03 SAY "CIDADE:                                        UF:"
  @ 16,03 SAY "TELEFONE: (  )     -        CPF:    .   .   -  "
  @ 18,03 SAY "PROFISSAO:"
  @ 20,03 SAY "OBS.:"
  @ 22,03 SAY "CONFIRMA? (S/N) "
  MEM_COD = 0000
  MEM_NOME = SPACE(35)
  MEM_NASC = CTOD("  /  /    ")
  MEM_SEXO = SPACE(01)
  MEM_EC   = SPACE(01)
  MEM_ENDE = SPACE(35)
  MEM_NUM  = SPACE(10)
  MEM_BAIRRO = SPACE(20)
  MEM_CID  = SPACE(35)
  MEM_UF   = SPACE(02)
  MEM_CEP  = SPACE(10)
  MEM_FONE = SPACE(15)
  MEM_CPF  = SPACE(14)
  MEM_PROF = SPACE(20)
  MEM_OBS  = SPACE(50)
  CONFIRMA = SPACE(01)
  GO BOTTOM
  @ 04,13 SAY MEM_COD PICT "99999"
  @ 06,13 SAY MEM_NOME PICT "@!35"
  @ 08,13 SAY MEM_NASC PICT "  /  /    "
  @ 08,30 SAY MEM_SEXO PICT "!"
  @ 08,47 SAY MEM_EC PICT "!"
  @ 10,13 SAY MEM_ENDE PICT "@!35"
  @ 10,60 SAY MEM_NUM PICT "9999999999"
  @ 12,13 SAY MEM_BAIRRO PICT "@!20"
  @ 12,47 SAY MEM_CEP PICT "99.999-999"
  @ 14,13 SAY MEM_CID PICT "@!35"
  @ 14,56 SAY MEM_UF PICT "!!"
  @ 16,13 SAY MEM_FONE PICT "(99) 99999-9999"
  @ 16,36 SAY MEM_CPF PICT "999.999.999-99"
  @ 18,13 SAY MEM_PROF PICT "@!20"
  @ 20,13 SAY MEM_OBS  PICT "@!50"
  @ 22,19 SAY CONFIRMA PICT "!"
  @ 04,13 SAY COD PICT "99999"
  @ 06,13 GET MEM_NOME PICT "@!35"
  READ
  IF MEM_NOME = SPACE(35)
    EXIT
  ENDIF
  LOCATE FOR NOME = MEM_NOME
  IF FOUND()
    ENTER=SPACE(01)
    @ 24,03 SAY "CLIENTE JAH CADASTRADO <ENTER> " GET ENTER
    READ
    @ 24,03 SAY "                               "
    LOOP
  ENDIF
  @ 04,13 SAY COD PICT "99999"
  @ 06,13 GET MEM_NOME PICT "@!35"
  @ 08,13 GET MEM_NASC PICT "  /  /    "
  @ 08,30 GET MEM_SEXO PICT "!"
  @ 08,47 GET MEM_EC PICT "!"
  @ 10,13 GET MEM_ENDE PICT "@!35"
  @ 10,60 GET MEM_NUM PICT "9999999999"
  @ 12,13 GET MEM_BAIRRO PICT "@!20"
  @ 12,47 GET MEM_CEP PICT "99.999-999"
  @ 14,13 GET MEM_CID PICT "@!35"
  @ 14,56 GET MEM_UF PICT "!!"
  @ 16,13 GET MEM_FONE PICT "(99) 99999-9999"
  @ 16,36 GET MEM_CPF PICT "999.999.999-99"
  @ 18,13 GET MEM_PROF PICT "@!20"
  @ 20,13 GET MEM_OBS  PICT "@!50"
  @ 22,19 GET CONFIRMA PICT "!" 
  READ
  IF CONFIRMA = "S"
    APPEND BLANK
//  REPLACE COD    WITH MEM_COD
    REPLACE NOME   WITH MEM_NOME
    REPLACE NASC   WITH MEM_NASC
    REPLACE SEXO   WITH MEM_SEXO
    REPLACE EC     WITH MEM_EC
    REPLACE ENDE   WITH MEM_ENDE
    REPLACE NUM    WITH MEM_NUM
    REPLACE BAIRRO WITH MEM_BAIRRO
    REPLACE CEP    WITH MEM_CEP
    REPLACE CID    WITH MEM_CID
    REPLACE UF     WITH MEM_UF
    REPLACE FONE   WITH MEM_FONE
    REPLACE CPF    WITH MEM_CPF
    REPLACE PROF   WITH MEM_PROF
    REPLACE OBS    WITH MEM_OBS
  ENDIF
ENDDO
CLOSE ALL
RETURN
Obrigado por avisar-me da falha, tudo de bom!