Data types
Each variable and each activity result has a type of data. The type determines what you can do with that value: a text can be converted to uppercase, a number can be added, a table can be traversed row by row. Knowing the type of your variables is key to writing correct expressions.
Primitive types
Section titled “Primitive types”They are the simplest values: a text, a number, a yes/no.
| Type | Description | Examples |
|---|---|---|
string | Texto | "Hola mundo", "FAC-001" |
number | Whole number or decimal (the decimal separator is the period) | 42, 3.14, -7 |
boolean | Logical value: true or false | true, false |
DateTime | Fecha y hora | resultado de now(), today() |
Miembros de string
Section titled “Miembros de string”On a text you can call these methods (in addition to the built-in functions like upper, trim…):
| Miembro | Returns | Description |
|---|---|---|
.Length | int | Cantidad de caracteres |
.ToUpper() | string | Uppercase |
.ToLower() | string | Lowercase |
.Trim() / .TrimStart() / .TrimEnd() | string | Quita espacios |
.Contains(valor) | bool | Does it contain sub-text? |
.StartsWith(valor) / .EndsWith(valor) | bool | Does it start/end with? |
.Replace(viejo, nuevo) | string | Reemplaza ocurrencias |
.Split(separador) | string[] | Divide en partes |
.Substring(inicio) / .Substring(inicio, largo) | string | Extract a portion |
.IndexOf(valor) | int | Position of first appearance (-1 if not present) |
.PadLeft(ancho, car) / .PadRight(ancho, car) | string | Fills to a width |
= nombre.ToUpper()= codigo.Substring(0, 3) // primeros 3 caracteres= correo.Split("@")[1] // dominio del correoMiembros de DateTime
Section titled “Miembros de DateTime”| Miembro | Returns | Description |
|---|---|---|
.Year .Month .Day | int | Date components |
.Hour .Minute .Second .Millisecond | int | Components of time |
.DayOfWeek | DayOfWeek | day of the week |
.DayOfYear | int | Day of the year (1–366) |
.Date | DateTime | Only the date (00:00:00) |
.ToString(formato) | string | Da formato. Ej: "yyyy-MM-dd", "dd/MM/yyyy HH:mm" |
.AddDays(n) .AddHours(n) .AddMinutes(n) | DateTime | Suma tiempo (n puede ser negativo) |
.AddMonths(n) .AddYears(n) | DateTime | Add months/years |
.Subtract(otraFecha) | TimeSpan | Diferencia entre dos fechas |
= today().AddDays(-7) // hace una semana= now().ToString("yyyy-MM-dd_HH-mm") // útil para nombrar archivos= fechaVencimiento.Subtract(today()).Days // días que faltanCollection types
Section titled “Collection types”They group several values. The indices start at 0.
List — list ordenada
Section titled “List — list ordenada”A sequence of elements. It is created with the List Create activity, with the newList() function, or as a result of activities such as split or Page Extract Table.
| Miembro | Returns | Description |
|---|---|---|
.Count | int | Number of elements |
.Add(item) | — | Add an element to the end |
.Remove(item) / .RemoveAt(indice) | — | Remove an element |
.Clear() | — | Empty the list |
.Contains(item) | bool | Is the element there? |
.IndexOf(item) | int | Element position |
.First() / .FirstOrDefault() | elemento | First (FirstOrDefault returns null if empty) |
.Last() | elemento | Last |
.Any() / .All(cond) | bool | Are there any/do they all meet? |
.Where(cond) | IEnumerable | Filter (LINQ — end with .ToList()) |
.Select(proy) | IEnumerable | Transform (LINQ — end with .ToList()) |
.OrderBy(clave) | IEnumerable | Ordena (LINQ) |
.ToList() / .ToArray() | List / array | Materialize the result |
= productos.Count= productos.Where(p => p > 100).ToList()= nombres.Contains("Ana")Dictionary — key→value map
Section titled “Dictionary — key→value map”Associates a text key with a value. It is created with Dict Create or newDict().
| Miembro | Returns | Description |
|---|---|---|
.Count | int | Number of keys |
.Keys / .Values | collection | All keys/values |
.ContainsKey(clave) | bool | Does the key exist? |
.Add(clave, valor) | — | Add a couple |
.Remove(clave) | bool | Remove a key |
.GetValueOrDefault(clave) | value | Value or null if it does not exist |
= config["timeout"] // acceso por clave= config.ContainsKey("proxy")= config.GetValueOrDefault("idioma")DataTable — table of rows and columns
Section titled “DataTable — table of rows and columns”A table with named columns, like an Excel sheet. It is the common format shared by Excel, CSV, databases and Google Sheets: what you read from one source you can write to another without converting.
| Miembro | Returns | Description |
|---|---|---|
.Rows | DataRowCollection | The rows |
.Rows.Count | int | Number of rows |
.Columns | DataColumnCollection | The columns |
.Columns.Count | int | Number of columns |
.AsEnumerable() | IEnumerable<DataRow> | To use LINQ on rows |
.Select(filtro) | DataRow[] | Filter with a SQL expression (ex. "Total > 1000") |
.NewRow() | DataRow | Create an empty row with the same structure |
.Clone() | DataTable | Copy the structure without rows |
.Copy() | DataTable | Copy structure and rows |
Convenient functions for tables: rowCount(dt), colCount(dt), firstRow(dt), asRows(dt), selectRows(dt, cond) (see Expressions).
DataRow — a table row
Section titled “DataRow — a table row”Each element of a For Each on a DataTable is a DataRow. You access its cells by column name with square brackets:
= fila["Cliente"] // valor crudo (puede ser DBNull)= str(row["Cliente"]) // texto seguro (recomendado)= num(fila["Total"]) // número seguro| Miembro | Returns | Description |
|---|---|---|
fila["columna"] | object | cell value |
.Table | DataTable | Table to which it belongs |
.ItemArray | object[] | All cells as array |
.IsNull("columna") | bool | Is the cell empty? |
Editing collections by hand
Section titled “Editing collections by hand”When a parameter accepts a literal list, dictionary or table, the Properties panel shows an Edit button with a visual editor, so you don’t have to write the structure by hand. The same applies to filter conditions and row values.
All of the Designer’s visual editors are explained in Parameter editors.
Session types (open resources)
Section titled “Session types (open resources)”Some activities open a resource (a browser, an Excel workbook, a database connection) and return a session that represents that open resource. You move that session to the other activities in the same package, and at the end you close it. It’s the same pattern across the platform: open → use → close.
| Type | Opens | Closes | Purpose |
|---|---|---|---|
ZoanBrowserSession | Open Browser / Browser Attach | Browser Close | Web browser (Chrome/Edge) |
ZoanPageSession | Browser Open / Browser New Page | Page Close | A specific browser tab/page |
ZoanExcelSession | Excel Open / Excel Create | Excel Close | Libro de Excel |
ZoanWordSession | Word Open / Word Create | Word Close | Word document |
ZoanDbSession | DB Connect | DB Close | Database connection |
ZoanSftpSession | SFTP Connect | SFTP Close | Servidor SFTP |
ZoanGoogleSheetsSession | GoogleSheets Open | GoogleSheets Close | Google Spreadsheet |
ZoanOutlookSession | (Outlook activities) | — | Outlook session |
ZoanDesktopSession | Open App / Win Attach | Win Close | Windows desktop application |
// Patrón típico: la salida de "abrir" alimenta a las siguientes actividades// Open Browser → output: page// Page Navigate → page: = page// Page Get Text → page: = page → output: titulo// Browser Close → browser: = pageTypes of activity results
Section titled “Types of activity results”Other activities return an object with structured data that you do read for its properties.
ZoanHttpResponse — respuesta HTTP
Section titled “ZoanHttpResponse — respuesta HTTP”Result of HTTP activities (GET, POST, PUT, PATCH, DELETE).
| Property | Type | Description |
|---|---|---|
.StatusCode | number | HTTP code (200, 404, 500…) |
.Ok | boolean | true if the code is 2xx |
.Body | object | Response body. If it is JSON, it is automatically deserialized |
.Headers | Dictionary | Response headers |
= respuesta.Ok= respuesta.StatusCode == 200= respuesta.Body["token"] // si el body es JSON= respuesta.Headers["Content-Type"]ZoanMail — mail
Section titled “ZoanMail — mail”Result of mail reading activities (Outlook, IMAP, POP3).
| Property | Type | Description |
|---|---|---|
.Id | string | Unique identifier (use in move/delete/attachments) |
.Subject | string | Asunto |
.From | string | Remitente |
.To / .Cc / .Bcc | string[] | Destinatarios |
.Body | string | Body (plain text or HTML according to IsHtml) |
.IsHtml | boolean | Is the body HTML? |
.SentAt | DateTime | Send/receive date |
.IsRead | boolean | Is it read? |
.Attachments | ZoanAttachment[] | Attachments (if requested to include them) |
= correo.Subject= correo.From= count(correo.Attachments) > 0ZoanAttachment — adjunto
Section titled “ZoanAttachment — adjunto”| Property | Type | Description |
|---|---|---|
.Name | string | file name |
.ContentType | string | MIME type (e.g. application/pdf) |
.Content | byte[] | Contenido binario |
ZoanQueueItem — elemento de cola
Section titled “ZoanQueueItem — elemento de cola”Result of consuming a Zoan Cloud queue (Queue package).
| Property | Type | Description |
|---|---|---|
.Id | string | Item identifier |
.QueueId | string | Queue to which it belongs |
.Reference | string? | Business reference (e.g. invoice number) |
.Priority | string | low / normal / high |
.Status | string | new / inProgress / success / failed… |
.SpecificContent | Dictionary | Item data (the fields you entered when queuing it) |
.Output | Dictionary? | Result, once processed |
.Attempts | int | Number of attempts |
.CreatedAt | string | Creation date |
= item.Reference= item.SpecificContent["nit"]ZoanError — captured error
Section titled “ZoanError — captured error”The object the errorVariable of Try / Catch receives when something in the try fails.
| Property | Type | Description |
|---|---|---|
.Message | string | Error message |
.Type | string | Exception type (e.g. "HttpRequestException", "TimeoutException"); use it to distinguish errors |
.Source | string | Exception source |
.StackTrace | string | Stack trace |
= error.Message= error.Type == "TimeoutException" // branch on the error typeTreating it as text uses the message (= "Error: " + error), so reading it as a string still works.
Conversion between types
Section titled “Conversion between types”When a value arrives as text but you need a number (or the other way around), convert it explicitly:
= toNumber(fila["Total"]) // texto → número= toInt(cantidadTexto) // texto → entero= toString(contador) // número → texto= parseDouble(replace(monto, ",", ".")) // "1.234,56" con coma decimal → númeroSee the complete list in Expressions › Type Conversion.
Next steps
Section titled “Next steps”- Variables — declare variables with a type.
- Expresiones — operar sobre estos tipos.
- Activity Catalog — what type each activity returns.