{"id":679,"date":"2026-05-14T10:45:53","date_gmt":"2026-05-14T13:45:53","guid":{"rendered":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/?p=679"},"modified":"2026-05-18T10:49:12","modified_gmt":"2026-05-18T13:49:12","slug":"migrar-un-procedimiento-que-genera-un-pdf-y-un-excel-de-gx9-a-gx18","status":"publish","type":"post","link":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/?p=679","title":{"rendered":"Migrar un procedimiento que genera un PDF y un Excel de GX9 a GX18"},"content":{"rendered":"<div class=\"header\">\n<h1>\ud83d\udd04 Migraci\u00f3n GX9 \u2192 GX18: Como Migrar un procedimiento que genera un PDF y un Excel<\/h1>\n<p>Usaremos un caso de ejemplo de c\u00f3mo se separ\u00f3 un procedimiento original en GX9 en dos archivos independientes (PDF y Excel) en GX18<\/p>\n<div class=\"tags\"><strong><span class=\"htag old\">GX9: FiscImpr <\/span><span class=\"htag new\">GX18: PFiscImpPDF y<\/span><span class=\"htag new\">\u00a0PFiscImpExcel<\/span><\/strong><\/div>\n<\/div>\n<div class=\"section\">\n<h2>\ud83d\udccb\u00a0<u>Resumen de la migraci\u00f3n<\/u><\/h2>\n<p>En\u00a0<b>GeneXus 9<\/b>\u00a0exist\u00eda un \u00fanico procedimiento llamado\u00a0<code>FiscImpr<\/code>\u00a0que generaba tanto\u00a0<b>Excel<\/b>\u00a0como\u00a0<b>PDF<\/b>. En\u00a0<b>GeneXus 18<\/b>\u00a0se separ\u00f3 en dos procedimientos independientes para mayor claridad y mantenimiento:<\/p>\n<div class=\"arrow-box\">\n<div class=\"box old-f\">FiscImpr\u00a0<span class=\"muted\">(GX9)<\/span><\/div>\n<p><span class=\"arrow\">\u2192<\/span><\/p>\n<div class=\"box new-f\">PFiscImpPDF<\/div>\n<p><span class=\"arrow\">+<\/span><\/p>\n<div class=\"box new-f2\">PFiscImpExcel<\/div>\n<\/div>\n<\/div>\n<div class=\"section teal\">\n<h2>\ud83d\udcca\u00a0<u>Creaci\u00f3n de PFiscImprExcel<\/u><\/h2>\n<p>Se parti\u00f3 de una\u00a0<b>copia del original<\/b>\u00a0FiscImpr (GX9) y se aplicaron estos pasos:<\/p>\n<h3>Pasos realizados<\/h3>\n<div class=\"step\"><span class=\"step-num\">1<\/span><\/p>\n<p>Con\u00a0<span class=\"kbd\">Ctrl+F<\/span>\u00a0busqu\u00e9 todas las l\u00edneas que conten\u00edan\u00a0<code>print<\/code>\u00a0en el c\u00f3digo y las\u00a0<b>elimin\u00e9<\/b>, ya que pertenecen a la generaci\u00f3n del PDF.<\/p>\n<\/div>\n<div class=\"step\"><span class=\"step-num\">2<\/span><\/p>\n<p>En la secci\u00f3n de\u00a0<b>Layout<\/b>\u00a0borr\u00e9 todo el contenido (los printblocks del PDF).<\/p>\n<\/div>\n<div class=\"step\"><span class=\"step-num\">3<\/span><\/p>\n<p>Con\u00a0<span class=\"kbd\">Ctrl+H<\/span>\u00a0(Replace) reemplac\u00e9 todas las llamadas viejas del Excel:<br \/><code>&amp;Excel<\/code>\u00a0\u2192\u00a0<code>&amp;ExcelDocument<\/code><br \/>Esto convierte autom\u00e1ticamente las referencias como\u00a0<code>&amp;Excel.Cells<\/code>\u00a0a\u00a0<code>&amp;ExcelDocument.Cells<\/code>.<\/p>\n<\/div>\n<div class=\"step\"><span class=\"step-num\">4<\/span><\/p>\n<p>Reemplac\u00e9 la\u00a0<b>Sub &#8216;XLS&#8217;<\/b>\u00a0completa. Se elimin\u00f3 la llamada vieja a\u00a0<code>PCrtFile<\/code>\u00a0y se us\u00f3\u00a0<code>GetBlob<\/code>\u00a0+\u00a0<code>DownloadBlob<\/code>\u00a0en su lugar.<\/p>\n<\/div>\n<h3>Comparaci\u00f3n: Sub &#8216;XLS&#8217;<\/h3>\n<p><b>\u274c GX9 (antes):<\/b><\/p>\n<pre><code><span class=\"kw\">Sub<\/span> <span class=\"st\">'XLS'<\/span>\r\n    &amp;PlaNom = Upper(&amp;IdBienChr) + '_' + Upper(&amp;Tip)\r\n    &amp;PlaNom = Trim(&amp;PlaNom)\r\n    <span class=\"cm\">\/\/ Usaba PCrtFile para obtener la plantilla<\/span>\r\n    <span class=\"dl\">Call(PCrtFile, 2, 61,'','N',&amp;PlaNom,'N',&amp;PlaImp,&amp;PlaAbr,&amp;ArcDes,&amp;CantCopias,&amp;Ok)<\/span>\r\n    <span class=\"dl\">&amp;Exist = FileExist(&amp;ArcDes)<\/span>\r\n    <span class=\"dl\">if &amp;Exist = 0<\/span>\r\n        <span class=\"dl\">&amp;msg = 'No existe Plantilla ' + &amp;ArcDes<\/span>\r\n        <span class=\"dl\">Msg(&amp;msg)<\/span>\r\n        <span class=\"dl\">Return<\/span>\r\n    <span class=\"dl\">Else<\/span>\r\n        <span class=\"dl\">If &amp;ArcDes &lt;&gt; ''<\/span>\r\n            <span class=\"dl\">&amp;Err = &amp;Excel.Open(&amp;ArcDes)<\/span>\r\n            <span class=\"dl\">If &amp;Excel.ErrCode &lt;&gt; 0<\/span>\r\n                <span class=\"dl\">Msg('Error de carga de archivo')<\/span>\r\n                <span class=\"dl\">Return<\/span>\r\n            <span class=\"dl\">Else<\/span>\r\n                &amp;T = 7\r\n                &amp;P = 1\r\n                &amp;Excel.Cells(1,1).Text = &amp;Head(1)\r\n                <span class=\"cm\">\/\/ ...resto de celdas...<\/span>\r\n            <span class=\"dl\">EndIF<\/span>\r\n        <span class=\"dl\">EndIF<\/span>\r\n    <span class=\"dl\">Endif<\/span>\r\n<span class=\"kw\">EndSub<\/span><\/code><\/pre>\n<p><b>\u2705 GX18 (despu\u00e9s):<\/b><\/p>\n<pre><code><span class=\"kw\">Sub<\/span> <span class=\"st\">'XLS'<\/span>\r\n    <span class=\"cm\">\/\/ Obtener plantilla con GetBlob (c\u00f3digo 61)<\/span>\r\n    &amp;PlaCod = 61\r\n    <span class=\"nw\">getblob.Call(&amp;PlaCod, &amp;NuevoArchivo, &amp;PlaNom, &amp;PlaExtArc, &amp;mensaje, &amp;ok)<\/span>\r\n    <span class=\"kw\">If<\/span> &amp;Ok &lt;&gt; 'S'\r\n        msg(&amp;mensaje)\r\n        Return\r\n    <span class=\"kw\">EndIf<\/span>\r\n\r\n    <span class=\"cm\">\/\/ Abrir Excel<\/span>\r\n    <span class=\"nw\">&amp;ExcelDocument.Open(&amp;NuevoArchivo)<\/span>\r\n    <span class=\"kw\">If<\/span> &amp;ExcelDocument.ErrCode &lt;&gt; 0\r\n        msg(<span class=\"st\">'Error al abrir Excel: '<\/span> + &amp;ExcelDocument.ErrDescription)\r\n        &amp;ExcelDocument.Close()\r\n        Return\r\n    <span class=\"kw\">EndIf<\/span>\r\n\r\n    <span class=\"cm\">\/\/ Encabezados fijos<\/span>\r\n    &amp;ExcelDocument.Cells(1,  1).Text = &amp;Head(1)\r\n    &amp;ExcelDocument.Cells(6,  2).Text = &amp;Head(2)\r\n    &amp;ExcelDocument.Cells(6,  8).Text = &amp;Head(3)\r\n    &amp;ExcelDocument.Cells(6, 11).Text = DTOC(&amp;FisFecAct)\r\n    &amp;ExcelDocument.Cells(6, 13).Text = &amp;Head(4)\r\n    &amp;ExcelDocument.Cells(1,  8).Text = &amp;Head(6)\r\n\r\n    <span class=\"cm\">\/\/ Encabezados de columnas<\/span>\r\n    &amp;T = 7\r\n    &amp;P = 1\r\n    <span class=\"kw\">Do While<\/span> &amp;T &lt; 36\r\n        <span class=\"kw\">If<\/span> &amp;Head(&amp;T) &lt;&gt; ''\r\n            &amp;ExcelDocument.Cells(8, &amp;P).Text = &amp;Head(&amp;T)\r\n            &amp;ExcelDocument.Cells(8, &amp;P).Bold = True\r\n        <span class=\"kw\">EndIf<\/span>\r\n        &amp;T += 1\r\n        &amp;P += 1\r\n    <span class=\"kw\">EndDo<\/span>\r\n<span class=\"kw\">EndSub<\/span><\/code><\/pre>\n<div class=\"alert wiki\">\ud83d\udcd6 Existe documentaci\u00f3n aparte sobre c\u00f3mo utilizar\u00a0<b>GetBlob<\/b>\u00a0y\u00a0<b>DownloadBlob<\/b>\u00a0para reemplazar el viejo\u00a0<b>PCrtFile \/ PCrtFilev2<\/b>. Consultala en la wiki.<\/p>\n<p>Luego en el sub Mues_XLS que comunmente sule estar en todos los procedimientos lo dejamos asi:<br \/>Sub &#8216;MuesExc&#8217;<br \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0&amp;ExcelDocument.Save()<br \/>\u00a0 \u00a0 \u00a0 \u00a0 &amp;ExcelDocument.Close()<br \/>EndSub<\/p>\n<p>Es muy importante dejarlo asi ya que suele estar &amp;ExcelDocument.Show() lo cual nos dara un error invisible<\/p>\n<p><strong>Rules:<\/strong><br \/>Por ultimo agregaremos las variables nuevas del GetBlob como salida:<br \/><strong>out:&amp;mensaje, out:&amp;PlaExtArc, out:&amp;PlaNom,out:&amp;NuevoArchivo<\/strong><\/div>\n<h2>\u2699\ufe0f\u00a0<u>Propiedades del objeto<\/u><\/h2>\n<table>\n<tbody>\n<tr>\n<th>Propiedad<\/th>\n<th>Valor<\/th>\n<\/tr>\n<tr>\n<td><b>Call Protocol<\/b><\/td>\n<td><code>Internal<\/code><\/td>\n<\/tr>\n<tr>\n<td><b>Main Program<\/b><\/td>\n<td><code>False<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"section green\">\n<h2>\ud83d\udcc4\u00a0<u>Creaci\u00f3n de PFiscImpPDF<\/u><\/h2>\n<p>Tambi\u00e9n se parti\u00f3 de una copia del original FiscImpr (GX9) pero aplicando la l\u00f3gica inversa:<\/p>\n<div class=\"step\"><span class=\"step-num\">1<\/span><\/p>\n<p>Con\u00a0<span class=\"kbd\">Ctrl+F<\/span>\u00a0busqu\u00e9 todas las l\u00edneas que conten\u00edan\u00a0<code>Excel<\/code>\u00a0y las\u00a0<b>elimin\u00e9<\/b>, ya que este procedimiento solo genera PDF.<br \/>Al igual que la llamada del PCrtFile o PCrtFileV2 y las lineas que debugean esos procedimientos como:<\/p>\n<p>&amp;Exist = FileExist(&amp;ArcDes)<br \/>If &amp;Exist = 0<br \/>\u00a0 \u00a0 \u00a0 \u00a0 Msg(&#8216;No existe plantilla: &#8216; + &amp;ArcDes)<br \/>\u00a0 \u00a0 \u00a0 \u00a0 Return<br \/>EndIf<\/p>\n<p><strong>Rules:<\/strong><br \/>Agregamos el output_file:<br \/><strong>output_file(&#8216;Impresion_Fiscalizacion&#8217;,&#8217;PDF&#8217;);<\/strong><\/p>\n<\/div>\n<\/div>\n<div class=\"section orange\">\n<h2>\u2699\ufe0f\u00a0<u>Propiedades del objeto<\/u><\/h2>\n<table style=\"height: 135px\" width=\"379\">\n<tbody>\n<tr>\n<th>Propiedad<\/th>\n<th>\u00a0<\/th>\n<th>PFiscImpPDF<\/th>\n<\/tr>\n<tr>\n<td><b>Call Protocol<\/b><\/td>\n<td>\u00a0<\/td>\n<td><code>HTTP<\/code><\/td>\n<\/tr>\n<tr>\n<td><b>Main Program<\/b><\/td>\n<td>\u00a0<\/td>\n<td><code>True<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u00a0<\/td>\n<td>\u00a0<\/td>\n<td>\u00a0<\/td>\n<\/tr>\n<tr>\n<td>\u00a0<\/td>\n<td>\u00a0<\/td>\n<td>\u00a0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"section purple\">\n<p>\ud83d\udda5\ufe0f\u00a0<u>Pantalla que llama a los procedimientos: WFiscExte<\/u><\/p>\n<p>En la pantalla\u00a0<code>WFiscExte<\/code>\u00a0se agregaron\u00a0<b>2 checkboxes<\/b>: uno para\u00a0<b>XLS<\/b>\u00a0y otro para\u00a0<b>PDF<\/b>. Al lado hay botones de acci\u00f3n (Agentes Percepci\u00f3n, Contribuyentes, Fisco, etc.). Seg\u00fan qu\u00e9 checkbox est\u00e9 marcado, se llama al procedimiento correspondiente.<\/p>\n<h3>Ejemplo: Event &#8216;DoAgePer&#8217; (Agentes de Percepci\u00f3n)<\/h3>\n<pre><code><span class=\"kw\">Event<\/span> <span class=\"st\">'DoAgePer'<\/span>\r\n    <span class=\"cm\">\/\/ Si eligi\u00f3 PDF<\/span>\r\n    <span class=\"kw\">if<\/span> &amp;pdfgen = true\r\n        <span class=\"fn\">pfiscimpPDF<\/span>.Call(<span class=\"st\">'APE'<\/span>, ORGCOD, IdBien, FisCod, FisEstCod)\r\n    <span class=\"kw\">endif<\/span>\r\n\r\n    <span class=\"cm\">\/\/ Si eligi\u00f3 Excel<\/span>\r\n    <span class=\"kw\">If<\/span> &amp;GenExe = True\r\n        <span class=\"fn\">PFiscImprExcel<\/span>.call(<span class=\"st\">'APE'<\/span>, ORGCOD, IdBien, FisCod,\r\n                FisEstCod, &amp;GenExe, &amp;mensaje, &amp;PlaExtArc,\r\n                &amp;PlaNom, &amp;NuevoArchivo)\r\n        <span class=\"fn\">DownloadBlob<\/span>.link(&amp;PlaExtArc, &amp;PlaNom, &amp;NuevoArchivo)\r\n    <span class=\"kw\">EndIf<\/span>\r\n<span class=\"kw\">EndEvent<\/span><\/code><\/pre>\n<h3>Ejemplo: Event &#8216;DoPeriodosGenerados&#8217;<\/h3>\n<p class=\"muted\">En este caso la opci\u00f3n de Excel\u00a0<b>no est\u00e1 disponible<\/b>, solo funciona PDF. Si el usuario marca XLS se muestra un mensaje con un toast informativo.<\/p>\n<pre><code><span class=\"kw\">Event<\/span> <span class=\"st\">'DoPeriodosGenerados'<\/span>\r\n    <span class=\"kw\">if<\/span> &amp;pdfgen = true\r\n        <span class=\"kw\">If<\/span> FisEstCod = 2 <span class=\"kw\">OR<\/span> FisEstCod = 4\r\n            <span class=\"fn\">PFisPerGen<\/span>.Call(ORGCOD, IdBien, FisCod)\r\n        <span class=\"kw\">Else<\/span>\r\n            msg(<span class=\"st\">'Esta opci\u00f3n esta disponible para Fiscalizaci\u00f3n\/Sumario PROCESADOS'<\/span>)\r\n        <span class=\"kw\">EndIf<\/span>\r\n    <span class=\"kw\">EndIf<\/span>\r\n    <span class=\"kw\">If<\/span> &amp;GenExe = True\r\n        toast.Info(<span class=\"st\">'EXCEL NO DISPONIBLE'<\/span>,\r\n            <span class=\"st\">'Esta Opcion solo esta disponible en PDF'<\/span>, 5000, <span class=\"st\">''<\/span>)\r\n    <span class=\"kw\">endif<\/span>\r\n<span class=\"kw\">EndEvent<\/span><\/code><\/pre>\n<div class=\"alert info\">\u2139\ufe0f El patr\u00f3n es siempre el mismo: verificar el checkbox \u2192 llamar al procedimiento correspondiente. Para Excel, despu\u00e9s del\u00a0<code>.call<\/code>\u00a0siempre va el\u00a0<code>DownloadBlob.link<\/code>.<\/div>\n<div class=\"alert wiki\">\ud83d\udcd6 Existe documentaci\u00f3n en la wiki sobre c\u00f3mo funciona\u00a0<b>DownloadBlob<\/b>. Consultala para m\u00e1s detalle.<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udd04 Migraci\u00f3n GX9 \u2192 GX18: Como Migrar un procedimiento que genera un PDF y un Excel Usaremos un caso de ejemplo de c\u00f3mo se separ\u00f3 un procedimiento original en GX9 en dos archivos independientes (PDF y Excel) en GX18 GX9: FiscImpr GX18: PFiscImpPDF y\u00a0PFiscImpExcel \ud83d\udccb\u00a0Resumen de la migraci\u00f3n En\u00a0GeneXus 9\u00a0exist\u00eda un \u00fanico procedimiento llamado\u00a0FiscImpr\u00a0que generaba [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":680,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-679","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\/679","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=679"}],"version-history":[{"count":4,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts\/679\/revisions"}],"predecessor-version":[{"id":686,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/posts\/679\/revisions\/686"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=\/wp\/v2\/media\/680"}],"wp:attachment":[{"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=679"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=679"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.gobiernoriocuarto.gob.ar\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=679"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}