{"id":640,"date":"2026-04-06T09:11:46","date_gmt":"2026-04-06T12:11:46","guid":{"rendered":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/?p=640"},"modified":"2026-04-06T09:12:23","modified_gmt":"2026-04-06T12:12:23","slug":"como-crear-y-usar-un-dataprovider","status":"publish","type":"post","link":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/?p=640","title":{"rendered":"Como Crear y Usar un DataProvider"},"content":{"rendered":"<h3 data-path-to-node=\"3\">Paso 1: Crear y configurar el SDT<\/h3>\n<p data-path-to-node=\"4\">Primero necesitamos el &#8220;molde&#8221; donde el Data Provider va a volcar la informaci\u00f3n.<\/p>\n<ol start=\"1\" data-path-to-node=\"5\">\n<li>\n<p data-path-to-node=\"5,0,0\"><b data-path-to-node=\"5,0,0\" data-index-in-node=\"0\">Crear el objeto:<\/b> Ve a <i data-path-to-node=\"5,0,0\" data-index-in-node=\"22\">New Object<\/i> -&gt; <i data-path-to-node=\"5,0,0\" data-index-in-node=\"36\">Structured Data Type<\/i>.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"5,1,0\"><b data-path-to-node=\"5,1,0\" data-index-in-node=\"0\">Nombre ejemplo:<\/b> <code data-path-to-node=\"5,1,0\" data-index-in-node=\"17\">SDT_Factura<\/code> (Es buena pr\u00e1ctica ponerle el prefijo <code data-path-to-node=\"5,1,0\" data-index-in-node=\"67\">SDT_<\/code> para identificarlo r\u00e1pido).<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"5,2,0\"><b data-path-to-node=\"5,2,0\" data-index-in-node=\"0\">Estructura:<\/b> Este ejemplo esta hecho con una estructura de una cabecera y luego un subnivel collecion. F\u00edjate c\u00f3mo la ra\u00edz contiene campos sueltos y luego un subnivel que agrupa las l\u00edneas:<\/p>\n<div class=\"code-block ng-tns-c687071695-73 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwiQyrqxjdmTAxUAAAAAHQAAAAAQrAE\">\n<div class=\"code-block-decoration header-formatted gds-title-s ng-tns-c687071695-73 ng-star-inserted\">\n<div class=\"buttons ng-tns-c687071695-73 ng-star-inserted\">\u00a0<\/div>\n<\/div>\n<div class=\"formatted-code-block-internal-container ng-tns-c687071695-73\">\n<div class=\"animated-opacity ng-tns-c687071695-73\">\n<pre class=\"ng-tns-c687071695-73\"><code class=\"code-container formatted ng-tns-c687071695-73\" role=\"text\" data-test-id=\"code-content\">SDT_Factura\r\n\u251c\u2500\u2500 FacturaId (Numeric)\r\n\u251c\u2500\u2500 FacturaFecha (Date)\r\n\u251c\u2500\u2500 ClienteNombre (Character)\r\n    \u2514\u2500\u2500 SDT_FacturaItem (Ac\u00e1 haces clic derecho -&gt; 'Is Collection': True)\r\n        \u251c\u2500\u2500 ProductoId (Numeric)\r\n        \u251c\u2500\u2500 ProductoNombre (Character)\r\n        \u2514\u2500\u2500 LineaCantidad (Numeric)\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li>\n<p data-path-to-node=\"5,3,0\"><b data-path-to-node=\"5,3,0\" data-index-in-node=\"0\">Propiedades clave del SDT:<\/b><\/p>\n<ul data-path-to-node=\"5,3,1\">\n<li>\n<p data-path-to-node=\"5,3,1,0,0\">No hay que tocar mucho m\u00e1s, solo aseg\u00farate de que el nivel <code data-path-to-node=\"5,3,1,0,0\" data-index-in-node=\"59\">Item<\/code> tenga el tilde en la columna de colecci\u00f3n o la propiedad <b data-path-to-node=\"5,3,1,0,0\" data-index-in-node=\"121\">Is Collection = True<\/b>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<hr data-path-to-node=\"6\" \/>\n<h3 data-path-to-node=\"7\">Paso 2: Crear y configurar el Data Provider<\/h3>\n<p data-path-to-node=\"8\">Ahora creamos el motor que va a llenar ese SDT.<\/p>\n<ol start=\"1\" data-path-to-node=\"9\">\n<li>\n<p data-path-to-node=\"9,0,0\"><b data-path-to-node=\"9,0,0\" data-index-in-node=\"0\">Crear el objeto:<\/b> Ve a <i data-path-to-node=\"9,0,0\" data-index-in-node=\"22\">New Object<\/i> -&gt; <i data-path-to-node=\"9,0,0\" data-index-in-node=\"36\">Data Provider<\/i>.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"9,1,0\"><b data-path-to-node=\"9,1,0\" data-index-in-node=\"0\">Nombre sugerido:<\/b> <code data-path-to-node=\"9,1,0\" data-index-in-node=\"17\">DP_ObtenerFactura<\/code> (Prefijo <code data-path-to-node=\"9,1,0\" data-index-in-node=\"44\">DP_<\/code> y un verbo que indique la acci\u00f3n).<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"9,2,0\"><b data-path-to-node=\"9,2,0\" data-index-in-node=\"0\">Propiedades CLAVE del Data Provider:<\/b><\/p>\n<ul data-path-to-node=\"9,2,1\">\n<li>\n<p data-path-to-node=\"9,2,1,0,0\"><b data-path-to-node=\"9,2,1,0,0\" data-index-in-node=\"0\">Output:<\/b> <code data-path-to-node=\"9,2,1,0,0\" data-index-in-node=\"8\">SDT_Factura<\/code> <i data-path-to-node=\"9,2,1,0,0\" data-index-in-node=\"20\">(Esto es vital: le dice al DP qu\u00e9 tipo de dato debe devolver. Al poner esto, GeneXus te puede autocompletar la estructura en el c\u00f3digo).<\/i><\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"9,2,1,1,0\"><b data-path-to-node=\"9,2,1,1,0\" data-index-in-node=\"0\">Collection:<\/b> <code data-path-to-node=\"9,2,1,1,0\" data-index-in-node=\"12\">False<\/code> <i data-path-to-node=\"9,2,1,1,0\" data-index-in-node=\"18\">(Porque queremos devolver UNA sola factura que adentro tiene l\u00edneas, no una lista de facturas).<\/i><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p data-path-to-node=\"9,3,0\"><b data-path-to-node=\"9,3,0\" data-index-in-node=\"0\">Rules (Pesta\u00f1a Rules):<\/b> Para que el DP sepa qu\u00e9 factura buscar, le pasamos el ID por par\u00e1metro:<\/p>\n<div class=\"code-block ng-tns-c687071695-74 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwiQyrqxjdmTAxUAAAAAHQAAAAAQrQE\">\n<div class=\"code-block-decoration header-formatted gds-title-s ng-tns-c687071695-74 ng-star-inserted\"><span class=\"ng-tns-c687071695-74\">Fragmento de c\u00f3digo<\/span><\/p>\n<div class=\"buttons ng-tns-c687071695-74 ng-star-inserted\">\u00a0<\/div>\n<\/div>\n<div class=\"formatted-code-block-internal-container ng-tns-c687071695-74\">\n<div class=\"animated-opacity ng-tns-c687071695-74\">\n<pre class=\"ng-tns-c687071695-74\"><code class=\"code-container formatted ng-tns-c687071695-74\" role=\"text\" data-test-id=\"code-content\">parm(in:&amp;FacturaId);\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<\/ol>\n<hr data-path-to-node=\"10\" \/>\n<h3 data-path-to-node=\"11\">Paso 3: Escribir el c\u00f3digo del Data Provider<\/h3>\n<p data-path-to-node=\"12\">Ve a la pesta\u00f1a <b data-path-to-node=\"12\" data-index-in-node=\"16\">Source<\/b> del Data Provider. La sintaxis es declarativa. Asumiendo que ten\u00e9s las transacciones <code data-path-to-node=\"12\" data-index-in-node=\"108\">Factura<\/code> y su nivel <code data-path-to-node=\"12\" data-index-in-node=\"127\">Facturaitem<\/code> en la base de datos, el c\u00f3digo queda as\u00ed:<\/p>\n<div class=\"code-block ng-tns-c687071695-75 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwiQyrqxjdmTAxUAAAAAHQAAAAAQrgE\">\n<div class=\"code-block-decoration header-formatted gds-title-s ng-tns-c687071695-75 ng-star-inserted\"><span class=\"ng-tns-c687071695-75\">Fragmento de c\u00f3digo<\/span><\/p>\n<div class=\"buttons ng-tns-c687071695-75 ng-star-inserted\">\u00a0<\/div>\n<\/div>\n<div class=\"formatted-code-block-internal-container ng-tns-c687071695-75\">\n<div class=\"animated-opacity ng-tns-c687071695-75\">\n<pre class=\"ng-tns-c687071695-75\"><code class=\"code-container formatted ng-tns-c687071695-75\" role=\"text\" data-test-id=\"code-content\">SDT_Factura\r\nWhere FacturaId = &amp;FacturaId \/\/ Filtro para la cabecera\r\n{\r\n    \/\/ 1. Cargamos la \"estructura normal\" (Cabecera)\r\n    FacturaId = FacturaId\r\n    FacturaFecha = FacturaFecha\r\n    ClienteNombre = ClienteNombre\r\n\r\n    \/\/ 2. Cargamos el subnivel que es Colecci\u00f3n (L\u00edneas)\r\n    Lineas\r\n    {\r\n        \/\/ 'Item' es el nombre del nivel en el SDT. \r\n        \/\/ 'Input' le dice qu\u00e9 tabla recorrer (GeneXus lo suele inferir, pero es buena pr\u00e1ctica ponerlo)\r\n        SDT_Factura Input FacturaLinea\r\n        {\r\n            ProductoId = ProductoId\r\n            ProductoNombre = ProductoNombre\r\n            LineaCantidad = FacturaLineaCantidad\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p data-path-to-node=\"14\"><i data-path-to-node=\"14\" data-index-in-node=\"0\">Nota: F\u00edjate que no hay ning\u00fan <code data-path-to-node=\"14\" data-index-in-node=\"31\">For Each<\/code>. GeneXus autom\u00e1ticamente hace un <code data-path-to-node=\"14\" data-index-in-node=\"73\">For Each<\/code> impl\u00edcito de la cabecera por el <code data-path-to-node=\"14\" data-index-in-node=\"114\">Where FacturaId = &amp;FacturaId<\/code>, y otro <code data-path-to-node=\"14\" data-index-in-node=\"151\">For Each<\/code> anidado para cargar cada <code data-path-to-node=\"14\" data-index-in-node=\"185\">Item<\/code> de las l\u00edneas de esa factura.<\/i><\/p>\n<hr data-path-to-node=\"15\" \/>\n<h3 data-path-to-node=\"16\">Paso 4: Llamar al Data Provider desde un Web Panel<\/h3>\n<p data-path-to-node=\"17\">Ahora vamos a consumir ese Data Provider, por ejemplo, en el evento <code data-path-to-node=\"17\" data-index-in-node=\"68\">Start<\/code> o <code data-path-to-node=\"17\" data-index-in-node=\"76\">Enter<\/code> de un Web Panel (como podr\u00eda ser un paso de tu Wizard).<\/p>\n<ol start=\"1\" data-path-to-node=\"18\">\n<li>\n<p data-path-to-node=\"18,0,0\"><b data-path-to-node=\"18,0,0\" data-index-in-node=\"0\">Definir Variables en el Web Panel:<\/b><\/p>\n<ul data-path-to-node=\"18,0,1\">\n<li>\n<p data-path-to-node=\"18,0,1,0,0\"><code data-path-to-node=\"18,0,1,0,0\" data-index-in-node=\"0\">&amp;Factura<\/code> -&gt; Basada en el tipo de dato <code data-path-to-node=\"18,0,1,0,0\" data-index-in-node=\"38\">SDT_Factura<\/code>.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"18,0,1,1,0\"><code data-path-to-node=\"18,0,1,1,0\" data-index-in-node=\"0\">&amp;FacturaId<\/code> -&gt; Numeric (el ID de la factura que quer\u00e9s buscar).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p data-path-to-node=\"18,1,0\"><b data-path-to-node=\"18,1,0\" data-index-in-node=\"0\">C\u00f3digo en la pesta\u00f1a Events:<\/b><\/p>\n<\/li>\n<\/ol>\n<div class=\"code-block ng-tns-c687071695-76 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation\" data-hveid=\"0\" data-ved=\"0CAAQhtANahgKEwiQyrqxjdmTAxUAAAAAHQAAAAAQrwE\">\n<div class=\"code-block-decoration header-formatted gds-title-s ng-tns-c687071695-76 ng-star-inserted\"><span class=\"ng-tns-c687071695-76\">Fragmento de c\u00f3digo<\/span><\/p>\n<div class=\"buttons ng-tns-c687071695-76 ng-star-inserted\">\u00a0<\/div>\n<\/div>\n<div class=\"formatted-code-block-internal-container ng-tns-c687071695-76\">\n<div class=\"animated-opacity ng-tns-c687071695-76\">\n<pre class=\"ng-tns-c687071695-76\"><code class=\"code-container formatted ng-tns-c687071695-76\" role=\"text\" data-test-id=\"code-content\">Event 'CargarDatos'\r\n    \/\/ Supongamos que queremos cargar la factura n\u00famero 10\r\n    &amp;FacturaId = 10 \r\n    \r\n    \/\/ Llamada m\u00e1gica: La variable SDT recibe el resultado del DP directamente\r\n    &amp;Factura = DP_ObtenerFactura(&amp;FacturaId)\r\n    \r\n    \/\/ A partir de ac\u00e1, ya ten\u00e9s la variable &amp;Factura cargada en memoria.\r\n    \/\/ Pod\u00e9s usarla para mostrarla en pantalla, guardarla en Session, o recorrerla:\r\n    \r\n    Msg(\"El cliente es: \" + &amp;Factura.ClienteNombre)\r\n    \r\n    \/\/ Ejemplo de c\u00f3mo recorrer la colecci\u00f3n que devolvi\u00f3 el DP\r\n    For &amp;Linea in &amp;Factura.<code class=\"code-container formatted ng-tns-c687071695-75\" role=\"text\" data-test-id=\"code-content\">SDT_Facturaitem<\/code> Msg(\"Producto: \" + &amp;Linea.ProductoNombre + \" - Cantidad: \" + &amp;Linea.LineaCantidad.ToString()) EndFor EndEvent<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Paso 1: Crear y configurar el SDT Primero necesitamos el &#8220;molde&#8221; donde el Data Provider va a volcar la informaci\u00f3n. Crear el objeto: Ve a New Object -&gt; Structured Data Type. Nombre ejemplo: SDT_Factura (Es buena pr\u00e1ctica ponerle el prefijo SDT_ para identificarlo r\u00e1pido). Estructura: Este ejemplo esta hecho con una estructura de una cabecera [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":643,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-640","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-docs"],"_links":{"self":[{"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts\/640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=640"}],"version-history":[{"count":1,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts\/640\/revisions"}],"predecessor-version":[{"id":642,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts\/640\/revisions\/642"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/media\/643"}],"wp:attachment":[{"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}