Página 5 de 35
Meu modo de trabalho
Enviado: 21 Jan 2016 15:34
por JoséQuintas
A rotina de tbrowse com codeblock, tá permitindo facilitar.
A primeira tela com locadores, pessoas que alugam casas, mostrando totais mes a mes.
A função de usuário no codeblock é NavegaLocatario()
Código: Selecionar todos
STATIC FUNCTION NavegaLocador()
LOCAL dData, nCont
LOCAL oTBrowse := { ;
{ "NOME", { || templocador->Nome } }, ;
{ "LOCADOR", { || templocador->Locador } } }
dData := UltDia( Ctod( "01/01/" + StrZero( Year( Date() ) - 1, 4 ) ) )
FOR nCont = 1 TO 36
AAdd( oTBrowse, { Substr( Dtoc( dData ), 4 ), LocadorColMesBlock( dData, 1 ) } )
dData := UltDia( dData + 1 )
NEXT
Cls()
SELECT templocador
GOTO TOP
DO WHILE .T.
Mensagem( "ENTER Locatários do locador, ESC Sai" )
DBView( 2, 0, MaxRow() - 4, MaxCol(), oTBrowse, { | oBrowse, nKey | NavegaLocatario( oBrowse, nKey, templocador->Locador ) }, 1 )
IF LastKey() == K_ESC
EXIT
ENDIF
ENDDO
RETURN NIL
Meu modo de trabalho
Enviado: 21 Jan 2016 15:36
por JoséQuintas
Ao teclar ENTER, abre os locatários, os inquilinos daquele locador.
Também com totais mes a mes.
O codeblock com função de usuário daqui, LocatarioTotaisMes()
Código: Selecionar todos
STATIC FUNCTION NavegaLocatario( oBrowse, nKey, nLocador )
LOCAL dData, nCont, nSelect := Select()
LOCAL oTBrowse := { ;
{ "NOME", { || templocatario->Nome } }, ;
{ "LOCATÁRIO", { || templocatario->Locatario } } }
IF nKey != K_ENTER
RETURN NIL
ENDIF
dData := UltDia( Ctod( "01/01/" + StrZero( Year( Date() ) - 1, 4 ) ) )
FOR nCont = 1 TO 36
AAdd( oTBrowse, { Substr( Dtoc( dData ), 4 ), LocatarioColMesBlock( dData, 1, nLocador ) } )
dData := UltDia( dData + 1 )
NEXT
Cls()
@ 2,0 SAY templocador->Locador PICTURE "9999"
@ Row(), Col() + 2 SAY templocador->Nome
SELECT templocatario
SET SCOPE TO Str( nLocador, 4 )
GOTO TOP
DO WHILE .T.
Mensagem( "ENTER detalhes" )
DBView( 4, 0, MaxRow() - 4, MaxCol(), oTBrowse, { | oBrowse, nKey | LocatarioTotaisMes( oBrowse, nKey, nLocador, templocatario->Locatario ) }, 1 )
IF LastKey() == K_ESC
EXIT
ENDIF
ENDDO
SET SCOPE TO
SELECT ( nSelect )
HB_SYMBOL_UNUSED( oBrowse )
RETURN NIL
Meu modo de trabalho
Enviado: 21 Jan 2016 15:39
por JoséQuintas
Ao teclar ENTER no anterior, abre os totais mes a mes de um único locador.
É meio repetitivo do anterior, mas aqui está na vertical, e mostra valor e comissão mensal.
Aqui o codeblock de função de usuário é Lancamentos()
Código: Selecionar todos
FUNCTION LocatarioTotaisMes( oBrowse, nKey, nLocador, nLocatario )
LOCAL nSelect := Select(), dData, nCont, cTmpFile, oTBrowse
IF nKey != K_ENTER
RETURN 0
ENDIF
wSave()
cTmpFile := MyTempFile( "DBF" )
SELECT 0
dbCreate( cTmpFile, { { "DATA", "D", 8, 0 } } )
USE ( cTmpFile ) ALIAS tempmes
dData := UltDia( Ctod( "01/01/" + StrZero( Year( Date() ) - 1, 4 ) ) )
FOR nCont = 1 TO 36
SELECT tempmes
RecAppend()
REPLACE tempmes->Data WITH dData
dData := UltDia( dData + 1 )
NEXT
oTBrowse := { ;
{ "MES", { || Substr( Dtoc( tempmes->Data ), 4 ) } }, ;
{ "VALOR", { || LocatarioTotaisMesColValor( nLocador, nLocatario, tempmes->Data, 1 ) } }, ;
{ "COMISSAO", { || LocatarioTotaisMesColValor( nLocador, nLocatario, tempmes->Data, 2 ) } } }
Cls()
@ 2, 0 SAY locador->Locador PICTURE "9999"
@ Row(), Col() + 2 SAY templocador->Nome
@ 3, 0 SAY templocatario->Locatario PICTURE "9999999"
@ Row(), Col() + 2 SAY templocatario->Nome
GOTO TOP
dbView( 5, 0, MaxRow() - 4, MaxCol(), oTBrowse, { | oBrowse, nKey | Lancamentos( oBrowse, nKey, nLocador, nLocatario, tempmes->Data ) } )
USE
fErase( cTmpFile )
wRestore()
SELECT ( nSelect )
HB_SYMBOL_UNUSED( oBrowse )
RETURN 0
Meu modo de trabalho
Enviado: 21 Jan 2016 15:48
por JoséQuintas
Este aqui comecei agora, vai mostrar cada lançamento e permitir alteração.
A intenção é fazer ajustes nas datas. Um lançamento com data errada, pode transformar o que era isento, em 30% de imposto.
Código: Selecionar todos
STATIC FUNCTION Lancamentos( oBrowse, nKey, nLocador, nLocatario, dData )
@ 2, 0 SAY templocador->Locador PICTURE "9999"
@ Row(), Col() + 2 SAY templocador->Nome
@ 3, 0 SAY templocatario->Locatario PICTURE "9999999"
@ Row(), Col() + 2 SAY templocatario->Nome
HB_SYMBOL_UNUSED( oBrowse + nKey + nLocador + nLocatario + dData )
RETURN NIL
E no meio disso tudo, rotinas auxiliares, mostrar só uma:
Código: Selecionar todos
STATIC FUNCTION LocadorColMes( dData, nTipoVal, nLocador )
LOCAL nValor, cnMySql := ADOClass():New( AppcnMySqlLocal() )
cnMySql:cSql := "SELECT SUM( " + iif( nTipoVal == 1, "VALOR", "VALORCOMIS" ) + " ) AS SOMA FROM INFORME WHERE LOCOD=" + NumberSql( nLocador ) + " AND YEAR( IFDATPAG ) = " + ;
NumberSql( Year( dData ) ) + " AND MONTH( IFDATPAG ) = " + NumberSql( Month( dData ) )
cnMySql:Execute()
nValor := cnMySql:NumberSql( "SOMA" )
cnMySql:Close()
RETURN nValor
É um trem legal.
Um tborwse chamando outro, DBF, MySQL, tudo junto e misturado.
Meu modo de trabalho
Enviado: 21 Jan 2016 15:54
por JoséQuintas
Isso me lembrou uma coisa, esqueci de dizer naquela viagem no tempo...
Foi nos tempos do Clipper que criei meu webservice de CEP.
O aplicativo acabava pesquisando endereços diretamente nos correios pela internet, usando VBScript.
Isso há 14 anos atrás, e no Clipper.
E me lembrou outra mudança... o uso de MySQL.
Realmente, teve avanço de lá pra cá, e foi na parte que não se vê.
Por isso eu não estava vendo.... rs
Só o salário mesmo, é que andou pra trás....
Essa parte eu sempre esqueço de melhorar.
Meu modo de trabalho
Enviado: 21 Jan 2016 17:09
por JoséQuintas
Quase lá... Este é o que mostra os lançamentos.
Código: Selecionar todos
STATIC FUNCTION Lancamentos( oBrowse, nKey, nLocador, nLocatario, dData )
LOCAL cnMySql := ADOClass():New( AppcnMySqlLocal() ), nSelect := Select(), oTBrowse, cTmpFile
wSave()
Cls()
@ 2, 0 SAY templocador->Locador PICTURE "9999"
@ Row(), Col() + 2 SAY templocador->Nome
@ 3, 0 SAY templocatario->Locatario PICTURE "9999999"
@ Row(), Col() + 2 SAY templocatario->Nome
@ 4, 0 SAY Substr( Dtoc( dData ), 4 )
cnMySql:cSql := "SELECT IFID, DATA, VALOR, VALORCOMIS FROM INFORME WHERE LOCOD=" + NumberSql( nLocador ) + " AND COD=" + NumberSql( nLocatario ) + ;
" AND MONTH( IFDATPAG )=" + NumberSql( Month( dData ) )
cTmpFile := cnMySql:ExecuteDbf()
SELECT 0
USE ( cTmpFile ) ALIAS tempLancto
oTBrowse := { ;
{ "ID", { || templancto->ifId } }, ;
{ "DATA", { || templancto->Data } }, ;
{ "VALOR", { || templancto->Valor } }, ;
{ "VALORCOMIS", { || templancto->ValorComis } } }
dbView( 6, 0, MaxRow() -4, MaxCol(), oTBrowse, { | oBrowse, nKey | AlteraData( oBrowse, nKey, templancto->ifId, templancto->Data, templancto->Valor, templancto->ValorComis ) } )
USE
SELECT ( nSelect )
fErase( cTmpFile )
wRestore()
HB_SYMBOL_UNUSED( oBrowse + nKey )
RETURN NIL
Outra função de usuário.
Já passa todos os valores pra função de usuário.
Como é MySQL, vou ter o ID do registro pra atualizar depois.
Vai ser só GET e atualizar.
UFA.
Meu modo de trabalho
Enviado: 21 Jan 2016 17:53
por microvolution
olá professor...
tô passando aqui, só pra dizer q tô ligado nas suas postagens, tá enriquecendo cada vez mais esse fórum.
parabéns!
Meu modo de trabalho
Enviado: 22 Jan 2016 08:51
por JoséQuintas
Uma alteração nestes dias do menu:
Código: Selecionar todos
MenuOption( "Consulta Imóveis vhlal01", "VHLAL01", { || vhlal01() } )
MenuOption( "Rel.Imóveis (Fichas) p/alugar", "LISTAIMO", { || listaimo() } )
MenuOption( "Rel.Imóveis p/ alugar (Tipo)", "LISTAIMO2", { || listaimo2() } )
MenuOption( "Cadastro de Imóveis pra alugar", "PALUGUEL", { || paluguel() } )
Código: Selecionar todos
MenuOption( "Consulta Imóveis vhlal01", "PALUGUELPE", { || pAluguelPe() } )
MenuOption( "Rel.Imóveis (Fichas) p/alugar", "PALUGUELL1", { || pAluguelL1() } )
MenuOption( "Rel.Imóveis p/ alugar (Tipo)", "PALUGUELL2", { || pAluguelL2() } )
MenuOption( "Cadastro de Imóveis pra alugar", "PALUGUEL", { || paluguel() } )
Estou alterando o nome dos fontes, o que implica em configurar senhas,etc.
Fazer isso a mão no cliente? correr o risco de esquecer? de jeito nenhum.
Código: Selecionar todos
FUNCTION AlteradoEntreVersoes()
IF .NOT. AbreArquivos( "hlsenha" )
RETURN NIL
ENDIF
NovoAcesso( "PDIMOBCAD", "PDIMOB" )
NovoAcesso( "PNATALINI", "PININATAL" )
NovoAcesso( "PNATALETI", "PETINATAL" )
NovoAcesso( "PNATALLIS", "PLISNATAL" )
NovoAcesso( "PALUGUELPE", "VHLAL01" )
NovoAcesso( "PALUGUELL1", "LISTAIMO" )
NovoAcesso( "PALUGUELL2", "LISTAIMO2" )
CLOSE DATABASES
RETURN NIL
Ao trocar o programa, ele vai cadastrar acesso automaticamente, liberando a opção nova pra quem tinha acesso à opção velha.
É o que o nome diz mesmo.
É pra etiqueta de natal.
Só vai ser usado agora no ano que vém.
Já tá resolvido um ano antes, pra que esperar.
Daqui um ano já esqueci tudo, mas melhor esquecer deixando pronto.... rs
Meu modo de trabalho
Enviado: 22 Jan 2016 19:55
por JoséQuintas
Uia....
Minha mensagem de erro de hoje, recebi por email acessível pelo celular:
Problema não consta da lista de erros conhecidos
Horário : 22/01/2016 13:35:04
--------------------------------------------------------------------------------
Já pode tirar aonde apaga txtdimob2015.txt
Já pode tirar aonde apaga corre13.dbf
Já pode tirar aonde apaga corre14.dbf
Já pode tirar aonde apaga infoant.dbf
Ja pode tirar adição do campo CORRENTE.CRDATPAG
Já pode tirar adição do campo INFORME.IFDATPAG
Já pode tirar adição do campo INFORME.IFDATDIM
Já pode tirar adição do campo INFORME.IFDATDOC
Já pode tirar adição do campo INFORME.IFDATLAN
Já pode tirar remoção do campo INFORME.UFIR
Já pode tirar remoção do campo INFORME.UFM
Já pode tirar remoção do campo INFORME.URV
Já pode tirar remoção do campo INFORME.VALURV
Já pode tirar remoção do campo HLDIMO.UFIR
Já pode tirar remoção do campo HLDIMO.UFM
Já pode tirar remoção do campo HLDIMO.URV
Já pode tirar remoção do campo HLDIMO.VALURV
Já pode tirar remoção do campo HLDIMO1.UFM
Já pode tirar remoção do campo HLDIMO1.URV
Já pode tirar remoção do campo HLDIMO1.VALURV
O aplicativo me avisando que já posso remover essas rotinas!!!!
Os campos se referem a base de dados MySQL.
Isso é bom demais.
Meu modo de trabalho
Enviado: 22 Jan 2016 21:24
por microvolution
JoséQuintas escreveu:Minha mensagem de erro de hoje, recebi por email acessível pelo celular:
prezado professor, gostei dessa ideia, que por coincidência neste mesmo horário estava acabando de sair de uma cliente onde oferecia meu software (e dizia para ela) que em breve quem estivesse conectado receberia informações sobre as novas atualizações do sistema. Semelhante ao que nós vemos no Mozilla Firefox que quando a gente clica em "about..." e ele atualiza automaticamente...
aí o nobre professor posta uma coisa dessas que dá água na boca... que coisa não?
bom, nesse caso dá pra matar 2 coelhos com um tiro só né? ou seja:
- o cliente recebe atualizações e as instala automaticamente; e,
- a gente recebe (por email, sms ou zap).
muito bacana...
se puder me dar o link onde V.postou os códigos, quero estudar "PáVêSiCõsigoAprêdê" rsrsrs
Meu modo de trabalho
Enviado: 10 Fev 2016 21:03
por JoséQuintas
A rotina de erros padrão é a errorsys.prg
É ela quem apresenta as mensagens de erro usando @ SAY.
Só alterar pra salvar em disco.
E o envio, é o envio normal de e-mails.
Meu modo de trabalho
Enviado: 12 Jun 2016 01:15
por fladimir
Poderia compartilhar sua rotina errorsys Zé pra efeito de estudo? é a mesma do all-in-one?
Outro assunto meio q no mesmo...
Na minha eu tenho um comando para pegar o IP_Publico mas esta demorando pra retornar com o IP, antes era rapidinho mas o site q eu usava caiu fora do ar... caso já use isso na tua ou saiba outra forma mais rápida e puder passar o link agradeço, mas essa questão não é principal...
[]´s
Meu modo de trabalho
Enviado: 12 Jun 2016 09:48
por JoséQuintas
É praticamente a mesma.
A diferença é que a do aplicativo consegue pegar informações do aplicativo, como por exemplo o usuário logado e nome da empresa.
A única coisa que a errorsys faz é gravar no disco, no arquivo HB_OUT.LOG que é padrão do Harbour pra erros "não Clipper".
Erro por email não fica na errorsys.
É relativamente simples: ao abrir o aplicativo, se existe HB_OUT.LOG envia o conteúdo por email.
E acumula o conteúdo em um errogeral.log, apagando hb_out.log no final do email - precaução pra sempre ter o histórico de erros completo.
Vai ver lá, que procuro mostrar variáveis de ambiente, que contém nome de servidor, nome de usuário no Windows, nome do computador, etc.
Ajuda a identificar qual é a máquina.
Se preciso IP externo acabo usando meu site:
http://www.jpatecnologia.com.br/meuip.asp
Meu modo de trabalho
Enviado: 12 Jun 2016 22:56
por fladimir
Entendi.. obrigado zé...
[]´s
Meu modo de trabalho
Enviado: 12 Ago 2016 23:24
por JoséQuintas
Mudança de hoje, de:
Código: Selecionar todos
IF AppcnMySqlLocal() == NIL
cnMySql := ADOClass():New( AppcnMySqlJPA() )
ELSE
cnMySql := ADOClass():New( AppcnMySqlLocal() )
ENDIF
para
Código: Selecionar todos
IF AppcnMySqlLocal() == NIL
MsgExclamation( "Módulo não disponível sem base MySQL" )
RETURN
ENDIF
cnMySql := ADOClass():New( AppcnMySqlLocal() )
Continuando o:
- Chega de IFs com opção de base de dados
- tchau meu servidor MySQL remoto
- tchau DBF
- tchau hbnetio
- MySQL local obrigatório
- Harbour ou não Harbour, depois se vê