PANTHEON™ Help

 Toc
 PANTHEON Ajutor - Bun venit
[Collapse]PANTHEON
 [Collapse]Ghiduri pentru PANTHEON
  [Expand]Ghid pentru PANTHEON
  [Expand]Ghid pentru PANTHEON Retail
  [Expand]Ghid pentru PANTHEON Vet
  [Expand]Ghid pentru PANTHEON Fermă
 [Collapse]Manuale de utilizare pentru PANTHEON
  [Collapse]Manual de utilizare pentru PANTHEON
   [Collapse]Începerea
     Dicționar de termeni
     Primii pași cu PANTHEON
    [Expand]Folosind PANTHEON la Tecta, o companie fictivă
    [Expand]Instrucțiuni pentru asigurarea conformității PANTHEON cu SAS
    [Expand]Instalare PANTHEON
    [Collapse]SISTEMUL PANTHEON
     [Expand]Datele sistemului PANTHEON
     [Expand]MS SQL Server
     [Expand]Utilitare Microsoft Windows
     [Expand]Politica de Securitate
     [Collapse]Administrarea bazei de date
       Conversia postărilor într-o monedă diferită
       FormulaParser
       Corectarea datei documentului în cărți
      [Expand]Optimizarea Performanței
    [Expand]Bazele PANTHEON
    [Expand]PANTHEON Ajutor
    [Expand]Materiale și Mișcări de Bunuri
    [Expand]Atribuirea Identificatorilor
    [Expand]Întrebări frecvente despre Pantheon (F.A.Q.)
    [Expand]Arhivă
   [Expand]Manual de utilizare pentru eBusiness
   [Expand]Setări
   [Expand]Comenzi
   [Expand]Produse
   [Expand]Fabricare
   [Expand]Serviciu
   [Expand]Ajutor
   [Expand]Personal
   [Expand]Financiare
   [Expand]Analitică
  [Expand]Manual de utilizare pentru PANTHEON Retail
  [Expand]Manual de utilizare pentru PANTHEON Vet
  [Expand]Manual de utilizare pentru PANTHEON Farming
[Collapse]PANTHEON Web
 [Collapse]Ghiduri pentru PANTHEON Web
  [Expand]Ghid pentru PANTHEON Web Light
  [Expand]Ghid pentru Terminalul Web PANTHEON
  [Expand]Ghid pentru PANTHEON Web Legal
  [Expand]Arhivă produse vechi
 [Collapse]Manuale de utilizare pentru PANTHEON Web
  [Expand]Începerea PANTHEON Web
  [Expand]Manual de utilizare pentru PANTHEON Web Light
  [Expand]Manual de utilizare pentru terminalul web PANTHEON
  [Expand]Manual de utilizare pentru PANTHEON Web Legal
  [Expand]Arhivă produse vechi
[Collapse]PANTHEON Granule
 [Collapse]Ghiduri pentru granule PANTHEON
  [Expand]Granul Personal
  [Expand]Comenzi de Călătorie Granule
  [Expand]Documente și Sarcini Granul
  [Expand]Tabloul de bord Granule
  [Expand]Comenzi B2B Granule
  [Expand]Granul de Serviciu pe Teren
  [Expand]Granul Inventar Active Fixe
  [Expand]Inventar de Magazin Granule
 [Collapse]Manuale de utilizare pentru granulele PANTHEON
  [Expand]Începerea
  [Expand]Granul Personal
  [Expand]Comenzi de Călătorie Granule
  [Expand]Documente și Sarcini Granul
  [Expand]Comenzi B2B Granule
  [Expand]Tabloul de bord Granule
  [Expand]Serviciul de teren Granule
  [Expand]Granul Inventar Active Fixe
  [Expand]Inventar de Magazin Granule
  [Expand]Arhivă
[Expand]Site utilizator

Load Time: 453,1116 ms
"
  2709 | 3106 | 472485 | AI translated
Label

FormulaParser

FormulaParser

FormulaParser

Acest exemplu nu este atât de legat de SQL-InterActive, ci mai mult de modul de programare T-SQL. Deoarece știm cât de valoroase sunt exemplele de programare, l-am inclus totuși în instrucțiuni.

Exemplul ilustrează bine recursiile, procedurile stocate. Procedura principală este destinată calculării expresiilor matematice pe care le introducem sub formă de șir de caractere alfanumerice.

Procedurile sunt realizate astfel încât, dacă eliminăm --!! înainte de comenzile print, vedem fluxul de execuție și recursiile.

Procedura auxiliară, care returnează argumentele

create procedure [dbo].[dl_PA_ParserGetArg]
  @sExpression varchar(8000),
  @lLeft bit,
  @iOperand int,
  @iLimit integer output,
  @mResult float output,
  @sEr varchar(8000) output

-- parametrii de test
-- declara
--   @sExpression varchar(8000),
--   @lLeft bit,
--   @iOperand int,
--   @iLimit integer,
--   @mResult money,
--   @sEr varchar(8000)
-- 
-- set @sExpression='2*3'
-- set @lLeft=1
-- set @iOperand=2
-- exec dl_PA_GetArg @sExpression, @lLeft, @iOperand, @iLimit output,@mResult output, @sEr output
--  --!! print '-----'
--  --!! print @iLimit 
--  --!! print cast(@mResult as char)
--  --!! print @sEr

as

declare
  @sTempArg varchar(8000)

set nocount on
set @sTempArg = ' '+@sExpression+' '  --acesta este doar pentru a avea grijă de limite în buclă (pentru a nu obține j[0])
set @iOperand = @iOperand + 1
--!! print '    @sTempArg='+@sTempArg+'#'
--!! print '    @iOperand=' + Str(@iOperand) + '#' + SubString(@sTempArg,@iOperand,1) 
if @lLeft=1
  begin  -- argumentul din stânga
   set @iLimit = @iOperand - 1
   --!! print '      arg stâng'
   --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
   while (@iLimit > 0) and not (SubString(@sTempArg,@iLimit,1) in ('+','-','/','*','\','|'))
     set @iLimit = @iLimit-1
   -- să verificăm pentru "-" de început pentru argumentul din stânga.
   if @iLimit > 1 
     if SubString(@sTempArg,@iLimit,1) = '-'
        set @iLimit = @iLimit-1
   --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
   --!! print '      @iLimitg='+cast(@iLimit as varchar)
   set @sTempArg = SubString(@sTempArg,@iLimit+1,@iOperand-@iLimit-1)
   --!! print '      out left @sTempArg='+@sTempArg
  end
else
  begin  -- argumentul din dreapta
    set @iLimit = @iOperand + 1
    --!! print '      arg drept'
    --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
    set @iLimit = @iLimit+1
    --!! print '      Calculând...'
    while (@iLimit <= Len(@sTempArg)) and not (SubString(@sTempArg,@iLimit,1) in ('+','-','/','*','\','|'))
      set @iLimit = @iLimit+1
    --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
    set @sTempArg = SubString(@sTempArg,@iOperand+1,@iLimit-@iOperand-1)
    --!! print '    out right @sTempArg='+@sTempArg
  end
if @sTempArg = '' 
  begin
    if SubString(@sExpression,@iOperand,1) in ('+','-')  -- acesta este pentru gestionarea -x / +x
      set @mResult = 0
    else
      set @sEr = 'Utilizare invalidă a operatorilor în '+@sExpression
  end
else
  begin
    --!! print '    out @sTempArg='+@sTempArg
    set @mResult = Convert(float,@sTempArg,2)
    --!! print '    out @mResult='+Str(@mResult,35,15)
    -- !! verifică pentru eroare aici !! Gestionarea excepțiilor !!
    --    if code <> 0 then
    --      er = @sExpression+'nu este un număr!'
    --    else
    --      begin
    set @iLimit = @iLimit - 1
    --      end
  end

Procedura principală, care calculează expresia

create procedure [dbo].[dl_PA_ParseAritNew]
  @sExpression varchar(8000),
  @rResult float output,
  @sEr varchar(8000) output -- @sEr = ''<- fără eroare, @sEr <> '' <- eroare în expresie

-- Atenție ! ---
-- Funcția trebuie apelată întotdeauna ca ParseArit(0,expresie,'+',er) !!!!!
-- Expresia nu trebuie să conțină spații "2+3" = OK / "2 + 3" <> OK !!!!
-- Expresia nu trebuie să conțină paranteze neechilibrate (vezi testul 2)!
-- (c) A. Mertelj, 1997, 2002

as

declare
  @iBrackets int,       -- contor paranteze ()
  @i int,               -- contor 1
  @j int,               -- contor 2
  @iLen int,            -- lungimea @sExpression 
  @iLeftLimit int,      -- limita argumentului din stânga
  @iRightLimit int,     -- limita argumentului din dreapta
  @rLeft float,         -- valoarea argumentului din stânga
  @rRight float,        -- valoarea argumentului din dreapta
  @lOperatorsExist bit, -- a existat un operator în expresie
  @sOrigExpression varchar(8000),
  @sTemp varchar(8000)  -- variabilă temporară

set nocount on  

set @iLen = Len(@sExpression)
set @sOrigExpression = @sExpression
-- corectează "+x" în "x"
if SubString(@sExpression,1,1) = '+'
  set @sExpression = Right(@sExpression,@iLen-1)
-- corectează "--x" în "x"
set @sExpression = Replace(@sExpression,'--','')
--!! print 'în funcție exp = ' +@sOrigExpression
if @sEr = '' 
  begin   -- fără eroare la intrare
    set @lOperatorsExist = 0
    -- gestionează parantezele ()
    set  @i = Charindex('(',@sExpression)
    if @i > 0 -- @i > 0?
      begin -- există (,)
        --!! print '  -- există paranteze'
        set @lOperatorsExist = 1
        set @iBrackets = 1
        set @j = @i + 1  
        while (@j <= @iLen) and (@iBrackets > 0) -- găsește prima potrivire
          begin
            if SubString(@sExpression,@j,1) = ')'
              set @iBrackets = @iBrackets-1
            if SubString(@sExpression,@j,1) = '('
              set @iBrackets = @iBrackets+1
            set @j = @j + 1
          end
        set @sTemp = SubString(@sExpression,@i+1,@j-@i-2)
        -- calculează perechea exterioară
        exec dl_PA_ParseAritNew @sTemp,@rResult output,@sEr output 
        --!! print '    ()@rResult='+Str(@rResult,25,10)
        set @sTemp = LTrim(Str(@rResult,35,15))
        --!! print '    ()@sTemp='+@sTemp
        set @sTemp = Replace(@sTemp,',','.')  -- schimbă posibilele ',' în '.'
        --!! print '    ()@sTemp, după înlocuire ='+@sTemp
        -- înlocuiește perechea exterioară cu rezultatul
        set @sExpression = SubString(@sExpression,1,@i-1)+@sTemp+SubString(@sExpression,@j,@iLen-@j+1)  
        --!! print '    ()@sExpression=' + @sExpression 
      end -- există (,)
    else  -- @i > 0? nu, nu există (,)
      begin -- verifică pentru *,/
        set @i = 1
        while not (SubString(@sExpression,@i,1) in ('*','/')) and (@i < @iLen) 
          set @i = @i + 1
        if SubString(@sExpression,@i,1) in ('*','/') 
          begin  -- *,/ găsit
            --!! print '  -- există *,/  găsit la poziția ' + Str(@i)
            set @lOperatorsExist = 1
            exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
            exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
            --!! print '    */@rLeft='+Str(@rLeft,25,15)
            --!! print '    */@rRight='+Str(@rRight,25,15)
            --!! print '    */@sEr='+@sEr
            if @sEr = '' 
              begin
                if SubString(@sExpression,@i,1) = '*' 
                  set  @rResult = @rLeft*@rRight
                else
                  if SubString(@sExpression,@i,1) = '/'
                    exec dl_DivT @rLeft,@rRight,@rResult output
                set @sTemp = LTrim(Str(@rResult,35,15))
                --!! print '    */@rResult='+Str(@rResult,25,10)
                --!! print '    */@sTemp='+@sTemp
                set @sTemp = Replace(@sTemp,',','.')  -- schimbă posibilele ',' în '.'
                --!! print '    */@sTemp, după înlocuire ='+@sTemp
                --!! print '    */Desni del=#'+ SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1) + '#'
                -- înlocuiește *,/ cu rezultat
                if @iLeftLimit > 0
                   set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                else
                   set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
		--!! print '    */@sExpression(Final)=' + @sExpression 
              end
          end  -- *,/n găsit
        else
          begin -- verifică pentru div, mod
            set @i = 1
            while not (SubString(@sExpression,@i,1) in ('\','|')) and (@i < @iLen)
              set @i = @i + 1
            if SubString(@sExpression,@i,1) in ('\','|')
              begin  -- div, mod găsit
                --!! print '  -- există \,| (div,mod)  găsit la poziția ' + Str(@i)
                set @lOperatorsExist = 1
                exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
                exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
                --!! print '    \,|@rLeft='+Str(@rLeft,25,15)
                --!! print '    \,|@rRight='+Str(@rRight,25,15)
                --!! print '    \,|@sEr='+@sEr
                if @sEr = ''
                  begin
                    if SubString(@sExpression,@i,1) = '\'
                      begin
                        if @rRight <> 0
                          set @rResult = cast((@rLeft / @rRight + 0.0) as int)
                        else
                          set @rResult = 0
                      end
                    else
                      if SubString(@sExpression,@i,1) = '|'
                        begin
                          if @rRight <> 0
                            set @rResult = cast(@rLeft as int) % cast(@rRight as int)
                          else
                            set @rResult = 0
                        end
                    set @sTemp = LTrim(Str(@rResult,35,15))
                    set @sTemp = Replace(@sTemp,',','.')  -- schimbă posibilele ',' în '.'
                    -- înlocuiește div, mod cu rezultat
                    if @iLeftLimit > 0
                      set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    else
                      set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                  end
              end  -- div, mod găsit
            else
              begin -- verifică pentru adunări și scăderi
                set @i = 1
                if SubString(@sExpression,@i,1) = '-'
                  set @i = @i + 1
                while not (SubString(@sExpression,@i,1) in ('+','-'))  and (@i < @iLen)
                  set @i = @i + 1
                --!! print '    +,- @i='+cast(@i as varchar)
                if SubString(@sExpression,@i,1) in ('+','-')
                  begin  -- +,- găsit  
                    --!! print '  -- există +,-  găsit la poziția ' + Str(@i)
                    set @lOperatorsExist = 1
                    exec dl_PA_ParserGetArg @sExpression,1,@i,@iLeftLimit output,@rLeft output,@sEr output
                    exec dl_PA_ParserGetArg @sExpression,0,@i,@iRightLimit output,@rRight output,@sEr output
                    --!! print '    +,- @rLeft='+Str(@rLeft,25,15)
                    --!! print '    +,- @rRight='+Str(@rRight,25,15)
                    --!! print '    +,- @sEr='+@sEr
                    if SubString(@sExpression,@i,1) = '+'
                       set @rResult = @rLeft + @rRight
                    else
                      if SubString(@sExpression,@i,1) = '-'
                        set @rResult = @rLeft - @rRight
                    set @sTemp = LTrim(Str(@rResult,35,15))
                    --!! print '    +-@rResult='+Str(@rResult,25,10)
                    --!! print '    +-@sTemp='+@sTemp
                    set @sTemp = Replace(@sTemp,',','.')  -- schimbă posibilele ',' în '.'
                    --!! print '    +-@sTemp, după înlocuire ='+@sTemp
                    -- înlocuiește +,- cu rezultat
                    if @iLeftLimit > 0
                      set @sExpression = SubString(@sExpression,1,@iLeftLimit) + @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    else
                      set @sExpression = @sTemp + SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1)
                    --!! print '    +-@sExpression=' + @sExpression 
                  end -- +,- găsit
              end  -- verifică pentru adunări și scăderi
          end  -- verifică pentru div, mod
        end  -- verifică pentru înmulțiri, împărțiri
    if @sEr = ''
      begin  -- fără eroare până acum
        if @lOperatorsExist = 1
          begin
            --!! print '  out for recursion orig. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            exec dl_PA_ParseAritNew @sExpression,@rResult output,@sEr output -- analizează cu valoare
          end
        else
          begin
            --!! print '  out for orig. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            set @rResult = Convert(float,@sExpression,2)
          end
      end -- fără eroare până acum
  end -- fără eroare la intrare

Exemple de test

-- caz de test 1
 declare
   @sExpression varchar(8000),
   @mResult money,
   @sEr varchar(8000)
 set @sExpression='2*3'
 set @sEr = ''
 --!! print @sExpression
 exec dl_PA_ParseAritNew @sExpression, @mResult output,@sEr output
 --!! print '-----'
 --!! print Str(@mResult,35,15)
 --!! print @sEr
--caz de test 2
 create table _TEST_PARSER
 (
    FORMULA varchar(300),
    TEST money,
    ER varchar(500),
    REZULTAT money
 )
 declare
    @sExpression varchar(8000),
    @mTest float,
    @mResult float,
    @i int,
    @iBrackets int,
    @sEr varchar(8000)
  set nocount on 
  declare crKurzor cursor local fast_forward for 
    select FORMULA,TEST
      from _TEST_PARSER
  open crKurzor
  fetch next from crKurzor into @sExpression,@mTest
  while @@fetch_status = 0 
  while @@fetch_status = 0 
    begin
      -- verifică echilibrul parantezelor
      print '--------------------------------------------------------'
      print ' Testare: ' + @sExpression
      print ' Rezultatul așteptat = ' + Str(@mTest)
      set @i = 1  
      set @iBrackets = 0
      while (@i <= Len(@sExpression))  -- verifică întreaga expresie
        begin
          if SubString(@sExpression,@i,1) = ')'
            set @iBrackets = @iBrackets-1
          if SubString(@sExpression,@i,1) = '('
            set @iBrackets = @iBrackets+1
          set @i = @i + 1
        end
      if @iBrackets <> 0
        set @sEr = 'Paranteze dezechilibrate în ' + @sExpression
      else
        begin
          set @sEr = ''
          exec dl_PA_ParseAritNew @sExpression, @mResult output,@sEr output
        end
      print ' Rezultatul calculat = ' + Str(@mResult)
      if (@mResult = @mTest)
        print ' OK'
      else
        print ' Eroare (@mResult - @mTest) = ' + Str(@mResult - @mTest)
      print '--------------------------------------------------------'
      update _TEST_PARSER
        set REZULTAT = @mResult,
            ER = @sEr
        where LTrim(RTrim(FORMULA)) = LTrim(RTrim(@sExpression))
      fetch next from crKurzor into @sExpression,@mTest
    end
  close crKurzor
  deallocate crKurzor
  select LTrim(RTrim(FORMULA)) as 'Formula',TEST,REZULTAT,LTrim(RTrim(ER)) as 'ErrorMsg'
    from _TEST_PARSER
      where (TEST <> REZULTAT) or (TEST is null)


 

Rate this topic
Was this topic usefull?
Comments
Comment will also bo visible in forum!