Ejemplo xbscript

Ejemplo xbscript

Postby Cgallegoa » Fri Sep 13, 2024 10:03 pm

Aquí un ejemplo muy sencillo de lo que se puede hacer con xbscript. El límite es la imaginación, con míminos cambios. El prinicipal, en mi caso, es que he decidido omitir el uso de los comandos, por lo que no se incorporan "includes", pues cada vez que se ejecute un script se van a cargar los includes con el consabido consumo . de memoria. Sin
los includes va puro código preprocesado. Cuando tengo una duda de cómo escribir el código preprocesado, sobre todo el lo relacionado con la parte diseño, Windows, Dialogs, los diferentes controles, etc, lo que hago es un prg nomal sencillo de cómo quiero que quede el control y lo copilo con la opción "-p" o "/p" para que se genere el archivo "ppo". Lo abro y copio código y lo pego tal cual en el script, y ya está, rápido, sencillo y poderoso. Poco a poco se irán convirtiendo en maestros.

Pueden pasar variables, recibir variables, etc. Algunos trucos: No se pueden pasar objetos, o por lo menos no he descubierto cómo, pero yo guardo el objeto en un hash universal y le paso al escript el hash, y todo funciona perfecto. De un script puedo pasar a otro, u otros. Es decir pueden construir una aplicación completa en la que el prg princiapal ( exe ) sólo necesitaría la instrucción que invoque al primer script (Esto exagerando el minimalismo), pero lo he logrado con algunos desarrollo más o menos importantes para algunos clientes. Una vez que se lo entrego, les doy una capacitación y a partir de ahí pueden defenderse sólos. Si necesitan algo más avenzado, me conecto via Skype, o Anydesk, o RDP de Términal Server, etc., le modifico, agrego, cambio o quito código, sin necesidad de compilar, ni instalar herramientas, ni nada. Un simple editor de texto y hago maravillas.

Se necesita incluír el archivo xHarbour\utils\sbscript\xbscript.prg. Creo que es mejor crear una librería con el mismo y linkearla a su aplicación.

Archivo principal "PRUEBA1.PRG" (Será PRUEBA1.EXE)
Code: Select all  Expand view  RUN
#include "fivewin.ch"

REQUEST FW_DemoDB

Function Inicio()
   LOCAL oDlg
   LOCAL FWH_VERSION := FWVERSION
   DEFINE DIALOG oDlg SIZE 290,220 PIXEL TRUEPIXEL TITLE "Genérido para pruebas con script"
       @  20,75 BUTTON "&Ejecutar Script Op. 1" OF oDlg PIXEL SIZE 140,35 ACTION Make_PP_Run("_Script_Pruebas.scr",{"OpenTable"}, {FWH_VERSION})
       @  70,75 BUTTON "&Ejecutar Script Op. 2" OF oDlg PIXEL SIZE 140,35 ACTION Make_PP_Run("_Script_Pruebas.scr",{"MakeDialogo"})
       @ 150,75 BUTTON "&Salir" OF oDlg PIXEL SIZE 120,35 ACTION oDlg:End()
   ACTIVATE DIALOG oDlg CENTERED
Return(NIL)
//-----------------------------------//


Function Make_PP_Run(cElScript, mVar01, mVar02, mVar03, mVar04, mVar05)
   LOCAL oError
   hb_gcAll(.T.)
   TRY
       PP_RUN( cElScript , { mVar01 , mVar02 , mVar03 , mVar04 , mVar05 } )
   CATCH oError
       MSGSTOP( oError:description() + CRLF + CRLF + "Error Ejecución de Sentencia en ....", oDatos:cTitMsg )
       RETURN(NIL)
   END
   hb_gcAll(.T.)
Return(NIL)
//-----------------------------------//
 

Archivo Script "_Script_Pruebas.scr"
Code: Select all  Expand view  RUN
Function inicio(aVars1, aVars2)

   DO CASE
      CASE aVars1[1] == "OpenTable"
         AbreTabla(aVars2)
      CASE aVars1[1] == "MakeDialogo"
         MakeDialogo()
      CASE aVars1[1] == "Otrafuncion"
        // Otrafuncion().....

      OTHERWISE

   ENDCASE

Return(NIL)
//-----------------------------------//

Function AbreTabla(aVars2)
   local oCn
   local oRsState, oRsCity, oRsCust
   local oBrwState, oBrwCity, oBrwCust
   local oDlg, oFont

   MsgInfo( "Versión FWH:  " + aVars2[1] )

   oCn   := FW_DemoDB()

   bAccion := {|| oRsState := oCn:RowSet( "SELECT * FROM states ORDER BY name" ) ,;
                  oRsCity  := oCn:RowSet( "SELECT id, state, city FROM customer ORDER BY state, city" ) ,;
                  oRsCust  := oCn:RowSet( "SELECT id, state, CONCAT_WS( ', ', first, last ) AS Name FROM customer ORDER by state,Name" ) ,;
                  oRsCity:SetFilter( "STATE = ?", { oRsState:code } ) ,;
                  oRsCust:SetFilter( "STATE = ?", { oRsState:code } ) }

   MsgRun( "Reading tables", "Please Wait...", Eval(bAccion) )

   oFont := TFont():New( "Segoe UI", 0, -10,,,,,,,,,,,,,,, .T. )

   oDlg = TDialog():New(,,,, "MARIADB - PARENT WITH TWO CHILD TABLES - Time: " + TTOC(DateTime()),,, .F.,,,,,, .T.,, oFont,, 700, 600, .F.,, "oDlg",, .T., )
   IIF( HB_ISOBJECT( oFont ), oFont:End(), ) ; oFont := nil

   oBrwState := XbrowseNew( oDlg, 20, 20, 300, -20,,,,,,,,,,,, .F., oRsState,, .F.,, .T.,, .F., .F. ,, {"NAME","CODE"},,, .F., .F., .T., .T.,,,,, .F., .T., "oBrwState", )

   WITH OBJECT oBrwState
      :SetGroupHeader( "PARENT", 1, 2 )
      :nStretchCol   := 1
      :lHScroll      := .F.
      :bChange       := {|| ;
                        oRsCity:ReFilter( { oRsState:code } ) ,;
                        oRsCust:ReFilter( { oRsState:code } ) ,;
                        oBrwCity:Refresh() ,;
                        oBrwCust:Refresh() }
      :CreateFromCode()
   END

   oBrwCity := XbrowseNew( oDlg, 20, 300, 400, 260,,,,,,,,,,,, .F., oRsCity,, .F.,, .T.,, .F., .F. ,, {"STATE","CITY"},,, .F., .F., .T., .T.,,,,, .F., .T., "oBrwCity", )

   WITH OBJECT oBrwCity
      :SetGroupHeader( "CHILD-1", 1, 2 )
      :nStretchCol   := 2
      :lHScroll      := .F.
      :CreateFromCode()
   END

   oBrwCust := XbrowseNew( oDlg, 280, 300, 400, -20,,,,,,,,,,,, .F., oRsCust,, .F.,, .T.,, .F., .F. ,, {"STATE","NAME"},,, .F., .F., .T., .T.,,,,, .F., .T., "oBrwCust", )

   WITH OBJECT oBrwCust
      :SetGroupHeader( "CHILD-2", 1, 2 )
      :nStretchCol   := 2
      :lHScroll      := .F.
      :CreateFromCode()
   END

   oDlg:Activate( oDlg:bLClicked, oDlg:bMoved, oDlg:bPainted, .T.,,,, oDlg:bRClicked,,,,, @oDlg, )
   oCn:Close()

return nil
//-----------------------------------//

Function MakeDialogo()
   LOCAL oDlg
   oDlg = TDialog():New(,,,, "Dialogo creado al vuelo",,, .F.,,,,,, .T.,,,, 490, 320, .F.,, "oDlg",, .T., )
       TButton():New( 150, (oDlg:nWidth/2) - 60 , "&Salir", oDlg, {|| oDlg:End()}, 120, 35,,, .F., .T., .F.,, .F.,,, .F.,, .F.,, )
   oDlg:Activate( oDlg:bLClicked, oDlg:bMoved, oDlg:bPainted, .T.,,,, oDlg:bRClicked,,,,, @oDlg, )
Return NIL
//-----------------------------------//
 
Saludos,

Carlos Gallego

*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
Cgallegoa
 
Posts: 494
Joined: Sun Oct 16, 2005 3:32 am
Location: Quito - Ecuador

Re: Ejemplo xbscript

Postby sysctrl2 » Fri Sep 13, 2024 10:26 pm

Carlos que interesante,
pregunto:
1) que tan difícil es convertir una aplicación en este modelo? (una aplicación que ya está en producción en modelo tradicional)
2) pueden convivir código normal con script ?

gracias por compartir tus conocimientos

saludos C.C.C.
Cesar Cortes Cruz
SysCtrl Software
Mexico

' Sin +- FWH es mejor "
User avatar
sysctrl2
 
Posts: 1022
Joined: Mon Feb 05, 2007 7:15 pm

Re: Ejemplo xbscript

Postby Cgallegoa » Sat Sep 14, 2024 7:13 pm

Hola Cesar,

1.- Es muy fácil, pero puede ser tedioso, pues recuerda que dentro de los scripts (así lo he usado durante años sin problemas") no incorporo los archivos include necesarios. Esto significa que la programación via comandos no te va a funcionar, sino la sintaxis de ppo. La razón por la que no agrego los include es que cada vez que llames el script va a cargar el include pero no lo descarga al salir. Entonces, si tienen un proceso que vas a ejecutar 100 veces en el trasncurso del día, "Fivewin.ch" y cualquier otro "include" se va a ir agregando hasta que te revienta la memoria. Si alguien logra descubrir como descargar los includes cuando se salga del script, entonces sería suuuuuuuper fácil, tan simple como copy de tu codigo normal y paste en tus archivos scripts. Caso contrario, hacer la tarea de convertir de comandos a preprocesado. Todos los controles, clases, etc., los encontrarás en la carpeta "INCLUDE" de FWH o revisando los métodos "new" de la clase que quieras usar. Lo primeros días puede ser apabullante, pero luego te acostumbras. Si tengo un diseño conplicado, con muchos controles, que ya tengo funcionando en código normal (comandos), simplemente compilo con "-p" para que me genere el respectivo archivo_codigo.ppo, busco la función donde tengo el diseño, y copy y paste. De esta forma, he logrado convertir algunas aplicaciones medianamente complejas, con un poco de paciencia, con no más de un 10% o 20% de código en archivos fuente incluidos en el ejecutable, y el otro 80 % 90% en archivos abiertos scripts que cualquiera puede modificar, sin requerir nada más que de un simple editor como el Bloc de Notas de microsoft, y por supuesto, el conocimiento para hacerlo.

Me explico con un ejemplo:

Creamos un diálogo o window, o lo que sea, el principio es el mismo, y lo compilamos con la opción "-p" al genera el código xHarbour;
Code: Select all  Expand view  RUN
Function Main()
  LOCAL oDlg
  DEFINE DIALOG oDlg SIZE 300,200 PIXEL TRUEPIXEL TITLE "Prueba script"
     @ 20,20 BTNBMP PROMPT "&Salir" OF oDlg PIXEL SIZE 100,30 ACTION oDlg:End() FLAT
  ACTIVATE DIALOG oDlg CENTERED
Return nil 

Y este es su equivalente preprocesado, tomado del archivo "prueba.ppo" que se genere al momento de compilar con la opción "-p" o "/p"
Code: Select all  Expand view  RUN
Function Main()
  LOCAL oDlg
  oDlg = TDialog():New(,,,, "Prueba script",,, .F.,,,,,, .T.,,,, 300, 200, .F.,, "oDlg",, .T., )
     TBtnBmp():New( 20, 20, 100, 30,,,,, {|Self|oDlg:End()}, oDlg,,, .F., .F., "&Salir",,,, !.F.,, .F.,,, .F.,, !.F.,, .T., .F., .T.,,, .F.,, )
  oDlg:Activate( oDlg:bLClicked, oDlg:bMoved, oDlg:bPainted, .T.,,,, oDlg:bRClicked,,,,, @oDlg, )
Return nil

Espero que esto te haya medio aclarado tus dos pregunta: La conversión es fácil, y si, desde tu código fuente puedes llamar a tus scripts o funciones de tus scripts, y desde éstos puedes llamar funciones de tu código fuente, pasar y recibir variables, etc. La única limitación es lo de los includes, que en resumen lo que hacen es incluir defines propios de cada clase y convertir, usando "command" o "xcommand", código preprocesado en código basado en comandos, para hacer más amigable la escritura del código. Si llegas a necesitar algún "define" en tu script, pues lo agregas y listo.
Saludos,

Carlos Gallego

*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
Cgallegoa
 
Posts: 494
Joined: Sun Oct 16, 2005 3:32 am
Location: Quito - Ecuador


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: cmsoft, Google [Bot] and 69 guests