Você está na página 1de 36

Manejo de Power

builder 10.5

EJEMPLOS DE
POWER BUILDER
10.5
Este 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.

Ejemplos Power builder 10.5


1. LLAMADOS A LAS API DE WINDOWS DESDE POWER BUILDER
Power 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.

EJEMPLO DE LLAMADO A UN API DE WINDOWS


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).

2. Poner las nuevas filas en otro color


Este 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 string


Esta 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 string


A 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 ventanas


ESTA 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 PowerScript


Con 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 DW


Este 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 Messagebox


Muchas 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

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 ventana


Luego 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 Dinmicamente


Este 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 Tabla


Como 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 alternos


En 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 ENTER


Muchos 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 powerbuilder


Hola 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 Trabajo


A 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 powerbuilder


despues 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 group


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... 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 MDI


Uso 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 datawindow


Este 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 PowerScript


Cuando 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 columna


Para 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 DW


Hace 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 MENUID


Cuando 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 Computador


Para 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 DW
Cdigo 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)
ELSE
17

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 enter


Muchas 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 EJECUCION


El 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

31. como Utilizar la Funcion Setfilter y Filter del Control Datawindow


18

El 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
dw_trabajador
19

//----------------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 asociado


Este 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 DBERROR


Muchas 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
messagebox(Error al Guardar,s_msj, Exclamation! );
20

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 Enter


Para 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 red


Para 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:
SELECT 1 FROM DUAL WHERE 1 = 2;
21

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-ROM


El 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 )
LIBRARY kernel32.dll ALIAS FOR GetDriveTypeA
22

[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 arreglo


El 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

41. Como saber el path de nuestra aplicacin


23

Con 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 XP


Estoy 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;
OPEN DYNAMIC dyn_cursor;
24

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 Dinamica


Este 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)'
dw_1.Create((s1 + s2 + ')' + s3 + String(s4) + s5),errores)
25

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 Sistema


El 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 Semana


Este 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
d_FechaInicio = Date('01/01/'+String(Year(d_FechaActual)))
26

l_Semanas = DaysAfter(d_FechaInicio, d_FechaActual) / 7


Donde l_Semanas capturar el nmero de la semana.

48. Acentos en consulta SQL


Faciel 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
If b_juegocar Then
27

// 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 )
aux = aux + temp +
28

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 conectado


Aqui 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 Colores


Tengo 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:
istr_choosecolor.lpcustcolors = ibl_customcolors
30

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 transparentes


Input,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 Menu


Suponiendo 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 Duro


Para 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
long lpMaximumComponentLength, REF long lpFileSystemFlags, REF string
31

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 mes


Para 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 booleanas


Debido 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
ELSE
32

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

57. Evitar que se Maximice o Minimice una ventana


El 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-Click


El 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 PB


Este 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 Response


Las 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 Builder


Este 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 sheet


Este 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

Você também pode gostar