Foruma matematica armada por el usuario

Foruma matematica armada por el usuario

Postby dobfivewin » Sat Apr 05, 2008 10:29 am

A ver como se puede hacer y ver si me explico:

en una aplicación tengo acumuladores o totalizadores, ejemplo
mTOTAL:=1000, mCANT := 5

El usuario de un programa cargaría una formula en un campo o variable,
ejemplo: mVARIABLECALCULO := '((mTOTAL*mCANT) *10/100)' ; la idea es
generar una funciones que me arroje el resultado de la variable
cargada por el ususario :shock: .

:-))

chas gracias

David Barrio
dobfivewin
 
Posts: 325
Joined: Sun Feb 03, 2008 11:04 pm
Location: Argetnina

Re: Foruma matematica armada por el usuario

Postby mmercado » Sat Apr 05, 2008 4:00 pm

Hola David
dobfivewin wrote:El usuario de un programa cargaría una formula en un campo o variable,
ejemplo: mVARIABLECALCULO := '((mTOTAL*mCANT) *10/100)' ; la idea es
generar una funciones que me arroje el resultado de la variable
cargada por el ususario

Usa el evaluador de macros: &( cExpression ), te doy un ejemplo:
Code: Select all  Expand view
#include "FiveWin.ch"

MemVar mTOTAL, mCANT

Function Main()

   Local mVARIABLECALCULO := '((mTOTAL*mCANT) *10/100)'


   mTOTAL := 1000
   mCant  := 5

   MsgInfo( &( mVARIABLECALCULO ) )

Return Nil

Igual que con MsgInfo(), puedes hacerlo dentro de cualquier función que tú definas, solo cuida que las variables contenidas en la expresión a evaluar sean visibles para dicha función, no podrán ser variables locales ni estáticas.

Saludos.

Manuel Mercado
User avatar
mmercado
 
Posts: 782
Joined: Wed Dec 19, 2007 7:50 am
Location: Salamanca, Gto., México

Foruma matematica armada por el usuario

Postby dobfivewin » Sun Apr 06, 2008 12:39 pm

Antes de todo Muchas gracias por la respuesta, cargué el ejemplo y funciona.... pero.....

Es raro o normal??

If &(LIQUSUM)->TIPO == 4
mCANTID:= &(LIQUSUM)->CANT

*------------------------------------------------- ACA FUNCIONA
mCALCU := (mACUM01 * mCANTID / 100)

*------------------------------------------------- ACA NO FUNCIONA
* Me dice No existe la Variable mACUM01
mCALCUX := '(mACUM01 * mCANTID / 100)'
mCALCU := &( mCALCUX )
EndIf

La variable mACUM01 es un acumulador que viene sumando importes varios y la variable mCANTID lo traigo de la base de dato.


David Barrio
Argentina
dobfivewin
 
Posts: 325
Joined: Sun Feb 03, 2008 11:04 pm
Location: Argetnina

Postby mmercado » Sun Apr 06, 2008 3:26 pm

David:

Para que el evaluador de macros funcione correctamente, las variables contenidas en la expresión que se va a evaluar deben ser declaradas como MEMVAR y ser visibles para la función que evalúa la expresión, normalmente yo las defino como Public o Private. Si no se hace así, no funciona o el resultado es impredecible.

Saludos.

Manuel Mercado
User avatar
mmercado
 
Posts: 782
Joined: Wed Dec 19, 2007 7:50 am
Location: Salamanca, Gto., México

Postby RenOmaS » Tue Apr 08, 2008 11:06 am

Te alcanzo una funciones que utilizao para manejo de formulas definidas em tiempo de ejecucion
Code: Select all  Expand view

Function Main()
   Local cFormula := 'VALOR1 * VALOR2 / VALOR3"
   Local lOk

   //Chequear formula

   ? lOk := CheckFormula( cFormula, { 'VALOR1', 'VALOR2', 'VALOR3' }, .T. )

  // obtener resultado

   If lOk
   ? Compile( ReplaceFormula( cFormula, { 'VALOR1', 'VALOR2', 'VALOR3' }, { 10, 40, 2 } ) )
   EndIf

Return Nil




//-------------------------------------------------------------------------------//
// Formulas

Function CheckFormula( cFormula, aVar, lMsg )
   Local lReturn := .T.
   Local bOldManejador := ErrorBlock( { |oError| __ErrorFormula( oError, aVar, lMsg ) } )
   Local nValor
   Local oError

   DEFAULT lMsg := .T.

   If !Empty( Alltrim( cFormula ) )

      cFormula := ReplaceFormula( cFormula, aVar )

      Do While .T.

         BEGIN SEQUENCE // control de errores

               nValor := Eval( Compile( cFormula ) )

               RECOVER USING oError

               If Valtype( oError:cargo ) == 'L'
                  If oError:cargo
                     //
                  Else
                     //Error en la formula una item o constante no encontrado
                     nValor := 0
                     lReturn := .F.
                     Exit
                  EndIf
               Else
                  cFormula := StrTran( cFormula, oError:operation, Alltrim( Str( oError:cargo ) ) )
               EndIf
               LOOP
         END
         Exit
      EndDo
      ERRORBLOCK( bOldManejador )
   Endif

   If lMsg .and. lReturn
      MsgInfo( 'Formula Ok' )
   EndIf

   Return lReturn

Function ReplaceFormula( cFormula, aVar, aVal )
   DEFAULT aVal := {'(1)'}

   ASize( aVal, Len( aVar ) )
   AEval( aVal, { |x,n| If( Empty( aVal[ n ] ),  aVal[ n ] := '(1)', ) } )

   AEval( aVar, { |x,n| cFormula := StrTran(  cFormula, x, aVal[ n ] ) } )

   Return cFormula

Function __ErrorFormula( e, aVar, lMsg )

    If Ascan( aVar, { |x| e:operation == upper( x ) } ) > 0
       e:cargo := 1
    Else
       If lMsg
          If e:operation == '&'
             MsgInfo( "Error in Formula: Operation Error" )
          Else
             MsgInfo( "Error in Formula: Constant: " + e:operation + " not found" + CRLF + ;
                      "GenCode : " + Str( e:GenCode ) + CRLF + ;
                      "SubCode : " + Str( e:SubCode ) )
          EndIf
       EndIf
       e:cargo := .F. //Error en la formula
    EndIf

    BREAK e

    Return .T.

//-------------------------------------------------------------------------------//


Salu2[/code]
User avatar
RenOmaS
 
Posts: 205
Joined: Fri Oct 07, 2005 5:07 pm


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 37 guests