Página 2 de 2

Enviado: 31 Ago 2005 15:16
por Visitante
PERAÍ...

Eu acho que estou ficando louco!

O Cliente cria rotinas?

Pra que serve o programador, então?

Não seria mais fácil vender os fontes e deixar que ele se vire?

Se o problema é automatizar determinadas funções, parametrize o sistema, assim o sistema toma decisões com base nos parâmetros que podem ser alterados pelo sistema.
ISSO SIM EU JÁ VI.

Agora, o Cliente entrar, via run-time, com "rotinas" do sistema, é fazer do usuário o programador. ISSO EU NUNCA VI (E cá pra nós, não quero ver nunca! Imagine só... o cliente dando manutenção em meu sistema...)

Se eu entendi errado, me desculpe, mas foi o que a postagem do david me fez entender...

Enviado: 31 Ago 2005 15:34
por Stanis Luksys
100 % de acordo

Enviado: 31 Ago 2005 17:07
por gvc
O que nosso amigo esta falando é algo que a Microsiga utilizava, não sei se ainda utiliza, que funciona assim:

Vc tem o sistema que faz o faturamento com as entradas e saídas e todos os processos que nós conhecemos.
Na emissão da Nota Fiscal, muda o layout de um cliente para outro.
Se vc tem uma rotina externa, vc ou o próprio cliente pode mudar o necessário na emissão da N.F. sem ser necessário um novo fonte.
Isso tb poderia ser utilizado em uma rotina que mudaria de um cliente para outro.

Em resumo, o seu sistema pode trabalhar normalmente e permite ao usuário/programador mudar rotinas específicas, respeitando a sintaxe da linguagem. O núcleo é o seu sistema e vc pode agregar novos recursos sem ter que fazer versões do mesmo.

Enviado: 31 Ago 2005 17:22
por Visitante
Caro GVC...

Acho que você foi infeliz no seu exemplo, pois: 1º Não se muda de lay-out de Nota fiscal da noite para o dia, e 2º O caso do lay-out da nota fiscal é o mesmo caso que uso para emissão de bloquetos: Tenho um banco de dados com os parâmetros da boleta que utilizo na hora da impressão.

Isso se chama parametrizar o sistema. Isso não implica que o cliente irá montar rotinas para que o sistema passe a englobá-las como se fossem parte do executável.

Mais uma vez peço perdão se eu estiver vendo as coisas da forma como ela não são, mas eu li que o David disse que o cliente "cria rotinas" e não que ele determinasse uma forma de o sistema funcionar (que no caso seria através do conteúdo de algum(ns) parãmetro(s).)

Um Clip Abraço

Enviado: 31 Ago 2005 17:44
por Stanis Luksys
Novamente concordo em genero, numero e grau com o amigo Mlizander.

Nos meus sistemas eu crio uma tabela de parametros que tem todos os seus dados atribuidos a variaveis estaticas no fonte principal do programa (na verdade uma Init Procedure), incializando assim o AMBIENTE DE TRABALHO como um todo.

Essa tabela pode conter desde informaçoes simples como cor das telas até layouts de nota fiscal e preferencias gerais de fluxo financeiro etc...

Parto do princípio de que o usuário jamais deve necessitar de qualquer conhecimeto da sintaxe da linguagem aplicada no desenvolvimento do sistema. É claro que também levo em consideração o fato de que qualquer alteração desejada em alguma rotina do sistema cabe unicamente a mim realizar.

Quanto ao real objetivo do amigo David, creio que ainda nao ficou claro para ninguém, mas eu particularmente não entendi:

1. Por que testar se uma função existe?
2. Estamos falando de um sistema ou de um utilitário e/ou ferramenta de desenvovimento, onde o usuario cria rotinas?
3. Essa eu nao entendi mesmo: funcao que executa funcao??? exec( funcao() ), o q é isso???

Olha, bom mesmo seria o amigo David reformular sua dúvida com um exemplo pratico, dizendo exatamente onde e quando vai aplicar esta rotina, assim quem sabe a gente não possa ajudar dizendo como.

Enviado: 02 Set 2005 19:43
por david.miguel
Ola a todos,

Como o gvc disse, estou querendo pegar um ideia que o Microsiga utiliza.

Deixa eu ver se consigo explicar melhor esta minha ideia.

Eu tenho um titulo do contas a pagar q estou baixando, ele vai para uma tabela de movimento bancarios aonde tem um campo texto de HISTORICO. Este campo aparece para o meu cliente qdo ele vai efetuar a baixa do titulo para que o conteudo do campo, que já vem preenchido com alguma informacao, seja alterado. Mas o meu cliente quer q toda as vezes que este campo for um cheque, grave outra informação neste campo de HISTORICO. Ai eu tenho uma rotina assim:

BAIXA()

IF EXISTE(POS_BAIXA())
EXECULTE(POS_BAIXA())
ENDIF

PROCEDURE ROTINA POS_BAIXA()
CAMPO->HISTORICO := "CONTEUDO PARA CH"
RETURN

Espero ter sido mais claro. Obrigado

Enviado: 03 Set 2005 01:02
por vagucs
Cara, para avaliar a existencia de uma funcao uso o seguinte

Código: Selecionar todos

? type("cheque()")
? type("cheque(1)")
procedure cheque
Veja que o retorno de type é "UI" caso a função está anexada ao executável, o retorno de type é o tipo de expressão que a função representa, no caso de "U" a rotina é inexistente no sistema,os blocos em strings podem conter funções inexistentes no EXE o que gera um erro, logo a avaliação de bloco como indicado acima (=NIL) não ajudará em nada, pois mesmo se o bloco conter uma rotina que não exista no EXE ele não será NIL e o eval irá tentar avaliar uma expressão de uma rotina que não existe.

No caso da rotina não existir no EXE a função type retorna "U", assim, verificamos de forma simploria.

Uma rotina para executar PPO simples, vc faz o fonte clipper e compila com /P, vai ser gerado um programa PPO, agora façamos o seguinte, vamos ler este programa linha a linha e avaliar se as rotinas existem no EXE, claro, isso aqui é bem simples, não iremos avaliar IF, DO WHILE, DO CASE, FOR, somas, repassamentos, igualdades, sendo que isto pode ser feito, até mesmo via função, como o pessoal da microsiga fez, executando as rotinas saltando linhas. Vejamos entao um exemplo bem simples. Há, não aceita procedures também, apenas servirá como exemplo de execução de um script. Veja que isto funciona legal demais e pode ser levado ao estremo e permitir que se faça rotinas extensas deste modo, com aprimoramentos o usuario até pode criar suas próprias rotinas.

Código: Selecionar todos

// Programa EXECUTA
// Teste feito por Wagner Nunes - www.vagucs.com.br
request scroll
request dispbox
request setcolor

parameter script
if script=NIL
   ? "Fornecer o nome do arquivo a ser executado."
   quit
end if
if !file(script)
   ? "Arquivo de script nÆo encontrado"
   quit
end if
handle=fopen(script)
if ferror()#0
   ? "Erro na abertura do arquivo. Código do erro:"
   ?? ferror()
   quit
end if
endof_file=.f.
? "Executando..."
do while !endof_file
   linha=alltrim(fgetline(handle))
   if !empty(linha)
      if !left(linha,2)="//" .and. !left(linha,1)="#" // Não executa comentários
         if !type(linha)=="U"
            bloco="{||"+linha+"}"
            eval(&bloco)
         else
            alert("Fun‡Æo nÆo existente:"+linha)
         end if
      end if
   end if
enddo

function fgetline(script)
local return_lin, chunk, bigchunk, oldoffset, at_chr13
return_lin = ''
bigchunk = ''
oldoffset = fseek (script, 0, 1)
do while .t.
   chunk = ''
   chunk = freadstr (script, 100)
   if len (chunk) = 0
      endof_file = .t.
      exit
   endif
   bigchunk = bigchunk + chunk
   if at (chr (10), bigchunk) > 0
      at_chr13 = at (chr (10), bigchunk)
      fseek (script, oldoffset)
      return_lin = freadstr (script, at_chr13 - 1)
      exit
   endif
enddo
fseek (script, 1, 1)
if right(return_lin,1)=chr(13)
   return_lin:=left(return_lin,len(return_lin)-1)
end if
return return_lin

Os request no principio sao apenas para rodar o DEMO que criei.
Vejam

Código: Selecionar todos

// Teste.prg
#include "box.ch"
? "teste"
set color to gr+/b
@ 1,1,24,80 box B_DOUBLE
?? "Wagner Nunes"
? "Pressione uma tecla para sair"
inkey(0)
Compile o teste.prg com o parametro /P, vai ser gerado um PPO, este PPO que vc chama com o codigo acima, ele sai executando as rotinas no PPO uma a uma caso elas existam.

É um exemplo muito bacana.

Enviado: 03 Set 2005 01:12
por vagucs
Amigos, quanto a toda a polêmica, eu falo lhes uma coisa, um sistema que tem pontos de programação para os usuários é ótimo, não sai da sua mão, porém seu sistema não precisa ter rotinas de caixa 2 ou coisa do tipo, é o que a microsiga sempre fez com seus sistemas, ela vendia o sistema e anexava a eles pontos de programação, onde o usuário inseria rotinas que poderiam ler as variaveis do programa deles, assim manuzealos e fazer qualquer tipo de operação com estes dados, assim, já estive em grandes empresas que usam o sistema da microsiga por isso, por ser um software completo, homologado e com pontos de programação, esta programação a microsiga não faz, o cliente tem a opção de contratar um programador para fazê-las, ou seja, em si o cliente não programa, mas são rotinas que vc também não tem peso diante da lei se o seu cliente as implantou no sistema.

Em todos os meus sitemas, o pano de fundo é executado a partir de um script, apenas uso rotinas do proprio clipper no formato PPO como sugeri acima, assim em casa cliente eu formato as telas de um jeito, mas o script que ele executa vai alem disto, em certa vez fui a um cliente em uma cidade vizinha e ele tinha problemas com bancos de dados, na falta do note e de programas especificos, na verdade eu fui neste cliente ao acaso, como tinha que acertar alguns titulos o que fiz. No script dei um select no contas a receber e um browse, a na hora de desenhar a tela o programa executou o script e ele abriur o browse onde eu acertei o contas a receber do cliente diretamente, ou seja, foi meu salva vidas, e todo sistema meu tem um ponto de entrada no mínimo que me possibilita fazer isto usando rotinas internas.

Enviado: 03 Set 2005 02:20
por Clipper
Prezado Wagner

Discordo de um ponto na sua postagem.

Em grosso modo. Segundo as leis, um sistema não pode possuir e ou permitir rotinas que possam de alguma forma contrubuir para atos ilicitos. Neste caso o sistema não possui, porém permite que atos ilicitos possam ser cometidos já que deixa brechas para que outros o façam, seria mais ou menos como a pessoa que tem a chave do cofre mas não rouba explicitamente, ela apenas deixa o cofre aberto e avisa para quem o faz.
Digamos que um programador pegue o sistema da microsiga e faça um caixa 2, se isso for detectado e a empresa disser que não fez nada, que já veio no sistema, como é que a microsiga vai explicar ? Já que o software está no nome dela, e mesmo que ela consiga explicar que outro o fez, como vai explicar que o sistema permite tal ?

Até logo.

Marcelo

Enviado: 03 Set 2005 09:29
por vagucs
É cara, concordo, mas problema da microsiga...

Eu tenho apenas 1 ponto de entrada no meu sistemas, mas os usuarios nem sabem disto.

É apenas uma váuvula de escape para algumas circunstancias.

Enviado: 03 Set 2005 17:47
por rochinha
Amiguinhos

A unica forma de testar a validade de algo em Clipper é por meio das funções Type() e ValType().

Veja:

VALTYPE()
Determina o tipo de dado de uma expressão
------------------------------------------------------------------------------
Syntaxe

VALTYPE(<exp>) --> cType

Argumentos

<exp> ié uma expressão de qualquer tipo.

Returno

VALTYPE() returna um caracter que representa o resultado da expressão passada:

VALTYPE() Returno
------------------------------------------------------------------------
Returno Resulta
------------------------------------------------------------------------
A Array
B Bloco
C Caracter
D Data
L Logico
M Memo
N Numerico
O Objeto
U NIL
------------------------------------------------------------------------

Exemplos:

? VALTYPE(1) // Resultado: N
? VALTYPE("GOOB") // Resultado: C
? VALTYPE(NIL) // Resultado: U
? VALTYPE(array) // Resultado: A
? VALTYPE(block) // Resultado: B

Esta função faz parte de CLIPPER.LIB.

Presupõe-se que se avaliarmos uma função da forma como voce quer e a mesma for encontrada o retorno será B de bloco de código, ou o tipo de retorno da própria função, ou seja:

? VALTYPE(teste1()) // Resultado: L
? VALTYPE(teste2()) // Resultado: N
? VALTYPE(teste3()) // Resultado: C
? VALTYPE({|| teste() }) // Resultado: B

function teste1()
return .f.
function teste2()
return 0
function teste3()
return ""

Caso a função não exista na linkagem( coisa que o Blinker não permite ) o resultado poderá ser <b>U</b> ou erro de <b>Undefined Function</b>.

Espero que isto de uma força no que voce deseja fazer.

PS: estava digitando esta mensagem ante do Wagner postar as dele, portanto não confundam.

@braços :?)

Enviado: 03 Set 2005 17:57
por Stanis Luksys
Ola,

Muito bom o exemplo dado pelo Vagner.

Compilei, modifiquei e obtive otimos resultados.

Passada toda a polemica, apos e esclarecimento do proprio david, entendi a situacao. Mas do jeito como foi formulada a questao inicial estava dificil hein...

Acho que com este exemplo dado pelo Vagner o amigo ja pode comecar a desenvolver a rotina que precisa...

Quanto as questoes eticas... ah... deixa pra la...

Enviado: 03 Set 2005 18:54
por david.miguel
Obrigado a ajuda de todos. Vou testar a rotina do vagucs e ver se é isso mesmo que necessito. Agora sobre a polemica do ponto de entrada eu acho isso uma boa ideia. Trabalho com Microsiga a mais de 5 anos e eles sao bem utilizados.

:xau