GRIDs e GRID acesso direto

Desvendando as GRIDs

As grades de informações (GRID) desde o inicio sempre foram uma excelente maneira de exibir informações das tabelas em tela, na HMG no inicio podiamos usar GRID e BROWSE, porém este segundo foi descontinuado, pois o componente GRID passou a desempenhar muito bem a função do BROWSE.

Quem me conhece sabe que não gosto de fazer nada que não funcione muito bem, então de antecipação já aviso a todos que a movimentação do cursor de seleção dentro da GRID não é muito satisfatório, pois é possível ver a atualização dos dados acontecendo, felizmente posso dizer a todos que na HMG4 o problema já foi solucionado, porém ainda estamos usando a HMG3 então tenho este pequeno desagradável problema (muitos vão achar normal, é que eu sou chato mesmo).

As duas formas de usar uma GRID

Existem duas formas de usar uma GRID e você terá que escolher por uma delas dependendo o momento, aviso também que isso fica muito ao critério do programador. Mas enfim a primeira forma de utilizá-la, é abastecendo-a de maneira direta como se fosse uma variável matriz dimensional (array), exatamente através de um comando ADDITEM() você abastece a GRID com informações, ou seja ela exibe o resultado de uma pesquisa simplesmente abstencendo-a com os dados, a segunda maneira é acessando diretamente uma tabela DBF, e assim poder editar, alterar, apagar os dados sem precisar ficar criando códigos extra para isso.

Particularmente não gosto do segundo método, talvez por eu nunca ter gostado de ver meus usuários “olhando” e “mexendo” diretamente nos dados do meu sistema, segundo por não achar profissional esse método, pois imagine níveis de hierarquia do sistema onde determinadas informações são separadas para determinados grupos de usuários, você não tem como separar jogando simplesmente em uma GRID de acesso direto.

O que digo acima tem ressalvas, caso você utilize e faça uma programação com tratamento e separação dos dados, porém se for para fazer isso, então faça usando a GRID como se fosse uma variável array, te garanto que será muito mais profissional o resultado final, pois poderemos fazer filtros, limitar quantidade de dados listados e assim por diante.

Tanto para GRID de acesso direto, como para GRID de acesso indireto, podemos gerar o efeito de mostra listrada, ou seja, linhas que alternam de cores, mas para isso é muito importante que no programa principal (MAIN.PRG) tenhamos a seguinte declaração de variável:

PRIVATE bBackColor:={ || IF( THIS.CELLROWINDEX/2==INT(THIS.CELLROWINDEX/2),;
                         { 234,244,255 },{ 255,255,255 } ) }

Sem esta declaração ocorrerá um erro na sua GRID, e ai fica difícil de continuar o trabalho, não é mesmo?!

Programando a GRID para acesso direto ao DBF

Em primeiro lugar vamos imaginar que possuimos um arquivo DBF aberto com o alias “dbf”, o exemplo abaixo procurei fazer de um jeito que fosse o mais genérico possível, ou seja, você pode colocá-lo em seu formulário (.FMG) e depois apenas alterar as funções que você irá colocar em seu arquivo de código (.PRG), para criar novas grades você faz o mesmo, copia e troca os nomes das funções e altera os dados do DBF. Imaginamos também a seguinte estrutura para o seu arquivo DBF:

CODPRO N 05,00
NOMPRO C 50,00
PREPRO N 15,02
DATPRO D 08,00
SITPRO L 01,00
OBSPRO M 10,00

Então abaixo segue o código para a GRID que será colocado em seu FMG.

DEFINE GRID Grid_Data
        ROW    100
        COL    10
        WIDTH  770
        HEIGHT 440
        ITEMS Nil
        VALUE Nil
        WIDTHS grid_data_widths()
        HEADERS grid_data_headers()
        FONTNAME "Courier New"
        FONTSIZE 9
        TOOLTIP ""
        ONCHANGE main_grid_data_onchange()
        ONGOTFOCUS Nil
        ONLOSTFOCUS Nil
        FONTBOLD .F.
        FONTITALIC .F.
        FONTUNDERLINE .F.
        FONTSTRIKEOUT .F.
        ONDBLCLICK Nil
        ONHEADCLICK Nil
        ONQUERYDATA Nil
        MULTISELECT .F.
        ALLOWEDIT .T.
        VIRTUAL .F.
        DYNAMICBACKCOLOR grid_data_dynamicbackcolor()
        DYNAMICFORECOLOR Nil
        COLUMNWHEN Nil
        COLUMNVALID Nil
        COLUMNCONTROLS grid_data_columncontrols()
        SHOWHEADERS .T.
        CELLNAVIGATION .F.
        NOLINES .F.
        HELPID Nil
        IMAGE Nil
        JUSTIFY grid_data_justify()
        ITEMCOUNT Nil
        BACKCOLOR NIL
        FONTCOLOR NIL
        HEADERIMAGES Nil
        ROWSOURCE "dbf"
        COLUMNFIELDS grid_data_columnfields()
        ALLOWAPPEND .T.
        ALLOWDELETE .T.
        BUFFERED .F.
        DYNAMICDISPLAY Nil
        ONSAVE Nil
        LOCKCOLUMNS 0
    END GRID

Agora basta copiarmos as funções abaixo, para adaptar isso tudo ao seu sistema apenas altere as funções para que fiquem compatíveis com a sua tabela DBF.

FUNCTION grid_data_columnwhen()
LOCAL aColumnWhen

    // { || .T. } PERMITE A EDICAO
    // { || .F. } NAO PERMITE A EDICAO

   aColumnWhem := { { || .F. },;
                    { || .T. },;
                    { || .T. },;
                    { || .T. },;
                    { || .T. },;
                    { || .T. } }

RETURN aColumnWhen

FUNCTION grid_data_columncontrols()
LOCAL aColumnControls

   aColumnControls := { { "TEXTBOX","NUMERIC","99999" },;
                        { "TEXTBOX","CHARACTER" },;
                        { "TEXTBOX","NUMERIC","999999999999.99" },;
                        { "DATEPICKER","UPDOWN" },;
                        { "CHECKBOX",".T.",".F." },;
                        { "EDITBOX" } }

RETURN aColumnControls 

FUNCTION grid_data_columnfields()
LOCAL aColumnFields

   aColumnFields := { "dbf->codpro",;
                     "dbf->nompro",;
                     "dbf->prepro",;
                     "dbf->datpro",;
                     "dbf->sitpro",;
                     "dbf->obspro" }

RETURN aColumnFields

FUNCTION grid_data_headers()
LOCAL aheaders

   aheaders := { "Codigo",;
                 "Nome",;
                 "Preco",;
                 "Entrada",;
                 "Ativo",;
                 "observação" }

RETURN aheaders

FUNCTION grid_data_widths()
LOCAL awidths := {}

   aWidths := { 70,350,120,100,40,50 }

RETURN awidths

FUNCTION grid_data_justify()
LOCAL ajustify := {}

   ajustify := { GRID_JTFY_RIGHT,;
                 GRID_JTFY_LEFT,;
                 GRID_JTFY_RIGHT,;
                 GRID_JTFY_CENTER,;
                 GRID_JTFY_CENTER,;
                 GRID_JTFY_CENTER }

RETURN ajustify

FUNCTION grid_data_DynamicBackColor()
LOCAL aDynamicBackColor := {}

   aDynamicBackColor := { bBackColor,;
                          bBackColor,;
                          bBackColor,;
                          bBackColor,;
                          bBackColor,;
                          bBackColor }

RETURN aDynamicBackColor

Assim termino a primeira parte da explicação do uso da GRID, está primeira parte tratou do acesso direto as informações que estão dentro de uma tabela DBF.

Segue aqui o link com o exemplo:

http://www.mediafire.com/?vhc95nbw9odkwyc

No próximo post falarei sobre o acesso indireto.

Ate+

9 comentários em “GRIDs e GRID acesso direto

Adicione o seu

  1. Olá, bom dia!!
    Eu novamente…. rs rs

    Baixei os fontes do exemplos GRID_direto e compilou belezinha com a instalação do HMG 3. Porém quando tento compilar com a a instalação do HMG4 apresenta erro:

    Harbour 2.1.0beta2 (Rev. 15729)
    Copyright (c) 1999-2010, http://harbour-project.org/
    Compiling ‘main.prg’…
    main.prg(24) Error E0030 Syntax error “syntax error at ‘WINDOW'”
    main.prg(25) Error E0020 Incomplete statement or unbalanced delimiters
    main.prg(26) Error E0020 Incomplete statement or unbalanced delimiters
    3 errors

    No code generated.
    hbmk2: Erro: Executando o compilador Harbour (interno): 1

    Existe alguma diferença entre os dois, li em alguns site que o HMG iria manter a compatibilidade com o HMG3 ?

    Abrs

  2. Olá.

    Parabéns pelo excelente site.

    Ainda estou estudando a melhor alternativa para migrar alguns programas desenvolvidos em Clipper.
    Testei a versão mais recente do HMG (3.0.35) e gostei muito do resultado.

    Entretanto ainda não achei uma maneira de converter adequadamente as funções que utilizavam o dbEdit(), pois no HMG a função Grid requer um ou antes de editar cada célula.

    Estou buscando uma maneira de deixar o Grid editável como uma planilha, semelhante ao DBGrid do Delphi ou o próprio DbEdit() do Clipper, mas aparentemente este recurso não está disponível.

    Se tiver qualquer sugestão a esse respeito, agradeço pela informação.

    Abraços!

    Paulo.

    1. ****Parte do texto fui suprimida ao postar o comentário.****

      Segue retificação:

      “…… Entretanto ainda não achei uma maneira de converter adequadamente as funções que utilizavam o dbEdit(), pois no HMG a função Grid requer um ENTER ou DOUBLECLICK antes de editar cada célula …..”

      Obrigado.

  3. parabéns pelo site! Programa com clipper desde o tempo do computador a vela, e é bom pra variar encontrar programadores como você que falam o mesmo idioma “via unha” que a gente fala, do que meros formadores de bits escovados. Quanto ao uso da HMG, refiz todos meus sistemas e digo que se o programador, o bom programador, que lascou a espinha de tanto tentar fazer uma função em clipper, ou uma LIB no mesmo, está tendo sua recompensa. Dá um pouco de trabalho no inicio apenas para entender onde e o que colocar dentro das nossas regras e funções criadas no bom e velho clipper, depois, é uma festa, você faz coisas que te surpreendem, e se pergunta…”como isso é possível? eu estar programando mesmo em windows e não uma simples API.”

  4. Excelente, bem didático.
    Estou muito interessado em ver como faz da outra forma (acesso indireto), porque também concordo com as razões que você expos com relação a segurança e o usuário.
    Parabéns!

  5. Olá, boa noite!

    Estou eu aqui tentando “aprender” um pouco sobre programação no modo windows. Segui o exemplo acima para montar o grid. Coloquei as definições do grid no arquivo FMG e as funções no arquivo PRG. (espero ter feito correto…)

    Quando mando executar apresenta um erro:

    Error BASE/1102 Argument erro: UPPER
    Called from UPPER(0)
    Called from _DEFINEGRID(147)
    Called from MAIN(53)

    Não alterei em nada seu fonte, apenas copiei e coloquei para ver o resultado

    Abs

    Sinval

    1. Olá Sinval,

      Então este exemplo que passei neste post esta fragmentado, é apenas para fins didáticos.

      Vamos fazer assim, amanhã farei o possível para postar aqui neste post um link com um projeto funcionando, com estas mesmas funções que passei acima, ai é só abrir e usar.

      Obrigado pela visita.

      Ate+

    2. Ola Sinval,
      Agora consegui um tempo e ja encontrei o problema, foi falha minha, me desculpo e aviso que ja esta corrigido.

      O erro foi nao ter colocado os FIELDS entre aspas.
      Veja o correto:
      aColumnFields := { “dbf->codpro”,;
      “dbf->nompro”,;
      “dbf->prepro”,;
      “dbf->datpro”,;
      “dbf->sitpro”,;
      “dbf->obspro” }

      Agora tambem tem o exemplo no link do MEDIAFIRE para baixar este exemplo rodando.

      Obrigado

      Ate+

  6. Olá, muito bom o post e tb os: “NETIO, DBF via TCP IP na prática” e “Entendendo o NETIO na pratica”.

    Nos posts sobre NETIO, você fala a respeito do “DBF Server Lights for MS-Windows”, como e onde posso baixá-lo, para que posso fazer teste e quem sabe começar a usar o NETIO.

    Fico no aguardo,

    Sinval

Deixe um comentário

Acima ↑