Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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ónRetornoDescripció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()dateFecha 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ónParsea 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ónVerdadera 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)NumberDevuelve 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 argumentoQuita blancos a la izquierda. Un solo argumento.
RTrim(&Variable)igual al argumentoQuita blancos a la derecha. Un solo argumento.
Upper(&Variable)igual al argumentoConvierte 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 argumentoConvierte un char/varchar a minúsculas, incluidas las letras acentuadas. Mismas reglas que Upper. Se traduce a %lower.
Length(&Variable)numberTamañ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)numberBusca 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)varcharReemplaza 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ónVerdadera 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ónVerdadera si texto empieza con buscar. Mismas reglas que Contains.
EndsWith(texto, buscar)condiciónVerdadera 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 textoCambia cada carácter de desde por el que ocupa la misma posición en hasta (%xlate).
Abs(n)numberValor absoluto (%abs).
Sqrt(n)numberRaíz cuadrada (%sqrt).
Mod(a, b)numberResto 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)numberPosició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)varcharUne dos textos (+ de RPG). Cada operando conserva sus blancos.
Div(numero, divisor)numberCociente entero, truncado hacia cero (Div(-7, 2) es -3). Mapea a %div.
Min(numero1, numero2)numberEl menor de dos números. Mapea a %min.
Max(numero1, numero2)numberEl mayor de dos números. Mapea a %max.
DateTimeToTimestamp(fecha, hora)timestampUne 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ónRetornoDescripció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)numberDiferencia 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)numberIgual que DateDiff, sobre time, con Hours/Minutes/Seconds.
TimestampDiff(&Ts1, &Ts2, Unidad)numberIgual que DateDiff, sobre timestamp, con las 6 unidades habilitadas: Seconds/Minutes/Hours/Days/Months/Years.
DateAdd(&Fecha, cantidad, Unidad)dateSuma (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)timeIgual que DateAdd, sobre time, con Hours/Minutes/Seconds.
TimestampAdd(&Ts, cantidad, Unidad)timestampIgual 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])dateConvierte char/varchar a date. format admite también un patrón de texto.
NumberToDate(number[, format])dateConvierte number a date — mismas reglas de format que StringToDate (incluye patrones de texto).
StringToTime(string[, format])timeConvierte char/varchar a time.
StringToTimestamp(string[, format])timestampConvierte 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()timestampTimestamp 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 %subst por posición fija y los lee como *iso.
  • char/varchar: el valor debe tener exactamente el largo del patrón. Un varchar más corto falla en ejecución.
  • NumberToDate/IsDate con number: 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). El number debe tener tantos dígitos como el patrón (p.ej. number(8) para "DDMMYYYY").
  • DateToString: devuelve char del largo del patrón (máximo 10); p.ej. "YYYYMMDD" da char(8).
  • No se admite año de 2 dígitos (YY), campos repetidos o faltantes, ni letras distintas de Y/M/D: se reporta E00253.
&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, StartsWith y EndsWith son condiciones: se escriben directamente en If, While, And u Or, igual que Cursor.
  • Replace, Contains, StartsWith, EndsWith y Translate tratan los blancos de los argumentos como parte del texto. En un char con blancos finales, aplique Trim() antes de comparar.
  • PadLeft y PadRight devuelven siempre un char del ancho indicado; ancho y relleno deben ser literales (E00361 en 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.
  • Sqrt de un número negativo y Mod con divisor cero son errores de ejecución de RPG (estados 00101 y 00102) que abortan el programa si no se atrapan con Try/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:

FormaRPG
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:

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