Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Interprete de Comandos con VS.NET

89 views
Skip to first unread message

Carlos Bardales

unread,
Jan 19, 2003, 10:36:10 PM1/19/03
to
Quisiera pedirles por favor, si alguien sabe cómo
se hace en VB.NET, para interpretar comandos
contenidos en una variable tipo string.

Me explico:

1. Tengo las variables:

cComando1 = "FOR i = 1 TO 100: ?'prueba': NEXT" (ejecutar un bucle)
cComando2 = "IF X=Y THEN Z=5" (ejecutar una comparacion)
cComando3 = "miFuncion(parametros)" (ejecutar una funcion)


2. Ahora, deseo ejecutar dichos comandos, interpretando
el contenido de estas variables.

En Clipper, a esto se llama, macro-sustitucion, porque
sustituye el valor de una variable, por su verdadero
contenido. En clipper, se hacía así:

Resultado = &cComando (el operador &).
también se usaban un tipo de dato llamado CodeBlocks.

En el VB6 ya tengo una función que hace esto, pero
al importarlo al VS.NET ya no funciona.

Alguien sabe como hacerlo ?

Gracias.

Marino Posadas

unread,
Jan 20, 2003, 6:34:39 PM1/20/03
to

Hola Carlos

Recuerdo bien los "codeblocks" de Clipper. Y el operando de
macrosustitución. Era una curiosa funcionalidad que se perdió cuando pasamos
a lenguajes Windows. En VB6 existía una cosa llamada CallByName() que
permitía hacer algo -en ocasiones- parecido, pero no era esa funcionalidad
exacta. Posteriormente, cuando esta cuestión ha vuelto salir, los
comentarios iban por intérpretes de Script, y en concreto por el componente
COM MSScriptControl (que a pesar del nombre no es un control, sino
componente). Dispone de métodos ExecuteStatement() y Run() que ejecutan el
código que se le ha añadido con ciertas restricciones.

Si haces referencia a los componentes en .NET podrás usarlo a través de
Interop, porque todavía esta en la lista de componentes COM...


--
Saludos cordiales,
Marino Posadas
MCSD, MCT, MSF-P
www.ElAveFenix.net
"Carlos Bardales" <bard...@yahoo.com> wrote in message
news:7948860d.0301...@posting.google.com...

Tristan

unread,
Jan 20, 2003, 7:02:22 PM1/20/03
to
Tienes dos formas de hacer eso:

Por interpretación, tal y como Clipper o VB lo hacen, utilizando como
lenguaje VBScript (lo que harías en VB).

Solo tienes que añadir a tu cuadro de taréas el componente "Script Control
Object" y desde allí añadirlo a tu formulario. Ahora podrás ejecutar este
código:

Dim comando = "FOR I = 1 TO 100: MsgBox i: NEXT"
AxScriptControl1.ExecuteStatement(comando)

Por compilación. A través de la clase VBCodeProvider, con la cual puedes
compilar código en memoria y ejecutarlo sobre la marcha mediante reflection.
Me parece con mucha diferencia la mejor opción, pese a ser ligeramente más
complicada. Permite ejecutar CUALQUIER VB.NET, no VBScript, y además el
código es compilado, con lo cual la depuración es muchísimo más sencilla y
la ejecución más rápida. Puedes crear cualquier programa, depurarlo con
vs.net y una vez probado, asignarlo al string fuente. Eso si, hay que tener
cuidado con el tema de espacios de nombre y de referencias (solo añado
WinForms en el ejemplo)

Dim fuente As String = _
"Imports System.Windows.Forms" & vbCrLf & _
"Public Class ClaseEjecuta" & vbCrLf & _
"Public Shared Sub Ejecuta()" & vbCrLf & _
"Dim i as Integer" & vbCrLf & vbCrLf & _
"For i = 1 To 10" & vbCrLf & vbCrLf & _
"MessageBox.Show(i.ToString())" & vbCrLf & _
"Next i" & vbCrLf & _
"End Sub" & vbCrLf & _
"End Class"

Dim codeProvider As New VBCodeProvider()
Dim compilador As ICodeCompiler = codeProvider.CreateCompiler()
Dim parametros As New CompilerParameters()
'Puedes añadir otras referencias necesarias
parametros.ReferencedAssemblies.Add("System.Windows.Forms.dll")
parametros.GenerateInMemory = True
Dim resultado As CompilerResults =
compilador.CompileAssemblyFromSource(parametros, fuente)
If resultado.Errors.Count > 0 Then
Dim errores As String = ""
Dim mensaje As CompilerError
For Each mensaje In resultado.Errors
errores += "Error " & mensaje.ErrorNumber & ": " &
mensaje.ErrorText & vbCrLf
Next
Throw New Exception(errores)
End If
'ClaseEjecuta se corresponde con el nombre de la clase declarado en
fuente.
Dim clase As Type = resultado.CompiledAssembly().GetType("ClaseEjecuta")
'Ejecuta se corresponde con el nombre del método declarado en fuente.
clase.GetMethod("Ejecuta").Invoke(Nothing, Nothing)

--
Juan Carlos Badiola
MVP - C#


Carlos Bardales

unread,
Jan 21, 2003, 11:12:22 AM1/21/03
to
Muchas gracias Marino, voy a probar ese componente.
Por cierto, estoy revisando tu página Web, y te
felicito está excelente.

Carlos Bardales

"Marino Posadas" <mpos...@eidos.es> wrote in message news:<#6wkB1NwCHA.2372@TK2MSFTNGP09>...

Tristan

unread,
Jan 21, 2003, 1:51:14 PM1/21/03
to

Solo recuerda que mediante el Script Control, NO podrás ejecutar VB.NET sino
VBScript.

Marino Posadas

unread,
Jan 21, 2003, 5:11:41 PM1/21/03
to

Gracias, he incluido algunas cosas nuevas sobre todo en código fuente, y los
libros sobre .NET en español, así no tengo que mencionar nombres, solamente
la dirección...;)))


--
Saludos cordiales,
Marino Posadas
MCSD, MCT, MSF-P
www.ElAveFenix.net

"Carlos Bardales" <bard...@yahoo.com> wrote in message
news:7948860d.03012...@posting.google.com...

Carlos Bardales

unread,
Jan 21, 2003, 9:50:21 PM1/21/03
to
Vaya, este código es fantástico.

Quedo muy agradecido con Juan Carlos Badiola y con otros miembros
de este foro que me han ayudado, a pesar de ser nuevo en el mismo,
personas como ustedes hacen posible que aprendices como yo,
seamos un poco menos ignorantes.
Muchas gracias.

Ahora, estoy haciendo algunas pruebas para crear una funcion
genérica que utilice este interprete de comandos.

La idea es que a esa función, se le pase el comando que se desea
interpretar, y que la función devuelva el resultado de la ejecución
de dicho comando, como lo hacen las funciones normales.

Ejemplo:
Dim resultado as string
Resultado = EjecutarCmd( "IIF(5=4,'Falso','Verdadero')" )

Pienso que debe de existir alguna forma de devolver dicho valor.

Otra cosa, el interprete al indicarle algo que va entre comillas
simples, lógicamente interpreta que lo que sigue es un co-
mentario, por lo que da un error en tiempo de ejecución.

Perdón Juan Carlos, abusando de tu tiempo, tienes alguna idea
que cómo podría hacerse ?
De nuevo, Gracias mil.

Carlos Bardales,

"Tristan" <jcba...@hotmail.com> wrote in message news:<#AIaUBOwCHA.2292@TK2MSFTNGP10>...


Juan Carlos Badiola

Tristan

unread,
Jan 22, 2003, 10:34:48 AM1/22/03
to
Mira, acabo de crear una clase, con una funcionalidad
similar a ScriptObject, ya que permite evaluar
expresiones, añadir métodos u otro código, compilar y
posteriormente llamar a cualquier método.

Tiene un método shared Eval, de forma que puedes evaluar
en tiempo de ejecución cualquier expresión de forma
simple. Además mediante los miembros de instancia, permite
añadir código, compilarlo, y llamar a los métodos añadidos.

Este es un ejemplo de uso:

MsgBox(Evaluator.Eval("3 + 3").ToString())

Dim evaluador As New Evaluator()

Dim codigo As String = "return a + b"
evaluador.AddFunction("Suma", "a as integer, b as
integer", codigo)
evaluador.Compile()
'Ahora no face falta recompilar para las sucesivas llamadas
'ya que la función tiene parámetros
MsgBox(evaluador.EvalFunction("Suma", 2, 3).ToString())
MsgBox(evaluador.EvalFunction("Suma", 12, 23).ToString())

'Y ahora un procedimiento
codigo = _
"Dim i as Integer" & vbCrLf & _
"For i = 1 to limite" & vbCrLf & _
"MessageBox.Show(i)" & vbCrLf & _
"Next"
evaluador.AddSub("Bucle", "limite as integer", codigo)
evaluador.ImportsList.Add("System.Windows.Forms")
evaluador.References.Add("System.Windows.Forms.dll")
evaluador.Compile()
evaluador.CallSub("Bucle", 7)

Tristan

unread,
Jan 22, 2003, 10:56:03 AM1/22/03
to

Ahhh, se me ha olvidado tu pregunta sobre las comillas:

En VB, para incluir comillas dentro de un string, basta
con poner comillas dobles, el apóstrofe no se puede usar
en su lugar. Es decir:

En lugar de:

Resultado = EjecutarCmd( "IIF(5=4,'Falso','Verdadero')" )

Tendrías que poner:

Resultado =
EjecutarCmd( "IIF(5=4,""Falso"",""Verdadero"")" )

O utilizando mi clase:

Resultado = Evaluator.Eval("IIF
(5=4,""Falso"",""Verdadero"")").ToString()


Tristan

unread,
Jan 22, 2003, 12:16:04 PM1/22/03
to
Por si te interesa la clase anterior, acabo de hacer una
pequeña mejora. La excepción generada en caso de error de
compilación no es genérica, sino personalizada.

Carlos Bardales

unread,
Jan 22, 2003, 7:44:34 PM1/22/03
to
Muchas gracias Juan Carlos, esta clase puede ser de
mucha utilidad en un momento dado. Gracias por tu
esfuerzo.

Saludos
Carlos Bardales

SqlRanger

unread,
Jan 23, 2003, 3:01:29 AM1/23/03
to
Juan Carlos,
 
Esa clase que has hecho me parece genial. ¿ Me das tu permiso para colgarla en mi web para que así siempre esté disponible para todos ?

--
Saludos:
 
Jesús López
MCP SQL Server
 
"No darás tropezón ni desatino
que no te haga adelantar camino"
0 new messages