Ejemplos Power Builder 10.5

Embed Size (px)

Citation preview

EJEMPLOS DE POWER BUILDER 10.5Este documento contiene muchos ejemplos de script sobre el manejo de aplicaciones y proyectos realizados a base de power builder. Si le interesa aprender este lenguaje de programacin este documento posee la mayora cdigos para el desarrollo de sistemas informticos.

Manejo de Power builder 10.5

Ejemplos Power builder 10.51. LLAMADOS A LAS API DE WINDOWS DESDE POWER BUILDERPower Builder al igual que otros lenguajes de programacin, provee la capacidad de extender las posibilidades del lenguaje tomando funcionalidades que pertenecen al sistema operativo o controles de terceras partes. Este proceso es lo que se llama API (Application Programming Interface). Algunas personas incluyen DLLs que han realizado en C o C++, para usarlos en Power Builder. Pero los mas comunes llamados son los que se hacen a las API del sistema operativo, para que el programador acceda directamente a funciones que desde power builder tocara desarrollarlas, y el sistema operativo ya las tiene implementadas. COMO SE HACE EL LLAMADO Los llamados a los API se realizan a travs de la declaracin de funciones externas (External Function), que pueden ser globales o locales. Las Global external function, pueden ser utilizadas en cualquier lugar de la aplicacin y son guardadas con otras variables globales. las Local external function hacen parte de la definicin de una ventana, un men, o un objeto de usuario. Ahora en el bloque de cdigo de la external function, definimos la funcin que deseamos incluir, la cual tiene esta sintaxis: {acceso} FUNCTION tipodedatoqueretorna Nombredelafuncion ({argumentos}) LYBRARY nombredelalibreria {ALIAS FOR nombreexterno} La declaracin de acceso solo es valido para las local external functions donde puede ser Public, Private, y Protected. tipodedatoqueretorna es el tipo de dato que retorna la funcion. Nombredelafuncion es el nombre de la funcin tal como aparece en el archivo DLL. nombredelalibreria es el nombre del archivo DLL donde la funcin se encuentra. ALIAS FOR nombreexterno es un nombre diferente que se le puede dar a la funcin para usarla en el power script. Si por ejemplo usted necesita copiar un archivo de un directorio a otro, usted puede usar una funcin que se encuentra en Kernel32.dll llamada CopyFileA. Esta funcin le permite copiar un archivo de un sito a otro. Entonces en el bloque de instrucciones donde declara las Global External Function, coloca este cdigo (o la definicin de la funcin que necesite segn la tabla): FUNCTION boolean CopyFileA(ref string cfrom, ref string cto, boolean flag) LIBRARY Kernel32.dll Y luego desde el power script de la ventana o el sitio de la aplicacin donde necesite copiar un archivo, hace el llamado a la funcin as: string ls_desde, ls_hasta boolean lb_flag, lb_ rtn lb_flag = false ls_desde = c:prueba.bmp ls_hasta = c:directorio est.bmp lb_rtn = CopyFileA(ls_desde, ls_hasta, lb_flag) Si desea conocer mas profundamente informacin acerca de las funciones disponibles consulte la pagina web de los APIS de Windows (En Ingles).

EJEMPLO DE LLAMADO A UN API DE WINDOWS

1

2. Poner las nuevas filas en otro colorEste truco muestra como cuando se inserta una nueva fila se pone de un color diferente, y asi mismo se muestra como hacer para que las filas nuevas sean editables mientras que las existentes se dejan como solo lectura. Para poner las filas nuevas de un color diferente abra la expresin (expression) del campo de background color coloque la siguiente sentencia if ( IsRowNew(), 1090519039, Long(Describe(Datawindow.Color))) donde 1090519039 es color regular de una ventana Usando la misma idea, se puede hacer que las filas existentes sean de solo lectura y las nuevas sean editables, el codigo siguiente se coloca en la expresin (expression) de Protect: if ( IsRowNew() , 0 , 1 )

3. Rutina para buscar y remplazar un stringEsta Rutina trabaja genericamente para todos los strings. Por ejemplo si OLD_STR = red y NEW_STR = green, todas las ocurrencias de red sern remplazadoas con green. long ll_StartPos = 1 string ls_old_str, ls_new_str, ls_txt_str ls_txt_str = sle_1.Text ls_old_str = red ls_new_str = green // Busca la primera ocurrencia de ls_old_str ... ll_StartPos = Pos(ls_txt_str, ls_old_str, ll_StartPos) // Unicamente entra al loop si uted busca ls_old_str ... DO WHILE ll_StartPos > 0 // Remplaza old_str con ls_new_str ... ls_txt_str = Replace(ls_txt_str, ll_StartPos, Len(ls_old_str), ls_new_str) // Busca la siguiente ocurrencia de ls_old_str ll_StartPos = Pos(ls_txt_str, ls_old_str, ll_StartPos + Len(ls_old_str)) LOOP sle_2.Text = ls_txt_str

4. Funcin para encriptar y desencriptar un stringA continuacin se presenta la funcion of_encrypt que recibe un string y devuelve la cadena encriptada, y la funcion of_decrypt que recibe una cadena encriptada y la desencripta. [function string of_encrypt(as_str)] integer i, j string ls_enctext = CONSTANT string CRYPT_KEY = $#@%%@&* j = len(as_str) FOR i = 1 TO j ls_enctext += mid(CRYPT_KEY , mod(i,10) + 1, 1) ls_enctext += String(Char(255 - Asc(Mid(as_str, i, 1)))) NEXT RETURN ls_enctext [function string of_decrypt(as_str)] integer i, j string ls_encchar, ls_temp, ls_unasstr = ** Encryption Error boolean lb_ok = true CONSTANT string CRYPT_KEY = $#@%%@&*

2

j = len(as_str) IF NOT Mod(j, 2) = 1 THEN ls_temp = FOR i = 2 TO (j + 1) STEP 2 ls_encchar = Mid(as_str, i - 1, 1) IF mid(CRYPT_KEY, Mod(i / 2, 10) + 1, 1) ls_encchar THEN lb_ok = FALSE EXIT END IF ls_encchar = Mid(as_str, i, 1) ls_temp += string(char(255 - asc(ls_encchar))) NEXT END IF IF lb_ok THEN ls_unasstr = ls_temp RETURN ls_unasstr

5. Como agregar animacin a las ventanasESTA API SOLO ESTA DISPONIBLE EN WINDOWS 98 Y 2000. AGREGA LA SIGUIENTE FUNCION EXTERNA: Function boolean AnimateWindow(long lhWnd, long lTm, long lFlags ) library 'user32' DONDE EL PRIMER PARAMETRO ES EL ?HANDLE? DE TU VENTANA, EL SEGUNDO ES EL TIEMPO QUE SE DEBE TOMAR PARA LA ANIMACIN (MAYOR VALOR = MAYOR LENTITUD EN LA ANIMACIN), Y POR ULTIMO EL TIPO DE ANIMACIN QUE DESEAS AGREGAR. PARA LLAMAR LA APLICACIN, AGREGA EL SIGUIENTE CODIGO AL EVENTO OPEN DE TU VENTANA: // Anima la ventana de izquierda a derecha Constant long AW_HOR_POSITIVO = 1 // Anima la ventana de derecha a izquierda Constant long AW_HOR_NEGATIVO = 2 // Anima la ventana de arriba hacia abajo Constant long AW_VER_POSITIVO = 4 // Anima la ventana de abajo hacia arriba Constant long AW_VER_NEGATIVO = 8 // Anima la ventana hacindola que aparezca del centro hacia los lados Constant long AW_CENTRO = 16 // Oculta la ventana Constant long AW_OCULTA = 65536 // Activa la ventana Constant long AW_ACTIVA = 131072 // Usa la animacin de tipo diapositivas Constant long AW_DIAP = 262144 // Usa la animacin con efecto de transparencia Constant long AW_TRANS = 524288 AnimateWindow( Handle( this ), 500, AW_TRANS )

6. Crear una tabla desde PowerScriptCon las siguientes instrucciones usted puede crear una tabla desde power script o hacer un cambio a la tabla con alter table. Debe verificar que el autocommit de la transaccin este en TRUE. SQLCA.AutoCommit = True

3

ls_sql = create table #tmp (abc varchar(255)) EXECUTE IMMEDIATE :ls_sql USING SQLCA; //Para modificar la tabla, use la misma idea: ls_sql = 'ALTER TABLE dba.tbl_name ADD col_name' EXECUTE IMMEDIATE :ls_sql USING SQLCA;

7. Cargar un arreglo con todos los nombres de las columnas de un DWEste truco muestra como hacer para obtener los nombres de las columnas de un datawindow, cargandolas a un arreglo. int colNum, numCols string colName[] numCols = Integer(dw_control.Describe(Datawindow.Column.Count)) FOR colNum = 1 TO numCols // Toma el nombre de la columna con describe colName[colNum] = dw_control.Describe(# + String(colNum) + .name) NEXT

8. Como saber cuales dlls usa mi aplicacin?Bueno lo que debes hacer es correr tu aplicacion desde el ejecutable (aplicacion.exe), debes tener cerrado Power builder, y todas las aplicaciones, vas a inicio / ejecutar y buscas el lugar donde esta el ejecuble y lo corres. Ya cuando tu aplicacion este corriendo vas a inicio / ejecutar y escribes msinfo32.exe, este es un utilitario que tiene windows 98, o si usas Office el tambien lo trae. Este es un programa de informacion del sistema que te muestra los programas y dlls que usas actualmente. Ahi entra a entorno de software, modulos de 32 bits cargados, en la parte derecha te va a mostrar un listado de dlls del sistema que corren actualmente, para saber cuales con los que usa tu aplicacion busca los que el fabricante es Sybase Inc y empiezan por PB*.dll. Ahi encontraras los dlls. Ademas de esos hay uno dll que no tine fabricante pero es de sybase tambien que es uno llamado libjcc.dll, ahi podras ver el .pbd o .dll de las librerias de tu aplicacion y el .exe de la aplicacion, obviamente estos tambien hacen parte de la aplicacion. Anota todos estos archivos, y luego crea una carpeta y copia todos estos archivos dentro de la carpeta. Esta carpeta es la que debes llevar al equipo donde vas a poner a correr la aplicacin. Y con esto ya debe correr la aplicacion en el equipo que no tine PB.

9. Sobrecarga del MessageboxMuchas veces se usa la funcin messagebox para mostrar el valor de una variable. Powerbuilder trae la funcin messagebox() sobrecargada para que usted pueda llamarla con cualquier tipo de dato. Normalmente la funcin tiene estos parmetros MessageBox ( titulo, texto {, icono {, botn {, default } } } ) Donde los parmetros obligatorios titulo y texto son de tipo string. Esto hace que por ejemplo para mostrar una variable de tipo entero se realice esta conversin Int li_numero li_numero = 2 messagebox(?titulo mensaje?,string(li_numero)) Con la sobrecarga que tiene esta funcin usted puede hacer esto Int li_numero li_numero = 2 messagebox(?titulo mensaje?, li_numero) obteniendo el mismo resultado

10. Tomar el numero de filas seleccionas en un DW

4

Algunas veces es necesario contar cuantas filas se han seleccionado en un datawindow. Para esto se puede usar la siguiente expresin. long ll_Selected ll_Selected = long(dw_1.describe(evaluate('sum( if(IsSelected(), 1, 0) for all)',1)))

11. Pasar el contenido de un datawindow a otra ventanaLuego de tener un datawindow con informacin es posible pasar esos mismos datos a otra ventana para no tener que volver a hacer el retrieve y ahorrar un acceso a la base de datos. Se llama a la segunda ventana y se pasa por referencia el datawindow asi: OpenWithParm( w_window, dw_1 ) En el evento open de w_window digita: datastore lds_parm lds_parm = Message.PowerObjectParm dw_1.DataObject = lds_parm.DataObject lds_parm.ShareData(dw_1) Y en el evento close coloca: dw_1.ShareDataOff()

12. Crear un Datawindow DinmicamenteEste es un ejemplo de como crear un datawindow desde una instruccin select que se tiene. Es muy ltil y muy prctico el ejemplo string ls_select string ls_where string ls_dwsyntax string ls_err ls_select = Select id, fname, lname, address, city, state, zip from customer ls_where = where customer.fname like ' + is_cust + %' ls_dwsyntax = SQLCA.SyntaxFromSQL ( ls_select, Style(Type=grid), ls_err ) dw_1.Create ( ls_dwsyntax, ls_err ) IF ls_err '' THEN MessageBox ( error - Syntax, ls_err ) ELSE dw_1.SetTransObject ( SQLCA ) dw_1.Retrieve() END IF

13. Crear o modificar una TablaComo crear una tabla o modificar una tabla desde el power script. Usa la sentencia EXECUTE IMMEDIATE. Coloca el AutoCommit a TRUE porque el DDL SQL tiene que ejecutarse fuera de la transaccin. SQLCA.AutoCommit = True ls_sql = create table #tmp (abc varchar(255)) EXECUTE IMMEDIATE :ls_sql USING SQLCA; Para modificar una tabla se usa la misma idea: ls_sql = 'ALTER TABLE dba.tbl_name ADD col_name' EXECUTE IMMEDIATE :ls_sql USING SQLCA;

14. Datawindows con colores alternosEn los datawindows en Grid y columnas es posible hacer aparecer las filas con 2 colores alternos. Es decir se puede hacer que una fila aparezca azul y otra amarilla, una azul una amarilla.. y asi para todas las filas. Para altenar el color de las filas de un datawindow haga lo siguiente. Abra el objeto datawindow y seleccione todos las columnas. Luego abra la expresin (expression) del campo de background color coloque la siguiente sentencia

5

if ( mod(getrow(),2) = 0, color1, color2 ) Donde color1 y color 2 los puede cambiar por sus colores favoritos asi: if ( mod(getrow(),2) = 0, RGB(159,166,213), RGB(232,218,140) )

15. Pasar de un campo a otro con ENTERMuchos programadores, han encontrado la necesidad de pasar de un campo a otro del datawindow con Enter. Para esto se debe hacer un pequeo truco pero efectivo que a continuacion te lo enseamos. En el datawindow se define un evento de usuario con un nombre cualquiera y que se inicie cuando opriman enter, para eso seleccione el event ID pbm_dwnprocessenter. Luego como el evento se dispara cuando oprimen el enter, lo que se hace es enviar un tab en ese evento. El codigo que debe tener el evento de usuario que creamos es el siguiente Send(Handle(this),256,9,Long(0,0)) Con este codigo se pasa de un campo a otro del datawindow con el enter y con tab.

16. Split con powerbuilderHola comunidad... espero que a alguien le sirva este tip. es un split osea guardar datos en una array utilizando un delimitador. is_estado_credito = sle_nodo.Text + , String ls_array[ ] String ls_Right long ll_p, ll_contador, ll_i ls_Right = Right(is_estado_credito, 2) ll_p = Pos(is_estado_credito, ) if ls_Right ,, and ll_p = 0 then ll_i = 1 do while ll_contador = 0 ll_p = Pos(is_estado_credito, ,) if ll_p > 0 then ls_array[ll_i] = Mid(is_estado_credito, 1, ll_p - 1) is_estado_credito = Replace(is_estado_credito, 1, ll_p, ) ll_i = ll_i + 1 else ll_contador = 1 end if loop elseif ll_p > 0 then messagebox(,Error: Hay algun espacio en los nodos digitados) else messagebox(,Error: Verifique los nodos digitados) end if dw_split.Retrieve(ls_array)

17. Bloquear la Estacin de TrabajoA continuacin describimos como puede bloquear la estacin (en windows 2000 o XP) para proteger el equipo de usuarios no autorizados. Esto se hace utilizando el llamado de un API de windows as: Defina en [Global External Functions] la funcin asi: FUNCTION boolean LockWorkStation() LIBRARY User32.dll Luego para bloquear la consola llame la funcin as: LockWorkStation()

6

18. programando en visual studio.net como en powerbuilderdespues de instalar el datawindow.net en visual studio.net tienes que instanciar el objeto sqlca para que puedas trabajar de la misma forma como lo haces en porwerbuilder es decir tengas el mismo codigo ''dw_1.settransobject(sqlca)'' el codigo es el siguiente y lo haces en el evento load de la ventana o lo puedes declarar como instancia global finalmente agregas el datawindow a la ventana desde el cuadro de componenetes sybase, el datawindow puede estar construido en powerbuilder 10 o datawindow builder Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim SQLCA As New Sybase.DataWindow.Transaction SQLCA.Dbms = Sybase.DataWindow.DbmsType.Odbc SQLCA.AutoCommit = False SQLCA.DbParameter = ConnectString='DSN=base_cyber;UID=dba;PWD=sql' SQLCA.Connect() dw_1.settransobject(sqlca) End Sub

19. Numero de linea en datawindow con varios groupCuando tenemos un datawindow tabular (tipico reporte) nos vemos en la necesidad de poner un numero de linea... el mismo que debe reiniciarce al comenzar otro grupo ...si usamos un campo computado con getrow() nunca se reiniciara... Cuando tenemos un datawindow tabular (tipico reporte) nos vemos en la necesidad de poner un numero de linea... el mismo que debe reiniciarce al comenzar otro grupo ...si usamos un campo computado con getrow() nunca se reiniciara...lo que debemos hacer es crear un campo computado y usar la funcion *****ulativesum(1 for group n) el valor n correspone al grupo el cual querramos que se reinicie.... funciona se los aseguro.... da un mejor aspecto a los reportes...... suerte amigos..

20. Uso objeto MDIUso objeto MDIclient Trate de crear una IDE casi similar a Power Builder 9.0 en una aplicacin, en la cual el workspace de la aplicacion se pudiese dividir o acomodar, para dar cabida a otras ventanas, como sucede con la ventana del workspace de Power Builder 8 / 10, encontre el objeto mdiclient. Este es el encargado de dimensionar realmente el workspace de la aplicacion, no posee eventos, pero si unas funciones y propiedades para su naturaleza. Es referenciado asi: w_ventanamdi.mdi_1.propiedad Aqui muestro un ejemplo muy practico. En la ventana tipo mdi, inserto un objeto de usuario uo_1, que siempre debe estar mostrado, sobre las ventanas hijas de la aplicacion, en la parte inferior justo antes de la barra de estado. Lo hago de la siguiente manera: // w_main - ventana tipo mdi // uo_1 objeto de usuario, que tambien puede //ser una ventana u otro tipo de objeto visual. En el evento resize de w_main escrito el siguiente codigo: int nWidth, nHeight nWidth = this.WorkSpaceWidth( ) nHeight = this.WorkSpaceHeight( ) mdi_1.move(0,110) // muevo el mdi_client

7

//debajo de la barra de herramientas mdi_1.Resize (nWidth, nHeight - 200 ) //resto 200 para dar espacio a mi uo_1 // en la parte inferior de la ventana uo_1.move(0, mdi_1.height + 110 ) // muevo uo_1 hacia la parte inferior del workspace Espero les sirva en sus proyectos.

21. Modificar el Where de una datawindowEste trozo de codigo sirve para concaternar un trozo de WHERE a un SELECT ya realizado en este caso con sintaxis de ORACLE. Es util para realizar ventanas de filtro que solicitan una serie de condiciones que se recogen en un evento aceptar para montar un trozo de where del tipo: 'importe > 100 and importe k) or (j = 0) li_pos = Pos (ls_select, 'WHERE ',k) IF (li_pos > 0) THEN ls_select = MID (as_select, 1, li_pos - 1) ls_where = 'WHERE (' + as_where + ') AND ' + MID (as_select, li_pos + 6) goto fin END IF li_pos = Pos (ls_select, 'GROUP BY') IF (li_pos > 0) THEN ls_select = MID (as_select, 1, li_pos - 1) ls_where = 'WHERE (' + as_where + ') ' + MID (as_select, li_pos) goto fin END IF li_pos = Pos (ls_select, 'ORDER BY') IF (li_pos > 0) THEN ls_select = MID (as_select, 1, li_pos - 1) ls_where = 'WHERE (' + as_where + ') ' + MID (as_select, li_pos) goto fin END IF ls_select = as_select ls_where = ' WHERE (' + as_where + ') ' fin: return ls_select + ls_where

22. De Nmeros a Letras FINAL y bien hecho>>>Estoy cansado de bajar todos los programas que pusieron alli para convertir de numeros a letras, me dio tanta colera que ninguno funcionara bien que lo hice casi todo nuevo, OK, no me preocupa la lgica, ni lo dinmico que lo hayan tratado de hacer antes, yo lo hice que funcione perfectamente bien, SIN ERRORES.. no estoy diciendo que sea la super logica pero funciona mejor que cualquiera de los que estaban alli pues considera muchas circunstancias no contempladas antes...// //simplemente creen una ventana, agregar un sle_1 y un boton, alargar el sle_1 para que le quepa bastante ggg, luego ponen el siguiente script en el boton. lo corren y pongan el siguiente numero exactamente como yo lop pongo aqui... >>> 9842416527852.32 sin comas OK

8

luego precionan el boton y vern //**************************script String ls_unidades[], ls_decenas[], ls_centenas[] string ls_valor1[] = {' mil ', ' millones ', ' billones '} string ls_valor2[] = {' mil ', ' milln ', ' billn '} String ls_decimal Integer li_len, i string oracion_hasta_aqui ls_unidades[1] = 'un' ls_unidades[2] = 'dos' ls_unidades[3] = 'tres' ls_unidades[4] = 'cuatro' ls_unidades[5] = 'cinco' ls_unidades[6] = 'seis' ls_unidades[7] = 'siete' ls_unidades[8] = 'ocho' ls_unidades[9] = 'nueve' ls_unidades[10] = 'diez' ls_unidades[11] = 'once' ls_unidades[12] = 'doce' ls_unidades[13] = 'trece' ls_unidades[14] = 'catorce' ls_unidades[15] = 'quince' ls_unidades[16] = 'dieciseis' ls_unidades[17] = 'diecisiete' ls_unidades[18] = 'dieciocho' ls_unidades[19] = 'diecinueve' ls_unidades[20] = 'veinte' ls_unidades[21] = 'veintiun' ls_unidades[22] = 'veintidos' ls_unidades[23] = 'veintitres' ls_unidades[24] = 'veinticuatro' ls_unidades[25] = 'veinticinco' ls_unidades[26] = 'veintiseis' ls_unidades[27] = 'veintisiete' ls_unidades[28] = 'veintiocho' ls_unidades[29] = 'veintinueve' ls_decenas[3] = 'treinta' ls_decenas[4] = 'cuarenta' ls_decenas[5] = 'cincuenta' ls_decenas[6] = 'sesenta' ls_decenas[7] = 'setenta' ls_decenas[8] = 'ochenta' ls_decenas[9] = 'noventa' ls_centenas[1] = 'ciento' ls_centenas[2] = 'doscientos' ls_centenas[3] = 'trescientos' ls_centenas[4] = 'cuatrocientos' ls_centenas[5] = 'quinientos' ls_centenas[6] = 'seiscientos' ls_centenas[7] = 'setecientos'

9

ls_centenas[8] = 'ochocientos' ls_centenas[9] = 'novecientos' STRING cadena_total, cadena_entera, oracion, parte, caso_0, caso_1, caso_2, concatena1, envio1, caso_3, caso_4, envio4, concatena4, envio3, & caso_5, caso_6, concatena7, caso_7, envio6, caso_8, envio9, caso_9, concatena10, caso_10, para10, valor9, caso_11, caso_12, dos_decimales long deci_punto, li_i double parte1, parte0, parte3, parte4, parte7, parte6, parte9, parte10 cadena_total = sle_1.text deci_punto = pos(cadena_total,.) cadena_entera = left(cadena_total,deci_punto - 1) dos_decimales = right(cadena_total,2) for li_i = li_i to len(cadena_entera) -1 parte = mid(cadena_entera,len(cadena_entera) - li_i, 1 ) choose case li_i case 0 caso_0 = ls_unidades[(double(parte))] parte0 = (double(parte)) oracion_hasta_aqui = ls_unidades[(double(parte))] case 1 if ls_unidades[(double(parte))] = un or ls_unidades[(double(parte))] = dos then envio1 = ls_unidades[(double(parte))] parte1 = (double(parte)) concatena1 = string(parte1)+ string(parte0) caso_1 = ls_unidades[(double(concatena1) ) ] oracion_hasta_aqui = caso_1 else caso_1 = ls_decenas[(double(parte))] + y oracion_hasta_aqui = caso_1 + caso_0 end if case 2 caso_2 = ls_centenas[(double(parte))] if envio1 = un or envio1 = dos then oracion_hasta_aqui = caso_2 + + caso_1 else oracion_hasta_aqui = caso_2 + + caso_1 + caso_0 end if case 3 parte3 = (double(parte)) envio3 = ls_unidades[(double(parte))] if ls_unidades[(double(parte))] = un then caso_3 = ls_valor1[1] else caso_3 = ls_unidades[(double(parte))] + ls_valor1[1] end if if envio1 = un or ls_unidades[(double(parte))] = dos then oracion_hasta_aqui = caso_3 + + caso_2 + + caso_1 else oracion_hasta_aqui = caso_3 + +caso_2 + + caso_1 + caso_0 end if case 4

10

if ls_unidades[(double(parte))] = un or ls_unidades[(double(parte))] = dos then parte4 = (double(parte)) concatena4 = string(parte4)+ string(parte3) caso_4 = ls_unidades[(double(concatena4) ) ] if envio1 = un or envio1 = dos then oracion_hasta_aqui = caso_4 + +ls_valor1[1] + + caso_2 + + caso_1 else oracion_hasta_aqui = caso_4 + +ls_valor1[1] + + caso_2 + + caso_1 + + caso_0 end if else caso_4 = ls_decenas[(double(parte))] + y if envio1 = un or envio1 = dos then if envio3 = un then oracion_hasta_aqui = caso_4 + +envio3+ +ls_valor1[1] + + caso_2 + + caso_1 else oracion_hasta_aqui = caso_4 + +envio3+ +ls_valor1[1] + + caso_2 + + caso_1 end if else if envio3 = un then oracion_hasta_aqui = caso_4 + + envio3 + +caso_3 + +caso_2 + +caso_1 + + caso_0 else oracion_hasta_aqui = caso_4 + +caso_3 + +caso_2 + +caso_1 + + caso_0 end if end if end if case 5 caso_5 = ls_centenas[(double(parte))] oracion_hasta_aqui = caso_5 + + oracion_hasta_aqui case 6 parte6 = (double(parte)) if ls_unidades[(double(parte))] = un then caso_6 = ls_unidades[(double(parte))] + ls_valor2[2] else caso_6 = ls_unidades[(double(parte))] + ls_valor1[2] end if envio6 = oracion_hasta_aqui oracion_hasta_aqui = caso_6 + + oracion_hasta_aqui case 7 if ls_unidades[(double(parte))] = un or ls_unidades[(double(parte))] = dos then parte7 = (double(parte)) concatena7 = string(parte7)+ string(parte6) caso_7 = ls_unidades[(double(concatena7) ) ] oracion_hasta_aqui = caso_7 + + ls_valor1[2] +envio6 else caso_7 = ls_decenas[(double(parte))] + y oracion_hasta_aqui = caso_7 + oracion_hasta_aqui end if case 8 caso_8 = ls_centenas[(double(parte))]

11

oracion_hasta_aqui = caso_8 + + oracion_hasta_aqui case 9 parte9 = (double(parte)) if ls_unidades[(double(parte))] = un then para10 = si caso_9 = ls_valor1[1] valor9 = ls_unidades[(double(parte))] else caso_9 = ls_unidades[(double(parte))] + ls_valor1[1] end if envio9 = oracion_hasta_aqui oracion_hasta_aqui = caso_9 + + oracion_hasta_aqui case 10 if ls_unidades[(double(parte))] = un or ls_unidades[(double(parte))] = dos then parte10 = (double(parte)) concatena10 = string(parte10)+ string(parte9) caso_10 = ls_unidades[(double(concatena10) ) ] oracion_hasta_aqui = caso_10+ + ls_valor1[1] +envio9 else if para10 = si then caso_10 = ls_decenas[(double(parte))] + y + valor9 oracion_hasta_aqui = caso_10 + oracion_hasta_aqui else caso_10 = ls_decenas[(double(parte))] + y oracion_hasta_aqui = caso_10 + oracion_hasta_aqui end if end if case 11 caso_11 = ls_centenas[(double(parte))] oracion_hasta_aqui = caso_11 + + oracion_hasta_aqui case 12 if ls_unidades[(double(parte))] = un then caso_12 = ls_unidades[(double(parte))] + ls_valor2[3] oracion_hasta_aqui = caso_12 + oracion_hasta_aqui else caso_12 = ls_unidades[(double(parte))] + ls_valor1[3] oracion_hasta_aqui = caso_12 + oracion_hasta_aqui end if end choose next messagebox(tome chichi, oracion_hasta_aqui + +con + + dos_decimales + /100)

23. Equivalencias en el PowerScriptCuando empezamos a utilizar el PowerScrip, entendemos que existen propiedades y funciones predefinidas, creemos que es bueno saber algunas equivalencias en los scrip para mejorar nuestra forma de programar y llevarlo mas a objetos. Ejemplo: Para la asignacin de la propiedad visible de los objetos. cb_1.visible = false; cb_1.visible = true;

12

Equivale escribir Cb_1.hide(); Cb_1.show(); Para la asignacin de la funcin Move(x,y); Cb_1.x = 100; Cb_1.Y = 200; Equivale escribir Cb_1.move(100,200); Para la asignacin de la funcin resize ( widht, height ); Cb_1.widht = 450; Cb_1.height = 500; Equivale escribir Cb_1.resize(450,500); Para la asignacin de valores a las variables b = b+1 equivale b++ b=b-1 Equivale b-b=b+3 equivale b+=3 NOT b AND NOT c equivale NOT(b or c) En caso de utilizar SQL. String ls_apellidos, ls_nombres; SELECT apaterno, nombre INTO :ls_apellidos, :ls_nombres FROM tpersonal WHERE dni=40284874; sle_1.text = ls_apellidos; sle_2.text= ls_nombres; Equivale escribir: SELECT apaterno, nombre INTO :sle_1.text, :sle_2.text FROM tpersonal WHERE dni=40284874; Para la asignaciones de valores en el control datawindow Dw_1.object.nombre[dw_1.getrow()] =RONY; Equivale escribir Dw_1.setitem(dw_1.getrow(),nombre,RONY); //a diferencia del object, en esta sentencia puedo utilizar variables en la asignacin de campos,

24. Ordenar en un dw grid,tabular con click en el titulo de la columnaPara ordenar la informacion de un datawindow con solo hacer click sobre la columna o varias columnas con la combinacion de control + click se debe hacer lo siguiente. Para que funcione adecuadamente los titulos de los campos de un datawindow deben finalizar en _t

13

Ejemplo titulo: campo_t detalle : campo String ls_band, ls_name long ll_temp, i ls_band = this.GetBandAtPointer() ls_name = dwo.Name ls_name = Left(ls_name, Len(ls_name) - 2) // Verifico si dio el click en la cabecera if mid(ls_band,1,pos(ls_band,~t) - 1) = 'header' then // Verifico si es una columna if this.describe(ls_name + .ID) '!' then // Si es una columna pregunto ahora si tiene presionada la tecla de control if pos(is_sort, is_pre_sort) = 0 then if keydown( KeyControl! ) then // En el caso de que tuviese presionada la tecla de control se siguen sumando las columnas // seleccionadas con click if pos(is_sort, ls_name) = 0 then if is_sort then is_sort += , is_sort += ls_name + A else if pos(is_sort, ,) = 0 then is_sort = else if pos(is_sort, ls_name) = 1 then is_sort = replace(is_sort, pos(is_sort, ls_name), len(ls_name) + 4, ) else is_sort = replace(is_sort, pos(is_sort, ls_name) - 2, len(ls_name) + 4, ) end if end if end if else is_sort = This.SetSort(is_pre_sort + ls_name + A) This.Sort() This.GroupCalc() end if end if end if end if

25. Bloquear la rueda del mouse para evitar el zoom en una DWHace pocos das me percat que al estar posicionado en una DW y mover la rueda del mouse (esa que se usa para hacer scroll) junto con tener presionada la tecla control se hace zoom sobre la dw. Para evitar que esto suceda se agrega el siguiente cdigo en el evento other de la DW : CONSTANT integer WM_MOUSEWHEEL = 522 IF message.number = WM_MOUSEWHEEL AND KeyDown (KeyControl!) THEN message.processed = TRUE RETURN 1

14

END IF Esta solucin no la invent yo...es un dato de un amigo. Espero que les sirva.

26. Capturar los Nombres del Menu con el objeto MENUIDCuando nosotros trabajamos nuestra aplicacin, queremos dar permisos y restricciones a los usuario de la aplicacin y, los menus juegan un papel muy importante en el acceso a la interfaz de nuestra aplicacin. El siguiente ejemplo, muestra una idea sobre como podemos trabajar con las propiedades del Menu al que hace referencia nuestra ventana. En este caso capturaremos los nombres del menu, y submenu en los niveles 1 y 2. Para este ejemplo utilizaremos lo siguiente: La Propiedad de tu ventana contenga un menu en la propiedad MenuName; cb_nombres; //--------------------------------------------event cliked() //------------------------------------------// declaramos variables int li_totalitem[],li_a,li_b; string ls_name; //obtenemos la dimensin del item en nivel 1 li_totalitem[1] = upperbound (menuid.item); for li_a = 1 to li_totalitem[1] ls_name = ls_name + menuid.item[li_a].classname()+char(13) ; //obtenemos la dimensin del item en nivel 2 li_totalitem[2] = upperbound (menuid.item[li_a].item); ls_name = ls_name +( For li_b = 1 to li_totalitem[2] ls_name = ls_name + menuid.item[li_a].item[li_b].classname()+| ; //PUDES SEGUIR AGREGANDO HASTA EL NIVEL DE SUBMENU QUE TIENES next; ls_name =ls_name +)+CHAR(13); next; //visualizamos los nombres del menu MESSAGEBOX(mis_menus,ls_name);

27. Cambiar la fecha del ComputadorPara cambiar la fecha del computador es necesario utilizar un API de windows. La definicion seria la siguiente [declaracion de la local external function ] FUNCTION long SetLocalTime(ref str_systemtime lpSystemTime ) LIBRARY kernel32.dll Ademas se debe declarar una estructura de la siguiente manera [Definicion de la estructura str_systemtime] year uint month uint dayweek uint day uint hour uint min uint sec uint

15

millsec uint [evento clicked del boton] str_systemtime lstr_systemtime lstr_systemtime.year = 1999 lstr_systemtime.month = 1 // January = 1 and so on. lstr_systemtime.dayweek = 0 // not used lstr_systemtime.day = 3 lstr_systemtime.hour = 12 lstr_systemtime.min = 0 lstr_systemtime.sec = 0 lstr_systemtime.millsec = 0 SetLocalTime(lstr_systemtime)

28. Busqueda en un DWCdigo que permite hacer una busqueda en un DW tipo grid. Se ubica en la fila donde esta el dato buscado. El secreto esta en colocar los nombres de los titulos de las columnas del DW grid con el mismo nombre del campo adcionandole _t al final. Ejemplo: columna codigo, titulo codigo_t. En la propiedad text del titulo de la columna colocas Cdigo. Esta palabra ser la que se vea en la lista de campos a buscar Espero sea claro. /////////////////////////////////////////////////////////////////////////////////////////////////// // Nombre Programa :OPEN DE LA VENTANA DE BUSQUEDA // Fecha / Autor : ABAD // Descripcin: CARGA LOS DATOS DE LAS COLUMNAS DEL DATAWINDOWS ACTUAL ////////////////////////////////////////////////////////////////////////////////////////////////// // VARIABLES integer li_columnas, li_i, li_pos string ls_nombrecolumna, ls_name // //cargar las columnas del dw existente li_columnas = integer(w_mantenimiento.dw_1.Object.DataWindow.Column.Count) for li_i = 1 TO li_columnas w_mantenimiento.dw_1.setcolumn(li_i) ls_nombrecolumna = w_mantenimiento.dw_1.getcolumnname() ls_name = w_mantenimiento.dw_1.DESCRIBE(ls_nombrecolumna+_t.text) ls_name = ls_name +space(100)+*+ls_nombrecolumna ddlb_1.Additem(ls_name) NEXT sle_1.setfocus() dw_1.settransobject(sqlca) si_fila = 0 EVENTO CLIC DEL BOTON BUSCAR /////////////////////////////////////////////////////////////////////////////////////////////////// // // Nombre Programa :BUSCAR DATOS EN EL DATAWINDOW POR COLUMNA AL HACER CLIC EN ESTE BOTON // Fecha / Autor : ABAD

16

// // Descripcin: SE UBICA EN LA FILA DEL DATO BUSCADO // // Valor que Retorna : ninguno // ////////////////////////////////////////////////////////////////////////////////////////////////// // VARIABLES string ls_sql, ls_where, ls_columna, ls_buscar, ls_Dato, ls_dw integer li_pos, li_i // ls_sql = ddlb_1.text ls_dato = TRIM(sle_1.text) IF len(ls_dato) 0 THEN ls_dw = mid(ls_dw, 1, li_pos - 1) END IF // // adicionar al script del select el where de acuerdo a la columna // con el codigo a buscar ls_dw = ls_dw + WHERE +w_mantenimiento.dw_1.DESCRIBE(ls_columna+.dddw.datacolumn) + = '+ls_sql+' dw_1.setsqlselect(ls_dw) IF dw_1.retrieve() > 0 THEN ls_sql = TRIM(dw_1.getitemstring(1, w_mantenimiento.dw_1.DESCRIBE(ls_columna+.dddw.displaycolumn))) IF ls_sql = ls_dato THEN w_mantenimiento.dw_1.SelectRow(si_antselec, FAlSE) w_mantenimiento.dw_1.SelectRow(li_i, TRUE) w_mantenimiento.dw_1.scrolltorow(li_i) w_mantenimiento.dw_1.setrowfocusindicator(FocusRect! ,0,0) li_pos = li_i li_i = w_mantenimiento.dw_1.rowcount() END IF END IF NEXT ELSE w_mantenimiento.dw_1.setcolumn(ls_columna) //verificar si el valor es un numero ls_sql = ddlb_1.text IF pos(ls_sql, Valor, 1) > 0 THEN //es numerico ls_buscar = ls_columna + = +trim(sle_1.text)+ ELSE ls_buscar = ls_columna + = '+trim(sle_1.text)+' END IF li_pos = w_mantenimiento.dw_1.find(ls_buscar, 1, w_mantenimiento.dw_1.rowcount() ) IF li_pos > 0 THEN si_fila = li_pos w_mantenimiento.dw_1.SelectRow(si_antselec, FAlSE) w_mantenimiento.dw_1.SelectRow(li_pos, TRUE) w_mantenimiento.dw_1.scrolltorow(li_pos) w_mantenimiento.dw_1.setrowfocusindicator(FocusRect! ,0,0)

17

ELSE si_fila = 0 END IF END IF END IF END IF si_antselec = li_pos EVENTO CLIC DEL BOTON SIGUIENTE /////////////////////////////////////////////////////////////////////////////////////////////////// // Nombre Programa :BUSCAR DATOS EN EL DATAWINDOW POR COLUMNA AL HACER CLIC EN ESTE BOTON // DESDE LA FILA ACTUAL // Fecha / Autor : ABAD // Descripcin: SE UBICA EN LA FILA DEL DATO BUSCADO ////////////////////////////////////////////////////////////////////////////////////////////////// si_fila = w_mantenimiento.dw_1.getrow() IF si_fila = w_mantenimiento.dw_1.rowcount() THEN si_fila = 0 END IF cb_1.triggerevent(clicked!)

29. moverse por las columnas de datawindow usando enterMuchas veces el usuario necesita ingresar informacion en el menor tiempo de pulsaciones sin hacer uso del mouse, para lo cual es necesario hacer uso solo del teclado. Debera crear un evento: pbm_dwnprocessenter en el datawindow el cual contenga el siguiente codigo: this.setcolumn(this.getcolumn()+1) con esto podra moverse entre las columnas, sin necesidad de usar el mouse.

30. ORDENAR UNA DATAWINDOW EN TIEMPO DE EJECUCIONEl siguiente cdigo permite que una datawindow del tipo grid/tabular, sea ordenada ascendente/descendente, por una columna en particular a voluntad del usuario, clickeando en la cabecera de la columna. Declarar en la ventana madre, las siguientes variables de instancia: string is_name boolean ib_activa En el evento clicked de la datawindow, el siguiente cdigo: string ls_Mod if dwo.type = text then is_name = dwo.Name is_name = Left(is_name, Len(is_name) - 2) if ib_activa then ib_activa = false This.SetSort(is_name + , A) else This.SetSort(is_name + D) ib_activa = true end if this.Sort() this.SetRedraw( true ) end if

18

31. como Utilizar la Funcion Setfilter y Filter del Control DatawindowEl control datawindow posee estas dos funciones para filtrar la informacin despus de la recuperacin con la funcin retrieve(). En otras palabras las funciones de filtrado trabaja en base a los datos ya ledos desde la base de datos; estas dos funciones van de la mano y trabajan de la siguiente manera. Setfilter :_Esta funcin posee la misma sintaxis despus de la clusula WHERE de los comandos SQL. Filter :_ ejecuta la sentencia almacenada en la funcion Setfilter. Para este ejemplo se esta utilizando la siguiente tabla |--------------------------|ttrabajador |--------------------------|idtrabajador (CHAR(20) |apaterno (CHAR(30) |amateno (CHAR(30) |nombres (CHAR(50) |--------------------------y los siguientes controles en nuestra aplicacin cb_filtrar dw_trabajador //----------------cb_filtrar------------------------------event clicked //---------------------------------------------------------//declaramos las variables string ls_setfilter; //asignamos los parmetros de filtrado a la variable ls_setfilter = apaterno=CHATA and nombres=RONY; //utilizamos la funcion setfilter con los parametros de la variable ls_setfilter dw_trabajador.setfilter(ls_setfilter); //ejecutamos el filtrado dw_trabajador.filter();

32. Recuperar datos GetitemString

del

Control

Datawindow

con

la

funciones

Este ejemplo es practico para la recuperacin de la informacin que contiene nuestro control datawindow, quiero hacer mencin que la recuperacin que realiza esta funcin es solo para los campos de tipo caracater, pero descuiden que exiten otras funciones para la recuperacin de los distintos tipos de datos como (getitemdate, getitemdecimal, getitemnumber...) y la sintaxis es similar a esta. Para este ejemplo se esta utilizando la siguiente tabla |--------------------------|ttrabajador |--------------------------|idtrabajador (CHAR(20) |apaterno (CHAR(30) |amateno (CHAR(30) |nombres (CHAR(50) |--------------------------y los siguientes controles en nuestra aplicacin cb_extrae

19

dw_trabajador //----------------cb_extrae----------------------------------------------event clicked //-------------------------------------------------------------------------//declaramos las variables integer li_row; string ls_apaterno, ls_amaterno, ls_nombres; // ubicamos el registro activo del control datawindow li_row = dw_trabajador.getrow(); //recuperamos los datos desde el buffer del datawindow ls_apaterno = dw_trabajador.getitemstring(li_row,apaterno); //recuperamos el apellido paterno ls_amaterno = dw_trabajador.getitemstring(li_row,amaterno); //recuperamos el apellido materno ls_nombres = dw_trabajador.getitemstring(li_row,nombres); //recuperamos los nombres //visualizamos la informacin recuperada messagebox(trabajador, ls_apaterno+ +ls_amaterno+, +ls_nombres );

33. Abrir Fichero con su programa asociadoEste cdigo te solicita el programa asociado para abrir el fichero deseado (probado en XP) function integer gf_open_fichero (string as_fichero); IF FileExists (as_fichero) THEN Run ('rundll32 shell32,OpenAs_RunDLL ' + as_fichero) END IF return 0

34. Detectar errores usando el evento DBERRORMuchas veces nos preguntamos como suprimir el error que se muestra al guardar del control datawindow y, colocar nuestro propio mensaje de error, esto para que el usuario de la aplicacin pueda interpretarlo mejor. El presente cdigo muestra como detectar los errores al guardar usando el evento dberror del control datawindow. Para este ejemplo utilizamos los siguientes controles: cb_aceptar; dw_detalle; //------------------------------------------declare instance variables //-------------------------------------------string s_msj; //--------------------------------------------event cliked() //------------------------------------------dw_detalle.update(true); if s_msj= then //cuando no hay ningun error commit using sqlca; messagebox(Cambios guardados,Sus cambios han sido guardados con exito); else //cuando hay error se muestra nuestro dialog de error

20

messagebox(Error al Guardar,s_msj, Exclamation! ); end if; //--------------------------------------------event dberror) //------------------------------------------CHOOSE CASE SQLdbcode CASE -195 //error por falta de datos S_MSJ =S_MSJ+ - Verifique que todos los datos esten registrados+char(13)+char(13); CASE -194 //cuando la tabla maestra no encuentra relacion al detalle S_MSJ =S_MSJ+ - El ruc o Und/Costo no esta creado o no es correcto+char(13)+char(13); CASE -193 //cuando existen datos duplicados S_MSJ =S_MSJ+ - La partida ingresada ya existe, verifique los datos ingresados+char(13)+char(13); CASE -198 //error cuando la tabla maestra no puede eliminar el detalle S_MSJ =S_MSJ+ - Para eliminar este tratamiento contable Debe elimar sus relaciones, Posiblemente ya se haya utilizado en algunos do*****entos si es asi NO SE PUEDE ELIMINAR +char(13)+char(13); CASE ELSE //para otros errores no previstos S_MSJ =S_MSJ+ STRING (SQLDBCODE)+ +SQLERRTEXT; END CHOOSE; // retorna el codigo que suprime el error RETURN 1;

35. Inserta fila en dw presionando EnterPara poder insertar una fila en un dw, con solo presionar la tecla enter, debers crear un evento, con un parametro pbm_dwnprocessenter de tipo long, asi quedar el evento: enter( long pbm_dwnprocessenter) //nombre del evento dw_1.Selectrow(dw_1.insertrow(0),false) //script dentro del evento Eso es todo

36. Funcin para saber si el equipo esta en redPara saber si el equipo donde corre la aplicacin esta conectado a la red use el siguiente cdigo usando el llamado al API de windows GetSystemMetrics. [declara una external function ] FUNCTION Integer GetSystemMetrics (Integer nIndex) LIBRARY user32.dll [powerscript] integer SM_NETWORK = 63 IF GetSystemMetrics(SM_NETWORK) > 0 THEN MessageBox(Estado de red, La red esta arriba) END IF

37. !!! Imprimir varias datawindows en la misma pagina !!!Es algo complejo, pero funciona perfectamente en PB10 (supongo que igualmente en otras versiones): 1) necesitamos una libreria dinamica para trabajar sobre ella, que llamaremos composite.pbd 2) creamos una datawindow de tipo composite a la cual aadimos tantas datawindos como queramos imprimir (con 10 va bien). Las datawindows que aadimos son comodines que no deben devolver nada, posteriormente en tiempo de ejecucion las reemplazaremos por las buenas. por ejemplo en Oracle la datawindow comodin tendra este select:

21

SELECT 1 FROM DUAL WHERE 1 = 2; la llamamos dw_composite_hija, y la enganchamos 10 veces a la composite padre dandoles los nombres a los controles de dw_comp1, dw_comp2, dw_comp3, ... dw_comp10 a la composite la llamaremos dw_composite. me seguis a estas alturas? 3) asignamos las datawindows que deseamos imprimir a un array de datawindows que llamaremos adw_dw[] 4) creamos datawindows temporales en la libreria dinamica composite.pbd for li_idx = 1 to Min(UpperBound(adw_dw),10) ls_syntax = string(adw_dw[li_idx].object.datawindow.syntax) LibraryImport ('c:prjscomposite.pbd','dw_comp' + string(li_idx),ImportDataWindow!,ls_syntax,ls_er,'') next 5) Creamos un datastore con la composite original (la que tenia comodines) y reemplazamos las datawindows del array por las comodines, con un codigo del estilo siguiente: ds = CREATE datastore ds.dataobject = 'dw_composite' if UpperBound(adw_dw) > 0 then ds.object.dw_1.dataobject = 'dw_comp1' if UpperBound(adw_dw) > 1 then ds.object.dw_2.dataobject = 'dw_comp2' if UpperBound(adw_dw) > 2 then ds.object.dw_3.dataobject = 'dw_comp3' if UpperBound(adw_dw) > 3 then ds.object.dw_4.dataobject = 'dw_comp4' if UpperBound(adw_dw) > 4 then ds.object.dw_5.dataobject = 'dw_comp5' if UpperBound(adw_dw) > 5 then ds.object.dw_6.dataobject = 'dw_comp6' if UpperBound(adw_dw) > 6 then ds.object.dw_7.dataobject = 'dw_comp7' if UpperBound(adw_dw) > 7 then ds.object.dw_8.dataobject = 'dw_comp8' if UpperBound(adw_dw) > 8 then ds.object.dw_9.dataobject = 'dw_comp9' if UpperBound(adw_dw) > 9 then ds.object.dw_10.dataobject = 'dw_comp10' si has llegado hasta aqui ya te queda poco ... 6) Recuperamos los datos y los imprimimos ds.SetTransObject(SQLCA) ds.Retrieve() ds.Print () VOILA !!! Es un poco complejo pero funciona como la seda (El codigo lo tengo ya en produccion). Faltaran algunos detallitos: como recuperar el path de la pbd en ejecucion?, como recuperar el path de desarrollo? (para que funcione sin compilar) y alguna cosilla mas que no comento aqui por ser trucos ya comentados. Espero que el truquito os sea de tanta utilidad como a mi, y animo ... un saludo a todos de un programador ya veterano (desde la version PB3) Alfonso

38. Tomar la letra de la unidad de CD-ROMEl siguiente truco nos muestra la manera de crear una funcin que retorne la letra de la unidad de CR-ROM. Usa los llamados a los APIS de windows GetLogicalDrives() y GetDriveTypeA(). El cdigo es el siguiente: [Se declaran 2 Funciones externas] FUNCTION ulong GetLogicalDrives() LIBRARY Kernel32.dll FUNCTION uint GetDriveType( Ref String as_root_path )

22

LIBRARY kernel32.dll ALIAS FOR GetDriveTypeA [se declara una funcion que retorne un string of_GetCDRootPath()] integer li_ctr string ls_root ulong lul_drives, lul_rem lul_drives = GetLogicalDrives() DO lul_rem = MOD(lul_drives, 2) IF lul_rem = 1 THEN ls_root = Char(li_ctr + 64) + : IF GetDriveType(ls_root_path) = 5 THEN Return ls_root_path END IF li_ctr ++ END IF lul_drives /= 2 LOOP UNTIL lul_drives = 0 RETURN

39. Messagebox no aparece?Si usted hace un llamado a un messagebox donde alguno de sus parametros es NULL es messagebox no aparece. Por ejemplo: SELECT cli_nombre INTO :ls_nombreCliente FROM cliente WHERE cli_id = :ls_clid; MessageBox( Atencion!, Cliente: + ls_nombreCliente + Esta reportado. ) En el caso anterior si la variable ls_nombreCliente retorna NULL entonces no aparece el mensaje. Para corregir esto podemos usar la siguiente funcin en lugar de usar el messagebox.... f_MessageBox(string as_title,string as_text) IF IsNull(as_title) OR IsNull(as_text) THEN // Para la aplicacion y muestra un error MessageBox(Error Grave,No puede pasar nulos a un messagebox) HALT CLOSE ELSE // hace un llamado normal al messagebox MessageBox(as_title, as_text) END IF

40. Cargar los nombres de las columnas de un DW en un arregloEl siguiente truco muestra la manera de cargar un arreglo con los nombres de todas las columnas de un datawindow. El cdigo es el siguiente: int colNum, numCols string colName[] numCols = Integer(dw_control.Describe(Datawindow.Column.Count)) FOR colNum = 1 TO numCols // Toma el nombre de la columna con describe colName[colNum] = dw_control.Describe(# + String(colNum) + .name) NEXT

23

41. Como saber el path de nuestra aplicacinCon la ayuda del llamado del API GetModuleFileNameA podemos ver el path. Para usar este llamado de API desde PowerBuilder haga lo siguiente: Declarar la funcin externa: FUNCTION int GetModuleFileNameA(ulong hinstModule, REF string lpszPath, ulong cchPath) LIBRARY kernel32 [Powerscript] string ls_Path unsignedlong lul_handle ls_Path = space(1024) lul_handle = Handle(GetApplication()) GetModuleFilenameA(lul_handle, ls_Path, 1024) MessageBox(Path de la aplicacin, ls_path)

42. Validar usando el usuario y la clave de Windows XPEstoy usando esta api para validar el usuario y la password. me funciona con window xp pero no encuentro la forma de solucionar el problema para windows 2000, Se agradece cualquier ayuda. Atte. rodrigo //Valida usuario, dominio y password de Windows NT. //FUNCTION Boolean LogonUserA (string lpszUsername, String lpszDomain, string lpszPassword, Long dwLogonType, Long dwLogonProvider, REF uLong phToken) LIBRARY advapi32.dll //FUNCTION ulong GetLastError() LIBRARY kernel32.dll uLong l_token=0, l_ret Boolean lb_yes String ls_result, ls_error lb_yes = LogonUserA(gstr_us.nombre, gstr_us.dominio, gstr_us.password,2,0,l_token ) if (lb_yes) then //ls_result = Coneccin Satisfactoria CloseHandle(l_token) else ls_error = string(GetLastError()) //ls_result = Coneccin a Fallado end if return lb_yes 43. Funcin para llenar un ddlb desde la base de datos Defina una funcin que retorne un valor integer y que tenga los siguientes parametros: string tabla_parm, string columna_parm, dropdownlistbox ddlb_parm, string clausula_where Esta funcion se usa por ejemplo para llenar un drop down list box con los cdigos de una tabla. Suponiendo que la funcin la llamamos f_llenar_ddlb_desde_bd la funcin se llamara as: f_llenar_ddlb_desde_bd('tabla','columna',ddlb_allenar,'where condicion = 10'') El codigo de la funcin sera el siguiente ls_select_string = SELECT DISTINCT + columna_parm + FROM + tabla_parm + + clausula_where PREPARE sqlsa FROM :ls_select_string; DECLARE dyn_cursor DYNAMIC CURSOR FOR sqlsa;

24

OPEN DYNAMIC dyn_cursor; if sqlca.sqlcode < 0 then MessageBox(Error de Base de datos!, sqlca.sqlerrtext) return sqlca.sqlcode end if ddlb_parm.SetRedraw(false) ddlb_parm.Reset( ) Do While sqlca.sqlcode = 0 Fetch dyn_cursor into :ls_add_string; if sqlca.sqlcode = 0 then ddlb_parm.AddItem(ls_add_string) elseif sqlca.sqlcode < 0 then MessageBox(Error de Base de datos, sqlca.sqlerrtext) return sqlca.sqlcode else exit end if Loop ddlb_parm.SetRedraw(true) Close dyn_cursor; return 0

44. DataWindow External DinamicaEste es un pequeo ejemplo de como se puede crear una datawindow external de forma dinamica :D Primero que nada lo que se necesita es insertar en una ventana una Control DataWidow(dw_1) sin enlazarlo a ningun objeto el codigo siguiente lo pueden poner en un boton: String s1,s2,s3,s5,cadena,errores Long pos=14,i Blob s4 s1 = 'release 6;datawindow(units=2 timer_interval=0 color=1073741824 processing=1'& + ' print.margin.bottom=250 print.margin.left=250 print.margin.right=250'& + ' print.margin.top=250 print.preview.buttons=no ) table( ' s2='' For i=1 To n //numero de columnas k kieras s2 = s2 +'~n~r'+ 'column=(type=char(20) updatewhereclause = yes name=col'+String(i)+ ' dbname=col'+String(i)+') ' s4 = s4 + Blob('column(band=detail id='+String(i)+ ' x='+String(pos)+' y=8 height=156 width=1197 edit.limit=30'& +' alignment=0 tag=Descrip font.face=MS Sans Serif font.height=-8 font.weight=400'& +' font.charset=0 font.pitch=2 font.family=2 font.underline=0 font.italic=0'& +' border=0 color=0 background.mode=1 background.color=0 edit.autoselect=yes'& +' edit.autohscroll=yes edit.autovscroll=no edit.focusrectangle=no )'& +' text(band=header text=col'+String(i)+' x='+String(pos)+' y=8 height=145 width=1197'& +' font.face=Arial font.height=-8 font.weight=700 font.charset=0'& +' font.pitch=2 font.family=2 font.underline=0 font.italic=0 border=0'& +' color=0 background.mode=1 background.color=0 alignment=2 name=col'+string(i)+'_t)') pos = pos + 1210 Next s3 = ' header(height=161) detail(height=182) ' s5 = ' htmltable(border=0 cellpadding=1 cellspacing=1 generatecss=no nowrap=no)'

25

dw_1.Create((s1 + s2 + ')' + s3 + String(s4) + s5),errores) 45. EXPORTAR DATAWINDOWS A FICHERO Para exportar datawindos a Excel , se puede utilizar el mtodo SaveAsAscii del control DataWindow, por ejemplo: dw_listado.SaveAsAscii(ls_pathfichero, '~t', '') donde ls_pathfichero es la ruta entera del fichero en el cul queremos exportar el datawindow con extensin xls, txt etc ... El nombre del fichero lo podemos recoger con la funcin GetFileSaveName

46. Colores del SistemaEl siguiente truco nos muestra las Constantes del sistema, para los colores. Por ejemplo: window_background = 1073741824 window_text = 33554432 application_workspace = 268435456 A continuacin el resto de colores.... window_background = 1073741824 window_text = 33554432 application_workspace = 268435456 button_face = 67108864 scrollbar = 134217728 desktop = 134217729 active_title_bar = 134217730 inactive_title_bar = 134217731 menu_bar = 134217732 window_frame = 134217734 menu_text = 134217735 active_titlebar_text = 134217737 active_border = 134217738 inactive_border = 134217739 highlight = 134217741 highlight_text = 134217742 button_shadow = 134217744 disabled_text = 134217745 button_text = 134217746 inactive_titlebar_text = 134217747 button_highlight = 134217748 button_dark_shadow = 134217749 button_light_shadow = 134217750 tooltip_text = 134217751 tooltip = 134217752 link = 134217856 link_hover = 134217857 link_active = 134217858 link_visited = 134217859

47. Determinar la SemanaEste cdigo permitir determinar la semana del ao, es decir si estamos en la semana 3, semana 18, semana 25, etc. El cdigo es el siguiente: Date d_FechaActual Date d_FechaInicio Long l_Semanas

26

d_FechaInicio = Date('01/01/'+String(Year(d_FechaActual))) l_Semanas = DaysAfter(d_FechaInicio, d_FechaActual) / 7 Donde l_Semanas capturar el nmero de la semana.

48. Acentos en consulta SQLFaciel pero util.... retorna el juego de caracteres para reemplazar en la consulta....LIKE En todo caso las bases de datos actuales dependen de la configuracin de caracteres para resolucin de consultas $PBExportHeader$f_esvocal.srf global type f_esvocal from function_object end type forward prototypes global function integer f_esvocal (character c_letra) end prototypes global function integer f_esvocal (character c_letra);integer i choose case c_letra case A,,,, return 1 case E,,,, return 2 case I,,,, return 3 case O,,,, return 4 case U,,,, return 5 case else return 0 end choose end function llamado a la funcion anterior para reemplazar los caracteres $PBExportHeader$f_cambiarvocalessql.srf global type f_cambiarvocalessql from function_object end type forward prototypes global function string f_cambiarvocalessql (string str_texto, boolean b_juegocar) end prototypes global function string f_cambiarvocalessql (string str_texto, boolean b_juegocar);Integer i integer vocal String str_cambio[] str_cambio[1] = A str_cambio[2] = E str_cambio[3] = I str_cambio[4] = O str_cambio[5] = U for i=1 to len(str_texto) vocal=f_esvocal(upper(mid(str_texto,i,1))) If vocal > 0 Then

27

If b_juegocar Then // si es una palabra cambia las letras para realizar la busqueda str_texto= Replace(str_texto, i, 1,[+str_cambio[vocal]+]) i+=len([+str_cambio[vocal]+])-1 Else //para el caso de una frase si aplicas % no se puede utilizar [] str_texto= Replace(str_texto, i, 1,_) End if End if Next return str_texto end function

49. Recursividad (Explorador de Carpetas)Este es un pequeo ejemplo de recursividad, que recorre todas las capetas de alguna unidad de la PC, lo hice para crear un modulo para compactar carpetas con WinZip 9 (y un parche para correr desde 2) con un menu popup o puede ser con un boton.. Primeramente crear un listbox (lb_1) y un treeview (tv_1). [El list box es para traer los directorios] Declaramos estas variables de tipo instancias Int pos=1,posi=1; String aux,temp,raiz; y esto lo ponemos en un boton para que haga la recursividad Int total TreeViewItem var /*Yo tengo un procedimiento para leer las unidades disponibles pero eso se los dejo de tarea :P sino me preguntan en el foro*/ raiz = c: aux = raiz /*con esta instruccion buscamos un archivo que no estan y nos devueve los subdirectorios */ lb_1.DirList( raiz + *.xxx,16 ) total = lb_1.TotalItems() var.Children = True var.Label = raiz var.PictureIndex = 3 var.SelectedPictureIndex = 3 posi = tv_1.InsertItemLast(0,var) tv_1.ExpandAll(posi) recursivo() //************************** /*ahora bien crean un procedimiento que se llame recursivo(windowfunction que no regresa nada) y ponen lo siguiente*/ //Procedimiento de Recursividad TreeViewItem var Long total,i,j String array[] If posi 1 Then lb_1.Dirlist ( aux + temp + *.ppp, 16 )

28

aux = aux + temp + Else lb_1.DirList( raiz + *.ppp,16 ) End If total = lb_1.TotalItems() For i=1 to total array[i] = mid(lb_1.Text(i), 2,(Len(lb_1.Text(i))-2)) Next For j=1 to total if array[j] .. Then var.Children = True var.Label = array[j] var.PictureIndex = 1 var.SelectedPictureIndex = 2 st_1.Text = aux + var.label posi = tv_1.InsertItemLast(pos,var) //tv_1.ExpandAll(pos) temp = var.Label pos = posi recursivo() pos = tv_1.FindItem( ParentTreeItem!, pos ) If pos [-Directorio-] */ //con el siguiente codigo Boolean flag = False Int a=1,b b = len(aux)-1 aux = Mid(aux,1,b) b=1 Do While flag = False If Pos ( aux, '' , b ) = 0 Then flag = true Else a = Pos ( aux, '' , b ) b=a+1 End If Loop aux = Mid ( aux, 1 , a ) /* y listo ya tienen tu treeview con todas las carpetas del sistema ;D */ Saludos desde Ciudad Victoria, Tamaulipas, Mexico Si quieren que les pase el PLB mandenme un mail para que se los envie :D

50. Obtener nombre del PC y usuario conectadoAqui esta un ejemplo de como obtener el nombre de usuario conectado y PC a traves de APIs de Windows Es super sencillo el ejemplo... En la declaraciones de Funciones externas colocamos lo siguiente Function Long WNetGetUser (Ref String lpName, Ref String lpUserName, Ref Long lpnLength) Library mpr Alias For WNetGetUserA Function Long GetComputerName (Ref String lpBuffer, Ref Long nSize) Library kernel32 Alias For GetComputerNameA

29

luego podemos crear una funcion para obtener el nombre de usario llamada f_user que devuelve un string y escribimos lo siguiente string ls_NullString, ls_UserName long ll_largo SetNull (ls_NullString) ls_UserName = Space (256) ll_largo = 256 WNetGetUser(ls_nullString, ls_UserName, ll_largo) return trim (ls_UserName) Luego creamos la funcion f_namehost que devuelve un string y escribimos lo siguiente string ls_ComputerName long ll_largo ls_ComputerName = space (256) ll_largo = 256 GetComputerName (ls_ComputerName, ll_largo) return trim (ls_ComputerName) Luego llamamos de cualquier parte de nuestro codigo a las funciones string ls_namehost , ls_user ls_namehost = f_namehost() ls_user= f_user()

51. Cuadro de ColoresTengo como labor en mi trabajo (ASS), modificar una aplicacin. El cambio consiste en cambiar los colores asignados tanto a las ventanas como a las Datawindow. Disee funciones para tal efecto y descubri lo facil que era mostrar la ventana de dialogo de colores y recuperar el color seleccionado. Para ese fin disee una ventana, con el proposito que el Administrador cambiase los colores a su gusto e implemente la funcionalidad que les quiero mostrar, la del Dilogo de Colores. Para mostar la paleta de colores en Powerbuilder y recuperar el color seleccionado: 1.Crear la estructura : os_choosecolor Type Variable Name ---------------------------------------a) long lstructsize b) unsignedlong hwndowner c) unsignedlong hinstance d) long rgbresult e) blob lpcustcolors f) long flags g) long lcustdata h) long lpfnhook i) long lptemplatename 2.- Variables Globales os_ChooseColor istr_ChooseColor long il_CustomInitColors[16] blob{64} ibl_CustomColors 3.- Crear la Funcion Global Externa : ChooseColorA function boolean ChooseColorA( REF os_ChooseColor lpcc ) library comdlg32.dll 4.- Aplicacin en PB En el evento rbuttondown de cualquier DW, colocar el siguiente cdigo:

30

istr_choosecolor.lpcustcolors = ibl_customcolors istr_choosecolor.lStructSize = 36 SetNull(istr_choosecolor.hwndOwner) istr_choosecolor.flags = 3 istr_ChooseColor.rgbresult = 0 ChooseColorA ( istr_choosecolor ) this.modify(Datawindow.color='+ string(istr_ChooseColor.rgbresult)+') * Al ejecutar y dar click derecho sobre la datawindow seleccionada cambiar el color de fondo de ella. * Hagan pruebas cambiando el valor de istr_choosecolor.flags * Hago el alcanse que a partir de PowerBuilder 8, existe la funcion ChooseColor, similar a esta solucin.

52. Input, Text y checkbox transparentesInput,Text y checkbox, trasparentes Con este truco puedes poner este user object dentro de la ventana con un background de fondo. Solo arrastra el objeto hacia la ventana Pasos: crea un user object de tipo standar visual y escoges el objeto (singleline o el que quieras hacer trasp.) y luego pones este codigo en el constructor call super::constructor;this.BackColor = 2^29 tambien debes crear un nuevo evento llamado ue_paint, de tipo pbm_paint y pones este codigo if IsValid(this) then if ib_Painting then return 0 ib_Painting = TRUE this.visible = false do while yield() ; loop this.visible = true ib_painting=false end if return 0 y finalmente pones una variable de instancia boolean ib_Painting

53. Hacer referencia a una variable Instancia desde el MenuSuponiendo que deseamos saber en el menu, el valor de una variable instancia llamada ii_codigo de la ventana w_ejemplo. Para esto en el menu colocamos el siguiente cdigo: integer li_local w_ejemplo w_miventana w_miventana = ParentWindow li_local = w_miventana.ii_id

54. Tomar el numero Serial del Disco DuroPara poder tomar el serial del disco duro se debe definir una local external function, con los siguientes parmetros: FUNCTION long GetVolumeInformation (string lpRootPathName, REF string lpVolumeNameBuffer, long nVolumeNameSize, REF long lpVolumeSerialNumber, REF

31

long lpMaximumComponentLength, REF long lpFileSystemFlags, REF string lpFileSystemNameBuffer, long nFileSystemNameSize) LIBRARY Kernel32.dll ALIAS FOR GetVolumeInformationA Luego en el powerscript de donde lo necesite coloca lo siguiente: String ls_volbuffer, ls_fsname Long ll_serial, ll_MaxCompLength, ll_FileSystemFlags, ll_rtn ls_volbuffer = Space(255) ls_fsname = Space(255) ll_maxCompLength = 0 ll_FileSystemFlags = 0 ll_rtn = GetVolumeinformation(C:, ls_volbuffer, 255, ll_serial, & ll_MaxCompLength, ll_FileSystemFlags , ls_fsname, 255) // ls volbuffer - Nombre del volumen // ll_serial - Numero serial del disco Duro // ls_fsname - Nombre del sistema de Archivos Ej.. NTFS

55. Como saber el ultimo dia del mesPara tener un mejor uso de este codigo lo coloque en una funcion para poder utilizarla cuando la necesite. Espero que les sirva, aca va el codigo. // FUNCION PARA CALCULAR EL LTIMO DA DEL MES // Parametros: ai_month = integer // ai_year = integer // Return: date Date ld_fecha_final IF ai_month = 12 THEN ai_month = 1 ai_year ++ ELSE ai_month ++ END IF ld_fecha_final = Date(string(ai_month)+'/'+ '01/'+ String(ai_year)) ld_fecha_final = RelativeDate(ld_fecha_final, -1) Return ld_fecha_final

56. Asignacin rpida de variables booleanasDebido a que PowerBuilder es un lenguaje interpretado, el tamao de los scripts puede tener efectos en la velocidad del sistema. Para reducir el tamao de los objetos un 10%, los objetos sern cargados un 10% ms rpidos, ejecutados un 10% mas rpidos y se usar un 10% menos de memoria, deberemos de seguir esta simple tcnica de asignacin de variables: Antiguo script: IF a = b THEN cbx_1.checked = TRUE ELSE cbx_1.checked = FALSE END IF Nuevo script: cbx_1.checked = a = b Otro ejemplo: IF dw_1.GetItemString( 1, column ) = AND THEN lb_Bool = TRUE

32

ELSE lb_Bool = FALSE END IF Nuevo script: lb_Bool = dw_1.GetItemString( 1, column ) = AND Saludos.

57. Evitar que se Maximice o Minimice una ventanaEl siguiente truco evita que la ventana se maximice o minimice cuando el usuario hace click en los botones de minimizar o maximizar de la ventana. 1. Cree un evento personalizado (CUSTOM EVENT ) en la ventana Cree un evento de usuario llamado ue_maximizar donde el Event ID se mapea con pbm_syscommand, segun esto debe quedar de la siguiente manera: Event Name: ue_maximizar Event ID : pbm_syscommand 2. Coloque en el evento ue_maximizar el siguiente cdigo CHOOSE CASE message.wordparm CASE 61472 // Cuando hacen click en el boton minimizar message.processed = true message.returnvalue = 0 CASE 61488 // Cuando hacen click en el boton maximizar message.processed = true message.returnvalue = 0 CASE 61490 // maximiza cuando hace doble click a la barra de titulo message.processed = true message.returnvalue = 0 END CHOOSE

58. Seleccionar filas en un Datawindow usando Shift-Click y Ctrl-ClickEl siguiente script permite seleccionar varias filas continuas usando Shift-Click y seleccionar varias filas NO continuas con Ctrl-Click como se hace en el explorador de windows. Aunque es posible adicionar esta capacidad a los datawindows standard de power builder se recomienda crear un objeto de usuario a partir de un Standard Datawindow para que la funcionalidad de seleccionar filas con SHIFT-CLICK y CTRLCLICK pueda ser heredada luego a los datawindows hijos Para poder seleccionar filas con Shift-Click y Ctrl-Click en un datawindow haga lo siguiente: 1. Cree una variable de instancia (Instance Variable) as: //Esta variable guarda la ltima fila a la que se le hizo click long il_ultimafila 2. Cree un evento personalizado (CUSTOM EVENT ) en el datawindow . El nuevo evento llmelo ue_seleccionarfila que llevara un argumento de tipo long llamado al_fila, el evento no se mapea con ningun Event ID y no retorna nada, segun esto debe quedar de la siguiente manera: Retun type: (None) Event Name: ue_seleccionarfila Argument Type: Long Argument Name: al_fila Event ID : (None) 3. Coloque en el evento ue_seleccionarfila el siguiente cdigo

33

/*El argumento que se le pasa es la ltima fila a la que se le hizo click. Esta funcin usa una varianle de instacia existente llamada il_ultimafila para hace el scrolling. El cdigo de el evento es este:*/ integer li_i this.SetReDraw ( FALSE ) IF il_ultimafila = 0 THEN this.SelectRow ( al_fila, TRUE ) Return END IF IF il_ultimafila > al_fila THEN FOR li_i = il_ultimafila to al_fila STEP -1 this.selectrow( li_i, TRUE) NEXT ELSE FOR li_i = il_ultimafila to al_fila this.selectrow( li_i, TRUE) NEXT END IF this.SetReDraw ( TRUE ) 4. Coloque el siguiente cdigo en el evento clicked del datawindow /* Row es un argumento del evento clicked y contiene el nmero de fila al que se hizo click. Si row = 0, entonces el usuario no hizo en en una fila*/ IF row = 0 THEN Return IF KeyDown ( KeyShift! ) THEN /* El evento ue_seleccionarfila se describe en el punto 2 y 3 anteriormente */ this.Event ue_seleccionarfila ( row ) ELSEIF KeyDown ( KeyControl! ) THEN IF this.GetSelectedRow ( row - 1 ) = row THEN this.SelectRow ( row, FALSE ) ELSE this.SelectRow ( row, TRUE ) END IF ELSE this.SelectRow ( 0, FALSE ) this.SelectRow ( row, TRUE ) END IF // Salva la fila a la que se hace click en la variable de instancia para usarla en ue_seleccionarfila il_ultimafila = row

59. Activar el protector de Pantalla desde PBEste truco muestra la manera de activar el protector de pantalla desde Power Builder Para hacerlo solo es necesario colocar el siguiente cdigo donde necesite activar el protector. CONSTANT uint SC_SCREENSAVE = 61760 CONSTANT uint WM_SYSCOMMAND = 274 Send( Handle( this ), WM_SYSCOMMAND, SC_SCREENSAVE, Long( 0, 0 ) ) ltima actualizacin el Lunes 09 de Junio de 2003 01:02

60. Como Poner la letra de un botn en Negrilla

34

Para poder colocar el texto en negrilla de los botones de texto realiza lo siguiente: Si desea el texto en negrilla coloca cb_1.weight = 700 Pero si lo desea normal coloca cb_1.weight = 400

61. Como poner Menu a una ventana ResponseLas ventanas response por defecto no permiten incluir menus. Pero si necesitas colocar un menu en este tipo de ventana aqui te contamos como se hace. En el evento Open de la ventana response colocas ChangeMenu(m_nombremenu) Donde m_nombremenu es el nombre del menu que va a incluir.

62. Enviar archivos por FTP desde Power BuilderEste articulo explica como hacer para enviar un archivo via FTP a un servidor remoto desde una aplicacin de Power Builder. Priemero cree un archivo subir.bat en un editor de texto con los comandos similares a estos @rem This file will attempt to upload 1 files to the ftp server @c: @cd emp @echo open ftpserveripaddress >> t @echo userid >> t @echo password >> t @echo binary >> t @echo cd uploaddirectoryname >> t @echo mput filenametobeuploaded >> t @echo bye >> t @ftp -i -s:t @del t Luego declara en las PB external function la siguiente funcin FUNCTION long ShellExecute (uint ihwnd,string lpszOp,string lpszFile,string lpszParams, string lpszDir,int wShowCmd ) LIBRARY Shell32.dll ALIAS FOR ShellExecuteA Luego en la aplicacin para poder subir el archivo se coloca este cdigo string ls_parm, ls_dir uint ll_ret ls_parm = ls_dir = c:path ll_ret = ShellExecute( handle ( this ) , open , upload.bat , ls_parm , ls_dir , 0 ) IF ll_ret < 32 THEN MessageBox( cannot load , ll_ret ) END IF

63. Tomar La ventana Frame desde una sheetEste truco explica la manera de que desde una ventana hija pueda capturar en una variable la ventana Frame. w_frame w_parent w_parent = mySheet.ParentWindow()

35