PANTHEON™ Help

 Toc
 PANTHEON Hilfe - Willkommen
[Reduzieren]PANTHEON
 [Reduzieren]Leitfäden für PANTHEON
  [Vergrößern]Leitfaden für PANTHEON
  [Vergrößern]Leitfaden für PANTHEON Einzelhandel
  [Vergrößern]Leitfaden für PANTHEON Vet
  [Vergrößern]Leitfaden für PANTHEON Farming
 [Reduzieren]Benutzerhandbücher für PANTHEON
  [Reduzieren]Benutzerhandbuch für PANTHEON
   [Reduzieren]Erste Schritte
     Wörterbuch der Begriffe
     Erste Schritte mit PANTHEON
    [Vergrößern]Verwendung von PANTHEON bei Tecta, einem fiktiven Unternehmen
    [Vergrößern]Anweisungen zur Gewährleistung der Konformität von PANTHEON mit SAS
    [Vergrößern]PANTHEON Installation
    [Reduzieren]PANTHEON-System
     [Vergrößern]PANTHEON Systemdaten
     [Vergrößern]MS SQL Server
     [Vergrößern]Microsoft Windows-Dienstprogramme
     [Vergrößern]Sicherheitspolitik
     [Reduzieren]Datenbankverwaltung
       Beiträge in eine andere Währung umwandeln
       FormelParser
       Dokumentdatum in Büchern korrigieren
      [Vergrößern]Leistungsoptimierung
    [Vergrößern]PANTHEON Grundlagen
    [Vergrößern]PANTHEON Hilfe
    [Vergrößern]Material- und Warenbewegungen
    [Vergrößern]Zuordnen von Identifikatoren
    [Vergrößern]Häufig gestellte Fragen zu Pantheon (F.A.Q.)
    [Vergrößern]Archiv
   [Vergrößern]Benutzerhandbuch für eBusiness
   [Vergrößern]Einstellungen
   [Vergrößern]Bestellungen
   [Vergrößern]Waren
   [Vergrößern]Herstellung
   [Vergrößern]Service
   [Vergrößern]Hilfe
   [Vergrößern]Personal
   [Vergrößern]Finanzen
   [Vergrößern]Analytik
  [Vergrößern]Benutzerhandbuch für PANTHEON Einzelhandel
  [Vergrößern]Benutzerhandbuch für PANTHEON Vet
  [Vergrößern]Benutzerhandbuch für PANTHEON Farming
[Reduzieren]PANTHEON Web
 [Reduzieren]Leitfäden für PANTHEON Web
  [Vergrößern]Leitfaden für PANTHEON Web Light
  [Vergrößern]Leitfaden für das PANTHEON Web-Terminal
  [Vergrößern]Leitfaden für PANTHEON Web Rechtliches
  [Vergrößern]Alte Produkte Archiv
 [Reduzieren]Benutzerhandbücher für PANTHEON Web
  [Vergrößern]Erste Schritte PANTHEON Web
  [Vergrößern]Benutzerhandbuch für PANTHEON Web Light
  [Vergrößern]Benutzerhandbuch für das PANTHEON Web-Terminal
  [Vergrößern]Benutzerhandbuch für PANTHEON Web Legal
  [Vergrößern]Alte Produkte Archiv
[Reduzieren]PANTHEON Granulate
 [Reduzieren]Leitfäden für PANTHEON Granulate
  [Vergrößern]Personalgranulat
  [Vergrößern]Reiseaufträge Granulat
  [Vergrößern]Dokumente und Aufgaben Granule
  [Vergrößern]Dashboard Granule
  [Vergrößern]B2B-Bestellungen Granulat
  [Vergrößern]Feldservice-Granulat
  [Vergrößern]Bestandsgranule für Anlagevermögen
  [Vergrößern]Warenlager Inventar Granulat
 [Reduzieren]Benutzerhandbücher für PANTHEON Granulate
  [Vergrößern]Erste Schritte
  [Vergrößern]Personalgranulat
  [Vergrößern]Reiseaufträge Granulat
  [Vergrößern]Dokumente und Aufgaben Granule
  [Vergrößern]B2B-Bestellungen Granulat
  [Vergrößern]Dashboard Granule
  [Vergrößern]Feldservice-Granulat
  [Vergrößern]Bestandsgranulat für Anlagevermögen
  [Vergrößern]Lagereinlagerung Granulat
  [Vergrößern]Archiv
[Vergrößern]Benutzerseite

Load Time: 421,8511 ms
"
  2709 | 3106 | 485180 | AI translated
Label

FormelParser

FormelParser

FormelParser

Der erste Teil ist nicht so sehr an SQL-InterActive gebunden, sondern mehr an die Art der Programmierung von T-SQL. Da wir wissen, wie wertvoll Programmbeispiele sind, haben wir es dennoch in die Anleitung aufgenommen.

Das Beispiel veranschaulicht gut Rekursionen, gespeicherte Prozeduren. Die Hauptprozedur dient der Berechnung mathematischer Ausdrücke, die wir in Form eines Strings alphanumerischer Zeichen eingeben.

Die Prozeduren sind so gestaltet, dass wir, wenn wir --!! vor den Print-Befehlen entfernen, den Ablauf der Ausführung und der Rekursionen sehen.

Hilfsprozedur, die Argumente zurückgibt

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

-- Testparameter
-- Deklaration
--   @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+' '  -- dies dient nur dazu, die Grenzen in der Schleife zu berücksichtigen (um nicht j[0] zu erhalten)
set @iOperand = @iOperand + 1
--!! print '    @sTempArg='+@sTempArg+'#'
--!! print '    @iOperand=' + Str(@iOperand) + '#' + SubString(@sTempArg,@iOperand,1) 
if @lLeft=1
  begin  -- linkes Argument
   set @iLimit = @iOperand - 1
   --!! print '      linkes Argument'
   --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
   while (@iLimit > 0) and not (SubString(@sTempArg,@iLimit,1) in ('+','-','/','*','\','|'))
     set @iLimit = @iLimit-1
   -- Überprüfen auf führendes "-" für das linke Argument.
   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  -- rechtes Argument
    set @iLimit = @iOperand + 1
    --!! print '      rechtes Argument'
    --!! print '      @iLimit=' + Str(@iLimit) + '#' + SubString(@sTempArg,@iLimit,1) 
    set @iLimit = @iLimit+1
    --!! print '      Berechnung...'
    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 ('+','-')  -- dies ist für -x / +x Behandlung
      set @mResult = 0
    else
      set @sEr = 'Ungültige Verwendung von Operatoren in '+@sExpression
  end
else
  begin
    --!! print '    out @sTempArg='+@sTempArg
    set @mResult = Convert(float,@sTempArg,2)
    --!! print '    out @mResult='+Str(@mResult,35,15)
    -- !! Überprüfen auf Fehler hier !! Ausnahmebehandlung !!
    --    if code <> 0 then
    --      er = @sExpression+'ist keine Zahl!'
    --    else
    --      begin
    set @iLimit = @iLimit - 1
    --      end
  end

Die Hauptprozedur, die den Ausdruck berechnet

create procedure [dbo].[dl_PA_ParseAritNew]
  @sExpression varchar(8000),
  @rResult float output,
  @sEr varchar(8000) output -- @sEr = ''<- ohne Fehler, @sEr <> '' <- Fehler im Ausdruck

-- Warnung ! ---
-- Rufe die Funktion immer als ParseArit(0, Ausdruck, '+', er) !!!!!
-- Im Ausdruck dürfen keine Leerzeichen sein "2+3" = OK / "2 + 3" <> OK !!!!
-- Im Ausdruck dürfen keine unausgeglichenen Klammern sein (siehe Test 2)!
-- (c) A. Mertelj, 1997, 2002

as

declare
  @iBrackets int,       -- Klammern () Zähler
  @i int,               -- Zähler 1
  @j int,               -- Zähler 2
  @iLen int,            -- Länge von @sExpression 
  @iLeftLimit int,      -- linke Argumentgrenze
  @iRightLimit int,     -- rechte Argumentgrenze
  @rLeft float,         -- Wert des linken Arguments
  @rRight float,        -- Wert des rechten Arguments
  @lOperatorsExist bit, -- gab es einen Operator im Ausdruck
  @sOrigExpression varchar(8000),
  @sTemp varchar(8000)  -- temporäre Variable

set nocount on  

set @iLen = Len(@sExpression)
set @sOrigExpression = @sExpression
-- korrigiere "+x" in "x"
if SubString(@sExpression,1,1) = '+'
  set @sExpression = Right(@sExpression,@iLen-1)
-- korrigiere "--x" in "x"
set @sExpression = Replace(@sExpression,'--','')
--!! print 'in function exp = ' +@sOrigExpression
if @sEr = '' 
  begin   -- kein Fehler beim Eintritt
    set @lOperatorsExist = 0
    -- bearbeite Klammern ()
    set  @i = Charindex('(',@sExpression)
    if @i > 0 -- @i > 0?
      begin -- es gibt (,)
        --!! print '  -- es gibt Klammern'
        set @lOperatorsExist = 1
        set @iBrackets = 1
        set @j = @i + 1  
        while (@j <= @iLen) and (@iBrackets > 0) -- finde das erste Paar
          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)
        -- berechne das äußere Paar
        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,',','.')  -- mögliche ',' in '.' ändern
        --!! print '    ()@sTemp, nach Ersetzung ='+@sTemp
        -- ersetze das äußere Paar durch das Ergebnis
        set @sExpression = SubString(@sExpression,1,@i-1)+@sTemp+SubString(@sExpression,@j,@iLen-@j+1)  
        --!! print '    ()@sExpression=' + @sExpression 
      end -- es gibt (,)
    else  -- @i > 0? nein, keine (,)
      begin -- überprüfe auf *,/
        set @i = 1
        while not (SubString(@sExpression,@i,1) in ('*','/')) and (@i < @iLen) 
          set @i = @i + 1
        if SubString(@sExpression,@i,1) in ('*','/') 
          begin  -- *,/ gefunden
            --!! print '  -- es gibt *,/  gefunden an Position ' + 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,',','.')  -- mögliche ',' in '.' ändern
                --!! print '    */@sTemp, nach Ersetzung ='+@sTemp
                --!! print '    */Rechter Teil=#'+ SubString(@sExpression,@iRightLimit,Len(@sExpression)-@iRightLimit+1) + '#'
                -- ersetze *,/ durch Ergebnis
                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  -- *,/ gefunden
        else
          begin -- überprüfe auf 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 gefunden
                --!! print '  -- es gibt \,| (div,mod)  gefunden an Position ' + 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,',','.')  -- mögliche ',' in '.' ändern
                    -- ersetze div, mod durch Ergebnis
                    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 gefunden
            else
              begin -- überprüfe auf Additionen und Subtraktionen
                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  -- +,- gefunden  
                    --!! print '  -- es gibt +,-  gefunden an Position ' + 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,',','.')  -- mögliche ',' in '.' ändern
                    --!! print '    +-@sTemp, nach Ersetzung ='+@sTemp
                    -- ersetze +,- durch Ergebnis
                    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 -- +,- gefunden
              end  -- überprüfe auf Additionen und Subtraktionen
          end  -- überprüfe auf div, mod
        end  -- überprüfe auf Multiplikationen, Divisionen
    if @sEr = ''
      begin  -- bisher kein Fehler
        if @lOperatorsExist = 1
          begin
            --!! print '  out for recursion orig. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            exec dl_PA_ParseAritNew @sExpression,@rResult output,@sEr output -- parse mit Wert
          end
        else
          begin
            --!! print '  out for orig. @sExpression='+@sExpression+' @sExpression=' + @sExpression
            set @rResult = Convert(float,@sExpression,2)
          end
      end -- bisher kein Fehler
  end -- kein Fehler beim Eintritt

Testfälle

-- Testfall 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
-- Testfall 2
 create table _TEST_PARSER
 (
    FORMEL varchar(300),
    TEST money,
    ER varchar(500),
    ERGEBNIS 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 FORMEL,TEST
      from _TEST_PARSER
  open crKurzor
  fetch next from crKurzor into @sExpression,@mTest
  while @@fetch_status = 0 
  while @@fetch_status = 0 
    begin
      -- Überprüfen auf Klammerausgleich
      print '--------------------------------------------------------'
      print ' Testen: ' + @sExpression
      print ' Erwartetes Ergebnis = ' + Str(@mTest)
      set @i = 1  
      set @iBrackets = 0
      while (@i <= Len(@sExpression))  -- gesamten Ausdruck überprüfen
        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 = 'Unausgeglichene Klammern in ' + @sExpression
      else
        begin
          set @sEr = ''
          exec dl_PA_ParseAritNew @sExpression, @mResult output,@sEr output
        end
      print ' Berechnetes Ergebnis = ' + Str(@mResult)
      if (@mResult = @mTest)
        print ' OK'
      else
        print ' Fehler (@mResult - @mTest) = ' + Str(@mResult - @mTest)
      print '--------------------------------------------------------'
      update _TEST_PARSER
        set ERGEBNIS = @mResult,
            ER = @sEr
        where LTrim(RTrim(FORMEL)) = LTrim(RTrim(@sExpression))
      fetch next from crKurzor into @sExpression,@mTest
    end
  close crKurzor
  deallocate crKurzor
  select LTrim(RTrim(FORMEL)) as 'Formel',TEST,ERGEBNIS,LTrim(RTrim(ER)) as 'Fehlermeldung'
    from _TEST_PARSER
      where (TEST <> ERGEBNIS) or (TEST is null)


 

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