Automatizando el control de asientos descuadrados

📝 Uno de los puntos habituales a repasar cuando estamos revisando nuestros cierres contables es el que no haya ningún asiento descuadrado.

⚖️​Es decir, que se cumpla el principio de partida doble (si nos ponemos técnicos), o “las gallinas que entran por las que salen” si hablamos en lenguaje coloquial 😉

Los programas de contabilidad o ERPs suelen tener avisos que nos protegen ante errores al introducir asientos descuadrados.

En la siguiente imagen, muestro un mensaje que proporciona SAGE 200 Advanced cuando pretendo introducir un asiento descuadrado:          

NOTA: Los pasos e imágenes que veremos en el post están basados en SAGE 200 Advanced.

No obstante, si el usuario pulsa sobre el botón “Sí”, el asiento se graba en la base de datos tan tranquilamente…🤔

Incluso hay muchos asientos que no les introduce ningún usuario manualmente, sino que se generan automáticamente desde algún proceso que tengamos configurado bien desde la versión estándar del programa, o alguna personalización que hayamos implementado (contabilización automática de facturas de venta/compra, control de riesgos por descuento de efectos, recepción de albaranes de compra…)

En esos casos también corremos el riesgo de que algún asiento automático entre al programa con algún descuadre por alguna incidencia que se haya saltado los controles…

Los programas suelen incluir también una opción para sacar un listado con los asientos descuadrados que se han introducido en el sistema.

En SAGE 200 Advanced la pantalla sería la siguiente (si tenemos la contabilidad de varias empresas en la interfaz de SAGE debemos ir cambiando de empresa para ir consultando la pantalla empresa por empresa, mientras que en Power BI podremos consultar todas las empresas al mismo tiempo):

Vemos que en el asiento 15.314, del 15/04/2025, hay un descuadre de 201,25 €, ya que hay más gallinas que han entrado por el Debe de las que han salido por el Haber 😉.

Podemos comprobarlo entrando al asiento:

En el post de hoy vamos a ver cómo generar un proceso que nos compruebe periódicamente si hay algún asiento descuadrado y, en caso afirmativo, nos envíe un email avisándonos de la incidencia para poder corregirla.

Lo primero que vamos a hacer es entrar en Power BI y, a través del conector de SQL Server de Power Query, conectarnos a la base de datos del ERP, concretamente a la tabla “Movimientos”, que es donde se almacena la información de los apuntes contables:

Nos quedamos únicamente con las siguientes columnas:

Me voy a quedar a continuación únicamente con los asientos que sean del ejercicio actual o del anterior (de forma dinámica), porque entendemos que los periodos anteriores ya deberían estar cerrados y con la contabilidad revisada y bloqueada.  Lo hacemos mediante el siguiente código M:

A partir de las columnas “CodigoEmpresa”, “Ejercicio” y “Asiento” (las selecciono en ese mismo orden con el “Control” pulsado) nos construimos el identificador único del asiento; ya que el campo “Asiento” se puede repetir para distintos ejercicios y códigos de empresa (resalto en amarillo en la imagen anterior que tenemos asientos de distintas empresas).

Lo hacemos a través de la opción “Transformar” => “Combinar columnas” y usamos el separador que queramos (yo suelo usar un guión bajo) y el nombre de la nueva columna (en mi caso “idAsiento”):

Quedaría así la información:

Como vemos, SAGE nos da el importe del apunte en la columna “ImporteAsiento” y en la columna “CargoAbono” nos indica si ese importe va al Debe o al Haber.

En el caso de otros ERPs nos aparecen los importes directamente separados en columnas de Debe y Haber.

Vamos a hacer esa separación a través de agregar nuevas columnas condicionales que nos den los importes de debe y haber por separado.

Muestro a continuación cómo sería la creación de la columna “Debe” y seguiríamos el mismo patrón para crear la del “Haber”:

Con esos pasos ya tendría creadas las nuevas columnas:

Ahora simplemente voy a darle formato Número Decimal Fijo a estas nuevas 2 columnas y voy a eliminar las columnas “ImporteAsiento” y “CargoAbono”, ya que ya no las voy a necesitar.

Llegaríamos a la siguiente situación:

Lo siguiente que voy a hacer es agrupar los datos por el campo “idAsiento” para obtener el total de importe al Debe y total importe al Haber de cada uno de los asientos, ya que mi único objetivo es saber si están descuadrados (los datos vienen a granularidad de apunte contable y cada asiento contable puede tener N apuntes):

Ahora voy a hacer una nueva columna calculada a la que voy a llamar “Saldo” y que calcularé como la resta de las columnas “Total_Debe” y “Total_Haber”. Tendré que seleccionar las 2 columnas con el Control en el orden indicado (primero Total_Debe y luego Total_Haber), y posteriormente seguir los pasos de la siguiente pantalla:

En la siguiente pantalla vemos los resultados de la nueva columna. Resalto en amarillo algunos valores que debería ser cero pero cuyo resultado no es exactamente cero. Como se aprecia en el valor marcado en azul, del origen nos vienen valores que no están correctamente redondeados, lo cual es el motivo de esos valores resaltados en amarillo:

Vamos a modificar el nombre de la columna “Resta” por el de “Saldo” y modificamos el tipo de dato a la columna para ponerlo como “Numero decimal fijo” para resolver ese problema de los redondeos. Vemos en la siguiente pantalla que los mismos registros que en la pantalla anterior no aparecían con valor cero ahora sí que lo hacen gracias al cambio de tipo de dato:

Si filtramos los valores de la columna “Saldo” por los que sean distintos a cero, veremos cómo pasamos a tener un único registro en la tabla, que es precisamente el que nos marcaba la interfaz del ERP, el asiento nº 15314 del ejercicio 2025 de la empresa 1:

Por último, eliminaría las columnas Total_Debe y Total_Haber, dado que ya no las necesito, y pulso sobre cerrar y aplicar para llevarme los datos desde Power Query a Power BI.

Vemos a continuación los datos desde la vista de tabla de Power BI Desktop:

Tras esto, haremos una sencilla medida DAX que lo que hará será contar el número de filas de nuestra tabla y que nos dará como el resultado el número de asientos que tenemos descuadrados en nuestra contabilidad. Vemos a continuación el resultado sobre un visual de tarjeta:

Ahora lo que vamos a hacer es obtener la consulta DAX que genera el objeto visual para después poder pasársela a Power Automate.

Para ello, vamos el menú “Ver” => “Analizador de rendimiento”. Pulsamos sobre “Actualizar objetos visuales” y copiamos la consulta con el botón “Copiar consulta”:

El texto que se nos copia en el portapapeles es el siguiente:

// DAX Query

EVALUATE

               ROW(

               «v__Asientos_Descuadrados», ‘Movimientos'[# Asientos Descuadrados]

)

Ahora lo que vamos a hacer es publicar nuestro informe en el servicio de Power BI desde el botón “Publicar”, y seleccionar el área de trabajo donde queramos publicarlo.

Una vez publicado, configuraremos la sincronización con la puerta de enlace al servidor donde esté la base de datos del ERP; y estableceremos las actualizaciones programadas que consideremos (en nuestro caso una actualización diaria a las 01:00 a.m.).

A continuación, nos vamos a Power Automate y creamos un flujo de nube programado que se ejecute todos los días a las 02:00 a.m. (como hemos indicado en el servicio de Power BI que el informe se actualice a las 01:00 a.m., a las 02:00 a.m. ya nos aseguremos que el informe esté actualizado y que podamos “pillar” a los nuevos asientos descuadrados):

A continuación, añadimos una nueva acción al flujo y elegimos la acción de ejecutar una consulta contra un conjunto de datos de Power BI.

Debemos seleccionar el área de trabajo y el modelo semántico y, posteriormente, pegar en el “Texto de la consulta” la consulta DAX que copiamos en el portapapeles cuando seguimos los pasos de ver el analizador de rendimiento de Power BI Desktop:

Tras ello, añadimos una nueva acción y elegimos la acción “Seleccionar”. 

En el apartado “Desde” pulsamos sobre el icono de un rayo que nos permite obtener datos del paso anterior:

Elegimos la opción “Primeras filas de la tabla”:

Dejamos configurados los campos de la opción “Mapa” de la siguiente forma:

A continuación, añadimos un nuevo paso con la acción “Redactar” e introducimos la siguiente expresión desde el botón con las iniciales “fx”:

first(first(body(‘Seleccionar’))[‘#Asientos’])[‘[v__Asientos_Descuadrados]’]

‘Seleccionar’ hace referencia al nombre del paso anterior del flujo de Power Automate.

‘#Asientos’ es el nombre que hemos dado al parámetro en la sección “Mapa” de la imagen del paso anterior.

‘[v__Asientos_Descuadrados]’ nos viene establecido desde la consulta DAX del objeto visual de tarjeta.

Este último paso ya nos devuelve como Output el valor de la tarjeta, en nuestro caso, la salida es el valor “1”. Lo podemos comprobar si ejecutamos el flujo manualmente y comprobamos los resultados:

A continuación, añadimos un nuevo paso de condición con el objetivo de que si el valor de salida del paso anterior (que es el valor de la tarjeta de Power BI) es mayor que cero, nos envíe un email de alerta para que sepamos que hay algún asiento descuadrado:

Posteriormente, indicamos en si se cumple la condición, envíe un email al destinatario que indiquemos y en el cuerpo del email añadimos el nº de asientos descuadrados a través de la salida del paso “Redactar”:

Ya lo tendríamos todo preparado….

Falta ver que todo funcione y a continuación os muestro la prueba de que puntualmente a las 02:00, tenía un email en mi buzón de entrada:

Podríamos adaptar el proceso si queremos incluir en el aviso las cuentas contables que intervienen en los apuntes de cada asiento, o incluso los conceptos, y enviar por email una tabla que represente el asiento tal y como lo vemos en el ERP.

Por simplificarlo lo hemos dejado en una notificación que nos indique que hay algún asiento descuadrado y ya con ese aviso iremos nosotros a ver la pantalla de descuadres al ERP y modificaremos los errores que detectemos.

También podemos incorporar a Power BI una sencilla tabla con los asientos de Power BI y comprobarlos desde nuestro informe en Power BI:

Sencillo y realmente útil, ¿no crees?.

La verdad es que esta combinación de Power Automate y Power BI es realmente potente y es uno de los desafíos en los que quiero centrarme en el corto plazo.

Veremos a dónde nos lleva y, como siempre, os iré compartiendo nuevos retos y funcionalidades.

Seguimos!!! 👊

Si te ha gustado, compártelo!!! 👇 No te guardes el secreto 😜