• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Break into 24 hour schedules

Is there a way to time slot a list into 24 hour schedules.


Eg I have a production run scheudled as

Product A | 40 hrs

Product B | 20 hrs

CIP | 5 hrs

Product C | 15 hrs

etc


the output should be on another sheet/area

Day 1 | Product A | 24hrs

Day 2 | Product A | 16hrs

Day 2 | Product B | 8hrs

Day 3 | Product B | 12hrs

Day 3 | CIP | 4 hrs

Day 4 | CIP | 1 hr

Day 4 | Product C | 15hrs

etc
 
Hi,

Could you clarify your requirements?


In your example, you indicate that Day 3 for CIP should be 4 hrs, even though there are 8 hours remaining in the 24 hour schedule for Day 3. That seems to be different from the schedule for Day 1 and Day 2.


Shouldn't the breakdown be as follows?

[pre]
Code:
Day	Product	      Duration
1	ProductA	24
2	ProductA	16
2	ProductB	8
3	ProductB	12
3	CIP	        5
3	ProductC	7
4	ProductC	8
[/pre]
-Sajan.
 
Are you open to use a macro or a UDF? I can't think of a nice way to do this using just formulas w/o getting caught in a circular loop.
 
Hi Luke,

I think the following formula would do the job, as long my interpretation of the requirments are correct. (i.e. there are 24 hours in a day, and you would try to allocate each day to the maximum.)


I changed the layout of the result as follows (to be more of a GANTT view)

[pre]
Code:
---------------Day1	Day2	Day3	Day4
ProductA	24	16	0	0
ProductB	0	8	12	0
CIP	        0	0	5	0
ProductC	0	0	7	8
[/pre]
Assumptions:

1. source list is in the range A2:B5

2. Result list is in the range starting D1:H5 (with D1 being the blank cell, and E1 saying "Day1", etc. Similarly, "ProductA" is listed on cell D2, "ProductB" is in cell D3, etc.)

3. The allocation of hours to each day would be in the same order as the listing of products


Put the following formula in cell E2, and copy to the right and down (to the rest of the range E2:H5):

=IF(($B2-SUM($D2:D2)) > (24-SUM(E$1:E1)), (24-SUM(E$1:E1)), $B2-SUM($D2:D2))


You can extend this approach to additional days or products as needed, as well as format the cells so that the zeros are not displayed.


Cheers,

Sajan.


Edit: Since the columns were not aligning correctly, I added the dashes in the sample result.
 
@Sajan


Very nice Sajan! I like the Gantt layout and the flexibility of the formula. We could even set it up to use something other than 24 hrs / day if we needed to. Again, tip my hat to you!
 
Hi Luke,

Thanks for the kind words! I am glad we were able to identify a solution.


Regards,

Sajan.
 
Hi Sajan & Luke,


thanks for ideas. it is indeed what is required.


Would be interesting to see a vba based solution as well. the only drawback with the formula is that everytime the order is changed by moving cells the formuals will have to be recopied. A flat out will be helpful in then pivoting similar output for multiple ranges (production lines)


thanks again,
 
@Bluetaurean,


For a VBA based solution, one of the VBA experts on this forum will need to help you.


As far as your comment about needing to adjust the formula when the source cells are moved, you could make two adjustments to my formula to avoid that:

1. Reference the source product names using formulas that are independent of the location using INDEX() and ROW() functions

2. Change the reference to B2 in the formula with a reference using INDEX() and MATCH() functions


For example,

For the data ranges in my sample referenced in the previous post, change the formula for cell E2:E5 with =INDEX(A:A,ROW())


For cell F2, use the following formula:

=IF((INDEX($B:$B, MATCH($E2,$A:$A, 0))-SUM($E2:E2)) > (24-SUM(F$1:F1)), (24-SUM(F$1:F1)), INDEX($B:$B, MATCH($E2,$A:$A, 0))-SUM($E2:E2))


copy it down and to the right as needed.


VBA might offer a more elegant solution for a "flat listing" (instead of the pivot-table like view provided by the formula). Hopefully, someone else will help you with that.


Cheers,

Sajan.
 
Hi, bluetaurean!


Give a look at this file:

https://dl.dropbox.com/u/60558749/Break%20into%2024%20hour%20schedules%20%28for%20bluetaurean%20at%20chandoo.org%29.xlsm


Load/type columns A:B and then run GenerateDailyProduction macro to fulfill columns D:F.

Take care of the two dynamically defined named ranges when implementing the solution in your real workbook.


Regards!


PS: Posting code regarding CASFFML Luke M's favorite excuse...

-----

[pre]
Code:
Option Explicit

Sub GenerateDailyProduction()
' constants
Const ksProduct = "ProductList"
Const ksDaily = "DailyList"
Const kiHours = 24
' declarations
Dim rngP As Range, rngD As Range
Dim I As Long, J As Integer
Dim lDay As Long, iHours As Integer, lDayProduction As Long
Dim sProduct As String, iProductionHours As Integer, iAllocatedHours As Integer
' start
Application.DisplayAlerts = False
Set rngP = Range(ksProduct)
Set rngD = Range(ksDaily)
With rngD
If .Rows.Count > 1 Then Range(.Rows(2), .Rows(.Rows.Count)).ClearContents
End With
' process
With rngP
lDayProduction = 1
lDay = 0
iHours = kiHours
For I = 1 To .Rows.Count
' values
sProduct = .Cells(I, 1).Value
iProductionHours = _
Val(Left$(.Cells(I, 2).Value, InStr(.Cells(I, 2).Value, " ") - 1))
' distribute hours
iAllocatedHours = 0
Do While iAllocatedHours < iProductionHours
' new day
If iHours >= kiHours Then
iHours = 0
lDay = lDay + 1
End If
' new day production
If iProductionHours - iAllocatedHours <= kiHours - iHours Then
J = iProductionHours - iAllocatedHours
Else
J = kiHours - iHours
End If
iAllocatedHours = iAllocatedHours + J
iHours = iHours + J
lDayProduction = lDayProduction + 1
rngD.Cells(lDayProduction, 1).Value = lDay
rngD.Cells(lDayProduction, 2).Value = sProduct
rngD.Cells(lDayProduction, 3).Value = J
Loop
Next I
End With
' end
rngD.Cells(2, 1).Select
Set rngD = Nothing
Set rngP = Nothing
Application.DisplayAlerts = True
Beep
End Sub
-----
[/pre]
 
SirJB7 beat me this time, but here's my take at a macro. Takes data in columns A:B, starting in row 2 and going however long is needed, outputting to columns D:F, starting in row 2.

[pre]
Code:
Sub CreateSchedule()
Dim LastRow As Long
Dim DayCount As Long 'What day are we on
Dim HourCount As Long 'How many hours left for a product
Dim HoursRemain As Long 'Hours left in day
Dim HoursUsed As Long 'How many hours used from product so far
Dim ProductList As Range
Dim HourList As Range
Dim i As Long 'List counter
Dim OutputRow As Long
Dim PName As String 'Product name

With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

Set ProductList = Range("A2", Cells(LastRow, "A"))
Set HourList = ProductList.Offset(0, 1)

DayCount = 1
HoursRemain = 24

'What row does output begin on?
OutputRow = 2

i = 1
PName = ProductList.Cells(i).Value
HourCount = HourList.Cells(i).Value
HoursUsed = 0
'Start building list

Application.ScreenUpdating = False
Range("D:F").ClearContents 'clear old list
Do Until i > ProductList.Count

Cells(OutputRow, "D").Value = DayCount
Cells(OutputRow, "E").Value = PName
HoursUsed = WorksheetFunction.Min(HourCount, HoursRemain)
Cells(OutputRow, "F").Value = HoursUsed

HoursRemain = HoursRemain - HoursUsed
If HoursRemain <= 0 Then 'Out of hours for the day
HoursRemain = 24
HourCount = HourCount - HoursUsed
DayCount = DayCount + 1
Else
'Product is complete, go to next product
i = i + 1
PName = ProductList.Cells(i).Value
HourCount = HourList.Cells(i).Value
HoursUsed = 0
End If

'Happens when hours left on product
'equals number of hours left in day
If HourCount = 0 Then
'Product is complete, go to next product
i = i + 1
PName = ProductList.Cells(i).Value
HourCount = HourList.Cells(i).Value
HoursUsed = 0
End If
OutputRow = OutputRow + 1

Loop
Application.ScreenUpdating = True

End Sub
[/pre]
 
Hello,

For purely academic interests, here is a formula based approach that produces a flat listing.


I have used one helper column, to calculate the cumulative durations.


Source data is assumed to be in A1:C5 as shown in the sample:

[pre]
Code:
#  A           B          C
1  Product     Duration	  CumDuration
2  ProductA	10	  10
3  ProductB	20	  30
4  CIP	        3	  33
5  ProductC	4	  37
i.e. first product is listed in cell A2, etc.


For ease of reference, I have also used the following Named Ranges:

PList refers to A2:A5

PDuration refers to B2:B5

CumDuration refers to C2:C5


CumDuration was calculated as =SUM(B$2:B2) in cell C2, and then copied down through C5.


In my sample output, I have put them in the range E8:G14, and looks as follows:

#    E          F               G
8    Day	Product	        Duration
9    1	        ProductA	10
10   1	        ProductB	14
11   2	        ProductB	6
12   2	        CIP	        3
13   2	        ProductC	4
14   …	        …	        …
[/pre]
In cell E8, put the following formula (entered with Ctrl+Shift+Enter):

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…", IF(N(E8)=0, 1, IF(SUMIFS(G$8:G8, E$8:E8, E8)>=24, E8+1, E8)))


Copy it to the rows below (i.e. through E14)


In cell F8, put the following formula (entered with Ctrl+Shift+Enter):

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…",INDEX(PList, MATCH(1, IF(CumDuration-SUM(G$8:G8) > 0, 1), 0)))


Copy it to the rows below (i.e. through F14)


In cell G8, put the following formula (entered with Ctrl+Shift+Enter):

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…",IF(INDEX(PDuration, MATCH(1, IF(CumDuration-SUM(G$8:G8) > 0, 1), 0)) - SUMIFS(G$8:G8, F$8:F8,F9) > 24-SUMPRODUCT(--(E$8:E8=E9), IF(ISNUMBER(G$8:G8), G$8:G8, 0)), 24-SUMPRODUCT(--(E$8:E8=E9), IF(ISNUMBER(G$8:G8), G$8:G8, 0)), INDEX(PDuration, MATCH(1, IF(CumDuration-SUM(G$8:G8) > 0, 1), 0)) - SUMIFS(G$8:G8, F$8:F8,F9)))


Copy it to the rows below (i.e. through G14)


As the last row in the sample output shows, if you copy the formula to more rows than available duration to allocate, it will display "..."


I have not attempted to optimize the formulas in any way, since this was more to illustrate what is possible with just formulas. If anyone wants to know what the formulas are doing, let me know, and I can write up an explanation.


Cheers,

Sajan.
 
@Luke M

Hi!

Looking over my shoulder again?

Almost only changed the variable names...

:p

Regards!
 
@SirJB7

I'll go w/ "great minds think alike". Besides, you know I have CASFFML issues! =P
 
@SirJB7

Hi, myself!

So long...

Ok, I think I got it, the guy with the more than convenient CASFFML issue is one of those, but who the hell might be the others?

Regards!
 
Hi bluetaurean,


Here are the formulas for creating a flat list, slightly shortened. Essentially, the shorter formula replaces IF(A<B, B, A) logic with MIN(A,B)


Formula for cell E9 (to be copied down through E14), entered with Ctrl+Shift+Enter:

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…", MAX( N(E8) + 1*(SUMIFS(G$8:G8, E$8:E8, E8)>=24), 1))


Formula for cell F9 (to be copied down through F14), entered with Ctrl+Shift+Enter:

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…",INDEX(PList, MATCH(TRUE, (CumDuration-SUM(G$8:G8)) > 0, 0)))


Formula for cell G9 (to be copied down through G14), entered with Ctrl+Shift+Enter:

=IF(SUM(G$8:G8)>=SUMPRODUCT(PDuration), "…",MIN(INDEX(PDuration, MATCH(TRUE, CumDuration-SUM(G$8:G8) > 0, 0)) - SUMIFS(G$8:G8, F$8:F8,F9), 24-SUMPRODUCT((E$8:E8=E9)* IF(ISNUMBER(G$8:G8), G$8:G8, 0))))


Now you could use the formula approach or VBA approach. You have choices!!


Cheers,

Sajan.
 
Back
Top