Clipper On Line • Ver Tópico - Cadastro

Cadastro

Discussão sobre a linguagem CA-Clipper.

Moderador: Moderadores

 

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 15:21

chega a ser estranho postar em Clipper mas...
de repente pode ser interessante chamar a atenção de que não precisa trocar de linguagem de programação pra ter as coisas mais fáceis.

Bom... O Flagship obriga a trabalhar no estilo Clipper, então, como comecei um cadastro básico (ou nem tanto), aproveitando pra postar.

Não é exatamente um cadastro padrão, já que se trata de notas fiscais, com produtos, financeiro, etc.
Estou ajustando aos poucos, porque a limitação de 25 x 80 existe no Flagship (no Clipper não, dá pra usar 28 x 80, 43 x 80, 50 x 80 - neste caso limitações do DOS).
Como testo em Harbour... tem mais espaço na tela.

cadastro.png


Clipper... console e não GUI....
Trocentas linhas de fonte....
Sem usar classe....
Calma...
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 15:35

Comecem pensando de um jeito humano... sem detalhes...

O que tem num cadastro?
Abrir arquivos, mostrar dados, o menu, opções próximo, anterior, primeiro, último, código específico, inclui, altera, exclui, e outros. Conforme a opção faz uma coisa diferente....
Poderia ser click num botão (em GUI), mas tudo bem, não é.
Deixar como imagem pra visualizar melhor.

fontegeral.png


É basicamente o que descrevi antes.
Aquele SET ORDER TO 0, GOTO BOTTOM é pra posicionar na última nota que foi incluída.
Flg_Mov e Num_Nf são as chaves do arquivo - não é bom, mas é a chave de acesso disponível, que não posso mexer.
Pra usar como locais, e não public/private, acabei passando por referência pra sub-rotinas.

É o esqueleto da coisa.
Serviria pra qualquer cadastro.
Em Clipper... copiamos essa parte do fonte.... em Harbour... temos a opção de transformar em classe, pra não precisar ficar copiando, mas não vém ao caso agora.

É um fonte relativamente simples, de fácil manutenção !!!! E poderia ser usado pra diversas situações.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 15:45

O que precisa, caso o usuário selecione PRIMEIRO ?
Ué.. ir para o primeiro.

cadastro.png
cadastro.png (8.86 KiB) Visualizado 2148 vezes


Rotina complicada né.
Será que funciona pra qualquer cadastro? kkkk

Também poderia ser a rotina de um buttton, em GUI, só precisaria chamar a atualização de tela depois de posicionar.
Tem como dar erro nessa rotina?
Simples, prático e funcional.

O fonte vai ficar longo separando em tantas partes....
Sinceramente... vai precisar olhar essa parte pra que?

O importante é:
Separando o fonte "complicado" em partes, acabou tendo rotinas bem simples de fazer manutenção.
A rotina Primeiro() trata de .... usar a opção Primeiro.
Nome simples, prático, fácil de entender, fonte simples de fazer manutenção (será que vai precisar manutenção?)

É simples, nem precisava fazer separado... mas... deixando separado, deixa até o fonte geral mais limpo e fácil de mexer.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 16:02

Mesma coisa para todos os posicionamentos.

STATIC FUNCTION FrmProximo()

   SKIP
   IF Eof()
      MsgStop( "Ja esta no ultimo lancamento" )
      GOTO BOTTOM
   ENDIF

   RETURN NIL

STATIC FUNCTION FrmAnterior()

   SKIP -1
   IF Bof()
      MsgStop( "Ja esta no primeiro lancamento" )
      GOTO TOP
   ENDIF

   RETURN NIL

STATIC FUNCTION FrmPrimeiro()

   GOTO TOP

   RETURN NIL

STATIC FUNCTION FrmUltimo()

   GOTO BOTTOM

   RETURN NIL


Estão como STATIC para serem visíveis só no módulo, por enquanto apenas testando.
Depois posso deixar como normais, e colocar em uma LIB.
E, se precisar, ainda posso criar módulos com funções STATIC pra tratamento específico, diferente do padrão.

Parece até coisa de classe, herança, modificar classe existente...

Pra quem não entendeu esta parte, sobre STATIC.
STATIC FUNCTION é uma função visível apenas dentro do módulo.
FUNCTION é uma função vista pelo aplicativo inteiro.

PROCEDURE Cadastro
   FrmUltimo()


No caso acima, vai ser usado FrmUltimo() que existir para o aplicativo inteiro.

PROCEDURE Cadastro
   FrmUltimo()
   RETURN
STATIC FUNCTION FrmUltimo()


No caso acima, mesmo que exista no aplicativo uma função FrmUltimo(), vai ser usada essa que está dentro do mesmo fonte.
Ou seja... podemos ter a função genérica pra o aplicativo, mas podemos trocar por uma particular do módulo, sem precisar retirar a genérica.
Isso é um recurso fantástico.
Funções para atender o aplicativo inteiro, mas que podem ser substituídas em alguns módulos, sem complicações.

Só pra curiosidade, classe e herança tem a ver com isso: usar algo pronto mas modificando uma parte
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:02

Pra encontrar uma nota específica:

STATIC FUNCTION FrmEspecifico( mFlg_Mov, mNum_Nf )

   LOCAL nRecNo := RecNo(), GetList := {}

   @ 1, 1 SAY ""
   @ Row() + 1, 1 SAY "Flag.Mov..:" GET mFlg_Mov PICTURE "!A" // C,1
   @ Row(), Col() + 2 SAY "Num.NF:" GET mNum_Nf  PICTURE "@R X-XXXXXX"
   Mensagem( "Numero de nota fiscal <ESC> Sai" )
   READ
   Mensagem()
   IF LastKey() == K_ESC
      RETURN .F.
   ENDIF
   mNum_Nf := Substr( mNum_Nf, 1, 1 ) + StrZero( Val( Substr( mNum_Nf, 2 ) ), 6 )
   SEEK mFlg_Mov + mNum_Nf
   IF Eof()
      MsgStop( "Numero nao cadastrado" )
      GOTO ( nRecNo )
      RETURN .F.
   ENDIF

   RETURN .T.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:05

O Browse dos produtos, que pode ser na parte de baixo, ou na tela inteira.

STATIC FUNCTION FrmItens( nTop, nLeft, nBottom, nRight, lWait )

   LOCAL oTBrowse, nSelect, cTela

   hb_Default( @lWait, .T. )
   nSelect := Select()
   SELECT MOV1
   SET ORDER TO 4
   SEEK mov2->Cod_Flg
   IF lWait
      SAVE SCREEN TO cTela
   ENDIF
   oTBrowse := { ;
      { "PRODUTO",   { || MOV1->Cod_Pro + " " + iif( Encontra( mov1->Cod_Pro, "PRO1", 1 ), "", "" ) + PRO1->Nome } }, ;
      { "QTDE",      { || Transform( mov1->Quant, "@E 99999" ) } }, ;
      { "V.UNIT",    { || Transform( mov1->Valor,"@E 999,999.99" ) } }, ;
      { "V.TOTAL",   { || Transform( mov1->Quant * mov1->Valor, "@E 999,999.99" ) } }, ;
      { "V.ICMS",    { || Transform( mov1->Vl_Icm, "@E 999,999.99" ) } }, ;
      { "%ICMS",     { || Transform( mov1->Ali_Icm, "@E 999.99" ) } }, ;
      { "V.BASE",    { || Transform( mov1->Base_Icm, "@E 999,999.99" ) } } }
   IF ! lWait
      KEYBOARD Chr(27)
   ENDIF
   DBView( nTop, nLeft, nBottom, nRight, oTBrowse,,, mov2->Cod_Flg, { || mov1->Cod_Flg } )
   SELECT ( nSelect )
   IF lWait
      RESTORE SCREEN FROM cTela
   ENDIF

   RETURN NIL
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:05

O Browse do financeiro:

STATIC FUNCTION FrmFinanceiro()

   LOCAL oTBrowse, nSelect, cTela

   SAVE SCREEN TO cTela
   nSelect := Select()
   SELECT REC2
   SEEK MOV2->Num_Nf
   OTBrowse := { ;
      { "NF/PARC", { || rec2->Num_Nf } }, ;
      { "DT.EMIT", { || rec2->Dt_Emit } }, ;
      { "VALOR",   { || Transform( rec2->Valor, "@E 999,999.99" ) } }, ;
      { "VCTO",    { || rec2->Vcto } }, ;
      { "REPRO",   { || rec2->Repro } }, ;
      { "RCTO",    { || rec2->Rcto } }, ;
      { "VALOR_R", { || Transform( rec2->Valor_r, "@E 999,999.99" ) } } }

   DbView( 2, 0, MaxRow() - 2, MaxCol(), oTBrowse,,, mov2->Num_Nf, { || Left( rec2->Num_Nf, 7 ) } )
   SELECT ( nSelect )
   RESTORE SCREEN FROM cTela

   RETURN NIL
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:06

Exclusão - não liberada, por isso incompleta:

STATIC FUNCTION FrmExclui()

   IF ! MsgYesNo( "Confirma exclusao?" )
      RETURN NIL
   ENDIF
   // checagens e arquivos relacionados
   RETURN NIL
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:07

A tela de informações.
Não permite incluir/alterar, então deixei só anotado pra se fosse gravar:

STATIC FUNCTION FrmTelaDados( lUpdate, cOpcao, mFlg_Mov, mNum_Nf )

   LOCAL GetList   := {}, nRow
   LOCAL mCodigo   := mov2->Codigo
   LOCAL mVendedor := mov2->Vendedor
   LOCAL mData     := mov2->Data
   LOCAL mCod_Flg  := mov2->Cod_Flg
   LOCAL mOrdem    := mov2->Ordem
   LOCAL mDat_Ent  := mov2->Dat_Ent
   LOCAL mDat_Emi  := MOV2->Dat_Emi
   LOCAL mIcm_Bas  := mov2->Icm_Bas
   LOCAL mIcm_Ali  := mov2->Icm_Ali
   LOCAL mIcm_Val  := mov2->Icm_Val
   LOCAL mNat_Ope  := mov2->Nat_Ope
   LOCAL mObs      := mov2->Obs
   LOCAL mTra_Tip  := mov2->Tra_Tip
   LOCAL mTra_Nom  := mov2->Tra_Nom
   LOCAL mTra_End  := mov2->Tra_End
   LOCAL mLoc_Ent  := mov2->Loc_Ent
   LOCAL mIsento   := mov2->Isento
   LOCAL mOutras   := mov2->Outras

   hb_Default( @lUpdate, .F. )
   hb_Default( @cOpcao, "C" )

   @ 1, 1 SAY ""
   @ Row() + 1, 1 SAY "Flag.Mov..:" GET mFlg_Mov // C,1
   @ Row(), Col() + 2 SAY "Num.NF:" GET mNum_Nf PICTURE "@R X-XXXXXX"
   @ Row(), Col() + 2 SAY "ID(CodFlg):" GET mCod_Flg // C,6
   @ Row(), Col() + 2 SAY "Ordem:" GET mOrdem // C,6
   @ Row() + 1, 1 SAY "Datas.....:" GET mData
   @ Row(), Col() + 2 SAY "Emissao:" GET mDat_Emi
   @ Row(), Col() + 2 SAY "Ent:" GET mDat_Ent
   @ Row() + 1, 1 SAY "CFOP......:" GET mNat_Ope PICTURE "@R X.XXX" // C,4
   Encontra( mNat_Ope, "NATO", 1 )
   @ Row(), 22 SAY nato->Nom_Abr
   @ Row() + 1, 1 SAY "Codigo....:" GET mCodigo // C,5
   Encontra( mCodigo, "CLIE", 1 )
   @ Row(), 22 SAY clie->Fantasia
   @ Row() + 1, 1 SAY "Vendedor..:" GET mVendedor // C,2
   Encontra( mVendedor, "VEND", 1 )
   @ Row(), 22 SAY vend->Nome
   @ Row() + 1, 1 SAY "Obs.......:" GET mObs
   @ Row() + 1, 1 SAY "Icms......:" GET mIcm_Bas PICTURE "@E 999,999.99"
   @ Row(), Col() + 2 GET mIcm_Ali PICTURE "99"
   @ Row(), Col()     SAY "%"
   @ Row(), Col() + 2 GET mIcm_Val PICTURE "@E 999,999.99"
   @ Row() + 1, 1 SAY "Transp.Tip:" GET mTra_Tip // C,1
   @ Row(), COl() + 2 SAY "Nom:" GET mTra_Nom
   @ Row() + 1, 1 SAY "Transp.End:" GET mTra_End
   @ Row() + 1, 1 SAY "Loc.Entreg:" GET mLoc_Ent
   @ Row() + 1, 1 SAY "Isento....:" GET mIsento PICTURE "@E 999,999.99"
   @ Row() + 1, 1 SAY "Outras....:" GET mOutras PICTURE "@E 999,999.99"
   nRow := Row() + 1
   //IF ! lUpdate
      CLEAR GETS
      //RETURN NIL
   //ENDIF
   //Mensagem( "Digite campos, <ESC> Sai" )
   //READ
   //Mensagem()
   //IF LastKey() == K_ESC
      //RETURN NIL
   //ENDIF
   FrmItens( nRow, 0, MaxRow() - 2, MaxCol(), .F. )

   //IF cOpcao == "I"
      // RecAppend()
      // REPLACE ;
      //   mov2->Flag_Mov WITH mFlag_Mov, ;
      //   mov2->Num_NF   WITH mNum_Nf
      // RecUnlock()
   //ENDIF
   //RecLock()
   //REPLACE ;
   //   mov2->Data WITH mData
   //RecUnlock()

   RETURN NIL
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:14

O menu das opções.... esse é um caso a parte...
(Sim, o que parece apenas uma mensagem é um menu)

STATIC FUNCTION FrmMenu( cOpc, cOpcTxt )

   LOCAL nKey, nKeyList := {}, nPos, aOpcList := {}, nOpc, nCont

   IF "I" $ cOpcTxt
      AAdd( aOpcList, { "I", "<I>Inclui" } )
      AAdd( nKeyList, { Asc( "I" ), "I" } )
      AAdd( nKeyList, { Asc( "i" ), "I" } )
      AAdd( nKeyList, { K_INS,      "I" } )
   ENDIF
   IF "A" $ cOpcTxt
      AAdd( aOpcList, { "A", "<A>Altera" } )
      AAdd( nKeyList, { Asc( "A" ), "A" } )
      AAdd( nKeyList, { Asc( "a" ), "A" } )
   ENDIF
   IF "E" $ cOpcTxt
      AAdd( aOpcList, { "E", "<E>Exclui" } )
      AAdd( nKeyList, { Asc( "E" ), "E" } )
      AAdd( nKeyList, { Asc( "e" ), "E" } )
      AAdd( nKeyList, { K_DEL,      "E" } )
   ENDIF

   AAdd( aOpcList, { "C", "<C>Consulta" } )
   AAdd( nKeyList, { Asc( "C" ), "C" } )
   AAdd( nKeyList, { Asc( "c" ), "C" } )

   AAdd( aOpcList, { "+", "<+>Seguinte" } )
   AAdd( nKeyList, { K_PGDN,     "+" } )

   AAdd( aOpcList, { "-", "<->Anterior" } )
   AAdd( nKeyList, { K_PGUP,     "-" } )

   AAdd( aOpcList, { "P", "<P>Primeiro" } )
   AAdd( nKeyList, { Asc( "P" ), "P" } )
   AAdd( nKeyList, { Asc( "p" ), "P" } )
   AAdd( nKeyList, { K_HOME,     "P" } )

   AAdd( aOpcList, { "U", "<U>Ultimo" } )
   AAdd( nKeyList, { Asc( "U" ), "U" } )
   AAdd( nKeyList, { Asc( "u" ), "U" } )
   AAdd( nKeyList, { K_END,      "U" } )

   IF "D" $ cOpcTxt
      AAdd( aOpcList, { "D", "<D>Detalhe" } )
      AAdd( nKeyList, { Asc( "D" ), "D" } )
      AAdd( nKeyList, { Asc( "d" ), "D" } )
   ENDIF

   IF "F" $ cOpcTxt
      AAdd( aOpcList, { "F", "<F>Financeiro" } )
      AAdd( nKeyList, { Asc( "F" ), "F" } )
      AAdd( nKeyList, { Asc( "f" ), "F" } )
   ENDIF

   IF "X" $ cOpcTxt
      AAdd( aOpcList, { "X", "<X>Xml " } )
      AAdd( nKeyList, { Asc( "X" ), "X" } )
      AAdd( nKeyList, { Asc( "x" ), "X" } )
   ENDIF

   AAdd( aOpcList, { Chr( K_ESC ), "<ESC>Sai" } )
   DO WHILE .T.
      nOpc := ASCan( aOpcList, { | e | e[ 1 ] == cOpc } )
      Mensagem()
      FOR nCont = 1 TO Len( aOpcList )
         IF Col() + Len( aOpcList[ nCont, 2 ] ) > MaxCol()
            @ Row() + 1, 0 SAY ""
         ENDIF
         @ Row(), Col() SAY aOpcList[ nCont, 2 ] COLOR iif( nCont == nOpc, "N/W", "W/N" )
         @ Row(), Col() SAY " " COLOR "W/N"
      NEXT
      nKey := Inkey(0)
      IF nKey == K_ESC
         EXIT
      ENDIF
      nPos := AScan( nKeyList, { | e | e[ 1 ] == nKey } )
      IF nPos != 0
         cOpc := nKeyList[ nPos, 2 ]
         EXIT
      ENDIF
      DO CASE
      CASE nKey == K_RIGHT ; nOpc := iif( nOpc == Len( aOpcList ), 1, nOpc + 1 ); cOpc := aOpcList[ nOpc, 1 ]
      CASE nKey == K_LEFT  ; nOpc := iif( nOpc == 1, Len( aOpcList ), nOpc - 1 ); cOpc := aOpcList[ nOpc, 1 ]
      CASE nKey == K_ENTER ; EXIT
      ENDCASE
   ENDDO
   Mensagem()

   RETURN cOpc


O que tem especial no menu:

Aceita Insert, Delete, PgUp, PgDn, Home, End, P(primeiro), U(ultimo), +(Seguinte), -(anterior), aceita passear com as setas, só não aceita mouse porque Flagship não tem isso.
E se uma linha não for suficiente, são usadas duas linhas.

relembrar o menu discreto:

menu.png


E se futuramente usar Harbour e colocar buttons... é só o button fazer o KEYBOARD correspondente à opção....

Importante:
Para o restante do programa, tanto faz, as outras rotinas nem sabem que o menu existe.
As outras rotinas só precisam saber qual é a opção.

Conclusão:
Cada parte do fonte cuida de "sua parte"
Manutenção fácil, só precisa olhar a parte que interessa.
Se fosse um fonte linguição, tudo dentro de um DO WHILE.... ferrou... ainda mais se fosse usando o EDIT do DOS.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes

Cadastro

Mensagempor JoséQuintas » 24 Jul 2019 18:32

Um complemento:

Os fontes em ambiente GUI te obrigam a fazer nesse estilo, porque cada componente tem lá sua rotina a ser executada quando for clicado.
Como dá pra ver.... dá pra tirar proveito disso mesmo fora do ambiente GUI.

Percebi isso quando mexi com Visual Basic 6.
Achei interessante, e passei a usar no Clipper, dividindo "por assunto".
Na hora de fazer manutenção... só ir direto ao "assunto".

E dividir por assunto, pode ser uma prévia de ambiente GUI, porque já deixa organizado/preparado para o que vém depois.

É o que sempre digo: Não importa se é Clipper, Flagship, Harbour, ambiente gráfico... esse aprendizado e essa organização/simplificação vale pra todos. Até mesmo se for trocar de linguagem de programação - criaria o equivalente a cada parte, uma coisa de cada vez.
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 13770
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 847 vezes




Retornar para CA-Clipper

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 1 visitante


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro