dBase para 32 bits

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

tonyx
Usuário Nível 3
Usuário Nível 3
Mensagens: 303
Registrado em: 07 Jul 2004 15:26

dBase para 32 bits

Mensagem por tonyx »

velho dbase de 16 bits "DOS" onde consigo
"DBASE para 32 btis" para funcionar em "XP e no seveN"

ou existe outra ferramenta facil de criacao e abertura para DBF ??

grato a todos
:f
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

DBASE PARA 32 BITS

Mensagem por Pablo César »

O Dbase eu consigo chamar no XP sem ser de 32 bits. Só que no Windows Seven não executa, dá erro...
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.
lucimauro
Usuário Nível 3
Usuário Nível 3
Mensagens: 465
Registrado em: 21 Set 2004 21:02
Localização: Sobral-CE

DBASE PARA 32 BITS

Mensagem por lucimauro »

Voce pode usar o proprio DBU que vem junto com o clipper ou o dbx que tambem faz o esse trabalho!!
Avatar do usuário
billy1943
Usuário Nível 4
Usuário Nível 4
Mensagens: 570
Registrado em: 12 Mai 2009 17:33
Localização: Bauru-SP

DBASE PARA 32 BITS

Mensagem por billy1943 »

Eu uso normalmente o DBASE III Plus - Version 1.0 (1984, 1985, 1986) no Windows 7 Ultimate.

Nem penso em procurar ou usar outro.
O bom do computador é que ele resolve os problemas, sem nunca levantar nenhum.
Hoje atuo mais com Clipper 52E, e um pouquinho com XHarbour.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

dBase para 32 bits

Mensagem por JoséQuintas »

Se for pra acessar DBFs digitando comandos, pode usar o foxpro/Dos.
É estilo foxplus.
No meu sistema embuti um dbase-like que fiz, que quebra o galho, mas andei mexendo e nem sei se ainda compila no Clipper.
A vantagem é ele ficar igual ao sistema: se trabalhar com ntx, cdx, ou o que for, ele está compilado junto e trabalharia igual.

Acho até curioso, mas tem gente que nem conheceu o dbase, e não conhece as facilidades de poder digitar comandos e ver o resultado.

Vai aí o código, mas pra clipper vai precisar no mínimo voltar o nome das funções pra 8 letras.
Vão faltar funções, mas vão ser autoexplicativas, e deve ajustar de acordo com seu sistema.

Tipo....
SayScroll() é pra fazer um say na última linha, após um scroll, tipo... scroll(0,0,24,79,1);@ 24,0 say texto
wSave() e wRestore() clássicas de salvar/restaurar tela em array, pode substituir por x = savescreen() restore from x ou variáveis diferentes, se precisar
MsgExclamation(), meio equivalente ao alert(), só mostra a mensagem no meio da tela e aguarda ENTER
GravaLog(), pra registrar o que for feito
DosRun(programa), equivalente a run (programa)
Essas todas seriam só pra efeito de tela, pra ficar compatível com o resto do sistema.
Tenho usado muito pouco, então só colocando em prática pra ver se falta algo.
É uma lógica meio simples, vai pegando as partes do texto digitado, e conforme o que for encontrando vai desviando para a rotina que interessa, que analisa o resto do texto.
Provavelmente com recursos do Harbour dê pra melhorar muito.

Código: Selecionar todos

*****************************************************************
* SISTEMA....: INTEGRADO                                        *
* PROGRAMA...: RDBASE - ACESSO DIRETO A DBFS                    *
* CRIACAO....: 13.02.99 - JOSE                                  *
*****************************************************************

* ...
* 10.02.12 - Corrigido para mais ordens no disp stat
* 02.07.12 - Alias temporario quando nome com mais de 8 letras
* 02.07.02 - Ajuste ref funcionar goto alem de go
*----------------------------------------------------------------


#include "jpa.ch"

Static nTempAlias := 1

Procedure RDBASE
Private CfgSetExclusive := .f.
Private CfgHistoTxt[16]
Private CfgHistNum := 50
Private CfgOdometer := 100

MsgExclamation( "Proibido para inexperientes! Ninguem pode estar usando! Se alterar algo, reindexe! Para retornar QUIT")
For nCont = 1 to MaxRow()
   SayScroll()
Next
Mensagem("Digite o comando seguido de ENTER, ou QUIT para sair")

Set Exclusive off

CfgOdometer = 100
CfgHistNum = 16
Afill( CfgHistoTxt, "" )

mTexto := ""
mPulaLinha := .f.
Do While .t.
   if mPulaLinha
      SayScroll()
      mPulaLinha := .f.
      mTexto     := ""
   Endif
   mTexto := Pad(mTexto,200)
   @ MaxRow()-3,0 Get mTexto Picture "@S"+Ltrim(Str(MaxCol()-1))
   Read
   mInkey := LastKey()
   Do Case
   case LastKey() == 27
      Loop
   case mInkey = 5
      if CfgHistNum > 1
         CfgHistNum = CfgHistNum - 1
         if len( trim( CfgHistoTxt[ CfgHistNum ] ) ) = 0
            CfgHistNum = CfgHistNum + 1
            ?? chr(7)
         Else
            mTexto := CfgHistoTxt[ CfgHistNum ]
         Endif
      Endif
      loop

   case mInkey = 24
      if CfgHistNum < len( CfgHistoTxt )
         CfgHistNum = CfgHistNum + 1
         mTexto := CfgHistoTxt[ CfgHistNum ]
      Endif
      loop
   case Empty(mTexto)
      loop
   EndCase
   mPulaLinha := .t.
   mTexto := Trim(mTexto)
   adel( CfgHistoTxt, 1 )
   CfgHistNum = len(CfgHistoTxt) - 1
   CfgHistoTxt[CfgHistNum] = alltrim(mTexto)
   CfgHistNum = len(CfgHistoTxt)
   CfgHistoTxt[CfgHistNum] = ""

   mTexto   := AllTrim("&mTexto")
   if file("jplogsi.dbf") .And. .Not. Empty(mTexto)
      GravaLog("(*)"+mTexto)
   Endif
   mComando := Lower(Trim(Left(PegaParam(@mTexto," "),4)))
   if mComando+"," $ "disp,list,appe,brow,cont,copy,dele,edit,inde,loca,"+;
      "pack,reca,rein,repl,seek,sum,unlo,zap," ;
      .or. mComando = "modi" .And. "stru" $ Lower(mTexto)
      if .Not. Used()
         MsgExclamation("Nao tem arquivo em uso!")
         loop
      Endif
   Endif
   if mComando+"," $ "pack,rein,reind,reinde,reindex,zap,"
      // if .Not. fLock()
      //    SayScroll("Nao executado, arquivo nao pode ser bloqueado")
      //    loop
      // Endif
      if .Not. CfgSetExclusive
         SayScroll("Nao executado, arquivo nao exclusivo")
         Loop
      Endif
   Endif
   Do Case
   case mComando == "quit"
      Exit
   case mComando == "!" .or. mComando == "run"
      wSave()
      DosRun(mTexto)
      ?
      @ MaxRow(), 0 Say "Tecle ESC para prosseguir"
      Do While MyInkey(0) != 27
      Enddo
      wRestore()
   case mComando == "?"
      RotinaPrint()
   case mComando == "go" .or. mComando == "goto" ;
      .or. (Type(mComando)=="N" .And. Empty(mTexto))
      if Lower(mTexto) == "top"
         GoTo top
      Elseif Lower(Left(mTexto,4)) == "bott"
         GoTo bottom
      Elseif Type(mTexto) != "N"
         SayScroll("Parametros aceitos TOP, BOTT ou numero")
      Elseif &mTexto > LastRec() .or. &mTexto < 1
         SayScroll("Registro invalido")
      Else
         GoTo &mTexto
      Endif
   case mComando == "disp" .or. mComando == "list"
      RotinaList()
   case mComando == "appe"
      RotinaAppend()
   case mComando == "brow"
      wSave()
      mRow := Row()
      mCol := Col()
      Mensagem("Selecione e tecle ENTER para alterar o campo, ESC abandona")
      Browse(2,0,MaxRow()-3,MaxCol())
      wRestore()
      @ mRow, mCol Say ""
   case mComando == "clea"
      Scroll(2,0,MaxRow()-3,MaxCol(),0)
   case mComando == "clos"
      close databases
   case mComando == "cont"
      continue
      if LastKey() == 27
         SayScroll("Interrompido")
      Elseif Eof()
         SayScroll("Fim de arquivo")
      Endif
   case mComando == "copy"
      RotinaCopy()
   case mComando == "crea"
      RotinaCreate()
   case mComando == "dele"
      RotinaDelete()
   case mComando == "dir"
      RotinaDir(mTexto)
   case mComando == "edit"
      RotinaEdit()
   case mComando == "ejec"
      eject
   case mComando == "inde"
      if Lower(PegaParam(@mTexto," ")) != "on"
         SayScroll("Erro de sintaxe")
         loop
      Endif
      mChave := AllTrim(Substr(mTexto,1,At(" to ",Lower(mTexto))-1))
      if .Not. Type(mChave) $ "NCD"
         SayScroll("Chave invalida")
         loop
      Endif
      mArquivo := AllTrim(Substr(mTexto,At(" to ",Lower(mTexto))+4))
      if Len(mArquivo) == 0
         SayScroll("Arquivo invalido")
         loop
      Endif
      index on &mChave tag jpa to &mArquivo
      SayScroll(Str(LastRec()) + " registro(s) indexado(s)")
   case mComando == "loca"
      RotinaLocate()
   case mComando == "modi"
      RotinaModify()
   case mComando == "pack"
      pack
      SayScroll(Str(LastRec()) + " registro(s) copiado(s)")
   case mComando == "reca"
      RotinaRecall(mTexto)
   case mComando == "rein"
      reindex
      SayScroll(Str(LastRec()) + " registro(s) reindexado(s)")
   case mComando == "repl"
      RotinaReplace()
   case mComando == "seek"
      if Len(Trim(OrdKey())) == 0
         SayScroll("Arquivo nao indexado")
      Elseif Type(mTexto) != Type(OrdKey())
         SayScroll("Ordem do arquivo nao combina com chave digitada")
      Else
         seek &mTexto
         if Eof()
            SayScroll("Nao encontrado")
         Endif
      Endif
   case mComando == "sele"
      if Select(mTexto) == 0
         SayScroll("Area nao existe")
      Else
         select (Select(mTexto))
      Endif
   case mComando == "set"
      RotinaSet(mTexto)
   case mComando == "skip"
      if Empty(mTexto)
         skip
      Elseif Type(mTexto) != "N"
         SayScroll("Nao foi informado numero")
      Elseif &mTexto < 0 .And. Bof()
         SayScroll("Ja' esta' no inicio do arquivo")
      Elseif &mTexto > 0 .And. Eof()
         SayScroll("Ja' esta' no fim do arquivo")
      Else
         skip &mTexto
      Endif
   case mComando == "sum"
      RotinaSum()
   case mComando == "unlo"
      if mTexto == "all"
         unlock all
      Else
         unlock
      Endif
   case mComando == "use"
      RotinaUse()
   case mComando == "zap"
      zap
      SayScroll("Arquivo foi limpo")
   case mComando == "stor"
      RotinaStore()
   case Left(mTexto,1) == "="
      mTexto := Substr(mTexto,2) + " to " + mComando
      RotinaStore()
   otherwise
      SayScroll("Comando invalido")
   EndCase
   dbCommitAll()
Enddo
close databases
set unique    off
set Exclusive off
set deleted   on
set confirm   on
MsgExclamation( "Se voce alterou algo, e' obrigatoria a reindexacao!")
Return
*----------------------------------------------------------------


// Separa parametros do comando

function PegaParam(mTexto,mTipo,mLista)

private mParametro, mTemp, mContini, mContfim

mTexto = AllTrim(mTexto)

Do Case
case mTipo == " "  .or. mTipo == ","
   mParametro = substr( mTexto, 1, at( mTipo, mTexto + mTipo ) - 1 )
   mTexto = substr( mTexto, at( mTipo, mTexto + mTipo ) + 1 )
   mParametro = AllTrim(mParametro)
   mTexto = AllTrim(mTexto)
   Return mParametro

case mTipo == "alias"
   mTexto = " " + mTexto + " "
   mContini = at( " alias ", mTexto )
   if mContini = 0
      Return ""
   Endif
   mContfim = mContini + 7
   Do While substr( mTexto, mContfim, 1 ) == " " ;
      .And. mContfim < len( mTexto )
      mContfim = mContfim + 1
   Enddo
   mParametro = AllTrim(PegaParam(substr(mTexto,mContfim)," "))
   mTexto = substr( mTexto, 1, mContini ) + ;
             substr( mTexto, mContfim + len( mParametro ) + 1 )
   mTexto = AllTrim(mTexto)
   Return mParametro

case mTipo == "set"
   mParametro = ""
   if Lower( mTexto ) == "on"
      mParametro = .t.
   Elseif Lower( mTexto ) == "off"
      mParametro = .f.
   Elseif Type( mTexto ) == "L"
      mParametro = &mTexto
   Endif
   Return mParametro

case mTipo == "par,"
   mParametro = 0
   Do While len( mTexto ) > 0
      mTemp = ""
      Do While len( mTexto ) > 0
         mContini = at( ",", mTexto + "," )
         mTemp    = mTemp + substr( mTexto, 1, mContini - 1 )
         mTexto   = substr( mTexto, mContini + 1 )
         if Type(mTemp) $ "NCDLM"
            Exit
         Endif
         mTemp = mTemp + ","
      Enddo
      mParametro = mParametro + 1
      mLista[ mParametro ] = mTemp
   Enddo
   Return mParametro

case mTipo == "escopo"

// localiza posicao de escopos e condicoes

   for mCont = 1 to 5
      Do Case
      case mCont = 1
         mTipo = "all"
      case mCont = 2
         mTipo = "next"
      case mCont = 3
         mTipo = "record"
      case mCont = 4
         mTipo = "for"
      case mCont = 5
         mTipo = "while"
      EndCase
      mTexto = " " + mTexto + " "
      Declare m_Posi[ 6 ]
      mContfor  = at( " for ", Lower( mTexto ) )
      mContwhil = at( " while ", Lower( mTexto ) )
      if mContwhil = 0
         mContwhil = at( " whil ", Lower( mTexto ) )
      Endif
      mContall  = at( " all ",  Lower( mTexto ) )
      mContnext = at( " next ", Lower( mTexto ) )
      mContReco = at( " record ", Lower( mTexto ) )
      if mContReco = 0
         mContReco = at( " recor ", Lower( mTexto ) )
         if mContReco = 0
            mContReco = at( " reco ", Lower( mTexto ) )
         Endif
      Endif
      m_Posi[ 1 ] = mContall
      m_Posi[ 2 ] = mContnext
      m_Posi[ 3 ] = mContReco
      m_Posi[ 4 ] = len( mTexto )
      m_Posi[ 5 ] = mContfor
      m_Posi[ 6 ] = mContwhil
      asort( m_Posi )

// retira parametro all

      Do Case
      case mTipo = "all" .And. mContall != 0
         m_all    = .t.
         m_Inicio = ascan( m_Posi, mContall )
         m_Final  = m_Posi[ m_Inicio + 1 ]
         mTexto  = stuff( mTexto, mContall, 4, "" )

// retira e valida parametro next

      case mTipo == "next" .And. mContnext != 0
         m_Inicio = ascan( m_Posi, mContnext )
         m_Final  = m_Posi[ m_Inicio + 1 ]
         m_Next   = substr( mTexto, mContnext+1, m_Final - mContnext )
         mTexto  = stuff( mTexto, mContnext, m_Final - mContnext, "" )
         m_Next   = substr( m_Next, at( " ", m_Next ) )
         m_all    = .f.
         if Type( m_Next ) != "N"
            SayScroll("NEXT invalido")
            Return .f.
         Endif
         if &m_Next < 0
            SayScroll("NEXT invalido")
            Return .f.
         Endif
         m_Next = &m_Next

// retira e valida parametro record

      case mTipo=="record" .And. mContReco != 0
         m_Inicio = ascan( m_Posi, mContReco )
         m_Final  = m_Posi[ m_Inicio + 1 ]
         m_Record = substr( mTexto, mContReco+1, m_Final - mContReco )
         mTexto  = stuff( mTexto, mContReco, m_Final - mContReco, "" )
         m_Record = substr( m_Record, at( " ", m_Record ) )
         if Type( m_Record ) != "N"
            SayScroll("RECORD invalido")
            Return .f.
         Endif
         m_Record = &m_Record
         if m_Record < 1 .or. m_Record > lastrec()
            SayScroll("Registro indicado nao existe")
            Return .f.
         Endif

// retira e valida parametro for

      case mTipo=="for" .And. mContfor != 0
         m_Inicio = ascan( m_Posi, mContfor )
         m_Final  = m_Posi[ m_Inicio + 1 ]
         m_For    = substr( mTexto, mContfor+1, m_Final - mContfor )
         mTexto  = stuff( mTexto, mContfor, m_Final - mContfor, "" )
         m_For    = substr( m_For, at( " ", m_For ) )
         m_all    = .t.
         if Type( m_For ) != "L"
            SayScroll("FOR invalido")
            Return .f.
         Endif

// retira e valida parametro while

      case mTipo=="while" .And. mContwhil != 0
         m_Inicio = ascan( m_Posi, mContwhil )
         m_Final  = m_Posi[ m_Inicio + 1 ]
         m_while  = substr( mTexto, mContwhil+1, m_Final - mContwhil )
         mTexto  = stuff( mTexto, mContwhil, m_Final - mContwhil, "" )
         m_while  = substr( m_while, at( " ", m_while ) )
         m_all    = .f.
         if Type( m_while ) != "L"
            SayScroll("WHILE invalido")
            Return .f.
         Endif
      EndCase
      mTexto = alltrim( mTexto )
   next
   mParametro = .t.

case mTipo == "to"
   mTexto = " " + mTexto + " "
   mParametro = ""
   if " to " $ Lower( mTexto )
      mParametro = AllTrim(Lower( substr( mTexto, at( " to ", Lower( mTexto ) ) + 4 ) ))
      if mParametro == "prin"
         mParametro = "print"
      Endif
      mTexto = AllTrim(substr( mTexto, 1, at( " to ", Lower( mTexto ) ) - 1 ))
   Endif

case mTipo == "structure" .or. mTipo == "status" ;
     .or. mTipo == "Exclusive" .or. mTipo == "index" ;
     .or. mTipo == "sdf" .or. mTipo == "extended"

   mTexto = " " + mTexto + " "
   mParametro = .f.
   for mCont = 4 to 9
      m_procu = " " + substr( mTipo, 1, mCont ) + " "
      if m_procu $ Lower( mTexto )
         mParametro = .t.
         mTexto = stuff( mTexto, at( m_procu, ;
                   Lower( mTexto ) ), len( m_procu ) - 1, "" )
      Endif
   next
   mTexto = alltrim( mTexto )

otherwise
   clear
   SayScroll("Erro de sintaxe")
   cancel
EndCase
mTexto := AllTrim(mTexto)
Return mParametro
*----------------------------------------------------------------


// Valida parametro conforme o uso

Static Function Param_ok
Parameters mTexto, mTipo
Local nCont

Do Case
case mTipo == "alias"
   if len( mTexto ) = 1  .or. val( mTexto ) # 0
      Return .f.
   Endif
   For nCont = 1 To Len( mTexto )
      if .Not. Lower( Substr( mTexto, nCont, 1 ) ) $ ;
               "abcdefghijklmnopqrstuvwxyz_0123456789"
         Return .f.
      Endif
   Next
   Return .t.

EndCase
Return .f.
*----------------------------------------------------------------


Static Function RotinaDelete()

m_all    = .f.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."
if .Not. PegaParam( @mTexto, "escopo" )
   Return
Endif

if len( mTexto ) != 0
   SayScroll("Invalido " + mTexto)
   Return
Endif

if m_Record=0 .And. m_Next=0 .And. m_For == ".t." ;
              .And. m_while == ".t." .And. .Not. m_all
   m_Record = recno()
Endif

// executa comando

Do Case
case m_all
   GoTo top
case m_Record != 0
   GoTo m_Record
EndCase

m_Contreg = 0
m_Contdel = 0
mInkey   = 0
SayScroll()
Do While mInkey != 27 .And. .Not. Eof()
   mInkey = MyInkey()
   if .Not. &m_while
      Exit
   Endif
   m_Contreg = m_Contreg + 1
   if &m_For
      exclui(.t.)
      m_Contdel = m_Contdel + 1
      if mod( m_Contdel, CfgOdometer ) = 0
         @ MaxRow()-3, 0 Say str(m_Contdel) + " registro(s) deletado(s)"
      Endif
   Endif
   if m_Record != 0
      Exit
   Endif
   skip
   if m_Contreg = m_Next
      Exit
   Endif
Enddo
@ MaxRow()-3, 0 Say str(m_Contdel)+ " registro(s) deletado(s)"
if LastKey() = 27
   SayScroll("Interrompido")
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaEdit()

if len( mTexto ) != 0
   if Type( mTexto ) != "N"
      SayScroll("So' pode ser numero")
      Return
   Endif
   if &mTexto < 1 .or. &mTexto > LastRec()
      SayScroll("Numero de registro invalido")
      Return
   Endif
   GoTo &mTexto
Endif

// edita registro

m_inclui = Eof()
m_fCount = fCount()
mPageRec := MaxRow()-6
m_QtTela = int( ( m_fCount + mPageRec - 1 ) / mPageRec)
Declare m_Name[ m_fCount ], m_Type[ m_fcount ], ;
        m_Len[  m_fCount ], m_Dec[  m_fcount ], ;
        m_Pic[  m_fCount ], m_Read[ m_fcount ]

afields( m_name, m_type, m_len, m_dec )

Do While .t.
   if .Not. m_inclui
      if .Not. rLock()
         SayScroll("Nao foi possivel travar o registro")
         Return
      Endif
   Endif
   for m_Cont = 1 to m_fcount
       m_Conteudo       = m_name[ m_Cont ]
       m_read[ m_Cont ] = &m_Conteudo
       m_pic[ m_Cont ]  = ""
       if Type( m_Conteudo ) = "C"
          m_pic[ m_Cont ] = iif( len( &m_Conteudo ) > (MaxCol()-25), "@S"+Ltrim(Str(MaxCol()-25)), "@X" )
       Endif
   next
   m_grava = .f.
   m_tela  = 1
   Do While .t.
      Scroll(2,0,MaxRow()-3,MaxCol(),0)
      m_ini = m_tela * mPageRec - mPageRec + 1
      m_fim = iif( m_tela = m_qttela, m_fcount, m_ini + mPageRec - 1 )
      @ 2,1 Say iif( m_inclui .or. Eof(), "INCLUSAO ", "ALTERACAO" ) + ;
                " - Registro.: " + STR( RecNo() ) + ;
                "   " + iif( deleted(),"(EXCLUIDO)","")
      For m_Cont = m_ini To m_fim
          @ m_Cont + 3 - m_ini, 1 Say Pad( m_name[ m_Cont ],18,".") + ": " ;
                   Get m_read[ m_Cont ] Picture ( m_pic[ m_Cont ] )
      Next
      Read
      m_grava = iif( updated(), .t., m_grava )
      Do Case
      case LastKey() = 27
         Exit
      case LastKey() = 18 // .or. (LastKey()==5 .And. Pad(ReadVar(),10) == Pad(GetList[1,2],10))
         m_tela = m_tela - 1
      case LastKey() = 23
         m_grava = .t.
         Exit
      otherwise
         m_tela = m_tela + 1
      EndCase
      if m_tela < 1 .or. m_tela > m_qttela
         Exit
      Endif
   Enddo
   if LastKey() != 27 .And. m_grava
      if m_inclui .or. Eof()
         append blank
         Do While NetErr()
            MyInkey(.2)
            append blank
         Enddo
      Endif
      for m_Cont = 1 to m_fcount
         m_campo = m_name[ m_Cont ]
         replace &m_campo with m_read[ m_Cont ]
      next
   Endif
   Do Case
   case LastKey()=27 .or. LastKey()=23
      Exit
   case LastKey()=18
      if .Not. bof()
         skip -1
      Endif
      if bof()
         Exit
      Endif
      if m_inclui
         m_inclui = .f.
      Endif
   otherwise
      if .Not. Eof()
         skip
      Endif
      if Eof() .And. .Not. m_inclui
         m_inclui = .t.
      Endif
   EndCase
Enddo
Return NIL
*----------------------------------------------------------------


Static Function RotinaList()
parameters m_All

m_toname  = PegaParam( @mTexto, "to" )
m_status  = PegaParam( @mTexto, "status" )
m_struct  = PegaParam( @mTexto, "structure" )

m_Cont = 0 + iif( m_status, 1, 0 ) + iif( m_struct, 1, 0 ) + ;
             iif( len( mTexto )=0, 0, 1 )

if m_Cont > 1
   SayScroll("Parametros invalidos")
   Return NIL
Endif

Do Case
case m_status
   RotinaListStatus()
case m_struct
   RotinaListStructure()
otherwise
   RotinaListData()
EndCase

if LastKey() = 27
   SayScroll("Interrompido")
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaListStatus()

m_select = select()
for m_Cont = 1 to 255
   if len( trim( alias( m_Cont ) ) ) != 0
      select ( m_Cont )
      SayScroll()
      SayScroll("Area " + Str(m_Cont,2) + " -> " + Alias() + ;
         iif( m_Cont == m_Select, "  ==> Area Atual", "" ))
      For m_Cont2 = 1 To 100
         if len( trim( OrdKey(m_Cont2 ) ) ) == 0
            Exit
         Endif
         SayScroll("   Tag "+OrdName(m_Cont2)+ " -> " + OrdKey(m_Cont2))
      Next
      if len( trim( dbfilter() ) ) != 0
         SayScroll("          Filtro: ", dbfilter())
      Endif
      if len( trim( dbrelation() ) ) != 0
         SayScroll("          Relacao: " + dbRelation() + ;
            " Area: " + Alias(dbRSelect()) )
      Endif
   Endif
next
select ( m_select )
SayScroll("Diretorio atual -> " + DirPath() )
SayScroll()
Return NIL
*----------------------------------------------------------------


Static Function RotinaListStructure()

m_fcount = fcount()
declare m_nome[ m_fcount ], m_tipo[ m_fcount ], ;
        m_tam[ m_fcount ], m_dec[ m_fcount ]

afields( m_nome, m_tipo, m_tam, m_dec )

SayScroll("Nome do arquivo.: " + Alias())
SayScroll("Qtde. Registros.: " + lTrim(Str(LastRec())))
SayScroll()
SayScroll("Seq  ---Nome---  Tipo  Tamanho  Decimais")
SayScroll()
m_lin = 5
for m_Cont = 1 to m_fcount
   SayScroll( Str(m_Cont,3) + "  " + pad( m_nome[ m_Cont ], 14 ) + ;
     m_tipo[ m_Cont ] + "      " + str( m_tam[ m_Cont ], 3 ) + ;
     "      " + str( m_dec[ m_Cont ], 3 ) )
   m_lin = m_lin + 1
   if m_lin > (MaxRow()-8) .And. Len(Trim(m_toname)) == 0
      SayScroll("Tecle algo para prosseguir")
      MyInkey(0)
      if LastKey() == 27
         Exit
      Endif
      m_lin = 0
   Endif
next
if LastKey() != 27
   SayScroll()
   SayScroll("Tamanho total do registro.: " + str( recsize() ) + " bytes")
   SayScroll()
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaListData()

m_all    = .f.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."

mTexto = " " + mTexto + " "

if " all " $ Lower( mTexto )
   mTexto = stuff( mTexto, at( " all ", mTexto ), 4, "" )
   m_all   = .t.
Endif

if mComando == "list"
   m_all = .t.
Endif

if .Not. PegaParam( @mTexto, "escopo" )
   Return
Endif

if m_Record=0 .And. m_Next=0 .And. m_For == ".t." ;
              .And. m_while == ".t."
   if .Not. m_all
      m_Record = recno()
   Else
      m_all    = .t.
   Endif
Endif

// prepara lista dos dados

mTexto = alltrim( mTexto )
declare m_lista[ 100 ]
if len( mTexto ) = 0
   afields( m_lista )
   m_qtparam = fcount()
Else
   m_qtparam = PegaParam( mTexto, "par,", @m_lista )
Endif

// lista do indicado

Do Case
case m_all
   GoTo top
case m_Record != 0
   GoTo m_Record
EndCase

m_Contreg = 0
m_Contdis = 0
mInkey   = 0
Do While mInkey != 27 .And. .Not. Eof()
   mInkey = MyInkey()
   if .Not. &m_while
      Exit
   Endif
   m_Contreg = m_Contreg + 1
   mTexto := ""
   if &m_For
      mTexto := mTexto + Str(RecNo(),6) + " " + ;
         iif( Deleted(), "del", "   ") + " "
      for m_Cont = 1 to m_qtparam
         m_item = m_lista[ m_Cont ]
         if .Not. Type( m_item ) $ "NCLDM"
            if right( m_item, 1 ) == ","
               m_item = substr( m_item, 1, len( m_item ) - 1 )
            Endif
            SayScroll("Variavel nao encontrada")
            Return
         Endif
         Do Case
         case Type( m_item ) $ "CLDN"
            mTexto += Transform(&m_Item,"")
         case Type( m_item ) = "M"
            mTexto += "memo"
         EndCase
         if m_Cont != m_qtparam
            mTexto += " "
         Endif
      next
      mTexto := Trim(mTexto)
      Do While Len(mTexto) != 0
         SayScroll(Left(mTexto,MaxCol()+1))
         mTexto := Substr(mTexto,MaxCol()+2)
      Enddo
      m_Contdis = m_Contdis + 1
   Endif
   if m_Record != 0
      Exit
   Endif
   skip
   if m_Contreg = m_Next
      Exit
   Endif
Enddo
Return NIL
*----------------------------------------------------------------


Static Function RotinaModify()

m_tipo   = Lower( PegaParam( @mTexto, " " ) )

Do Case
case empty( m_tipo )
   SayScroll("Faltou parametros")

case len( m_tipo ) < 4
   SayScroll("parametro invalido")

case Lower( m_tipo ) == substr( "structure", 1, len( m_tipo ) )
   do RotinaModifyStructure with mTexto

case Lower( m_tipo ) == substr( "command", 1, len( m_tipo ) )
   do RotinaModifyCommand with mTexto

otherwise
   SayScroll("parametro invalido")

EndCase
Return NIL
*----------------------------------------------------------------


Static Function RotinaModifyCommand(cFileName)

if len( trim( cFileName) ) = 0
   SayScroll("faltou o nome do programa")
   Return
Endif

if .Not. "." $ cFileName
   cFileName = cFileName + ".pro"
Endif

wSave()
RotinaEditAFile(cFileName)
wRestore()
SayScroll()
Return NIL
*----------------------------------------------------------------


Static Function RotinaEditAFile(cFileName)

if Type( "cFileName" ) != "C"
   cFileName = "none"
Endif

store .f. to altered
store 0   to ret_val
cTexto := memoread(cFileName)

clear
@ 1, 0 to MaxRow()-1, MaxCol()

@ MaxRow(), 0 Say Pad(Lower(cFileName),54)

cTexto = memoedit(cTexto,2,1,MaxRow()-2,MaxCol()-1,.t.,"mfunc",132,3)

if .Not. cFileName=="none" .And. .Not. Empty(cTexto) .And. ret_val==23
   altered = .F.

   DosRun( "copy " + cFileName + " *.bak > nul" )

   memowrit( cFileName, cTexto)

Endif

Return NIL
*----------------------------------------------------------------


****
*       mfunc()
*
*       memoedit user function
****
function mfunc

parameters mode, line, col
private keypress

ret_val = 0

Do Case

case mode = 3

case mode = 0
   * idle
   @ MaxRow(), MaxCol()-20 Say "line: " + pad( ltrim( str( line ) ), 4 )
   @ MaxRow(), MaxCol()-8 Say "col: "  + pad( ltrim( str( col ) ), 3 )

otherwise
   * keystroke exception
   keypress = LastKey()

   * save values to possibly resume edit
   line_num = line
   col_num  = col
   rel_row  = row() - 2
   rel_col  = col() - 1

   if mode = 2
      altered = .t.

   Endif

   Do Case

   case keypress = 23
      * ctr-w..write file
      if .Not. altered
         * no changes to write
         @ MaxRow(), 0 Say pad( "nenhuma alteracao a gravar.", 54 )

      Else
         * write and resume
         @ MaxRow(), 0 Say space( 54 )
         @ MaxRow(), 0 Say "gravando " + Lower( memofile ) + "..."
         ret_val = 23

      Endif

   case keypress = 27
      * esc..Exit
      if .Not. altered
         * no change
         ret_val = 27

      Else
         * changes have been made to memo
         Response := iif(MsgYesNo("Abandona?"),"S","N")
         Do Case
         case response = "s"
            * abort
            ret_val = 27

         case response = "n"
            * ignore
            ret_val = 32

         case response = "g"
            * save and Exit
            Mensagem("gravando " + Lower( memofile ) + "...")
            ret_val = 23

         EndCase
      Endif

   EndCase
EndCase
Return ret_val
*----------------------------------------------------------------


Function RotinaCreate()

if Empty(mTexto)
   SayScroll("Parametros invalidos")
   Return NIL
Endif

if " from " $ Lower( " " + mTexto + " " )
   m_Posi  = at( " from ", Lower( " " + mTexto + " " ) )
   m_from  = substr( mTexto, m_Posi + 5 )
   mTexto = substr( mTexto, 1, m_Posi - 1 )
   if mTexto == ""
      SayScroll("Faltou o nome do arquivo")
      Return
   Endif
   if .Not. "." $ m_from
      m_from = m_from + ".dbf"
   Endif
   if .Not. file( m_from )
      SayScroll("Arquivo de origem nao existe")
      Return
   Endif
   if .Not. "." $ mTexto
      mTexto = mTexto + ".dbf"
   Endif
   if file( mTexto )
      if .Not. MsgYesNo("Arquivo ja existe, sobrepor?")
         Return
      Endif
   Endif
   create ( mTexto ) from ( m_from )
   Return NIL
Endif

if .Not. "." $ mTexto
   mTexto = mTexto + ".dbf"
Endif

if file( mTexto + ".dbf" )
   if .Not. MsgYesNo("Arquivo ja existe, sobrepor?")
      Return NIL
   Endif
Endif

RotinaModifyStructure(mTexto)
Return NIL
*----------------------------------------------------------------


Static Function RotinaSum()

// valida parametros

m_to     = PegaParam( @mTexto, "to" )
m_all    = .f.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."

if .Not. PegaParam( @mTexto, "escopo" )
   Return NIL
Endif

if m_Record=0 .And. m_Next=0 .And. m_For == ".t." ;
              .And. m_while == ".t." .And. .Not. m_all
   m_Record = recno()
Endif

declare m_lista[ 100 ], m_soma[ 100 ], m_vari[ 100 ]
afill( m_soma, 0  )

m_qtparam = PegaParam( @mTexto, "par,", @m_lista )
m_qtvar   = PegaParam( @m_to,    "par,", @m_vari  )

if m_qtvar != 0 .And. m_qtvar != m_qtparam .or. len( mTexto ) != 0
   SayScroll("Parametros invalidos")
   Return NIL
Endif

for m_Cont = 1 to m_qtparam
   m_item = m_lista[ m_Cont ]
   if Type( m_item ) != "N"
      SayScroll("Campo nao numerico")
      Return NIL
   Endif
next

// executa comando

Do Case
case m_all
   GoTo top
case m_Record != 0
   GoTo m_Record
EndCase

m_Contreg = 0
m_Contsum = 0
mInkey   = 0
SayScroll()
Do While mInkey != 27 .And. .Not. Eof()
   mInkey = MyInkey()
   if .Not. &m_while
      Exit
   Endif
   m_Contreg = m_Contreg + 1
   if &m_For
      for m_Cont = 1 to m_qtparam
         m_item = m_lista[ m_Cont ]
         m_soma[ m_Cont ] = m_soma[ m_Cont ] + &m_item
      next
      m_Contsum = m_Contsum + 1
         if mod( m_Contsum, CfgOdometer ) = 0
            @ MaxRow()-3, 0 Say str(m_Contsum) + " registro(s) somado(s)"
         Endif
   Endif
   if m_Record != 0
      Exit
   Endif
   skip
   if m_Contreg = m_Next
      Exit
   Endif
Enddo
@ MaxRow()-3, 0 Say str(m_Contsum)+" registro(s) somado(s)"
mTexto := ""
for m_Cont = 1 to m_qtparam
   mTexto += Str( m_soma[m_Cont] ) + " "
next
SayScroll(mTexto)
if LastKey() = 27
   SayScroll("Interrompido")
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaSetRelation(cComando)
Local lAdditive := .f., cTrecho := "", cRelationTo := "", cRelationInto := "", nSelect := 0
Local nCont := 0, nQtRelation := 0
Local cOrdKeyFromType := cOrdKeyToType := ""

cTrecho := PegaParam(cComando," ")
if Lower(cTrecho) == substr( "additive", 1, Max( Len( cTrecho ), 4 ) )
   lAdditive = .t.
   cTrecho := PegaParam(@cComando," ")
Endif

if .Not. lAdditive
   Set Relation To
Endif

if Empty(cComando)
   Return NIL
Endif

if .Not. " into " $ Lower(cComando)
   SayScroll("Parametros invalidos")
   Return NIL
Endif

// retira parametros to, into

Declare acRelationTo[8],acRelationInto[8]
afill( acRelationTo, "" )
afill( acRelationInto, "" )
nQtRelation := 0
Do While Len(cComando) != 0 .And. nQtRelation < 8
   nQtRelation += 1
   acRelationTo[ nQtRelation ]   = substr( cComando, 1, at( " into ", Lower( cComando) )-1 )
   acRelationInto[ nQtRelation ] = substr( cComando, at( " into ", Lower( cComando ) ) + 6 )
Enddo

// valida relacoes, valida alias e executa

if .Not. lAdditive
   set relation to
Endif

For nCont = 1 to nQtRelation - 1

   cRelationInto := acRelationInto[nCont]
   cRelationTo   := acRelationTo[nCont]

   if Type( cRelationInto ) = "N"
      if Alias(cRelationInto) = 0
         SayScroll("Area nao esta' em uso " + cRelationInto)
         Return NIL
      Endif
   Elseif Select(cRelationInto) = 0
      SayScroll("Area nao esta' em uso " + cRelationInto)
      Return NIL
   Endif
   nSelect := Select()
   select (Select(cRelationInto))
   If Empty( OrdKey() )
      if cRelationTo != "recno()"
         Select (nSelect)
         SayScroll("Sem indice nao pode ser feito este relacionamento")
         Return NIL
      Endif
   Else
      cOrdKeyFromType := Type(OrdKey(IndexOrd()))
      Select (nSelect)
      cOrdKeyToType := Type(cRelationTo)
      if cOrdKeyFromType != cOrdKeyToType
         Select (nSelect)
         SayScroll("Tipo da chave "+cOrdKeyToType+", tipo indicado "+cOrdKeyFromType)
         Return NIL
      Endif
   Endif
   Select (nSelect)
   Set Relation Additive To &(cRelationTo) into &(cRelationInto)

Next
Return NIL
*----------------------------------------------------------------


Static Function RotinaStore()

if .Not. " to " $ Lower( mTexto )
   SayScroll("Faltou TO")
   Return NIL
Endif

m_nomvar = PegaParam( @mTexto, "to" )
m_Conte  = mTexto

if .Not. Type( m_Conte ) $ "NCLD"
   SayScroll("Conteudo invalido")
   Return NIL
Endif

//declare m_lista[ 100 ]
//m_qtparam = PegaParam( @mTexto, "par,", @m_lista )
//
//for m_Cont = 1 to m_qtparam
//   m_nomevar  = m_lista[ m_Cont ]
   &m_nomvar = &m_Conte
//next
Return NIL
*----------------------------------------------------------------


Static Function RotinaAppend()

if Empty(mTexto)
   GoTo bottom
   skip
   RotinaEdit("append")
   Return NIL
Endif

// verifica se e' append blank

if Lower( mTexto ) == "blan" .or. Lower( mTexto ) == "blank"
   append blank
   Do While NetErr()
      MyInkey(.2)
      append blank
   Enddo
   Return NIL
Endif

// valida append from

if Lower(PegaParam( @mTexto, " " )) != "from"
   SayScroll("Parametro invalido")
   Return NIL
Endif

// parametros default

m_For    = ".t."
m_while  = ".t."
m_sdf    = .f.
m_all    = .f.
m_Record = 0
m_Next   = 0

// valida para append sdf

m_sdf      = PegaParam( @mTexto, "sdf" )

m_filename = PegaParam( @mTexto, " " )

if .Not. "." $ m_filename
   m_filename = m_filename + iif( m_sdf, ".txt", ".dbf" )
Endif

if .Not. file( m_filename )
   SayScroll("Arquivo nao existe")
   Return NIL
Endif

if select( m_filename ) != 0
   SayScroll("Arquivo esta' em uso")
   Return NIL
Endif

if .Not. PegaParam( @mTexto, "escopo" )
   Return NIL
Endif

if len( mTexto ) != 0 .or. m_Record != 0 .or. m_Next != 0 .or. m_While != ".t."
   SayScroll("Parametros invalidos para APPEND")
   Return NIL
Endif

// executa comando

mQtRec := LastRec()
if m_sdf
   append from &m_filename for &m_For while ( MyInkey()!=27 ) sdf
Else
   append from &m_filename for &m_For while ( MyInkey()!=27 )
Endif
SayScroll(Ltrim(Str(LastRec()-mQtRec))+" Registro(s) incluso(s)")
Return NIL
*----------------------------------------------------------------


Static Function RotinaCopy()

// valida parametros

m_all    = .f.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."
m_struct = PegaParam( @mTexto, "structure" )
m_extend = PegaParam( @mTexto, "extended" )
m_sdf    = PegaParam( @mTexto, "sdf" )
m_To     = PegaParam( @mTexto,"to")
if .Not. PegaParam( @mTexto, "escopo" )
   Return NIL
Endif
if len( mTexto ) != 0
   SayScroll("Parametro invalido " + mTexto)
   Return NIL
Endif
if len( m_to ) = 0
   SayScroll("Faltou o arquivo destino")
   Return NIL
Endif
if m_Next == 0 .And. m_Record == 0
   m_Next := LastRec()
Endif

if .Not. "." $ m_to
   m_to = m_to + ".dbf"
Endif

if file( m_to )
   if .Not. MsgYesNo("Arquivo ja' existe, sobrepor?")
      SayScroll("Operacao cancelada")
      Return NIL
   Endif
Endif

Do Case
case m_struct
   if m_extend
      copy to ( m_to ) structure extended
   Else
      copy to ( m_to ) structure
   Endif

case m_Record != 0
   if m_Sdbf
      copy to (m_To) sdf record (m_Record)
   Else
      copy to (m_To) record (m_Record)
   Endif

case m_While != ".t." .or. "while .t." $ Lower(CfgHistoTxt[CfgHistNum])
   if m_Sdbf
      copy to (m_To) for &m_For while &m_While next m_Next sdf
   Else
      copy to (m_To) for &m_For while &m_While next m_Next
   Endif

case .Not. m_Next != 0
   if m_Sdf
      copy to (m_To) for &m_For next m_Next sdf
   Else
      copy to (m_To) for &m_For next m_Next
   Endif

otherwise
   GoTo top
   if m_sdf
      copy to ( m_to ) for &m_For sdf
   Else
      copy to ( m_to ) for &m_For
   Endif

EndCase
Return NIL
*----------------------------------------------------------------


Static Function RotinaReplace()

m_all    = .f.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."

if " all " $ Lower( mTexto )
   m_all = .t.
   mTexto = stuff( mTexto, at( " all ", Lower( mTexto ) ), 4, "" )
Endif

if .Not. PegaParam( @mTexto, "escopo" )
   Return NIL
Endif

if m_Record=0 .And. m_Next=0 .And. m_For == ".t." ;
              .And. m_while=".t." .And. .Not. m_all
   m_Record = recno()
Endif

// retira nomes dos campos e conteudos

if len( mTexto ) = 0
   SayScroll("Parametros invalidos")
   Return NIL
Endif

declare m_name[ 100 ], m_with[ 100 ]
afill( m_name, "" )
m_Cont = 1
Do While len( mTexto) > 0
   m_expr  = alltrim( substr( mTexto, rat( " with ", ;
             Lower( mTexto ) ) + 5 ) )
   mTexto = alltrim( substr( mTexto, 1, rat( " with ", ;
             Lower( mTexto ) ) ) )
   mTexto = "," + mTexto
   m_campo = alltrim( substr( mTexto, rat( ",", ;
             Lower( mTexto ) ) + 1 ) )
   mTexto = alltrim( substr( mTexto, 2, rat( ",", ;
             Lower( mTexto ) ) - 2 ) )
   Do Case
   case Type( m_expr ) $ "U,UI,UE"
      SayScroll("Expressao invalida")
      Return NIL

   case Type( m_campo ) $ "U,UI,UE"
      SayScroll("Campo invalido")
      Return NIL

   case Type( m_campo ) != Type( m_expr )
      SayScroll("Tipos nao combinam -> " + m_campo + " with " + m_expr)
      Return NIL
   EndCase
   m_name[ m_Cont ] = m_campo
   m_with[ m_Cont ] = m_expr
   m_Cont = m_Cont + 1
Enddo

// executa comando

Do Case
case m_all
   GoTo top
case m_Record != 0
   GoTo m_Record
EndCase

m_Contreg = 0
m_Contrep = 0
mInkey   = 0
SayScroll()
Do While mInkey != 27 .And. .Not. Eof()
   mInkey = MyInkey()
   if .Not. &m_while
      Exit
   Endif
   m_Contreg = m_Contreg + 1
   if &m_For
      Do While .t.
         if rLock()
            Exit
         Endif
         @ Row(), 0 Say space(79)
         @ Row(), 0 Say "Aguardando liberacao do registro " + ;
                    str( recno() )
      Enddo

      m_Cont = 1
      for m_Cont = 1 to 100
         if len( m_name[ m_Cont ] ) = 0
            Exit
         Endif
         m_campo = m_name[ m_Cont ]
         m_expr  = m_with[ m_Cont ]
         replace &m_campo with &m_expr
      next

      m_Contrep = m_Contrep + 1
         if mod( m_Contrep, CfgOdometer ) = 0
            @ row(), 0 Say str( m_Contrep ) + ;
               " registro(s) bloqueado(s) e trocado(s)"
         Endif
   Endif
   if m_Record != 0
      Exit
   Endif
   skip
   if m_Contreg = m_Next
      Exit
   Endif
Enddo
@ row(), 0 Say str( m_Contrep ) + ;
   " registro(s) bloqueado(s) e trocado(s)"
if LastKey() = 27
   SayScroll("Operacao cancelada")
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaLocate()

m_all    = .t.
m_Record = 0
m_Next   = 0
m_For    = ".t."
m_while  = ".t."

if .Not. PegaParam( @mTexto, "escopo" )
   Return NIL
Endif

if len( mTexto ) != 0 .or. m_Record != 0
   SayScroll("Parametro invalido " + mTexto)
   Return NIL
Endif

if m_all
   GoTo top
Endif

locate for &m_For while &m_while .And. MyInkey()!=27

if LastKey() = 27
   SayScroll("Operacao cancelada")
Else
   if Eof() .or. .Not. &m_while
      SayScroll("Nao encontrado")
   Endif
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaModifyStructure()

// salva configuracao atual

m_row    = row()
m_col    = col()
wSave()
Scroll(2,0,MaxRow()-3,MaxCol(),0)

// prepara tela da estrutura

@ 4,20 Say "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"
@ 5,20 Say "³                                      ³"
@ 6,20 Say "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´"
@ 7,20 Say "³ Nome         Tipo        Tam.    Dec ³"
@ 8,20 Say "ÃÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄ´"
mTextovazia = "³            ³           ³       ³     ³"
for i=9 to 19
   @ i,20 Say mTextovazia
next
@ 20,20 Say "ÃÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄ´"
@ 21,20 Say "³    ESC ENTER Inclui Exclui Grava   ³"
@ 22,20 Say "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"

m_vetorvazio = substr( mTextovazia, 2, len( mTextovazia ) - 2 )
m_tipos      = "CaractereNumerico Data     Logico   Memo     "

if len( mTexto ) = 0
   mTexto    = Alias()
   m_jaexiste = .T.
Else
   m_jaexiste = .F.
Endif

// mostra campos na tela

declare m_campos[ 200 ]
afill( m_campos, "" )
m_campos[ 1 ] = m_vetorvazio
@ 5, 20 + int( ( 38 - len( mTexto ) ) / 2 ) Say mTexto

if m_jaexiste
   m_regs = fcount()
   declare m_name[ m_regs ], ;
           m_type[ m_regs ], ;
           m_len[  m_regs ], ;
           m_dec[  m_regs]
   afields( m_name, m_type, m_len, m_dec )
   for m_Cont=1 to m_regs
      m_campos[ m_Cont ] = " " + pad( m_name[ m_Cont ], 10 ) + " ³ " + ;
              substr( "CaractereNumerico Logico   Data     Memo     ", ;
              at( m_type[ m_Cont ], "CNLDM" ) * 9 - 8, 9 ) + " ³  " +  ;
              str( m_len[ m_Cont ], 3 ) + "  ³ " + ;
              str( m_dec[ m_Cont ], 3 ) + " "
   next
   m_campos[ m_regs + 1 ] = m_vetorvazio
Endif

// permite selecao e alteracao

m_mudou = .F.
store 1 to m_opc, m_inivet
Do While .t.
   achoice( 9, 21, 19, 58, m_campos, .t., "func_modi", m_opc, m_inivet )
   Do Case
   case LastKey()==27 .or. Lower( chr( LastKey() ) ) == "q"
      if MsgYesNo("Abandona?")
         Exit
      Endif

   case Lower( chr( LastKey() ) ) == "e"
      m_row = ROW()
      IF m_campos[ m_opc ] # m_vetorvazio
         adel(   m_campos, m_opc )
         scroll( m_row, 21, 19, 58, 1 )
         @ 19,21 Say m_vetorvazio
         m_mudou = .t.
      Endif

   case Lower( chr( LastKey() ) ) = "g"
      if m_campos[ 1 ] == m_vetorvazio .or. .Not. m_mudou
         Exit
      Endif
      if .Not. MsgYesNo("Confirma?")
         loop
      Endif
      mTempFile := Sistema:TempFile()
      create (mTempFile)
      for m_Cont = 1 to 200
         if m_campos[ m_Cont ] == m_vetorvazio
            m_Cont = 200
         Else
            m_name = substr( m_campos[ m_Cont ], 2, 10 )
            m_type = substr( m_campos[ m_Cont ], 15, 1 )
            m_len  = val( substr( m_campos[ m_Cont ], 28, 3 ) )
            m_dec  = val( substr( m_campos[ m_Cont ], 35, 3 ) )
            append blank
            replace field_name with m_name, field_type with m_type,;
                    field_len  with m_len,  field_dec  with m_dec
         Endif
      next
      if lastrec() > 0
         if m_jaexiste
            use
            if file(mTexto+".bak")
               fErase(mTexto+".bak")
            Endif
            fRename(mTexto+".dbf",mTexto+".bak")
         Endif
         create (mTexto) from (mTempFile)
         use ( mTexto )
         if m_jaexiste
            append from (mTexto+".bak")
         Endif
         use (mTexto)
      Endif
      fErase(mTempFile)
      Exit

   case Lower( chr( LastKey() ) ) == "i" .or. LastKey()==13
      m_row = ROW()
      if Lower( chr( LastKey() ) ) == "i" .or. ;
         m_campos[ m_opc ] = m_vetorvazio
         if m_row < 19
            scroll( m_row, 21, 19, 58, -1 )
            @ m_row, 21 Say m_vetorvazio
         Endif
         ains( m_campos, m_opc )
         m_campos[ m_opc ] = m_vetorvazio
      Endif
      m_name = substr( m_campos[ m_opc ], 2, 10 )
      m_type = substr( m_campos[ m_opc ], 15, 1 )
      m_len  = val( substr( m_campos[ m_opc ], 28, 3 ) )
      m_dec  = val( substr( m_campos[ m_opc ], 35, 3 ) )
      m_row  = row()
      @ m_row, 22 Get m_name Picture "@!"  Valid name_ok()
      @ m_row, 35 Get m_type Picture "!A"  Valid type_ok()
      @ m_row, 48 Get m_len  Picture "999" Valid len_ok()
      @ m_row, 56 Get m_dec  Picture "99"  Valid dec_ok()
      read
      if LastKey()#27
         m_campos[ m_opc ] = " " + m_name + " ³ " + ;
            substr( m_tipos, at( m_type, m_tipos ), 9 ) + ;
            " ³  " + str( m_len, 3 ) + "  ³ " + str( m_dec, 3 ) + " "
         m_mudou = .t.
      Else
         adel( m_campos, m_opc )
      Endif
   EndCase
Enddo
wRestore()
Return NIL
*----------------------------------------------------------------

// funcao de movimentacao

function func_modi

parameters modo, opc, inivet

m_opc    = opc
m_inivet = inivet
Do Case
case modo#3
   Return 2
case LastKey()=1
   keyboard chr(31)
   Return 2
case LastKey()=6
   keyboard chr(30)
   Return 2
case str( LastKey(), 3 ) $ " 27, 13"
   Return 0
case Lower( chr( LastKey() ) ) $ "qgie"
   Return 0
EndCase
Return 2
*----------------------------------------------------------------

// funcao para validar nome

function name_ok

Do Case
case LastKey() =27
   Return .t.
case empty( m_name )
   Return .f.
EndCase
for m_Cont=1 to 200
   Do Case
   case m_campos[ m_Cont ] = m_vetorvazio
      m_Cont = 200
   case substr( m_campos[ m_Cont ], 2, 10 ) == m_name .And. m_Cont#m_opc
      Return .f.
   EndCase
next
Return .t.
*----------------------------------------------------------------

// funcao para validar tipo

function type_ok

Do Case
CASE m_Type $"CN"
   @ m_row,35 Say iif( Lower( m_type ) == "c", "Caractere","Numerico " )
   Return .t.
case m_Type $ "LDM"
   m_len = iif( Lower( m_type ) == "l", 1, ;
           iif( Lower( m_type ) == "d", 8, 10 ) )
   m_dec = 0
   keyboard chr(13)+chr(13)
   Return .t.
EndCase
@ m_row,35 Say space(9)
Return (LastKey()==5)
*----------------------------------------------------------------

// funcao para validar tamanho

function len_ok

Do Case
case m_Type=="L" .And. m_len=1
   Return .t.
case m_type == "D" .And. m_len=8
  Return .t.
case m_type == "M" .And. m_len=10
   Return .t.
case m_len > 0
   Return .t.
EndCase

Return (LastKey()==5)
*----------------------------------------------------------------

// funcao para validar decimais

function dec_ok

Do Case
case m_type $ "LDM" .And. m_dec=0
   Return .t.
case m_dec > 15 .And. m_type == "N"
   Return .f.
case m_dec >= 0
   Return .t.
EndCase
Return .f.
*----------------------------------------------------------------


Static Function RotinaPrint()
private m_picture, m_lista[ 100 ], m_qtparam, m_item, m_picture

if Empty(mTexto)
   SayScroll()
   Return NIL
Endif

m_qtparam = PegaParam( mTexto, "par,", @m_lista )

mTexto := ""
for m_Cont = 1 to m_qtparam
   m_item = m_lista[ m_Cont ]
   if .Not. Type(m_item) $ "NCLDM"
      if right( m_item, 1 ) == ","
         m_item = substr( m_item, 1, len( m_item ) - 1 )
      Endif
      SayScroll("variavel nao encontrada")
      Return NIL
   Endif
   Do Case
   case Type( m_item ) $ "CLDN"
      mTexto += Transform(&m_Item,"") + " "
   case Type( m_item ) = "M"
      mTexto += "memo" + " "
   EndCase
next
SayScroll(mTexto)
Return NIL
*----------------------------------------------------------------


Static Function RotinaUse()

private m_file, m_Exclusive, m_alias, m_indice[ 7 ]

afill( m_indice, "" )

if Empty(mTexto)
   use
   Return NIL
Endif

m_file = PegaParam( @mTexto, " " )

if len( m_file ) = 0
   SayScroll("Nome de arquivo invalido")
   Return NIL
Endif

if .Not. "." $ m_file
   m_file = m_file + ".dbf"
Endif

if .Not. file( m_file )
   SayScroll("Arquivo nao encontrado")
   Return NIL
Endif

// Valida uso exclusivo

m_Exclusive = PegaParam( @mTexto, "Exclusive" )

// Valida nome de alias

m_alias = PegaParam( @mTexto, "alias" )

if .Not. param_ok( m_alias, "alias" )
   SayScroll("Alias invalido")
   Return NIL
Endif

If Len(m_Alias) == 0
   If Len(Substr(m_File,1,At(".",m_File+".")-1)) > 8
      m_Alias := "TMP" + StrZero(nTempAlias,7)
   Else
      m_Alias := Substr(m_File,1,At(".",m_File+".")-1)
   Endif
Endif

// Abre e confirma abertura de dbfs

if m_Exclusive
   use ( m_file ) alias &m_alias Exclusive
   if NetErr()
      SayScroll("Nao pode abrir arquivo para uso exclusivo")
      Return NIL
   Endif
Else
   use ( m_file ) alias &m_alias
   if NetErr()
      SayScroll("Esta' em uso exclusivo por outro usuario")
      Return NIL
   Endif
Endif

nTempAlias += 1

// Valida abertura de indice

if .Not. PegaParam( @mTexto, "index" )
   Return NIL
Endif
Do While .t.
   mIndice := PegaParam(@mTexto,",")
   if Len(mIndice) = 0
      Exit
   Endif
   if .Not. "." $ mIndice
      mIndice += ".idx"
      if .Not. file(mIndice)
         SayScroll( mIndice + " nao encontrado")
      Else
         dbSetIndex(mIndice)
      Endif
   Endif
Enddo
Return NIL
*----------------------------------------------------------------


Static Function RotinaRecall(cComando)
Local lparAll := .f., lParRecord := 0, lParNext := 0, cParFor := ".t.", cParWhile := ".t."
Local nContReg := 0, nContDel := 0, mInkey := 0

if .Not. PegaParam( @cComando, "escopo" )
   Return NIL
Endif

if Len(cComando) != 0
   SayScroll("Parametro invalido " + cComando)
   Return NIL
Endif

if nParRecord=0 .And. nParNext=0 .And. cParFor == ".t." ;
              .And. cParWhile == ".t." .And. .Not. lParAll
   lParRecord := RecNo()
Endif

Do Case
case lParAll
   GoTo top
case nParRecord != 0
   GoTo (nParRecord)
EndCase

nContReg = 0
nContDel = 0
nInkey   = 0
SayScroll()
Do While nInkey != 27 .And. .Not. Eof()
   nInkey = MyInkey()
   if .Not. &(cParWhile)
      Exit
   Endif
   nContreg += 1
   if &(cParFor)
      Bloqueia(.t.)
      Recall
      nContDel += 1
      if Mod( nContDel, CfgOdometer ) = 0
         @ MaxRow()-3, 0 Say Str(nContDel) + " registro(s) recuperado(s)"
      Endif
   Endif
   if nParRecord != 0
      Exit
   Endif
   skip
   if nContReg == nParNext
      Exit
   Endif
Enddo
@ MaxRow()-3, 0 Say Str(nContDel) + " registro(s) recuperado(s)"

if LastKey() = 27
   SayScroll("Interrompido")
Endif
Return NIL
*----------------------------------------------------------------


Static Function RotinaSet(cComando)
Local cSet, lOnOff

cSet := Lower(Trim(Left(PegaParam(@cComando," "),3)))
Do Case
Case cSet $ "cen,del,uni,con,exc"
   if Upper(cComando) != "ON" .And. Upper(cComando) != "OFF"
      SayScroll("So' pode usar ON ou OFF")
      Return NIL
   Endif
   lOnOff := iif(Upper(cComando)=="ON",.t.,.f.)
   Do Case
   Case cSet == "cen"
      Set Century (lOnOff)
   Case cSet == "con"
      Set Confirm (lOnOff)
   case cSet == "del"
      Set Deleted (lOnOff)
   Case cSet == "uni"
      Set Unique (lOnOff)
   Case cSet == "exc"
      Set Exclusive (lOnOff)
      CfgSetExclusive := (lOnOff)
   EndCase
Case cSet $ "fil,his,ind,ord,rel"
   if cSet $ "fil,ind,ord,rel" .And. .Not. Used()
      SayScroll("Nao tem arquivo em uso")
      Return NIL
   Endif
   if Lower(PegaParam(@cComando," ")) != "to"
      SayScroll("Sintaxe errada")
      Return NIL
   Endif
   If cSet == "rel"
      RotinaSetRelation(cComando)
   Elseif cSet == "ord"
      if Empty(cComando)
         Set Order to 1
         Return NIL
      Endif
      if Type(cComando) != "N"
         SayScroll("Ordem so' pode ser numerica")
         Return NIL
      Endif
      Set Order To &(cComando)
   Elseif cSet == "fil"
      if Empty(cComando)
         Set Filter To
         Return NIL
      Endif
      if Type(cComando) != "L"
         SayScroll("Filtro so' pode ser verdadeiro ou falso")
         Return NIL
      Endif
      Set Filter To &(cTexto)
   Elseif cSet == "ind"
      Set Index To
      If Len(cComando) == 0
         Return NIL
      Endif
      Do While .t.
         cIndice := PegaParam(@cComando,",")
         if Len(cIndice) = 0
            Exit
         Endif
         If .Not. "." $ cIndice
            If .Not. file(cIndice+".cdx")
               SayScroll(cIndice + " nao encontrado")
            Else
               dbSetIndex(cIndice)
            Endif
         Endif
      Enddo
   Endif
Otherwise
   SayScroll("Configuracao invalida ou nao permitida")
EndCase
Return NIL
*----------------------------------------------------------------


Static Function RotinaDir(cComando)
Local acTmpFile, nTotalSize, nCont, nLin

if Empty(cComando)
   acTmpFile := Directory("*.dbf")
   nTotalSize := 0
   nLin := 0
   For nCont = 1 to Len(acTmpFile)
      use (acTmpFile[mCont,1]) alias temp
      SayScroll( Pad(acTmpFile[nCont,1],15) + Transform(LastRec(),"99,999,999") + " " + ;
         Transform(acTmpFile[nCont,2],"999,999,999,999") + " " + Dtoc(acTmpFile[nCont,3]) + " " + acTmpFile[nCont,4])
      nTotalSize += acTmpFile[nCont,2]
      nLin += 1
      use
      if nLin > MaxRow()-7
         SayScroll("Tecle algo para prosseguir")
         if MyInkey(0) == 27
            Exit
         Endif
         nLin := 0
      Endif
   Next
   SayScroll("Total "+Str(Len(acTmpFile))+" arquivo(s) " + Transform(nTotalSize,"999,999,999")+" byte(s)")
Else
   acTmpFile := Directory(cComando)
   nTotalSize := 0
   For nCont = 1 to Len(acTmpFile)
      SayScroll(Pad(acTmpFile[nCont,1],15)+Transform(acTmpFile[nCont,2],"999,999,999")+" "+;
               dtoc(acTmpFile[nCont,3])+" "+acTmpFile[nCont,4])
      nTotalSize += acTmpFile[nCont,2]
   Next
   SayScroll("Total "+Str(Len(acTmpFile))+" arquivo(s) " + Transform(nTotalSize,"999,999,999")+" byte(s)")
Endif
Return NIL
*----------------------------------------------------------------
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder