Somar valor de uma formula? Firebird 2.0

Firebird

20/07/2007

Pessoal, tem como criar uma formula nesta SQL?

dm.qRestrFolha.sql.clear;
  dm.qRestrFolha.sql.text:=´ select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, ´+
   ´ case ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then ´+
         ´ A.salario ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar (10))||B.formula ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then ´+
         ´ B.vl_Informado ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar (10))||B.formula ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then ´+
         ´ B.vl_informado ´+
   ´ end as CamposM_N ´+
   ´ from salario_m A left join formulas B on B.id_gerarformula = A.id_sal ´+
   ´ WHERE (B.marcar = ´´True´´)order by 1,6 ´; //--condiçao se nao tiver marcado gera restricao
  dm.qRestrFolha.open;

Bom explicando a SQL
Ela mostra nome funcionario, id_empresa, salario etc...
Bom mais no caso tem a coluna [b:f15d788b1a]CamposM_N[/b:f15d788b1a] que mostra o resultado do case desta SQL
Que nada mais eh do que uma formula de expressao, esta tudo certo cfe. os funcionarios de cada empresa, mostra a formula corretamente + salario * quantia etc e tal... como podem ver acima.

Ou seja fica + ou - assim:
[b:f15d788b1a]CamposM_N[/b:f15d788b1a]
900.00/30
900.00*30/100
900.00*50/100
...
...
*********************************************
Gostaria de saber se tem como calcular esta formula em mais um campo no SQL.

Nao sei se tem como converter estas ´Ta como string´ em resultado de uma formula, e mostrar assim
[b:f15d788b1a]CamposM_N*********Resultado[/b:f15d788b1a]
900.00/30*15.....................450.00
900.00*30/100...................270.00
900.00*50/100...................450.00
...
...
Tenho um modelo feito em piradox com duas tabelas
function ResultFormulas( IdFormula:Integer; ValorCHave:String ; db:TDatabase):Variant;
var
  qry:TQuery;
  sql:String;
begin
  qry := TQuery.Create(Nil);
  qry.DatabaseName := db.DatabaseName;
  qry.SQL.Text := ´Select * from FORMULAS where ID=:ID´;
  qry.ParamByName(´ID´).AsInteger := IdFormula;
  qry.Open;
  if qry.RecordCount = 0 then begin
    Showmessage(´Formula Não Encontrada!´);
    qry.Close;
    qry.Free;
    Result := ´´;
    Exit;
  end;
  sql := ´SELECT (´+qry.FieldByName(´FORMULA´).AsString+´) AS RESULTADO FROM ´+qry.FieldByName(´TABELA´).AsString;
  if ValorChave <> ´´ then
    sql := sql + ´ WHERE ´+qry.FieldByName(´CAMPOCHAVE´).AsString+´=´+ValorChave;
  qry.Close;
  qry.SQL.Text := sql;
  qry.Open;
  Result := qry.FieldByName(´RESULTADO´).Value;
  qry.Close;
  qry.Free;
end;
Mais nao me serve essa funçao apesar que calcula certinho as formulas.

Bom eh isso ai pessoal, se eu conseguir fazer assim vai me poupar um bom trabalho de linhas e linhas de codigo no programa, alem de facilitar depois na manutençao.
Se alguem puder me ajudar!!! Fico grato.
Adriano


Adriano_servitec

Adriano_servitec

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

20/07/2007

acho que você só consegue isso numa stored procedure, usando o comando [i:2d7b1c2df4]execute statement[/i:2d7b1c2df4]


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

acho que você só consegue isso numa stored procedure, usando o comando [i:2fb73a9624]execute statement[/i:2fb73a9624]


Amigo, vc nao teria um exemplo de como se usa o [b:2fb73a9624]comando [i:2fb73a9624]execute statement[/i:2fb73a9624][/b:2fb73a9624]

Grato
Adriano.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Nao tenho nem ideia como fazer esta SP

Nao sei como usar este comando, pra que ele serve, por isso fico cego na SP
CREATE PROCEDURE ESSQLFUNC (
    id_empresa integer,
    b_calculo varchar(80),
    valor numeric(15,2),
    salario numeric(15,2),
    marcar varchar(10),
    quantidade varchar(10),
    vl_informado numeric(15,2),
    id_gerarformula integer,
    id_sal integer)
returns (
    salcontratformulas numeric(15,2),
    salgovformulas numeric(15,2),
    salariofixo numeric(15,2),
    salvlinformado numeric(15,2))
as
declare variable sqles varchar(1050) character set win1252;
begin
   SQLES = ´select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula,
    case
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then
          A.salario
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then
          cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then
          cast(A.salario as varchar (10))||B.formula
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then
          B.vl_Informado
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then
          cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then
          cast(A.salario as varchar (10))||B.formula
      when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then
          B.vl_informado
    end as CamposM_N
    from salario_m A left join formulas B on B.id_gerarformula = A.id_sal
    WHERE (B.marcar = ´´True´´)order by 1,6´;
    for execute statement
    SQLES
    into

    do
    begin
       SELECT COALESCE(SUM(A.Salario),0) FROM salario_m A INTO :SalarioFixo;
      suspend;
end^



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Assim eu obtenho o resultado da SQL
begin
with dm.qRestrFolha do
  begin
    Sql.Text:=´select ´+dm.qRestrFolha.FieldByName(´CamposM_N´).asString+´ from rdb$database´;
    open;
  end;
end;

Mais nao mostra em uma nova coluna do lado do campo [b:b793245525]CamposM_N[/b:b793245525]

E nao estou conseguindo fazer a SP


GOSTEI 0
Cn.sistemas

Cn.sistemas

20/07/2007

coloca as tabelas pra fazer teste e ter um bom intendimento


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

coloca as tabelas pra fazer teste e ter um bom intendimento
Olah amigo, obrigado por responder, bom as tabelas estao certinhas. Pelo menos mostram o resultado que eu quero no grid.

Fiz uma funçao (Nao sei se esta correta, mais compila) :D Se puderem analizar ela tambem!!!
{$R *.dfm}
function ResultFormulas(Id_GerarFormula: Integer):Variant;
var
  sql: String;
begin
   dm.qRestrFolha.sql.clear;
   dm.qRestrFolha.sql.text:=´ select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, ´+
   ´ case ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then ´+
         ´ A.salario ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar (10))||B.formula ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then ´+
         ´ B.vl_Informado ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´  then ´+
         ´ cast(A.salario as varchar (10))||B.formula ´+
     ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´  then ´+
         ´ B.vl_informado ´+
   ´ end as CamposM_N ´+
   ´ from salario_m A left join formulas B on B.id_gerarformula = A.id_sal ´+
   ´ WHERE (A.id_empresa between :pEini and :pEfin) and (A.id_func between :pFini and :pFfin) and (B.marcar = ´´True´´)order by 1,6 ´; //--condiçao se nao tiver marcado gera restricao
   //--passando os parametros dos edits
   dm.qRestrFolha.parambyname(´pEini´).asInteger := EIni;
   dm.qRestrFolha.parambyname(´pEfin´).asInteger := EFin;
   dm.qRestrFolha.parambyname(´pFini´).asInteger := FIni;
   dm.qRestrFolha.parambyname(´pFfin´).asInteger := FFin;
   dm.qRestrFolha.open;
   if dm.qRestrFolha.RecordCount = 0 then begin
      Showmessage(´Formula Não Encontrada!´);
      dm.qRestrFolha.Close;
      dm.qRestrFolha.Free;
      Result := ´´;
      Exit;
   end;
   Sql :=´select (´+dm.qRestrFolha.FieldByName(´CamposM_N´).asString+´)as resultado from rdb$database´;

   dm.qRestrFolha.Close;
   dm.qRestrFolha.SQL.Text := sql;
   dm.qRestrFolha.Open;
   Result := dm.qRestrFolha.FieldByName(´RESULTADO´).Value;
   dm.qRestrFolha.Close;
   dm.qRestrFolha.Free;
end;


E a principio tentei passar o resultado da funçao em um listbox
procedure TFAutoCalc.Button1Click(Sender: TObject); var vresultado : String; begin listbox1.clear; dm.qRestrFolha.DisableControls; dm.qRestrFolha.First; while not dm.qRestrFolha.Eof do begin //passa para o listbox o valor do dbgrid [color=red:b745e59fb9]vResultado := ResultFormulas( dm.qRestrFolha.FieldByName(´ID_GerarFormula´).AsInteger );[/color:b745e59fb9] listbox1.Items.Add(dm.qRestrFolha.FieldByName(´descricao´).AsString+´-´+vResultado); dm.qRestrFolha.Next; end; dm.qRestrFolha.enablecontrols; end;
Mais esta mostrando erro na linha em vermelho, nao na hora de compilar e sim na hora de executar.

Erro:
[b:b745e59fb9]´QRestrFolha: field ´ID_GerarFormula´ not found[/b:b745e59fb9] Bom nao sei eh pq nao coloquei este campo no fields do query pois carrego o Query somente dentro da unit e nao no componente query.

Se eu fazer assim
[b:b745e59fb9]vResultado := ResultFormulas( dm.qRestrFolhaID_GerarFormula.AsInteger );[/b:b745e59fb9]
Nao compila
Erro:
[color=red:b745e59fb9][Error] uAutocalc.pas(803): Undeclared identifier: ´qRestrFolhaID_GerarFormula´[/color:b745e59fb9]

Alguem pode me dizer o que esta acontecendo?
Grato Adriano.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

nos ajude a te ajudar...

não conhecemos o conteúdo das suas tabelas...
dê um exemplo dos registros da tabela FORMULAS.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Nao sei se consegue ver a imagem do grid corretamente, mais esta SQL acima me mostra o resultado desta imagem abaixo neste link

http://adrianoservitec.fotos.uol.com.br/DELPHI


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Pode ser ´caso a funçao esteja correta´ algum erro bobo de conversao de variavel

Pq quando aperto no button para confirmar e passar para um listbox apareçe o erro
[color=red:80fdab2901]´´ is not a valid integer value´[/color:80fdab2901]
E aponta para a linha em vermeho abaixo
procedure TFAutoCalc.Button1Click(Sender: TObject); var [b:80fdab2901]vresultado : Integer;[/b:80fdab2901] begin dm.qRestrFolha.Open; listbox1.clear; dm.qRestrFolha.DisableControls; dm.qRestrFolha.First; while not dm.qRestrFolha.Eof do begin //passa para o listbox o valor do dbgrid [color=red:80fdab2901]vResultado := ResultFormulas(vResult); //variavel global que recebe o resultado da função[/color:80fdab2901] listbox1.Items.Add(dm.qRestrFolha.FieldByName(´descricao´).AsString+´-´+IntToStr(vResultado)); dm.qRestrFolha.Next; end; dm.qRestrFolha.enablecontrols; end;
A variavel eu ja tentei como string, real, currency e integer e o erro eh o mesmo.

a variavel [b:80fdab2901]VResult[/b:80fdab2901] deixei como global que faz parte da funçao, tembem ja deixei como string, real, currency e esta como integer no momento.
A funçao joguei o [b:80fdab2901]Result[/b:80fdab2901] para a variavel [b:80fdab2901]VResult[/b:80fdab2901]
{Funçao de Calculos de Formulas} function TFAutoCalc.ResultFormulas(Id_GerarFormula: Integer):Variant; var sql: String; begin EIni:=StrToInt(e1.text); //-variavel recebendo valor do edit EMPRESAS EFin:=StrToInt(e2.text); //-variavel recebendo valor do edit EMPRESAS FIni:=StrToInt(e3.text); //-variavel recebendo valor do edit FUNCIONARIOS FFin:=StrToInt(e4.text); //-variavel recebendo valor do edit FUNCIONARIOS dm.qRestrFolha.sql.clear; dm.qRestrFolha.sql.text:=´ select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, ´+ ´ case ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then ´+ ´ A.salario ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar (10))||B.formula ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+ ´ B.vl_Informado ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar (10))||B.formula ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+ ´ B.vl_informado ´+ ´ end as CamposM_N ´+ ´ from salario_m A left join formulas B on B.id_gerarformula = A.id_sal ´+ ´ WHERE (A.id_empresa between :pEini and :pEfin) and (A.id_func between :pFini and :pFfin) and (B.marcar = ´´True´´)order by 1,6 ´; //--condiçao se nao tiver marcado gera restricao //--passando os parametros dos edits dm.qRestrFolha.parambyname(´pEini´).asInteger := EIni; dm.qRestrFolha.parambyname(´pEfin´).asInteger := EFin; dm.qRestrFolha.parambyname(´pFini´).asInteger := FIni; dm.qRestrFolha.parambyname(´pFfin´).asInteger := FFin; dm.qRestrFolha.open; if dm.qRestrFolha.RecordCount = 0 then begin Showmessage(´Formula Não Encontrada!´); dm.qRestrFolha.Close; dm.qRestrFolha.Free; Result := ´´; Exit; end; Sql :=´select (´+dm.qRestrFolha.FieldByName(´CamposM_N´).asString+´)as resultado from rdb$database´; dm.qRestrFolha.Close; dm.qRestrFolha.SQL.Text := sql; dm.qRestrFolha.Open; {Result eh o resultado do campo ´CamposM_N´ cfe select acima} [b:80fdab2901]Result := dm.qRestrFolha.FieldByName(´resultado´).Value;[/b:80fdab2901] //--pasando o resultado para uma variavel global [color=blue:80fdab2901]VResult := Result;[/color:80fdab2901] dm.qRestrFolha.Close; dm.qRestrFolha.Free; end; //********************final da funcao de calculo de formulas********


Entao pessoal, pode ser um erro bobo, mais ta me tirando o sono.
Grato a ajuda de todos.
Adriano.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Fuçando daqui, fuçando dali, fazendo alguns testes cheguei a este resultado. Ou seja mudei a função.

1º criei uma Procedure para filtrar a SQL cfe. a condição do where
var FAutoCalc: TFAutoCalc; [b:641a32f57e]{As variaveis globais}[/b:641a32f57e] Eini, Efin, Fini, Ffin : Integer; //variaveis dos edits deixei como global edtDt : TDate; //variavel tipo data VResult : Integer; //variavel da funçao ResultFormulas implementation uses uDM, uRestricaoFolha, UFGerarFolhaMes; {$R *.dfm} [b:641a32f57e]Procedure TFAutoCalc.SQLFormulas;[/b:641a32f57e] // A procedure begin FIni:=StrToInt(e3.text); //-variavel recebendo valor do edit FUNCIONARIOS FFin:=StrToInt(e4.text); //-variavel recebendo valor do edit FUNCIONARIOS dm.qRestrFolha.sql.clear; dm.qRestrFolha.sql.text:=´ select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, ´+ ´ case ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then ´+ ´ A.salario ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar (10))||B.formula ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+ ´ B.vl_Informado ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+ ´ cast(A.salario as varchar (10))||B.formula ´+ ´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+ ´ B.vl_informado ´+ ´ end as CamposM_N ´+ ´ from salario_m A left join formulas B on B.id_gerarformula = A.id_sal ´+ ´ WHERE (A.id_func between :pFini and :pFfin) and (B.marcar = ´´True´´)order by 1,6 ´; //--condiçao se nao tiver marcado gera restricao //--passando os parametros dos edits dm.qRestrFolha.parambyname(´pFini´).asInteger := FIni; dm.qRestrFolha.parambyname(´pFfin´).asInteger := FFin; dm.qRestrFolha.open; if dm.qRestrFolha.RecordCount = 0 then begin Showmessage(´Formula Não Encontrada!´); dm.qRestrFolha.Close; dm.qRestrFolha.Free; Exit; end; end;


Depois chameia procedure dentro da Função
{Funçao de Calculos de Formulas} function TFAutoCalc.ResultFormulas(Id_GerarFormula: Integer):Variant; var sql: String; begin [b:641a32f57e]SQLFormulas; //Procedure que filtra a SQL das tabelas[/b:641a32f57e] {SQL para calcular o resultado da Formula do campo ´CamposM_N´} Sql :=´select (´+dm.qRestrFolha.FieldByName(´CamposM_N´).asString+´)as resultado from rdb$database´; dm.qRestrFolha.Close; dm.qRestrFolha.SQL.Text := sql; dm.qRestrFolha.Open; Result := dm.qRestrFolha.FieldByName(´resultado´).Value; //--pasando o resultado para uma variavel global [b:641a32f57e]VResult := Result;[/b:641a32f57e] Variavel globar resebendo o valor do resultado dm.qRestrFolha.Close; dm.qRestrFolha.Free; end;


E depois como ainda nao sei do jeito de fazer outra coluna para receber a soma do campo aonde estao as formulas tentei passar para um ListBox, somente pra ver o resultado.

procedure TFAutoCalc.Button1Click(Sender: TObject); var vresultado : String; begin SQLFormulas; // Procedure da SQL Formulas listbox1.clear; dm.qRestrFolha.DisableControls; dm.qRestrFolha.First; while not dm.qRestrFolha.Eof do begin //passa para o listbox o valor do dbgrid listbox1.Items.Add(dm.qRestrFolha.FieldByName(´camposM_N´).AsString); vResultado := ResultFormulas(vResult); //variavel global que recebe o resultado da função Listbox1.Items.Add(vResultado); //passando o calculo da formula no listbox na segunda linha dm.qRestrFolha.Next; end; dm.qRestrFolha.enablecontrols; end;


Bom entao fiu para o resultado.
Primeiro eu filtro por codigo de funcionarios, e esta filtrando como eu quero e depois aperto neste button para jogar para o listbox apareçe aquela mensagem [b:641a32f57e]Access violation adress[/b:641a32f57e], e soh joga o primeiro resultado filtrado, que no caso fica somente assim no listbox

500.00/30*2.0000
33,32 //aqui cheou a calcular e jogar o resultado, mais depois disso nao joga mais nada do filtro e o dbgrid fica fechado.

Pareçe que nao esta aceitando o loop na tabela e jogar o resultado da formula.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Consegui passar no listbox usando esta funçao aqui

{$R *.dfm}
function Calcular(SMyExpression: string; digits: Byte): string;
  // Funçao para calcular uma simples operação matematica
var
  z: Char;
  ipos: Integer;

  function StrToReal(chaine: string): Real;
  var
    r: Real;
    Pos: Integer;
  begin
    Val(chaine, r, Pos);
    if Pos > 0 then Val(Copy(chaine, 1, Pos - 1), r, Pos);
    Result := r;
  end;

  function RealToStr(inreal: Extended; digits: Byte): string;
  var
    S: string;
  begin
    Str(inreal: 0: digits, S);
    realToStr := S;
  end;

  procedure NextChar;
  var
    s: string;
  begin
    if ipos > Length(SMyExpression) then
    begin
      z := #9;
      Exit;
    end
    else
    begin
      s := Copy(SMyExpression, ipos, 1);
      z := s[1];
      Inc(ipos);
    end;
    if z = ´ ´ then nextchar;
  end;

  function Expression: Real;
  var
    w: Real;

    function Factor: Real;
    var
      ws: string;
    begin
      Nextchar;
      if z in [´0´..´9´] then
      begin
        ws := ´´;
        repeat
          ws := ws + z;
          nextchar
        until not (z in [´0´..´9´, ´.´]);
        Factor := StrToReal(ws);
      end
      else if z = ´(´ then
      begin
        Factor := Expression;
        nextchar
      end
      else if z = ´+´ then Factor := +Factor
      else if Z = ´-´ then Factor := -Factor;
    end;

    function Term: Real;
    var
      W: Real;
    begin
      W := Factor;
      while Z in [´*´, ´/´] do
        if z = ´*´ then w := w * Factor
      else
        w := w / Factor;
      Term := w;
    end;
  begin
    w := term;
    while z in [´+´, ´-´] do
      if z = ´+´ then w := w + term
    else
      w := w - term;
    Expression := w;
  end;
begin
  ipos   := 1;
  Result := RealToStr(Expression, digits);
end;

Procedure TFAutoCalc.SQLFormulas; // A procedure
begin
FIni:=StrToInt(e3.text); //-variavel recebendo valor do edit FUNCIONARIOS
FFin:=StrToInt(e4.text); //-variavel recebendo valor do edit FUNCIONARIOS
dm.qRestrFolha.sql.clear;
dm.qRestrFolha.sql.text:=´ select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, ´+
´ case ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Fixo´´ and B.valor = ´´False´´ Then ´+
´ A.salario ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+
´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+
´ cast(A.salario as varchar (10))||B.formula ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Contratado´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+
´ B.vl_Informado ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´True´´ and B.valor = ´´False´´ then ´+
´ cast(A.salario as varchar(10))||B.formula||´´*´´||B.quantia ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´False´´ then ´+
´ cast(A.salario as varchar (10))||B.formula ´+
´ when B.marcar = ´´True´´ and B.B_Calculo = ´´Salario_Governo´´ and B.quantidade = ´´False´´ and B.valor = ´´True´´ then ´+
´ B.vl_informado ´+
´ end as CamposM_N ´+
´ from salario_m A left join formulas B on B.id_gerarformula = A.id_sal ´+
´ WHERE (A.id_func between :pFini and :pFfin) and (B.marcar = ´´True´´)order by 1,6 ´; //--condiçao se nao tiver marcado gera restricao
//--passando os parametros dos edits
dm.qRestrFolha.parambyname(´pFini´).asInteger := FIni;
dm.qRestrFolha.parambyname(´pFfin´).asInteger := FFin;
dm.qRestrFolha.open;
if dm.qRestrFolha.RecordCount = 0 then begin
Showmessage(´Formula Não Encontrada!´);
dm.qRestrFolha.Close;
dm.qRestrFolha.Free;
Exit;
end;
end;


E chamando no ListBox assim
procedure TFAutoCalc.Button1Click(Sender: TObject);
var
vresultado : String;
begin
SQLFormulas; // Procedure da SQL Formulas
listbox1.clear;
dm.qRestrFolha.DisableControls;
dm.qRestrFolha.First;
while not dm.qRestrFolha.Eof do
begin
//passa para o listbox o valor do dbgrid
vResultado := dm.qRestrFolha.FieldByName(´camposM_N´).AsString; //pegando o resultado da formula
vResultado := Calcular(VResultado, 2); //variavel global que recebe o resultado da função
Listbox1.Items.Add(dm.qRestrFolha.FieldByName(´camposM_N´).AsString+´  -  ´+vResultado); //passando o calculo da formula no listbox na segunda linha
dm.qRestrFolha.Next;
end;
dm.qRestrFolha.enablecontrols;

end;


Agora funcionou no ListBox, mais infelismente nao consegui abrir uma nova coluna e passar o resultado no DBGrid.

Mais ja ta bom assim.

Valeu pela ajuda pessoal
Adriano.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

a melhor opção realmente é stored procedures.
mas para dar uma solução mais próxima da sua necessidade, eu gostaria que você publicasse alguns registros da sua tabela FORMULAS.

mais uma vez: alguns registros da sua tabela FORMULAS. não o resultado dessa sua instrução. preciso conhecer o conteúdo e o tipo dos campos da tabela FORMULAS para poder fazer um stored procedure que lhe seja satisfatória.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

a melhor opção realmente é stored procedures. mas para dar uma solução mais próxima da sua necessidade, eu gostaria que você publicasse alguns registros da sua tabela FORMULAS. mais uma vez: alguns registros da sua tabela FORMULAS. não o resultado dessa sua instrução. preciso conhecer o conteúdo e o tipo dos campos da tabela FORMULAS para poder fazer um stored procedure que lhe seja satisfatória.


A DLL eh esta
[code]CREATE TABLE FORMULAS (
ID_SEQ INTEGER NOT NULL,
ID_FORMULA INTEGER NOT NULL,
ID_GERARFORMULA INTEGER NOT NULL,
DESCRICAO VARCHAR(60),
FORMULA VARCHAR(80),
P_D CHAR(1),
MARCAR VARCHAR(10),
QUANTIDADE CHAR(10),
VALOR CHAR(10),
QUANTIA FLOAT,
B_CALCULO VARCHAR(60),
VL_INFORMADO NUMERIC(15,2),
INSS CHAR(10),
IRRF CHAR(10),
FGTS CHAR(10),
SFAMILIA CHAR(10),
DINSS CHAR(10),
DIRRF CHAR(10),
DFGTS CHAR(10),
DSFAMILIA CHAR(10),
REPETE VARCHAR(10)
);

[code]


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

acho que esta stored procedure funciona para o que você precisa. note que eu não coloquei nenhum parâmetro de entrada, pois não sei qual a sua real necessidade (talvez você faça o cálculo por funcionário e seja necessário um parâmetro de entrada).
CREATE PROCEDURE ESSQLFUNC 
returns (
    id_empresa integer,
    salario numeric(15,2),
    id_sal integer,
    id_formula integer,
    descricao varchar(100),
    id_func integer,
    nome varchar(50),
    id_gerarformula integer,
    calculo varchar(100),
    resultado numeric(15,2))
as
declare variable b_calculo varchar(50);
declare variable valor varchar(50);
declare variable quantidade varchar(50);
declare variable formula varchar(50);
declare variable quantia varchar(50);
declare variable vl_informado varchar(50);
begin
    for  
        select
            A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao,
            A.id_func, A.nome, B.id_gerarformula, b.b_calculo, b.valor,
            b.quantidade, b.formula, b.quantia, b.vl_informado
        from
            salario_m A
        left join
            formulas B on B.id_gerarformula = A.id_sal
        where
            (B.marcar = ´True´)
        order by
            a.id_empresa, a.id_func
    into :id_empresa, :salario, :id_sal, :id_formula, :descricao,
         :id_func, :nome, :id_gerarformula, :b_calculo, :valor,
         :quantidade, :formula, :quantia, :vl_informado
    do
    begin
        if (b_calculo = ´Fixo´) then
            calculo = salario;
        else
        begin
            if (quantidade = ´True´) then
               calculo = cast(salario as varchar(10)) || formula || ´*´ || quantia;
            else
            begin
                if (valor = ´True´) then
                    calculo = vl_informado;
                else
                    calculo = cast(salario as varchar (10)) || formula;
            end
        end

        --- *** Aqui será executada a fórmula ***
        execute statement ´select ´ || calculo || ´ from rdb$database´ into resultado;

        suspend;
    end
end



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Emerson, testei aqui e ficou do jeito que eu postei, mais tem como fazer esta SP usando a soma em vez da coluna RESULTADO assim Proventos ----- Descontos e somar cfe. o campo P_D da tabela formula?


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

deve ser isso:
CREATE PROCEDURE ESSQLFUNC
returns (
    id_empresa integer,
    salario numeric(15,2),
    id_sal integer,
    id_formula integer,
    descricao varchar(100),
    id_func integer,
    nome varchar(50),
    id_gerarformula integer,
    calculo varchar(100),
    proventos numeric(15,2),
    descontos numeric(15,2))
as
declare variable b_calculo varchar(50);
declare variable valor varchar(50);
declare variable quantidade varchar(50);
declare variable formula varchar(50);
declare variable quantia varchar(50);
declare variable vl_informado varchar(50);
declare variable prov_desc char(1);
begin
    for  
        select
            A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao,
            A.id_func, A.nome, B.id_gerarformula, b.b_calculo, b.valor,
            b.quantidade, b.formula, b.quantia, b.vl_informado, b.p_d
        from
            salario_m A
        left join
            formulas B on B.id_gerarformula = A.id_sal
        where
            (B.marcar = ´True´)
        order by
            a.id_empresa, a.id_func
    into :id_empresa, :salario, :id_sal, :id_formula, :descricao,
         :id_func, :nome, :id_gerarformula, :b_calculo, :valor,
         :quantidade, :formula, :quantia, :vl_informado, :prov_desc
    do
    begin
        if (b_calculo = ´Fixo´) then
            calculo = salario;
        else
        begin
            if (quantidade = ´True´) then
               calculo = cast(salario as varchar(10)) || formula || ´*´ || quantia;
            else
            begin
                if (valor = ´True´) then
                    calculo = vl_informado;
                else
                    calculo = cast(salario as varchar (10)) || formula;
            end
        end

        proventos = 0;
        descontos = 0;

        --- Aqui será executada a fórmula
        if (prov_desc = ´P´) then
           execute statement ´select ´ || calculo || ´ from rdb$database´ into proventos;
        else
           execute statement ´select ´ || calculo || ´ from rdb$database´ into descontos;

        suspend;
    end
end



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Obrigado amigo.

Testado e aprovado. :D

Ficou show a SP

Valeu pela ajuda ai.

Grato
Adriano


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Abusando mais um pouco amigo

Mais se eu quiser uma coluna com o total dos proventos e total dos descontos de cada funcionarios terei que fazer um IF assim if (TotFunc <> 0) and (prov_desc = ´P´) then? --aqui vai ser executado a formula.

coloquei mais esta variaveis, soh nao sei se tem como fazer
CREATE PROCEDURE ESSQLFUNC2 returns ( id_empresa integer, salario numeric(15,2), id_sal integer, id_formula integer, descricao varchar(100), id_func integer, nome varchar(50), id_gerarformula integer, calculo varchar(100), proventos numeric(15,2), descontos numeric(15,2), [b:acdf8e3d8f]totproventos_f numeric(15,2), totdescontos_f numeric(15,2))[/b:acdf8e3d8f] as declare variable b_calculo varchar(50); declare variable valor varchar(50); declare variable quantidade varchar(50); declare variable formula varchar(50); declare variable quantia varchar(50); declare variable vl_informado varchar(50); declare variable prov_desc char(1); [b:acdf8e3d8f]declare variable totfunc integer;--aqui eu nao sei se esta certo[/b:acdf8e3d8f] begin for select A.id_empresa, A.salario, A.id_sal, B.id_formula, B.descricao, A.id_func, A.nome, B.id_gerarformula, b.b_calculo, b.valor, b.quantidade, b.formula, b.quantia, b.vl_informado, b.p_d from salario_m A left join formulas B on B.id_gerarformula = A.id_sal where (B.marcar = ´True´) order by a.id_empresa, a.id_func into :id_empresa, :salario, :id_sal, :id_formula, :descricao, :id_func, :nome, :id_gerarformula, :b_calculo, :valor, :quantidade, :formula, :quantia, :vl_informado, :prov_desc do begin if (b_calculo = ´Fixo´) then calculo = salario; else begin if (quantidade = ´True´) then calculo = cast(salario as varchar(10)) || formula || ´*´ || quantia; else begin if (valor = ´True´) then calculo = vl_informado; else calculo = cast(salario as varchar (10)) || formula; end end proventos = 0; descontos = 0; --- Aqui será executada a fórmula [b:acdf8e3d8f]if (totfunc = ???) and (prov_desc = ´P´) then--esse pornto de interrogação eh pq. nao sei como comparar por cada ID de funcionario[/b:acdf8e3d8f] execute statement ´select ´ || calculo || ´ from rdb$database´ into proventos; else execute statement ´select ´ || calculo || ´ from rdb$database´ into descontos; suspend; end end^


Grato pela ajuda amigo
Adriano.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Emerson, aqui em casa funcionou certinho a select que vc me passou
select c1.*,(select sum(c2.proventos - c2.descontos) 
from essqlfunc c2 
where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func)saldo 
from essqlfunc c1


Mais teria como passar 3 colunas, tipo assim:

select c1.*,(select sum(c2.proventos)TotProv, sum(c2.descontos)TotDesc, sum(c2.proventos - c2.descontos)as Total 
from essqlfunc c2 
where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func) 
from essqlfunc c1

=============================================

[b:8810513bc1]Sobre a Stored Procedure[/b:8810513bc1]

E tambem percebi uma diferença no calculo dentro da SP

me pareçe que esta arredondando pra baixo o valor

se eu puxar este valor
500.00/220*150/100*35.000000 o resultado tem que ficar assim 119,32

e no calculo da SP esta arredondando pra baixo
500.00/220*150/100*35.000000 o resultado ta ficando assim 119,00

Outro que eu percebi a diferença
500.00/30*2.000000 preciso que fique assim 33.33

e na SP esta calculando assim
500.00/30*2.000000 = 33.32

Sao centavos de diferença, mais que nao bate com os valores individuais, por isso preciso se possivel que fique o valor maior.

Outra coisa que percebi tambem foi que nao calcula certo se a formula estiver assim
500.00/220*(150/100)*35.000000 (desta forma da uma diferença grande pra baixo)

tem que ser sem parenteses
500.00/220*150/100*35.000000
Mais isso nao eh problema, posso fazer uma funçao para nao aceitar parenteses.

Bom amigo eh isso ai.

Grato pela ajuda
Adriano.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

para obter 3 colunas você deve ter 3 sub-selects.

quanto às diferenças notadas nos cálculos, coloque todos os valores com decimais (como exemplo eu coloquei 3 casas):

troque
500.00/220*150/100*35.000000 o resultado tem que ficar assim 119,32
por
500.00/220[b:f76336108e].000[/b:f76336108e]*150[b:f76336108e].000[/b:f76336108e]/100[b:f76336108e].000[/b:f76336108e]*35.000000

troque
500.00/30*2.000000
por
500.00/30[b:f76336108e].000[/b:f76336108e]*2.000000

quanto você divide 500.00/30, o resultado é 16.66[b:f76336108e]*[/b:f76336108e], que multiplicado por 2.000000 dá 33.32;
com a alteração - 500.00/30.000 - o resultado será 16.66666, que multiplicado por 2.000000 será 33,33332

[b:f76336108e]*[/b:f76336108e]resulta em duas casas decimais porque a soma de dígitos decimais é 2: dois dígitos no dividendo + nenhum no divisor


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Valeu amigo, vou modificar aqui, mais este subselect eu nao sei como fazer

select c1.*,
(select sum(c2.proventos)
from essqlfunc c2
where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func)TotoProv

(select sum(c2.descontos)
from essqlfunc c2
where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func)TotDesc

(select sum(c2.proventos - c2.descontos)
from essqlfunc c2
where c4.id_empresa = c1.id_empresa and c4.id_func = c1.id_func)Saldo

from essqlfunc c1

Achei que fosse mais facil :D


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

é assim mesmo. deve ter dado algum erro porque você está tentando utilizar um alias (c4) que nem foi criado. sem contar que estava faltando a vírgula entre os campos.

utilize somente c2 e coloque as devidas vírgulas.

select c1.*,
  (select sum(c2.proventos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotoProv,

  (select sum(c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotDesc,

  (select sum(c2.proventos - c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) Saldo
 from essqlfunc c1



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Agora sim,

Valeu amigo.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Emerson, tomei a liberdade de modificar a SP pois precisava fazer calculos por base de salario do governo tambem, e ficou assim
(Nao sei se esta correto, mais esta funcionando)
CREATE PROCEDURE ESSQLFUNC 
returns (
    id_empresa integer,
    salario numeric(16,2),
    salgoverno numeric(15,2),
    id_sal integer,
    id_formula integer,
    descricao varchar(100),
    id_func integer,
    nome varchar(50),
    id_gerarformula integer,
    inss varchar(10),
    calculo varchar(100),
    proventos numeric(15,2),
    descontos numeric(15,2))
as
declare variable b_calculo varchar(50);
declare variable valor varchar(50);
declare variable quantidade varchar(50);
declare variable formula varchar(50);
declare variable quantia varchar(50);
declare variable vl_informado varchar(50);
declare variable prov_desc char(1);
--Essa Stored Procedure soh funciona se na tabela Formulas o campo marcar
--estiver como True - caso contrario retorna os valores em branco ou null
begin 
    for  
        select 
            A.id_empresa, A.salario, A.salgoverno, A.id_sal, B.id_formula, B.descricao,
            A.id_func, A.nome, B.id_gerarformula, b.b_calculo, b.valor, 
            b.quantidade, b.formula, b.quantia, b.vl_informado, b.inss, b.p_d
        from 
            salario_m A 
        left join 
            formulas B on B.id_gerarformula = A.id_sal 
        where 
            (B.marcar = ´True´) 
        order by 
            a.id_empresa, a.id_func, b.p_d desc
    into :id_empresa, :salario, :salgoverno, :id_sal, :id_formula, :descricao,
         :id_func, :nome, :id_gerarformula, :b_calculo, :valor, 
         :quantidade, :formula, :quantia, :vl_informado, :inss, :prov_desc
    do 
    begin 
        --Passando as condiçoes se for Salario Contratado
        if ((b_calculo = ´Fixo´)) then
            calculo = salario; 
        else 
        begin 

        if ((B_Calculo = ´Salario_Contratado´) and (quantidade = ´True´)) then
           calculo = cast(salario as varchar(10)) || formula || ´*´ || quantia;
        else
        begin

        if ((B_Calculo = ´Salario_Contratado´) and (valor = ´False´)) then
           calculo = cast(salario as varchar (10)) || formula;
        else
        begin
        if ((B_Calculo = ´Salario_Contratado´) and (valor = ´True´)) then
           calculo = vl_informado;
        else
        begin
        ---passando as condiçoes se for salario do governo

        if ((B_Calculo = ´Salario_Governo´) and (quantidade = ´True´)) then
           calculo = cast(salgoverno as varchar(10)) || formula || ´*´ || quantia;
        else
        begin

        if ((B_Calculo = ´Salario_Governo´) and (quantidade = ´False´))  then
           calculo = cast(salgoverno as varchar (10))||formula;
        else
        begin

        if ((B_Calculo = ´Salario_Governo´) and (valor = ´False´)) then
           calculo = cast(salgoverno as varchar (10)) || formula;
        else
        begin
        if ((B_Calculo = ´Salario_Governo´) and (valor = ´True´)) then
           calculo = vl_informado;

        end
        end
        end
        end
        end
        end

      end

      proventos = 0;
      descontos = 0;
      --- Aqui será executada a fórmula
      if (prov_desc = ´P´) then
         execute statement ´select ´ || calculo || ´ from rdb$database´ into proventos;
      else
         execute statement ´select ´ || calculo || ´ from rdb$database´ into descontos;

      suspend;
   end
end


Bom mais o problema eh este amigo:

Ja estou fazendo o calculo do INSS dentro da select
Entao baseado na select inicial, fiz um modelo de select assim
select c1.*, 
  (select sum(c2.proventos) 
   from essqlfunc c2 
   where c2.id_empresa = c1.id_empresa 
      and c2.id_func = c1.id_func and c2.inss = ´True´) TotoProv,

  (select sum(c2.descontos) 
   from essqlfunc c2 
   where c2.id_empresa = c1.id_empresa 
      and c2.id_func = c1.id_func) TotDesc,

  (select sum(c2.proventos - c2.descontos) 
   from essqlfunc c2 
   where c2.id_empresa = c1.id_empresa 
      and c2.id_func = c1.id_func) Saldo,

  --compara com o indice da tabela do inss 7.65¬ 8.65¬ 9.0¬ e 11.0¬
  case
     when ((select sum(c2.proventos) 
            from essqlfunc c2
     where c2.id_empresa = c1.id_empresa
     and c2.id_func = c1.id_func and c2.inss = ´True´) <= 868.29) Then
          (select sum(c2.proventos * 7.65/100.000000)
          from essqlfunc c2
          where c2.id_empresa = c1.id_empresa
          and c2.id_func = c1.id_func and c2.inss = ´True´)
     when ((select sum(c2.proventos) 
           from essqlfunc c2
     where c2.id_empresa = c1.id_empresa
     and c2.id_func = c1.id_func and c2.inss = ´True´) >= 868.30)  then
          (select sum(c2.proventos * 8.65/100.000000)
          from essqlfunc c2
          where c2.id_empresa = c1.id_empresa
          and c2.id_func = c1.id_func and c2.inss = ´True´)
  end as TotINSS

 from essqlfunc c1
Observe que esta calculando o inss caso o valor for = ou < que 868.29 aplica um indice de 7.65, caso for maior que este valor aplica um indice maior. Bom funciona, mais nao eh assim que eu preciso, o que eu preciso eh comparar esta select com uma tabela que ja tem gravado certinho os valores e indices do inss para depois jogar o resultado do calculo.

[color=green:04cfb3dbe3]Lembrando que a tabela do INSS tem mais do que este dois indices, pra ser exato sao 4 indices de calculos diferentes, fis somente estes dois para efeito de testes[/color:04cfb3dbe3]

Se puder me ajudar mai uma vez...

Tai minhas duvidas amigo.

No mais muito obrigado pela força e ajuda ai.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

que monte de [i:cf4456a9e8]end[/i:cf4456a9e8]´s eram aqueles?!?!?!? simplifique sempre que puder, para melhorar a performance na execução e também a legibilidade do código. e por falar em legibilidade, faça também a identação correta, assim você [b:cf4456a9e8]se ajuda[/b:cf4456a9e8] e [b:cf4456a9e8]nos ajuda[/b:cf4456a9e8] também.
create procedure ESSQLFUNC
returns (
    id_empresa integer,
    salario numeric(16,2),
    salgoverno numeric(15,2),
    id_sal integer,
    id_formula integer,
    descricao varchar(100),
    id_func integer,
    nome varchar(50),
    id_gerarformula integer,
    inss varchar(10),
    calculo varchar(100),
    proventos numeric(15,2),
    descontos numeric(15,2))
as
declare variable b_calculo varchar(50);
declare variable valor varchar(50);
declare variable quantidade varchar(50);
declare variable formula varchar(50);
declare variable quantia varchar(50);
declare variable vl_informado varchar(50);
declare variable prov_desc char(1);
declare salario_calc numeric(15,2);
-- Esta Stored Procedure só funciona se na tabela Formulas o campo marcar
-- estiver como True, caso contrario retorna os valores em branco ou null
begin
    for
        select
            a.id_empresa, a.salario, a.salgoverno, a.id_sal, b.id_formula, B.descricao,
            a.id_func, a.nome, b.id_gerarformula, b.b_calculo, b.valor,
            b.quantidade, b.formula, b.quantia, b.vl_informado, b.inss, b.p_d
        from
            salario_m a
        left join
            formulas b on b.id_gerarformula = a.id_sal
        where
            (b.marcar = ´True´)
        order by
            a.id_empresa, a.id_func, b.p_d desc
    into :id_empresa, :salario, :salgoverno, :id_sal, :id_formula, :descricao,
         :id_func, :nome, :id_gerarformula, :b_calculo, :valor,
         :quantidade, :formula, :quantia, :vl_informado, :inss, :prov_desc
    do
    begin
        -- passando as condiçoes de cálculo
        if (b_calculo = ´Fixo´) then
            calculo = salario;
        else
        begin
            -- verificando QUAL salário será manipulado
            if (b_calculo = ´Salario_Contratado´) then
               salario_calc = salario;
            else
               salario_calc = salgoverno;

            -- montando a fórmula
            if (quantidade = ´True´) then
                calculo = cast(salario_calc as varchar(10)) || formula || ´*´ || quantia;
            else
            if (quantidade = ´False´) then
                calculo = cast(salario_calc as varchar (10)) || formula;
            else
            if (valor = ´False´) then
                calculo = cast(salario_calc as varchar (10)) || formula;
            else
            if (valor = ´True´) then
                calculo = vl_informado;
        end

        proventos = 0;
        descontos = 0;

        -- executando a fórmula
        if (prov_desc = ´P´) then
           execute statement ´select ´ || calculo || ´ from rdb$database´ into proventos;
        else
           execute statement ´select ´ || calculo || ´ from rdb$database´ into descontos;

        suspend;
    end
end

quanto ao INSS, a instrução abaixo traz alíquota e valor corretos, porém eu recomendo fazer o cálculo do valor num terceiro passo, e não diretamente na instrução.
select c1.*,
  (select sum(c2.proventos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotoProv,

  (select sum(c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotDesc,

  (select sum(c2.proventos - c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) Saldo,

  -- compara o valor dos proventos (?) com a faixa de inss
  -- e traz a alíquota correta - 7.65¬, 8.65¬, 9.0¬ ou 11.0¬
  (select first 1 taxa from tabela_inss inss where inss.valor >=
     (select sum(c2.proventos)
      from essqlfunc c2
      where c2.id_empresa = c1.id_empresa
        and c2.id_func = c1.id_func)
   order by inss.valor) Aliquota_INSS,

  -- calcula o valor do inss, em função do valor dos proventos (?)
  -- (para melhorar a performance essa parte poderia ser calculada
  -- no aplicativo, e não na instrução)
  (select sum(c2.proventos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
     and c2.id_func = c1.id_func) *
  (select first 1 taxa from tabela_inss inss where inss.valor >=
     (select sum(c2.proventos)
      from essqlfunc c2
      where c2.id_empresa = c1.id_empresa
        and c2.id_func = c1.id_func)
   order by inss.valor) / 100.00 Valor_INSS
from
  essqlfunc c1

note que para melhorar e performance tanto da instrução quanto da stored procedure, devem ser criados índices nas tabelas envolvidas, em função dos campos utilizados nos relacionamentos e ordenações.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Otimo Emerson, esta pegando o indice do INSS corretamente agora, mais tem + um probleminha amigo, tentei de varias formas mais nao consegui.

Por exemplo tenho alguns campos que nao devem calcular INSS como Faltas por exemplo, tenho varios tipos de faltas, como faltas dias - faltas horas, etc...Por isso tenho na tabela formula um campo chamado INSS que eh tipo booleano e se este campo estiver como False, nao deve calcular o INSS

Entao nao da para calcular o provento e descontar o inss, se tiver faltas, preciso descontar estas faltas antes de criar o indice do inss

tipo vamos supor que esteja assim

Vou fazer de outra forma, mais o processo eh o mesmo da grid
O correto seria
salario P
500.00
faltas D
33.33
INSS D
35.70

e esta calculando somente o proventos

salario P
500.00
faltas D
33.33
INSS D
38.25

Tentei fazer um case no select mais nao funciona.

Acho que so falta este detalhe para mostrar corretamente.

Obrigado pela ajuda amigo.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

veja se funciona com as alterações assinaladas:
select c1.*,
  (select sum(c2.proventos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotoProv,

  (select sum(c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) TotDesc,

  (select sum(c2.proventos - c2.descontos)
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
      and c2.id_func = c1.id_func) Saldo,

  -- compara o valor dos proventos (?) com a faixa de inss
  -- e traz a alíquota correta - 7.65¬, 8.65¬, 9.0¬ ou 11.0¬
  (select first 1 taxa from tabela_inss inss where inss.valor >=
     (select sum(c2.proventos - c2.descontos) -- alterei aqui
      from essqlfunc c2
      where c2.id_empresa = c1.id_empresa
        and c2.id_func = c1.id_func
        and c2.inss = ´True´) -- e adicionei esta condição
   order by inss.valor) Aliquota_INSS,

  -- calcula o valor do inss, em função do valor dos proventos (?)
  -- (para melhorar a performance essa parte poderia ser calculada
  -- no aplicativo, e não na instrução)
  (select sum(c2.proventos - c2.descontos) -- alterei aqui
   from essqlfunc c2
   where c2.id_empresa = c1.id_empresa
     and c2.id_func = c1.id_func
     and c2.inss = ´True´) * -- adicionei esta condição
  (select first 1 taxa from tabela_inss inss where inss.valor >=
     (select sum(c2.proventos - c2.descontos) -- alterei aqui
      from essqlfunc c2
      where c2.id_empresa = c1.id_empresa
        and c2.id_func = c1.id_func
        and c2.inss = ´True´) -- adicionei esta condição
   order by inss.valor) / 100.00 Valor_INSS
from
  essqlfunc c1



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Eu ja tinha tentado assim como vc postou, mais nao funcionou, e continua nao funcionando.

Estranho que o campo INSS aonde esta as faltas esta como False.

Outra duvida amigo

devo criar indices de todos os campos das tabelas?

Esta uma carroça, como vc me disse, mais se melhroar mais um pouco a performance ta de bom tamanho.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Emerson, me pareçe que assim funciona
select c1.*, (select sum(c2.proventos) from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func) TotoProv, (select sum(c2.descontos) from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func) TotDesc, (select sum(c2.proventos - c2.descontos) from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func) Saldo, -- compara o valor dos proventos (?) com a faixa de inss -- e traz a alíquota correta - 7.65¬, 8.65¬, 9.0¬ ou 11.0¬ (select first 1 indice from indiceinss inss where inss.ate >= (select sum(c2.proventos - c2.descontos) -- alterei aqui from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func and [color=blue:cf2f7f97be]c1.inss = ´True´[/color:cf2f7f97be]) -- no lugar do c2 mudei para c1 order by inss.ate) Aliquota_INSS, -- calcula o valor do inss, em função do valor dos proventos (?) -- (para melhorar a performance essa parte poderia ser calculada -- no aplicativo, e não na instrução) (select sum(c2.proventos - c2.descontos) -- alterei aqui from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func and c1.inss = ´True´) * -- adicionei esta condição (select first 1 indice from indiceinss inss where inss.ate >= (select sum(c2.proventos - c2.descontos) -- alterei aqui from essqlfunc c2 where c2.id_empresa = c1.id_empresa and c2.id_func = c1.id_func and [color=blue:cf2f7f97be]c1.inss = ´True´[/color:cf2f7f97be]) -- no lugar de c2 mudei para c1 order by inss.ate) / 100.00 Valor_INSS from essqlfunc c1


Bom ainda estou em testes, pode ser que haja mais problemas.

Ja criei indices de todos os campos envolvidos na tabela, mais ainda fica meio lento, estou verificando isso tambem.

No mais
Obrigado amigo pela força ai.
Adriano.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Tem como fazer um update deste select na grid?

Coloquei mais um campo chamado MARCAR no dbgrid aonde esta como checkbox.

Gostaria de saber como fazer um update para tipo se eu quiser eliminar um item do dbgrid fazer um update corrigindo com o saldo novo.

Tentei assim
procedure TFSuperCalculo.DBGradeFuncCellClick(Column: TColumn);
begin
//é a unica coluna que deve ser marcada e desmarcada (Se tiver mais coluna tem que mostrar aqui)
if Column.FieldName = ´MARCAR´ then
  begin
    DM.zspSomaFunc.Edit;
    if dm.zspSomaFunc.FindField(´MARCAR´).AsString = ´True´ then
       dm.zspSomaFunc.FindField(´MARCAR´).AsString := ´False´
    else
      DM.zspSomaFunc.FindField(´MARCAR´).AsString := ´True´;
      DM.zspSomaFunc.Post;
      DBGradeFunc.Refresh;
  end;
end;

Mais nao esta funcionando, mostra o seguinte erro.

´Cannot update this query type´

Ps:Sobre o resto me pareçe estar certinho agora.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

O update desta tabela seria algo tipo assim?
CREATE PROCEDURE ALTSQLFUNC (
    id_empresa integer,
    id_sal integer,
    id_func integer,
    nome varchar(50),
    id_formula integer,
    descricao varchar(100),
    id_gerarformula integer,
    marcar varchar(10))
as
begin 
  if (exists(
      select a.id_empresa, a.id_sal, a.id_func,
             a.nome, b.id_formula, b.descricao,
             b.id_gerarformula, b.marcar
      from
             salario_m a
      left join
             formulas b on b.id_gerarformula = a.id_sal
      where (id_empresa = :id_empresa and id_sal = :id_sal
             and id_func = :id_func and nome = :nome and
             id_formula = :id_formula and descricao = :descricao
             and id_gerarformula = :id_gerarformula and marcar = :marcar))) then
    --modalidade update da stored procedure conforme o select acima
     update formulas
     set    marcar = :marcar,
            descricao = :descricao,
            id_formula = :id_formula,
            id_gerarformula = :id_gerarformula
     where (id_formula = :id_formula and id_gerarformula = :id_gerarformula);
end



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Ja resolvi o problema.

Valeu


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

O problema agora esta sendo em buscar os nomes dos funcionarios na dbgrid atravez de um select

Fiz assim normal
if trim(edit2.Text)<>´´ then
  begin
    dm.zspSomaFunc.Close;
    dm.zspSomaFunc.SQL.Clear;
    dm.zspSomaFunc.SQL.Add(´select * from essqlfunc where upper(NOME)like :Busca´);
    dm.zspSomaFunc.ParamByName(´Busca´).AsString:=AnsiUpperCase(trim(edit2.Text))+´¬´;
    dm.zspSomaFunc.Open;
  end;

Mais acusa erro de fields no campo [b:b78d7a21d3]Proventos[/b:b78d7a21d3]

Mais esse campo esta inclusive no fields editor do query, esse e todos os campos estao la.

serah que essa select nao pode fazer uma busca?

{Procedure para mostrar o select da tabela na grid}
Procedure TFSuperCalculo.ChamaSP;
begin
dm.zspSomaFunc.Close;
dm.zspSomaFunc.sql.Clear;
dm.zspSomaFunc.sql.Text:=´ select c1.*, ´
  +´ (select sum(c2.proventos) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func) TotoProv, ´
  +´ (select sum(c2.descontos) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func) TotDesc, ´
  +´ (select sum(c2.proventos - c2.descontos) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func) Saldo, ´
  +´ (select first 1 indice from indiceinss inss where inss.ate >= ´
  +´ (select sum(c2.proventos - c2.descontos) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func and c1.Inss = ´´True´´) ´
  +´ order by inss.ate) Aliquota_INSS, ´
  +´ (select sum(c2.proventos - c2.descontos) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func and c1.Inss = ´´True´´) * ´
  +´ (select first 1 indice from indiceinss inss where inss.ate >= ´
  +´ (select sum(c2.proventos - c2.descontos ) ´
  +´ from essqlfunc c2 ´
  +´ where c2.id_empresa = c1.id_empresa ´
  +´ and c2.id_func = c1.id_func and c1.Inss = ´´True´´ ) ´
  +´ order by inss.ate) / 100.00 Valor_INSS ´
  +´ from essqlfunc c1 ´;
  dm.zspSomaFunc.Open;
end;



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Corrigindo, [color=blue:d1a70c2672]nao[/color:d1a70c2672] eh o campo [b:d1a70c2672]PROVENTOS[/b:d1a70c2672] e sim [b:d1a70c2672]TotoProv[/b:d1a70c2672]


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

creio que você deva ter persistido os campo, porém a instrução
dm.zspSomaFunc.SQL.Add(´select * from essqlfunc where upper(NOME)like :Busca´);
não traz nenhum dos campos agregados (TotoProv, TotDesc, Saldo, Aliquota_INSS, Valor_INS)
que são trazidos pela TFSuperCalculo.ChamaSP.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

creio que você deva ter persistido os campo, porém a instrução dm.zspSomaFunc.SQL.Add(´select * from essqlfunc where upper(NOME)like :Busca´); não traz nenhum dos campos agregados (TotoProv, TotDesc, Saldo, Aliquota_INSS, Valor_INS) que são trazidos pela TFSuperCalculo.ChamaSP.
Entao ai mudei assim a select

if trim(edit2.Text)<>´´ then
  begin
    dm.zspSomaFunc.Close;
    dm.zspSomaFunc.SQL.Clear;
    dm.zspSomaFunc.SQL.Text:=´select id_empresa, salario, salgoverno, id_sal,´
                            +´id_formula, descricao, id_func, nome, id_gerarformula,´
                            +´b_calculo, valor, quantidade, formula, quantia,´
                            +´vl_informado, inss, prov_desc, descinss, marcar´
                            +´from essqlfunc where upper(NOME)like :Busca´;
    dm.zspSomaFunc.ParamByName(´Busca´).AsString:=AnsiUpperCase(trim(edit2.Text))+´¬´;
    dm.zspSomaFunc.Open;
  end;
E assim nao reconhece o [b:30b35266ff]:Busca [/b:30b35266ff]depois do Like


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Poxa, nem do jeito que vc me ensinou nao funcionou :(

var
  sql, texto: string;
begin
  //--primeiro passo os dados para serem filtrados no edit com mais de um nome e com espaços
  //-serve para filtrar tipo assim ADR SERV, JOS DE S....
  if Trim(edtConsulta.text) = ´´ then
    exit;

  texto := AnsiUpperCase(StringReplace(TrimRight(edtConsulta.text),´ ´,´¬ ´,[rfReplaceAll]))+´¬´;

  sql := ´select id_empresa, salario, salgoverno, id_sal,´
        +´id_formula, descricao, id_func, nome, id_gerarformula,´
        +´b_calculo, valor, quantidade, formula, quantia,´
        +´vl_informado, inss, prov_desc, descinss, marcar ´
        +´from essqlfunc where upper(NOME)like :Busca´;

  sql := UpperCase(sql);

  //--CHAMANDO A QUERY PARA FILTAR (DEPOIS QUE CHAMO O FILTRO ABRO A QUERY)
  dm.zspSomaFunc.Close;
  dm.zspSomaFunc.SQL.Clear;
  dm.zspSomaFunc.SQL.Add(sql);
  dm.zspSomaFunc.ParamByName(´Busca´).AsString := texto;
  dm.zspSomaFunc.Open;



GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Nada? Nao sei pq nao funciona esta Pesquisa :(

Outra duvida tambem, agora no ListBox, quero mostrar somente uma vez os campos agregados, mais nao vem nenhum
procedure TFSuperCalculo.Button6Click(Sender: TObject);
var
Func, Empresa, vInss, TotProv, TotDesc, vSaldo, vSalario, vProventos, VDescontos : String;
I  : Integer;
begin
  {Chama o Select}
  ChamaSP;
  //Limpa o ListBox
  listbox2.clear;
  try
    dm.zspSomaFunc.DisableControls;
    dm.zspSomaFunc.First;
    Empresa := #121415;
    while not dm.zspSomaFunc.Eof do
    begin
    if Empresa <> dm.zspSomaFunc.fieldbyname(´id_EMPRESA´).AsString then
    begin
      if Empresa <> 121415 then
         ListBox2.Items.Add(´´);
         Empresa := dm.zspSomaFunc.fieldbyname(´id_EMPRESA´).AsString ;
         dm.qEmpresa.Open; //abre a tabela qEmpresa
         if dm.qEmpresa.Locate(´id_EMPRESA´, Empresa, []) then
            Func := dm.qEmpresa.fieldbyname(´empresa´).AsString
         else Func := ´Empresa não cadastrada´;
            ListBox2.Items.Add(´================================================================================´);
            ListBox2.Items.Add(´Data que foi gerada a Folha : ´ + ´ - ´ + DateToStr(now) + ´ - ´ + TimeToStr(now));
            ListBox2.Items.Add(´================================================================================´);
            ListBox2.Items.Add(Empresa + ´ - ´ + Func);
            ListBox2.Items.Add(´================================================================================´);
            Func := 121415;
            vINSS   := 121415;
            TotProv := 121415;
            TotDesc := 121415;
            vSaldo  := 121415;
         end;
         if Func <> dm.zspSomaFunc.fieldbyname(´id_func´).AsString then
         begin
         if Func <> #121415 then
            ListBox2.Items.Add(´********************************************************************************´);
            Func := dm.zspSomaFunc.fieldbyname(´id_func´).AsString;
            ListBox2.Items.Add(Func + ´ - ´ + dm.zspSomaFunc.fieldbyname(´nome´).AsString);
            vSalario:=FormatFloat(´,0.00;(,0.00)´,StrToFloat(dm.zspSomaFunc.fieldbyname(´salario´).AsString));
            ListBox2.Items.Add(´Salario Base para Calculos: ´  + vSalario);
            ListBox2.Items.Add(´Proventos/Descontos Ativos:´);
            ListBox2.Items.Add(´================================================================================´);

         end;
            vProventos:=FormatFloat(´,0.00;(,0.00)´,StrToFloat(dm.zspSomaFunc.fieldbyname(´Proventos´).asString));
            vDescontos:=FormatFloat(´#,0.00;(,0.00)´,StrToFloat(dm.zspSomaFunc.fieldbyname(´Descontos´).asString));
            //passa para o listbox o valor do dbgrid
            ListBox2.Items.Add(dm.zspSomaFunc.fieldbyname(´id_formula´).AsString +´ - ´
                               +dm.zspSomaFunc.fieldbyname(´descricao´).AsString +´  ´
                               +dm.zspSomaFunc.fieldbyname(´calculo´).asString +´  ´
                               +vProventos+´  ´
                               +vDescontos);

            if vINSS <> dm.zspSomaFunc.fieldbyname(´valor_inss´).AsString then
            begin
            if vINSS <> 121415 then
               ListBox2.Items.Add(´500 - Desconto do INSS´ +´  ´+dm.zspSomaFunc.fieldbyname(´aliquota_inss´).asString+´  ´+dm.zspSomaFunc.fieldbyname(´valor_inss´).asString);
               ListBox2.Items.Add(´================================================================================´);
            end;
            if TotProv <> dm.zspSomaFunc.fieldbyname(´totoprov´).AsString then
            begin
            if TotProv <> #121415 then
               ListBox2.Items.Add(´Total dos Proventos   ´ +´  ´+dm.zspSomaFunc.fieldbyname(´totoprov´).asString);
            end;
            if TotDesc <> dm.zspSomaFunc.fieldbyname(´totdesc´).AsString then
            begin
            if TotDesc <> 121415 then
               ListBox2.Items.Add(´Total dos Desconto    ´ +´  ´+dm.zspSomaFunc.fieldbyname(´totdesc´).asString);
            end;
            if vsaldo <> dm.zspSomaFunc.fieldbyname(´saldo´).AsString then
            begin
            if vsaldo <> 121415 then
               ListBox2.Items.Add(´Total Liquido da Folha´ +´  ´+dm.zspSomaFunc.fieldbyname(´saldo´).asString);
            end;
            dm.zspSomaFunc.Next;
      end;
  finally
     dm.zspSomaFunc.enablecontrols;
  end;
    ListBox2.Items.Add(´*****************************FIM DO RELATORIO***********************************´);
end;


Aonde esta o erro, alem do locate nao esta comparando o campo ID_Empresa com a Tabela [b:c32cf9c7e0]qEmpresa[/b:c32cf9c7e0]


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

No listBox a parte da empresa ja resolvi, estava trazendo da query errada :oops:

Agora os campos agregate esse ainda nao consegui.

Grato
Adriano.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Tem jeito com [b:fa617f8aad]LOCATE[/b:fa617f8aad], fazer o mesmo efeito do[b:fa617f8aad] LIKE[/b:fa617f8aad] do SQL?

Pois com o Locate eu consigo apontar para o campo que eu quero, mais nao do mesmo modo do LIKE


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Ta dificil :x

Ou eu nao sei fazer uma consulta com select au nao tem jeito de fazer essa SQL funcionar, agora estou tentando fazer uma pesquisa no intervalo do campo ID_empresa, e o erro eh que nao reconheçe os parametros.

procedure TFSuperCalculo.Button8Click(Sender: TObject);
begin
dm.zspSomaFunc.Close;
dm.zspSomaFunc.SQL.Clear;
dm.zspSomaFunc.SQL.Add(´select id_empresa, salario, salgoverno, id_sal,´
                      +´id_formula, descricao, id_func, nome, id_gerarformula,´
                      +´b_calculo, valor, quantidade, formula, quantia,´
                      +´vl_informado, inss, prov_desc, descinss, marcar ´//--utilizando um espaço para nao ficar junto com o from
                      +´from essqlfunc where ID_EMPRESA between :pEmprIni and :pEmprFin´);
dm.zspSomaFunc.ParamByName(´pEmprIni´).asInteger :=StrToInt(EdtE1.Text);
dm.zspSomaFunc.ParamByName(´pEmprFin´).asInteger :=StrToInt(EdtE2.Text);
dm.zspSomaFunc.Open;
end;


Olhem o erro que causa
http://adrianoservitec.fotos.uol.com.br/delphi/photo.html?currentPage=1


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

20/07/2007

o erro acusado não é pela falta de parâmetros! é pelo uso de campos inexistentes. sua stored procedure possui os campos:

id_empresa integer
salario numeric(16,2)
salgoverno numeric(15,2)
id_sal integer
id_formula integer
descricao varchar(100)
id_func integer
nome varchar(50)
id_gerarformula integer
inss varchar(10)
calculo varchar(100)
proventos numeric(15,2)
descontos numeric(15,2)

altere sua instrução para algo como:
procedure TFSuperCalculo.Button8Click(Sender: TObject);
begin
  with dm.zspSomaFunc do
  begin
    Close;
    SQL.Text :=
      ´select id_empresa, salario, salgoverno, id_sal, ´+
      ´id_formula, descricao, id_func, nome, id_gerarformula, ´+
      ´calculo, inss, proventos, descontos ´+
      ´from essqlfunc ´+
      ´where ID_EMPRESA between :pEmprIni and :pEmprFin´;
    ParamByName(´pEmprIni´).asInteger :=StrToInt(EdtE1.Text);
    ParamByName(´pEmprFin´).asInteger :=StrToInt(EdtE2.Text);
    Open;
  end;
end;
onde há referência somente aos campos da stored procedure.
note que os campos [i:e488a2c4a3]b_calculo, valor, quantidade, formula, quantia, vl_informado, prov_desc, descinss[/i:e488a2c4a3] e [i:e488a2c4a3]marcar[/i:e488a2c4a3] não são retornados pela sua stored procedure.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Ateh que enfim funcionou :D

Tive que retirar os fields do editor do query, mais tudo bem, fiz as mascaras dentro da unit mesmo

{codigo para formatar o dbgrid - tem que ter DB no uses da unit}
(dm.zspSomaFunc.fieldbyname (´salario´) as tfloatfield).displayformat := ´#,0.00´;
(dm.zspSomaFunc.fieldbyname (´salgoverno´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´proventos´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´descontos´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´TOTOPROV´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´TOTDESC´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´SALDO´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´ALIQUOTA_INSS´) as tfloatfield).displayformat := ´,0.00´;
(dm.zspSomaFunc.fieldbyname (´VALOR_INSS´) as tfloatfield).displayformat := ´#,0.00´;


Mais uma vez obrigado amigo.

Agora ta tudo ok.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Poxa serah que nunca acaba isso :(

Que diaxo de erro eh este agora :?: :?: :?:

http://adrianoservitec.fotos.uol.com.br/delphi/photo.html?currentPage=1

Alguem pode me explicar isso?


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Bom tambem testei no IBExpert e aponta o mesmo erro podem ver na foto 02
http://adrianoservitec.fotos.uol.com.br/delphi


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Ha eu estava me esquecendo modifiquei a SP na parte em azul, será que tem algo haver ali?
CREATE PROCEDURE ESSQLFUNC returns ( id_empresa integer, salario numeric(16,2), salgoverno numeric(15,2), id_sal integer, id_formula integer, descricao varchar(100), id_func integer, nome varchar(50), id_gerarformula integer, inss varchar(10), calculo varchar(100), proventos numeric(15,2), descontos numeric(15,2), descinss varchar(10), marcar varchar(10)) as declare variable b_calculo varchar(50); declare variable valor varchar(50); declare variable quantidade varchar(50); declare variable formula varchar(50); declare variable quantia varchar(50); declare variable vl_informado varchar(50); declare variable prov_desc char(1); declare variable salario_calc numeric(15,2); begin for select a.id_empresa, a.salario, a.salgoverno, a.id_sal, b.id_formula, B.descricao, a.id_func, a.nome, b.id_gerarformula, b.b_calculo, b.valor, b.quantidade, b.formula, b.quantia, b.vl_informado, b.inss, b.p_d, b.descinss, b.marcar from salario_m a left join formulas b on b.id_gerarformula = a.id_sal where (b.marcar = ´True´) order by a.id_empresa, a.id_func, b.p_d desc into :id_empresa, :salario, :salgoverno, :id_sal, :id_formula, :descricao, :id_func, :nome, :id_gerarformula, :b_calculo, :valor, :quantidade, :formula, :quantia, :vl_informado, :inss, :prov_desc, :descinss, :marcar do begin -- passando as condiçoes de cálculo [color=blue:1e701b23d5] if (b_calculo = ´Fixo´ and quantia < 30) then --caso a quantia seja menor que 30 ai faz a soma e divisao calculo = (salario || ´/´ || ´30.000´ || ´*´ ||quantia); else if (b_calculo = ´Fixo´ and quantia = 30) then --caso a quantia seja igual 30 joga somente o valor do salario calculo = (salario);[/color:1e701b23d5] else begin -- verificando QUAL salário será manipulado if (b_calculo = ´Salario_Contratado´) then salario_calc = salario; else salario_calc = salgoverno; -- montando a fórmula if (quantidade = ´True´) then calculo = cast(salario_calc as varchar(10)) || formula || ´*´ || quantia; else if (quantidade = ´False´) then calculo = cast(salario_calc as varchar (10)) || formula; else if (valor = ´False´) then calculo = cast(salario_calc as varchar (10)) || formula; else if (valor = ´True´) then calculo = vl_informado; end proventos = 0; descontos = 0; -- executando a fórmula if (prov_desc = ´P´) then execute statement ´select ´ || calculo || ´ from rdb$database´ into proventos; else execute statement ´select ´ || calculo || ´ from rdb$database´ into descontos; suspend; end end


Mais como eu disse nem sempre apareçe o erro, isso aconteçe as vezes quando incluo Horas Extras de alguns funcionarios, mais nem de todos, tem alguns funcionários que a SP aceita a Hora Extra.


GOSTEI 0
Adriano_servitec

Adriano_servitec

20/07/2007

Emerson, me parece que achei o que estava criando conflito

Na tabela formula o campo aonde estava Horas Extras a formula era esta

/220.000*[color=red:a87aa2faea]150.000[/color:a87aa2faea]/100.000 (Gerava conflito)

dai mudei assim
/220.000*[color=blue:a87aa2faea]150[/color:a87aa2faea]/100.000 (Não gera conflito)

Bom pelo menos agora esta mostrando o resultado sem conflito nos quais estavam.

Espero que seja somente isto o erro :D


GOSTEI 0
POSTAR