Funciones builtin
Usables como expresión en cualquier lugar, p.ej. &Usuario = USERID(). La mayoría son de cero argumentos con tipo de retorno fijo; Val() es la excepción (ver su propia entrada).
| Función | Retorno | Descripción |
|---|---|---|
USERID() | char(10) | Perfil de usuario IBM i que ejecuta este programa. Sin argumentos. |
PGNAME() | char(10) | Nombre de objeto de este mismo programa — constante de compilación, no una consulta en tiempo de ejecución. Sin argumentos. |
TODAY() | date | Fecha actual del sistema. Sin argumentos. |
TIME() | char(8) | Hora actual del sistema formateada "HH:MM:SS" (8 caracteres). Sin argumentos. |
Val(&CharVariable) | igual al destino de la asignación | Parsea un valor char a Number, usando la precisión/escala del destino de la asignación — a diferencia de las demás builtin, no tiene tipo de retorno fijo. Sólo válida directamente como &NumberVariable = Val(&CharExpr); usarla en cualquier otro lugar (anidada en otra expresión, como argumento de Do/Call, etc.) es un error. |
CurrentInput() | char(30) | Ver @Source: Event y Screen. |
Cursor(&variable) | condición | Verdadera si el cursor está sobre el control atado a &variable (un Input o una columna visible del DataGridView). Se usa como condición directa: If Cursor(&Codigo), sin = 1. Mismo ámbito que CurrentInput(). Errores: E00336, E00337, E00338. Ver @Source: Event y Screen. |
String(&VariableNumber, enteros[, decimales][, relleno]) | char(enteros [+ decimales]) | Convierte un Number a char de ancho fijo, p.ej. para concatenarlo en un Message(...) (que sólo acepta texto). enteros/decimales deben ser literales enteros (constantes de compilación): el ancho del retorno es enteros + decimales y no lleva separador decimal. decimales es opcional (por defecto 0). relleno es opcional: un texto literal de exactamente un carácter (E00341 si no). Sin relleno, los ceros a la izquierda de la parte entera se reemplazan por espacios; con "0" se conservan los ceros; con otro carácter (p.ej. "*") se usa ese carácter. La unidad de la parte entera siempre se muestra: String(0, 5) da " 0". Los números negativos muestran el signo -, que ocupa una de las posiciones del ancho pedido (el resultado sigue midiendo enteros + decimales): con relleno "0" reemplaza el primer carácter (String(-2, 5, "0") = -0002); sin relleno queda pegado al primer dígito (String(-15, 6) = -15); con otro relleno, igual (String(-15, 6, "*") = ***-15). Si el número usa todas las posiciones, el signo reemplaza el dígito más significativo, así que para negativos hay que pedir una posición más en enteros. Positivos y cero no cambian. Formas: String(n, 5), String(n, 5, 2), String(n, 5, "0"), String(n, 5, 2, "0"), String(n, 5, "*"). Errores: E00206, E00207, E00208, E00341. |
Int(expresión) | Number | Devuelve la parte entera de un número: trunca hacia cero, no redondea (Int(10 / 3) es 3). Recibe exactamente 1 argumento de tipo Number (E00342 si la cantidad es distinta de 1; E00343 si no es numérico). Si el argumento es una variable o campo de tipo conocido, el resultado es Number(enteros del argumento, 0); con una expresión compuesta (p.ej. &a / &b) el tipo no se restringe y se puede guardar en cualquier Number (el RPG trunca al asignar). Se traduce a %dec(expr : 30 : 0). |
SubString(&Variable, inicio, longitud) | char(longitud) | Recorta un pedazo de ancho fijo de un valor char (variable o literal) para que quepa en una variable más chica — p.ej. &Corto40 = SubString(&Largo120, 1, 40). Sin esto, asignar un char más ancho directo a uno más angosto es error de compilación. inicio/longitud deben ser literales enteros. Cuando el tamaño del origen se conoce en tiempo de compilación, que inicio + longitud - 1 lo exceda también es error de compilación. |
Trim(&Variable) | igual al argumento (char/varchar) | Quita blancos a izquierda y derecha. Un solo argumento. |
LTrim(&Variable) | igual al argumento | Quita blancos a la izquierda. Un solo argumento. |
RTrim(&Variable) | igual al argumento | Quita blancos a la derecha. Un solo argumento. |
Upper(&Variable) | igual al argumento | Convierte un char/varchar a mayúsculas, incluidas las letras acentuadas. Un solo argumento (si no, error E00225); sobre un tipo que no es char/varchar da E00226. Se traduce a %upper. Ver Requisito de release de Upper y Lower. |
Lower(&Variable) | igual al argumento | Convierte un char/varchar a minúsculas, incluidas las letras acentuadas. Mismas reglas que Upper. Se traduce a %lower. |
Length(&Variable) | number | Tamaño de un valor char/varchar: para varchar, el contenido real en tiempo de ejecución; para char, su longitud fija declarada. Un solo argumento. |
IndexOf(needle, &haystack) | number | Busca needle dentro de haystack y devuelve la posición cruda (1-based si se encuentra, 0 si no), sin conversión aplicada. Exactamente dos argumentos (texto a buscar, texto donde buscar). |
Round(expresión, decimales) | number(30, decimales) | Redondea expresión con half-adjust (la mitad hacia arriba, %dech de RPG) a decimales. decimales debe ser un literal entero entre 0 y 29 (constante de compilación: define la escala del resultado). La expresión se evalúa completa antes de redondear, así que una división no se trunca antes. El primer argumento debe ser Number. Errores: E00328 (cantidad de argumentos), E00329 (decimales no es literal o está fuera de rango), E00330 (primer argumento no numérico). |
Replace(texto, buscar, nuevo) | varchar | Reemplaza todas las ocurrencias de buscar por nuevo, sin solaparse (%scanrpl). El resultado es varchar con el largo del texto de origen: si el reemplazo es más largo, al asignarlo a una variable más chica se trunca. Los blancos de buscar cuentan (igual que IndexOf): use Trim() si hace falta. |
Contains(texto, buscar) | condición | Verdadera si texto contiene buscar. Se usa como condición (If, While, And, Or), no se asigna a una variable. Mismo criterio de blancos que IndexOf. |
StartsWith(texto, buscar) | condición | Verdadera si texto empieza con buscar. Mismas reglas que Contains. |
EndsWith(texto, buscar) | condición | Verdadera si texto termina con buscar. Mismas reglas que Contains; se traduce a %scanr, que requiere IBM i 7.4 o superior. Para un char con blancos finales use EndsWith(Trim(&Texto), "fin"). |
PadLeft(texto, ancho[, relleno]) | char(ancho) | Alinea a la derecha rellenando por la izquierda. ancho es un literal entero entre 1 y 32766; relleno es un literal de un carácter (por defecto un espacio). Ignora los blancos finales del texto; si el texto es más largo que ancho, se corta por la izquierda. |
PadRight(texto, ancho[, relleno]) | char(ancho) | Alinea a la izquierda rellenando por la derecha. Mismas reglas que PadLeft; si el texto es más largo que ancho, se corta por la derecha. |
Translate(texto, desde, hasta) | igual a texto | Cambia cada carácter de desde por el que ocupa la misma posición en hasta (%xlate). |
Abs(n) | number | Valor absoluto (%abs). |
Sqrt(n) | number | Raíz cuadrada (%sqrt). |
Mod(a, b) | number | Resto de la división entera (%rem). Exige operandos sin decimales (E00362; use Int() para truncar). El signo del resultado es el del dividendo: Mod(17, 5) es 2 y Mod(-17, 5) es -2. |
ErrorCode() | number(5) | Estado del error atrapado (%status), p. ej. 102 para una división por cero. Sin argumentos. Solo dentro de un Catch (E00366 fuera). Ver Try / Catch. |
ErrorMessage() | char(80) | Texto del mensaje del error atrapado (subcampo de la PSDS, posiciones 91-170). Sin argumentos. Solo dentro de un Catch (E00366 fuera). Aplique Trim() para quitar los blancos finales. |
Check(texto, caracteres) | number | Posición (desde 1) del primer carácter de texto que no está en caracteres; 0 si todos están. Los blancos finales de un char no cuentan (son relleno). Mapea a %check. |
Concat(texto1, texto2) | varchar | Une dos textos (+ de RPG). Cada operando conserva sus blancos. |
Div(numero, divisor) | number | Cociente entero, truncado hacia cero (Div(-7, 2) es -3). Mapea a %div. |
Min(numero1, numero2) | number | El menor de dos números. Mapea a %min. |
Max(numero1, numero2) | number | El mayor de dos números. Mapea a %max. |
DateTimeToTimestamp(fecha, hora) | timestamp | Une un date y un time en un timestamp (la hora no tiene microsegundos, quedan en 000000). Se convierte con %timestamp a partir del texto ISO. |
Requisito de release de Upper y Lower
Upper y Lower se traducen a los BIFs de RPG %upper y %lower, que dependen del release de IBM i:
- IBM i 7.5: disponibles de forma nativa.
- IBM i 7.3 y 7.4: sólo con los PTF de abril de 2021. Compilador: SI76100 (7.3) o SI76101 (7.4). Además, el PTF de runtime SI76098 (7.3) o SI76099 (7.4) debe estar instalado en cada sistema donde corra el programa; sin él, el programa falla con MCH4437.
- IBM i 7.2 y anteriores: no existen.
Fecha, hora y timestamp
Year/Month/Days/Hour/Minute/Second son polimórficas: aceptan date/time/timestamp según corresponda (Year/Month/Days con date o timestamp; Hour/Minute/Second con time o timestamp) — no hace falta un nombre distinto por tipo.
format (donde aplica) es siempre opcional: si se omite, cae al valor configurado en @GeneratorConfig (Date Format/Time Format/Timestamp Format); si tampoco hay configuración, se usa el formato por defecto del sistema.
| Función | Retorno | Descripción |
|---|---|---|
Year(&Variable) | number(4) | Año de un date/timestamp. |
Month(&Variable) | number(2) | Mes de un date/timestamp. |
Days(&Variable) | number(2) | Día del mes de un date/timestamp. |
Hour(&Variable) | number(2) | Hora de un time/timestamp. |
Minute(&Variable) | number(2) | Minuto de un time/timestamp. |
Second(&Variable) | number(2) | Segundo de un time/timestamp. |
DateDiff(&Fecha1, &Fecha2, Unidad) | number | Diferencia entre dos date, en Days/Months/Years (palabra suelta, no string). Positivo cuando Fecha1 es posterior a Fecha2, negativo en caso contrario. |
TimeDiff(&Hora1, &Hora2, Unidad) | number | Igual que DateDiff, sobre time, con Hours/Minutes/Seconds. |
TimestampDiff(&Ts1, &Ts2, Unidad) | number | Igual que DateDiff, sobre timestamp, con las 6 unidades habilitadas: Seconds/Minutes/Hours/Days/Months/Years. |
DateAdd(&Fecha, cantidad, Unidad) | date | Suma (o resta, si cantidad es negativa) días/meses/años a una fecha. cantidad puede ser cualquier expresión number (no sólo literal). |
TimeAdd(&Hora, cantidad, Unidad) | time | Igual que DateAdd, sobre time, con Hours/Minutes/Seconds. |
TimestampAdd(&Ts, cantidad, Unidad) | timestamp | Igual que DateAdd, sobre timestamp, con las 6 unidades. |
IsDate(valor[, format]) | number(1) | Valida si valor (char/varchar/number) es una fecha válida en format (opcional — uno de Iso/Usa/Eur/Jis/Mdy/Dmy/Ymd/Jul, o un patrón de texto; ver Patrones de formato). Devuelve 1/0 (WARP no tiene tipo booleano). No es una expresión pura — igual que Val(), sólo es válida directamente como &NumberVariable = IsDate(...). |
IsTime(valor[, format]) | number(1) | Igual que IsDate, sobre time (format uno de Hms/Iso/Usa/Eur/Jis). |
IsTimestamp(valor[, format]) | number(1) | Igual que IsDate, sobre timestamp (format uno de Iso/Usa/Eur/Jis). Iso es el formato recomendado y de mayor compatibilidad. |
StringToDate(string[, format]) | date | Convierte char/varchar a date. format admite también un patrón de texto. |
NumberToDate(number[, format]) | date | Convierte number a date — mismas reglas de format que StringToDate (incluye patrones de texto). |
StringToTime(string[, format]) | time | Convierte char/varchar a time. |
StringToTimestamp(string[, format]) | timestamp | Convierte char/varchar a timestamp. |
DateToString(&Fecha[, format]) | char(10) | Convierte date a texto — mismas reglas de format. Con un patrón de texto devuelve char del largo del patrón (máximo 10). |
TimeToString(&Hora[, format]) | char(8) | Convierte time a texto. |
TimestampToString(&Ts[, format]) | char(26) | Convierte timestamp a texto (26 = ancho ISO con microsegundos). |
Now() | timestamp | Timestamp actual del sistema. Sin argumentos. |
Patrones de formato de fecha
En StringToDate, NumberToDate, IsDate y DateToString, el segundo argumento format acepta, además de las palabras sueltas (Iso, Usa, Eur, Jis, Mdy, Dmy, Ymd, Jul), un patrón de texto literal con YYYY (año de 4 dígitos), MM y DD. Cada uno debe aparecer exactamente una vez, en cualquier orden, con o sin separadores, y sin distinguir mayúsculas. Ejemplos: "YYYYMMDD", "DDMMYYYY", "DD/MM/YYYY", "YYYY-MM-DD", "MM.DD.YYYY".
- Se resuelve en compilación: el RPG extrae año, mes y día con
%substpor posición fija y los lee como*iso. char/varchar: el valor debe tener exactamente el largo del patrón. Unvarcharmás corto falla en ejecución.NumberToDate/IsDateconnumber: el número se pasa a texto con ceros a la izquierda (%editc(n : 'X')) y los separadores del patrón no cuentan (un número no los tiene). Elnumberdebe tener tantos dígitos como el patrón (p.ej.number(8)para"DDMMYYYY").DateToString: devuelvechardel largo del patrón (máximo 10); p.ej."YYYYMMDD"dachar(8).- No se admite año de 2 dígitos (
YY), campos repetidos o faltantes, ni letras distintas deY/M/D: se reportaE00253.
&Fecha = StringToDate(&TextoFecha, "DD/MM/YYYY")
&Fecha2 = NumberToDate(&Numero, "DDMMYYYY") // &Numero: number(8)
&EsValida = IsDate(&Numero, "YYYYMMDD")
&Texto = DateToString(&Fecha, "YYYYMMDD") // char(8)
Texto y cálculo: Replace, Contains, Pad, Translate, Abs, Sqrt, Mod
Contains,StartsWithyEndsWithson condiciones: se escriben directamente enIf,While,AnduOr, igual queCursor.Replace,Contains,StartsWith,EndsWithyTranslatetratan los blancos de los argumentos como parte del texto. En uncharcon blancos finales, apliqueTrim()antes de comparar.PadLeftyPadRightdevuelven siempre unchardelanchoindicado;anchoyrellenodeben ser literales (E00361en caso contrario).- Errores de cantidad de argumentos (
E00358), de tipo texto (E00359) y de tipo numérico (E00360) se reportan con el nombre de la función. Sqrtde un número negativo yModcon divisor cero son errores de ejecución de RPG (estados00101y00102) que abortan el programa si no se atrapan conTry/Catch.
&Limpio = Replace(&Texto, "-", " ")
If Contains(&Texto, "mundo")
Message("Contiene la palabra", Info)
EndIf
If StartsWith(&Codigo, "AB") And EndsWith(Trim(&Codigo), "99")
Message("Código válido", Info)
EndIf
&Codigo5 = PadLeft(&Numero, 5, "0") // "00042"
&Etiqueta = PadRight(&Nombre, 20) // alineado a la izquierda, 20 caracteres
&Mayus = Translate(&Texto, "abc", "ABC")
&Resto = Mod(17, 5) // 2
&Absoluto = Abs(&Diferencia)
&Raiz = Sqrt(&Area)
Ejemplos
&Usuario = USERID()
&Programa = PGNAME()
&FechaHoy = TODAY()
&HoraActual = TIME()
&Cantidad = Val(&CantidadTexto)
Message("Total: " + String(&Total, 9, 2), Info)
&PorParte = Int(&Total / &Partes) // parte entera: 100 / 3 -> 33
&Texto1 = String(&Fila, 5) // " 7" (espacios)
&Texto2 = String(&Fila, 5, "0") // "00007" (ceros)
&Texto3 = String(&Fila, 5, "*") // "****7"
&Texto4 = String(&Importe, 6, 2, "0") // 6 enteros + 2 decimales, con ceros
&Corto = SubString(&Largo, 1, 40)
&Limpio = Trim(&ConEspacios)
&Codigo = Upper(Trim(&Entrada))
&Texto = Lower(&Texto)
&Tam = Length(&Descripcion)
&Pos = IndexOf("@", &Email)
&Importe = Round(&Total / &TipoCambio, 2)
&Nuevo = Replace(&Texto, "a", "b")
&Cod5 = PadLeft(&Numero, 5, "0")
&Resto = Mod(&Total, 7)
&FechaVencimiento = DateAdd(&FechaHoy, 30, Days)
&DiasHastaVencer = DateDiff(&FechaVencimiento, &FechaHoy, Days)
&EsFechaValida = IsDate(&TextoFecha, Dmy)
&Ahora = Now()
&HorasTranscurridas = TimestampDiff(&Ahora, &Inicio, Hours)
Int y String con relleno
Cambio incompatible en
String. Antes,String(n, enteros)rellenaba con ceros a la izquierda. Ahora, por defecto, esos ceros se reemplazan por espacios. Para conservar el comportamiento anterior hay que indicar el relleno:String(n, 5, "0").
Equivalencias en RPG generado:
| Forma | RPG |
|---|---|
String(n, 5) (espacios) | %editw(%dec(n : total : dec) : ' 0') |
String(n, 5, "0") (ceros) | %editc(%dec(n : total : dec) : 'X') |
String(n, 5, "*") (otro carácter) | %xlate(' ' : '*' : %editw(...)) |
Signo de los negativos
String muestra el signo - de los números negativos. El signo ocupa una de las posiciones del ancho pedido, por lo que el resultado sigue midiendo enteros + decimales:
| Llamada | Resultado |
|---|---|
String(-2, 5, "0") | -0002 |
String(-15, 6) | -15 |
String(-15, 6, "*") | ***-15 |
Si el número usa todas las posiciones, el signo reemplaza el dígito más significativo; para negativos conviene pedir una posición más en enteros. Los positivos y el cero no cambian. Los decimales siguen sin punto decimal (12.00 con 2 decimales da 1200). Para esto, el RPG generado incluye un procedimiento de apoyo WarpStrSign (una sola vez por programa).
Int se traduce a %dec(expr : 30 : 0). Ejemplo completo: example/programs/PNUM01.warp.