joaosolution Posted March 24, 2014 Report Share Posted March 24, 2014 Srs. Bom dia Trabalho com meus sistemas, utilizando vetor de campos para os gets. Normalmente utilizo aVetor[1], aVetor[2] etc. Efetuo a leitura dos dados utilizando FieldGet e assim sucessivamente. Gostaria de saber se alguém trabalha com os indices de vetor com os nomes dos campos dos banco de dados: Ex.: aVetor[i_codigo], aVetor[i_nome] Sei que se utilizar #Define i_codigo 1 #Define i_nome 2 etc Mas queria fazer isso de forma automática, direto via código, amrir o banco, ler os campos, criar os define e utilizar nos cadastros Sei que utilizando DbSctruct() e FieldName() leio os dados do banco, mas não consegui criar as variárieis com nome dos campos e a posição do vetor. Grato por qualquer ajuda. Att João Bosco Quote Link to comment Share on other sites More sharing options...
Ale SB Posted March 24, 2014 Report Share Posted March 24, 2014 Blz Joao; Cara o melhor seria neste caso vc criar uma classe para fazer tudo automatico. Eu criei uma baseada na TDataBase, mas tudo atraves de Hash muito mais pratico e rapido do q array, hoje trabalho com DBF/ADS mas na linha do Sql, os bancos ficam fechados, soh eh aberto para carregar as variaveis e para gravaçoes, abre e fecha. Qq alteraçao nos registros, a classe verifica soh oq houve alteraçao e manda para o banco soh os registros alterados, tudo muito rapido...vc ganha tempo e segurança trabalhando em rede. Mas, vc pode dar uma olhada nesta classe aqui, fazendo algumas pequenas alteraçoes personalizadas, acredito q vc vai conseguir fazer oq quer! http://forums.fivetechsupport.com/viewtopic.php?f=3&t=14019&hilit=xdatabase @braços Ale Quote Link to comment Share on other sites More sharing options...
emotta Posted March 24, 2014 Report Share Posted March 24, 2014 Não sei se entendi, mas o que vc quer é mais ou menos isso: hDados := Hash() // ou pode iniciar a variavel assim: hDados := {=>} For nI := 1 to FCount() hDados[FieldName(nI)] := FieldGet(nI) Next ? hDados["SP5_NOME"] // EDUARDO MOTTA ? hDados["SP5_CODIGO"] // 000001 Srs. Bom dia Trabalho com meus sistemas, utilizando vetor de campos para os gets. Normalmente utilizo aVetor[1], aVetor[2] etc. Efetuo a leitura dos dados utilizando FieldGet e assim sucessivamente. Gostaria de saber se alguém trabalha com os indices de vetor com os nomes dos campos dos banco de dados: Ex.: aVetor[i_codigo], aVetor[i_nome] Sei que se utilizar #Define i_codigo 1 #Define i_nome 2 etc Mas queria fazer isso de forma automática, direto via código, amrir o banco, ler os campos, criar os define e utilizar nos cadastros Sei que utilizando DbSctruct() e FieldName() leio os dados do banco, mas não consegui criar as variárieis com nome dos campos e a posição do vetor. Grato por qualquer ajuda. Att João Bosco Quote Link to comment Share on other sites More sharing options...
joaosolution Posted March 25, 2014 Author Report Share Posted March 25, 2014 Eduardo e Ale Obrigado pelas respostas. É isso mesmo que estou precisando, vou testar aki. Att João Bosco Quote Link to comment Share on other sites More sharing options...
fladimir Posted March 25, 2014 Report Share Posted March 25, 2014 Eduardo, vc saberia dizer se os nomes dos campos são Case Sensitive? Quote Link to comment Share on other sites More sharing options...
emotta Posted March 25, 2014 Report Share Posted March 25, 2014 sim, é case sensitive... aconselho a usar sempre com UPPER Quote Link to comment Share on other sites More sharing options...
oribeiro Posted March 26, 2014 Report Share Posted March 26, 2014 Eu criei uma baseada na TDataBase, mas tudo atraves de Hash muito mais pratico e rapido do q array, hoje trabalho com DBF/ADS mas na linha do Sql, os bancos ficam fechados, soh eh aberto para carregar as variaveis e para gravaçoes, abre e fecha. Qq alteraçao nos registros, a classe verifica soh oq houve alteraçao e manda para o banco soh os registros alterados, tudo muito rapido...vc ganha tempo e segurança trabalhando em rede. Ale, Eu me interessei nessa sua resposta. Trabalho 100% com array com os meus DBF/CDX e gostaria de mudar para Hash. Se eu entendi bem, você disse que abre e fecha o banco somente nos momentos exatos de ler e gravar. Nesse caso, como você faz para travar o registro que está sendo modificado para que outros não o alterem na rede? Aguardo, obrigado. Oscar Quote Link to comment Share on other sites More sharing options...
Ale SB Posted March 26, 2014 Report Share Posted March 26, 2014 Eu criei uma baseada na TDataBase, mas tudo atraves de Hash muito mais pratico e rapido do q array, hoje trabalho com DBF/ADS mas na linha do Sql, os bancos ficam fechados, soh eh aberto para carregar as variaveis e para gravaçoes, abre e fecha. Qq alteraçao nos registros, a classe verifica soh oq houve alteraçao e manda para o banco soh os registros alterados, tudo muito rapido...vc ganha tempo e segurança trabalhando em rede. Ale, Eu me interessei nessa sua resposta. Trabalho 100% com array com os meus DBF/CDX e gostaria de mudar para Hash. Se eu entendi bem, você disse que abre e fecha o banco somente nos momentos exatos de ler e gravar. Nesse caso, como você faz para travar o registro que está sendo modificado para que outros não o alterem na rede? Aguardo, obrigado. Oscar Blz Oscar, Bom na questao da Alteraçao vai depender do modulo, qualquer registro que eu tenha q travar eu defino no prg, se eu quero travar ele soh no momento da gravaçao dos dados ou quando abre o registro na tela( que eu acho inviável este ultimo caso). Se vc travar quando abrir o registro o usuario pode ir la tomar um cafezinho e por certo ninguem vai poder alterar nada. Entao prefiro travar na hora de salvar, a classe eh rapida entao mesmo q os dois ou mais estejam alterando o mesmo registro, nao da problema ja testei alterando dois registros apertando o botao de salvar ao mesmo tempo, foi de boa...oq manda neste caso e a maquina, a mais rapida faz a alteraçao 1º. O objetivo da classe e dar agilidade nos processos de gravaçao, 1º eu verifico quais os dados que foram alterados e depois mando gravar, com isso vc ja ganha muito tempo, assim, se tornando um processo rapido. Se vc tem um registro com 50 campos e o cara altera soh 01 campo, a classe identifica e grava soh a alteraçao de um campo ( mais rapido do que gravar os 50 neh), sem falar q pode acontecer de outro usuario estar alterando tb 1 campo, mas diferente, vc nao interfere na informaçao. Agora os dois estar alterando ao mesmo tempo, o mesmo campo eh dificil de acontecer, mas, pode acontecer ai vc tem q ter uma funçao para estes casos, por exemplo de uma venda os dois podem alterar o mesmo campo de estoque, ai o correto seria ter uma funçao informando o usuario q outra venda esta sendo realizada, se o produto tiver soh 01 em estoque, ai eh o vendedor mais experto q ganha a comissao..ehheheh....+- por ai. voltando para classe, seria +- isso : Inclusao/Novo registro: - Entro com os dados no buffers; - Salvo : --> Abro o banco --> A classe ja gera um codigo automatico e grava no registro( pronto aquele Registro eh meu, nao corro o risco de duplicaçao de codigo ) --> Travo e mando salvar os outros campos; --> A classe salva faz o commit, destravo e ja fecho o banco. Alteraçao/ediçao do registro -Apos a Ediçao, mando salvar - A Classe: --> Compara os campos do registro que estao no Buffers com os do hash que eu ja carreguei na hora de abrir o registro. --> se houve alteraçao a propria classe tem uma dialog q informa para o usuario oq esta sendo alterado e ele decide oq fazer. --> Caso seja Confirmar a alteraçao, --> A Classe Grava um log sobre as alteraçoes (automatico) *** --Cliente.log Código: 000020 Bairro : Centro ==> Alterado Por ==> jardim monte libano Fone 3 : ==> Alterado Por ==> 1899999999 Nome : Ana Paula Gomes Bertagnolli ==> Alterado Por ==> Teste log Usuário: USERMASTER - IP: 192.168.1.3 - Terminal: DEMOLIDOR Alterações Efetuadas em: 26/03/2014 às 10:24:45 ==================================================================================================== Código: 000001 Ender. : Rua Evandro B. Calvoso ==> Alterado Por ==> Rua Evandro B. Calvo Nome : Edna Lopes Batalha ==> Alterado Por ==> Alessandro Batalha Usuário: USERMASTER - IP: 192.168.1.3 - Terminal: DEMOLIDOR Alterações Efetuadas em: 26/03/2014 às 10:24:01 ==================================================================================================== --> Abro o Banco, dou um seek, travo, a classe salva e da o commit, destravo e fecho o BD. Eh +- por ai...este eh a parte de gravaçao do meu Prg. //----------------------------------------------------------------------------// METHOD SalvaReg(nCodIni, lMsg) CLASS TCliente_sb local cRet, cModulo local vTarefa := "I" DEFAULT lMsg := .T. //--> Envia as mensagens de Alteraçao. //--> cRet ==> (N) - Nao há Modificaçoes. // (A) - Alterar, Salva as Novas Informaçoes. // (C) - Cancelar, Cancela as Informaçoes Digitadas. // (R) - Retornar, retorna a tela de Edição, ainda com as Informaçoes Digitadas. //--> Ediçao Novo Registro, Se _nCodIn for # do Codigo Digitado eh uma Alteração. //--> Este procedimento soh ocorre depois do Codigo ja estar validado e o // Usuario estiver tentando Salvar o Registro. if nCodIni != Val(::oDbfClie:Codi_Cli) cRet := ::oDbfClie:hsChange(lMsg) if !lMsg cRet := "A" endif if ( cRet == "N" .or. cRet == "C" ) return .t. elseif cRet == "R" return .f. elseif cRet == "A" //--> Grava em um Arquivo de Texto as Alteraçoes. hb_FNameSplit( ProcFile(0),, @cModulo ) ::oDbfClie:hsChangeLog( cModulo, "Codi_Cli", oVar:cUsuario ) //--> Grava apenas as Modificaçoes. vTarefa := "A" endif endif if !::oDbfClie:dbOpen() return .f. endif ::oDbfClie:SetIndex() //--> default SetOrder 1 if vTarefa == "I" ::oDbfClie:GenCodeRec() && Tem q vir antes do Append, Gera codigo. ::oDbfClie:Append() if ::oDbfClie:NetError() ::oDbfClie:dbClose() return .f. endif ::oDbfClie:FieldPut("Codi_Cli") ::oDbfClie:Flag_Cli := "A" //--> Ativo ::oDbfClie:UsuarCli := oVar:cCodUser ::oDbfClie:Data_Cli := Date() ::oDbfClie:Hora_Cli := Time() endif if vTarefa == "A" ::oDbfClie:dbSeek(::oDbfClie:Codi_Cli) endif if ::oDbfClie:() ::oDbfClie:SaveBuf() ::oDbfClie:dbRUnLock() else ::oDbfClie:dbClose() return .f. endif ::oDbfClie:dbClose() if (nCodIni != Val(::oDbfClie:Codi_Cli)) .and. vTarefa == "I" MsgInfo( "Novo Código Gerado: " + ::oDbfClie:Codi_Cli, "..:: Atenção ::..") endif return .t. Quote Link to comment Share on other sites More sharing options...
Ale SB Posted March 26, 2014 Report Share Posted March 26, 2014 Ah e no caso dos browses/listbox, eu trabalhava com array, mudei tudo para temp( nos testes descobri q eh mais rapido) Abro o banco filtro se precisar e carrego tudo para o temp, fecho o banco e pronto...pode dar pau no terminal pode esquecer aberto o Browse o seu banco ta fechado e guardado. *****--- CARREGA TEMP ********************************************************** oDbfClie := ::oDbfClie if !oDbfClie:dbOpen() return .f. endif aEstru := (oDbfClie:cAlias)->( dbStruct() ) oDbfClie:dbClose() //--> Temporario //dbCreate( cFile, aStruct, cRDD, lKeepOpen, cAlias, cDelimArg, cCodePage, nConnection ) dbCreate( "mem:tCadaCli", aEstru, "DBFCDX", .T., "tCadaCli" ) Inde On Upper(sb_TiraAcento(tCadaCli->Nome_Cli)) Tag "Nome_Cli" Inde On Upper(sb_TiraAcento(tCadaCli->FantaCli)) Tag "FantaCli" Inde On tCadaCli->Fone1Cli Tag "Fone1Cli" Inde On tCadaCli->Fone2Cli Tag "Fone2Cli" Inde On tCadaCli->Fone3Cli Tag "Fone3Cli" dbSelectArea("tCadaCli") ::FiltroTab(1) tCadaCli->( dbSetOrder(1) ) //--> Nome tCadaCli->( dbGoTop() ) aFiltro := { "Todos Ativos", "Venda Liberada","Venda Travada", "Excluidos", "Todos" } //----------------------------------------------------------------------------// METHOD FiltroTab(oCbx_nAt) CLASS TCliente_sb local cTagOrd, cScope1, cScope2 local lFiltro := .t. local nOrd local oDbfClie, oAds oDbfClie := ::oDbfClie if !oDbfClie:dbOpen() return endif oDbfClie:SetIndex() //--> aFiltro := { "Todos Ativos", "Venda Liberada","Venda Travada", "Excluidos", "Todos" } if oCbx_nAt == 1 //--> Todos Clientes que nao sejam Excluidos. lFiltro := .f. nOrd := 9 cScope1 := "A" cScope2 := "A" elseif oCbx_nAt == 2 //--> Todos Clientes Vendas Liberadas que nao sejam Excluidos. nOrd := 8 // (.F.) Vendas Nao Travadas. cScope1 := .F. cScope2 := .F. elseif oCbx_nAt == 3 nOrd := 8 cScope1 := .T. cScope2 := .T. elseif oCbx_nAt == 4 lFiltro := .f. nOrd := 9 cScope1 := "E" cScope2 := "E" elseif oCbx_nAt == 5 //--> Todos lFiltro := .f. nOrd := 9 cScope1 := "A" cScope2 := "E" endif oDbfClie:SetOrder(nOrd) cTagOrd := oDbfClie:cTag dbSelectArea("tCadaCli") tCadaCli->( dbzap() ) oDbfClie:SelectArea() oDbfClie:dbGoTop() #ifdef __SB_ADSCDX__ oAds := TxAds_sb():New() if lFiltro oAds:xScopeFilter( cTagOrd, cScope1, cScope2,"Clientes->Flag_Cli == 'A'" ) else oAds:xScopeIndex(cTagOrd, cScope1, cScope2 ) endif oAds := nil #else #endif do while !oDbfClie:Eof() tCadaCli->( dbAppend() ) for x := 1 to ( oDbfClie:cAlias )->( FCOUNT() ) //oDbfCola:ordKeyCount() tCadaCli->( FieldPut(x, (oDbfClie:cAlias)->(FieldGet(x)) ) ) next oDbfClie:dbSkip() enddo oDbfClie:dbClose() dbSelectArea("tCadaCli") dbSetindex("tCadaCli") tCadaCli->( dbSetOrder(1) ) //--> Nome tCadaCli->( dbGoTop() ) return Quote Link to comment Share on other sites More sharing options...
oribeiro Posted March 26, 2014 Report Share Posted March 26, 2014 Muito boa essa classe alterada heim! Você a comercializa? Quote Link to comment Share on other sites More sharing options...
Ale SB Posted March 26, 2014 Report Share Posted March 26, 2014 Muito boa essa classe alterada heim! Você a comercializa? Cara eh boa sim, .... nao vou te falar q ela seja merecedora do Premio Nobel, mas, tem muita coisa nela que eu sempre quis ter de forma automatica no sistema e no desenvolvimento. Cara a classe nao cormecializo nao, somente o suporte...pq algumas coisas sao personalizadas para minhas necessidades. Para vc usar ai, talvez precise de alguns ajustes para sua necessidade e compatibilidade de suas ferramentas, coisa simples, mas sempre necessarias ate para ganhar tempo. qq coisa entra em contato: Skype: ale.seribeli ( nao fico conectado o dia Todo) email: aleseribeli@hotmail.com ( verifico os emails diariamente ) WhatsApp : 67-9147-3920 (24 horas p/dia, quando a Claro ta com boa vontade de sinal.) @braçao Ale Quote Link to comment Share on other sites More sharing options...
Ale SB Posted March 26, 2014 Report Share Posted March 26, 2014 Galera mudança de planos; vou Comercializar a Classe Sim. Mais detalhes eh soh entrar em contato. @braços Ale Quote Link to comment Share on other sites More sharing options...
Marca Posted March 28, 2014 Report Share Posted March 28, 2014 JoãoEu trabalho exatamente assim e a funcao faz a comparação dos campos da mesma maneira q. o Ale falou Na hora de gravar basta vc comparar se a posição 3 do vetor esta com o mesmo conteudo da posição 2 aStr := Ini_Var("OrdemSv", lAppendOs) If Len(aStr) > 0 For nA := 1 To Len(aStr) cGets := aStr[nA][1] &cGets := aStr[nA][2] NEXT ELSE Return(.F.) ENDIFCaso o campo seja codigo na tabela? f_Codigo Ou b_codigo Espero q. te ajude **************************************//***************************************FUNCTION Ini_Var(__cArqIni, lVazias)**************************************//***************************************LOCAL nContaVar ,; cCampoVars,; cTipoVar ,; cVarIni ,; cPathSave ,; aRetVars := {} LOCAL _eArea := Alias(),; _nOrd := IndexOrd() PRIVATE cVarBack ,cProdvarsPRIVATE dDate := Date()PRIVATE lLogic := .F. IF __cArqIni == NIL .OR. Empt(_eArea) mSg('Erro na criação das variáveis reveja o módulo ','Erro','STOP') RETURN aRetVars ENDIF cAlias := __cArqIni DbSelectArea(cAlias) IF (!lVazias .AND. Eof()) .OR. (!lVazias .AND. Bof()) IF Eof() DBSkip(-1) ENDIF IF Bof() DBSkip(1) ENDIF ENDIF IF RddName() = 'MYSQL' (cAlias)->(SQLRefresh()) ENDIF FOR nContaVar := 1 TO (cAlias)->(fCount()) IF Upper(Left(FieldName(nContaVar),4)) != "SQL_" .AND. !Empt(Left(FieldName(nContaVar),4)) cCampoVars := cAlias + '->' + (cAlias)->(FieldName(nContaVar)) cTipoVar := ValType(&cCampoVars) cVarIni := 'f_' + (cAlias)->(FieldName(nContaVar)) cVarBack := 'b_' + (cAlias)->(FieldName(nContaVar)) IF cTipoVar = 'C' &cVarIni := If(lVazias, Space(Len(&cCampoVars)), &cCampoVars) ELSEIF cTipoVar = 'D' &cVarIni := If(lVazias, CToD(''), &cCampoVars) ELSEIF cTipoVar = 'N' &cVarIni := If(lVazias, 0, &cCampoVars) ELSEIF cTipoVar = 'L' &cVarIni := If(lVazias, .F., &cCampoVars) ELSEIF cTipoVar = 'M' &cVarIni := If(lVazias, Space(254), &cCampoVars) ENDIF &cVarBack := &cVarIni AaDd(aRetVars,{cVarIni,&cVarIni,&cVarIni}) ENDIF NEXT DbSelectArea(_eArea) IF _nOrd > 0 (_eArea)->(DBSetOrder(_nOrd)) ENDIF RETURN aRetVars Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.