Calculate end date based on own particular work week

HI Everyone, I have an App in which I want select to configure a working week. A Enumlist where I choose the days in which I am going to execute my work:

Sunday

Monday

Tuesday

Wednesday

Thursday

Friday

Saturday

All are chosen by a check box.

Once the days have been chosen, I have to choose the start date of the work. Suppose I start today 3/17/2022 and that I will work Monday, Wednesday and Friday. Also assume a period of 30 business days. Also take into account holidays. What I need is to be able to calculate the end date of the work, taking into account a period of 30 business days, holidays and the previously chosen work week configuration.

This would give me a result with a date 10 weeks later if there is no holiday that falls on some of the days.

One of the formulas I used is WORKDAY() however it is limited as it only excludes Saturdays from the list, Sundays.

Is there a way to create my own WORKDAY formula excluding the days I want?


No matter how fancy the formula is, I'll do it the same

@Steve @TeeSee1 @Joseph_Seddik 

Solved Solved
0 26 818
3 ACCEPTED SOLUTIONS

Here it is, I've changed the display names to English, but was too lazy to change the expressions, but I think you'll be able to relate. In any case, please tell me if you have any difficulties. 

Todavía no he leído en detalle tu última respuesta, perdón amigo, voy a leerla más tarde con tranquilidad y te contesto.

Target Workday Calculator 2

View solution in original post

@Gustavo_Eduardo Yo calculaba basándome en que el día del inicio NO está incluido, pero el día final Sí. 

Si quieres incluir ambos días, en la expresión tendrás que cambiar:

[Date] >  [_ThisRow].[Date de début]

por:

[Date] >= [_ThisRow].[Date de début]

View solution in original post

@Gustavo_Eduardo 

This is a better, even simpler version, with no VCs, and functions both ways: with global settings for workdays and holidays, and also on a per-calculation basis. Calculation records now can be freely edited. Also, this version is focused on integrability so should serve you better. 

Target Workday Calculator 2

View solution in original post

26 REPLIES 26

I cannot think of any single formula that does this. (I very quickly gave up,,,)

Here is a 'brute force' approach that works but you may not like it.

Some preps

  • create a Holidays table which simply lists holidays that you do not want to include as part of your work/business days.
  • in your main table, create a temporary [count down] with Initial Val to [Required Business Days] <= you can use [Required Business Days] but wanted to preserve it.

Then, Create a actions below

1. Start of the sequence

2. Move End Date by one day

3. Reduce [count down] if it falls on the weekdays you chose AND not in the holidays table

4. Go back to 1. if [count down] > 0

Looping process is something AppSheet cannot do in an elegant way. (No Code 😁)

If you are interested I can share the demo app..

Perfecto @TeeSee1 apenas despierte la vemos !

TeeSee1_0-1647656494933.png

Just for anyone who might be interested..

https://www.appsheet.com/portfolio/3401559

"work days"

@TeeSee1 wow recien veo esto. Es otra manera de llegar a los valores. En este momento me estoy manejando con la respuesta de Joseph pero con gusto la estudio! Te agradezco que me hayas permitido verla! Saludos

Como estás @TeeSee1 Buen día, voy a intentar probando con tu solución. La forma que me da Joseph es buena pero mi app se pone muy lenta. Una vez que realice ambas adaptaciones pruebo y les comento.

Wow ! Were you tapping the calls some 10 days ago? 😄

I’ve implemented this very same requirement as part of a project presentation to a customer, and will be happy to share with the community. Let me just isolate it and do some UX translation to English and will post the sample app. No actions or complexities involved; just simple expressions. 

Wow!!! Joseph!! espectacular, Yo al menos de mi parte te agradecería mucho poder ver como lo has resuelto. Por ahora te comento como voy haciendolo (a la manera de un cavernícola no programador como yo soy). 

Tengo como dato:

  • Fecha de inicio del proyecto
  • Número de días que dura el trabajo
  • Cantidad de días trabajados por semana (que es una columna que se calcula sola en función de la selección del usuario de datos de una enumlist donde están los días de semana); si selecciono 5 días, la cantidad de días trabajados será 5
  • Fecha de finalización: que es un cálculo que hago de la siguiente manera

 

([Fecha de Inicio]-1)+(FLOOR([Plazo en días]/[Días laborales por semana])*7)+

(

   ([Plazo en días]/[Días laborales por semana])-

   FLOOR([Plazo en días]/[Días laborales por semana])

  )*([Días laborales por semana])

 

Esto me permite conocer cuanto se desplaza la fecha pero no es muy exacto y tampoco profesional. Estoy seguro que tu tienes algo muy profesional para mostrar. Te agradezco si puedes corregirme.

Ahora estoy por hacer un "recalculo" teniendo en cuenta los días festivos que hay en el lapso desde el inicio hasta la fecha final y luego recalcular la fecha final. Tengo que aclarar para que no te rias, soy un principiante, pero no me quedó más remedio que ingeniarmela para obtener el resultado. Si pudiera contar con algo como lo tuyo sería ideal.

COUNT(
              SELECT(
                               Feriados[Fecha Feriado],
                                                                                [Fecha Feriado]>=[Fecha de Inicio],
                                                                                [Fecha Feriado]<=[Fecha Final 1]
                      )
)

 

luego recalculo y obtengo

([Fecha de Inicio]-1)+(FLOOR(([Plazo en días]+[Feriados])/[Días laborales por semana])*7)+((([Plazo en días]+[Feriados])/[Días laborales por semana])-FLOOR(([Plazo en días]+[Feriados])/[Días laborales por semana]))*([Días laborales por semana])

Lo que tengo que hacer ahora es desplazar la fecha un día más si coinide con un día no laboral, haciendo que termine en un día laborable. Esta solución es muy rústica.

Hola Gus,

Una expresión similar fue la primera que he considerado mentalmente, pero el problema es que cuando desplaces la fecha target por el número de fechas no laborales y festivos encontrados, es muy probable que encuentres más días de este tipo y tendrás que desplazar de nuevo y será posible encontrar más días no laborales de nuevo, por eso descarté esta vía por la imposibilidad de ser controlado sobre todo porque el número de días del proyecto es indefinido. 

Aparte de eso, bien hecho 🙂 la creatividad es el mejor amigo al desarrollador. 

Here it is, I've changed the display names to English, but was too lazy to change the expressions, but I think you'll be able to relate. In any case, please tell me if you have any difficulties. 

Todavía no he leído en detalle tu última respuesta, perdón amigo, voy a leerla más tarde con tranquilidad y te contesto.

Target Workday Calculator 2

Tengo una duda respecto a cómo adaptarlo Joseph, Tu tienes en la App una vista de "Semana" donde puedes configurar la semana laborable sin embargo yo debo hacerlo para cada trabajo y dentro del formulario de trabajo. Para ello he adoptado una EnumList donde simplemente selecciono los días laborables de la semana y se crea una lista con los días que necesito. La diferencia radica en que en la fórmula de tu app haces referencia a una condición adoptada en la vista semana (Laborable o No laborable)

 

TOP(
        SELECT(

                         Dates[Date],

AND(
          [Date] > [_ThisRow].[Date de début],
         [Ouvrable]
         )

                             ),[Nombre de jours]
)

 

Sin embargo lo que yo necesito es adaptar esta fórmula para que, cuando yo seleccione directamente un elemento de la enumlist, los elementos seleccionados se consideren laborables.

Es eso posible?

El cálculo en realidad no se hace aquí, pero en la tabla Dates, columna "Ouvrable". 

AND(
  NOT( IN( WEEKDAY([Date]), SELECT(Semaine[Index], FALSE = [Ouvrable]) )),
  NOT( IN([Date], Jours Fériés[Date]) )
)

Esta es la formula que asigna el estado laboral o no laboral a una fecha. 

Ahora sobre la necesidad de hacer el cálculo por un trabajo. Esto es lo normal, lo esperado. Pero la cuestión es ¿cómo abordarlo? Primero, sí es posible adaptar la app para incorporar esta función y asignar fechas por trabajo, pero ¿sería el camino correcto?

Muchos desarrolladores suelen olvidarse de que la arquitectura del software es mas importante de su codificación. Sí, con algunos trucos de magia de codificación, se podría crear expresiones complejos con las cuales se incorporarán el calculo de fechas por proyecto y por usuario, etc. pero para mí esto sería una falta grave. Era exactamente el tema principal de mi presentación 🙂 KISS - Keep It Smart & Simple

La app se trata de una calculadora que se puede incorporar en contextos más grandes. El caso del cliente era más complejo, pero también en tu caso no necesitas hacer algo más para hacer el cálculo por trabajo:

  • Quédate con la tabla "Calculatrice" en tu app.
  • Tu tabla de Trabajos, debe tener las columnas: "Fecha Inicio", "Días laborales de la semana", "Nombre de Días" y "Fecha Final". 
  • Puedes copiar la expresión de "Date Cible" en "Fecha Final", o añadir una columna "TrabajoID" en "Calculatrice" y utilizar las Dereference Expressions para copiar el valor (en lugar de la expresión) de "Date Cible" en "Fecha Final".
  • Cuando añades un trabajo nuevo en la tabla Trabajos, en ese momento puedes elegir los días correspondientes, o hacerlo antes. 

Los datos de un trabajo en la tabla de Trabajos serán guardados en columnas normales en el spreadsheet, y así no serán cambiados si por ejemplo los días laborales han sido cambiados según un nuevo proyecto.

Además, puedes impedir que esos datos se cambien al editar la fila, poniendo la siguiente condición en el campo Editable? de cada columna:

ISBLANK([_This])

Así, una vez creado un trabajo, la información dinámica relacionada con los cálculos de fechas no se cambiarán nunca. 

Joseph, no sería lo mismo, e incluso algo más simple si a la expresión de cálculo la planteas así:

AND(
  IN( WEEKDAY([Date]), SELECT(Semaine[Index], TRUE= [Ouvrable]) ),
  NOT( IN([Date], Jours Fériés[Date]) )
)

 

Sí, es lo mismo, solo es una cuestión de estilo para mejorar la legibilidad (en mi pdv). 

Yo digo: selecciona las fechas que NI son laborales en la semana, NI son festivos.

Tú dices: selecciona las fechas que SÍ son no laborales, pero NO son festivos. 

 

Una pregunta Joseph! supongamos que tenemos trabajos de más de un año de demora y que la lista de fechas es pequeña.

No hay una manera de generar una lista virtual entre dos fechas de forma que podamos poner una fecha límite y una fecha de inicio de la lista y no todas las fechas del 2022, 23, .... 2070

Es obvio que quizás para esa época ya no exista Appsheet pero pienso que una lista carga mucho a la app. Por ahí una lista virtual sea menos pesada no crees?

Generar una lista dinámica implica utilizar Actions. Es posible, pero si lo prefieras, sería más sencillo utilizar la solución propuesta por @TeeSee1

Sin embargo, no creo que la lista de fechas cargaría la app o tendría un impacto sobre su rendimiento; porque la SELECT siempre se lanza en una tabla con solo siete filas. 

De todas formas la expresión en Dates se puede mejorar impidiendo  el cálculo para las fechas antiguas, por ejemplo así:

IF( [Date] < TODAY(), 
  FALSE, 
  AND( … )
)

Bien Joseph, la propuesta de ti si me dio la sensación que es buena y simple, pero no sé cómo implementarlas correctamente porque creo que en su solución él utiliza botones para calcular y yo necesito que sea automático como tu solución en realidad. Voy a intentar generar un comportamiento para ver si puedo lograrlo como él plantea pero la solución más fácil para mi es la tuya. Lo que si no puedo lograr es configurar la semana laboral desde la tabla trabajos todavía. Voy a sacar una captura de pantalla de mis tablas para ver si puedes ayudarme a adaptar seguro logramos hacerlo smart & simple 

De acuerdo. Por cierto, ¿me puedes mirar por favor el performance analyzer y decirme qué tablas o cálculos contribuyen más al tiempo de sync? Me interesa estudiar este tema en tu app, porque en mi lado no veo ningún impacto. Muchas gracias. 

UPDATE:

He añadido las fechas hasta finales de 2070, ¡son 19.700 filas! He podido calcular hasta 3.800 días, el único límite es los 50.000 caracteres en la celda porque estoy captando todas las fechas laborales en "Dates Ouvrés" sino no habrá límite. 

Cuando utilizas la Form, verás que el cálculo es casi inmediato, y el tiempo de sync es inferior a dos segundos. Copia la app de nuevo y pruébalo tú por favor. Gracias de nuevo.

@Gustavo_Eduardo 

Ok Joseph! voy a intentar inmediatamente lo que dices.

Mas tarde te envío una respuesta. Perdón la demora 

Respecto del "Target Day" a menos que sea considerado como fecha no incluida desde el inicio del conteo, estarías sumando un día más al plazo. 

Lo normal sería que si se arranca a trabajar un 1/3/2022 (todo el día) y tienes 20 días de plazo, el día 20/3/2022 termine el trabajo al final de la jornada, ya que se incluye el primer día como día completo trabajado dentro de los 20 de plazo. Si no se incluye este día, entonces está bien. Al menos en mi app es así, incluyo el día inicial dentro de los días hasta la fecha final. 

 

@Gustavo_Eduardo Yo calculaba basándome en que el día del inicio NO está incluido, pero el día final Sí. 

Si quieres incluir ambos días, en la expresión tendrás que cambiar:

[Date] >  [_ThisRow].[Date de début]

por:

[Date] >= [_ThisRow].[Date de début]

Perfecto Joseph, así lo hice como me lo planteas y está bien funciona.

Joseph te agradezco mucho tu buena forma de ser

@Gustavo_Eduardo 

This is a better, even simpler version, with no VCs, and functions both ways: with global settings for workdays and holidays, and also on a per-calculation basis. Calculation records now can be freely edited. Also, this version is focused on integrability so should serve you better. 

Target Workday Calculator 2

 

Joseph, la revisó, a mi app se aplica mucho mejor, el resultado es inmediato. Solo opté por la forma particular de elegir los días laborables y eliminé a general ya que no la utilizo. La simultanea, ahora, es rapida. Yo en mi app tampoco muestro los días laborables ni los feriados ya que se ven en otra tabla y vuelve engorroso el formulario, sin embargo entiendo que lo ha dejado de forma que se ve para mayor entendimiento. 

Realmente ahora anda perfecto, siendo que ha resuelto esto de la manera más práctica y que no existe fórmula para calcularlo así.

Respecto del Performance Analyzer, 00:00:01 es el tiempo que tarda en sincronizar, a la fecha. 

Lo que sí, me recomienda habilitar el almacenamiento en caché del servidor para mejorar el rendimiento. Lo estoy haciendo ahora mismo. 

Gracias Joseph infinitas, nuevamente. 

A toda la comunidad, quiero dejarle en claro que  @Joseph_Seddik es un usuario altruista y benéfico. Realmente sus soluciones me han sido de valor y me ha acompañado cada vez que él preguntó algo. Muchos de ustedes son similares a él y debo reconocerles su aporte también, como @TeeSee1 , @Steve@SkrOYC, @graham_howe y muchos otros que me ayudan a diario. Por si alguien lee, ojalá hubiera más miembros valiosos como ellos.

@Gustavo_Eduardo El beneficio es mutuo amigo 🙂 Yo había diseñado esta funcionalidad respondiendo a un requisito específico. Tener en cuenta tus necesidades, me ha permitido evolucionar el diseño y sacar una versión aún mejor, por lo tanto muchas gracias a ti 🙂 

También es importante decir que agradezco mucho tu amabilidad y que seas uno de pocos que ayudan a los demás para que ellos puedan prestar mejor apoyo y consejos. Se ve que siempre haces un esfuerzo importante en pensar y preparar tus preguntas en la manera más clara posible, siempre estás activo en la discusión sobre tus preguntas aportando informaciones que facilitan bastantemente el entendimiento y el trabajo de los demás, siempre estás dispuesto a leer la documentación, probar e investigar, todo eso junto con tu personalidad tan amable desde el primer día hace que participar en tus posts sea un verdadero placer. El miembro modelo de este comunidad ¡eres tú! 

¡Te lo agradezco sinceramente, mi amigo, Gus!

Te agradezco mucho nuevamente amigo, desde mi humilde lugar seguiré aportando lo que pueda, esta comunidad se ha hecho para mi un lugar de encuentro diario! Pero las estadísticas te muestran como el "mejor compañero de la clase"

Saludos desde argentina Joseph

Top Labels in this Space