Forum Discussion

rebrow31's avatar
rebrow31
Helper I
5 years ago
Solved

Complex IF Statement

I have a table with a machine column and a minutes column. There are 9 different machines and the table is recording the events in which a machine was stopped and how long it was stopped for (the minutes column). 

 

Now, for just 4 different machines I need to return a value base on the minutes column. But the values returned depend on both the machine and the minutes. For example:

 

Machine 1 - If minutes between 0-3, I need to return 0. If minutes between 3-8, I need to return 1. If minutes between 8-13, I need to return 2. If minutes in between 13-18, I need to return 3. If minutes between 18-23, I need to return 4. If minutes between 23-28, I need to return 5. If minutes are above 28, I need to return 6. 

 

Machine 2 - If minutes between 0-2, return 0. If minutes between 2-7, return 1. If minutes between 7-12, return 2. If minutes between 12-17, return 3. If minutes between 17-22, return 4. If minutes between 22-27, return 5. If minutes are above 27 minutes, I need to return 6. 

 

Machine 3 - If minutes between 0-3, return 0. If minutes between 3-8, return 1. If minutes between 8-13, return 2. If minutes between 13-18, return 3. If minutes between 18-23, return 4. If minutes between 23-28. return 5. If minutes above 28 minues, rturn 6. 

 

Machine 4 - If minutes between 0-2, return 0. If minutes between 2-7, return 1. If minutes between 7-12, return 2. If minutes between 12-17, return 3. If minutes between 17-22, return 4, If minutes between 22-27 return 5. If minutes above 27 minutes retun 6. 

 

There are 9 machines, so the additonal 5 machines I just want all the display 0. 

 

Does anyone know how I write this? 

  • Hi rebrow31 ,
     Make use of variables to do that:

    Shots = 
    Var Machine 1= IF(Downtime[Downtime] < 120, "0", IF(Downtime[Downtime] < 240, "1", IF(Downtime[Downtime] < 360, "2", IF(Downtime[Downtime] < 480, "3", IF(Downtime[Downtime] < 600, "4", IF(Downtime[Downtime] < 720, "5", IF(Downtime[Downtime] < 840, "6", IF(Downtime[Downtime] < 960, "7", IF(Downtime[Downtime] < 27000, "8"))))))))), IF(Downtime[Machine] = "DCM02", IF(Downtime[Downtime] < 300, "0", IF(Downtime[Downtime] < 600, "1", IF(Downtime[Downtime] < 900, "2", IF (Downtime[Downtime] < 1200, "3", IF (Downtime[Downtime] < 1500, "4", IF (Downtime[Downtime] < 1800, "5", IF (Downtime[Downtime] < 27000, "6"))))))))

    Var Machine 2= conditions for machine 2
    Var Machine 3= conditions for machine 2

    Return  IF (Downtime[Machine] = "DCM01", Var Machine 1, IF (Downtime[Machine] = "DCM02",Var Machine 1,
     IF (Downtime[Machine] = "DCM03", Var Machine 3)))

     

     

     

    I hope this helps!

  • Anonymous's avatar
    Anonymous
    5 years ago

    rebrow31 

    If all you want is a calculated column, then you should do it the way I'm going to describe. You should create a  MachineConfig table with the following columns:

    Machine|LowerBound|UpperBound|Value
    ------------------------------------
    Machine1|0|3|0
    Machine1|3|8|1
    ...
    Machine2|0|2|0
    Machine2|2|7|1
    ...
    This is what it should look like in a good professional model.

    Once you've got this table, it's dead easy to add a column with the right Value's to your table T.

     

     

    [Value] = /// calculated column in T
    var TheMachine = T[Machine]
    var TheMinutes = T[Minutes]
    var TheValue =
    	MAXX(
    		FILTER(
    			// This filter should return just
    			// one row if everything is correctly
    			// coded.
    			MachineConfig,
    			MachineConfig[Machine] = TheMachine
    			&&
    			// You should decide which bound
    			// is inclusive and which is exclusive.
    			Machine[LowerBound] <= TheMinutes
    			&&
    			TheMinutes < Machine[UpperBound]
    		),
    		MachineConfig[Value]
    	)
    return
    	TheValue

     

     

    The code will, of course, adjust itself automatically to the entries in the MachineConfig table.

9 Replies

  • Anonymous's avatar
    Anonymous
    Not applicable

    rebrow31 

    If all you want is a calculated column, then you should do it the way I'm going to describe. You should create a  MachineConfig table with the following columns:

    Machine|LowerBound|UpperBound|Value
    ------------------------------------
    Machine1|0|3|0
    Machine1|3|8|1
    ...
    Machine2|0|2|0
    Machine2|2|7|1
    ...
    This is what it should look like in a good professional model.

    Once you've got this table, it's dead easy to add a column with the right Value's to your table T.

     

     

    [Value] = /// calculated column in T
    var TheMachine = T[Machine]
    var TheMinutes = T[Minutes]
    var TheValue =
    	MAXX(
    		FILTER(
    			// This filter should return just
    			// one row if everything is correctly
    			// coded.
    			MachineConfig,
    			MachineConfig[Machine] = TheMachine
    			&&
    			// You should decide which bound
    			// is inclusive and which is exclusive.
    			Machine[LowerBound] <= TheMinutes
    			&&
    			TheMinutes < Machine[UpperBound]
    		),
    		MachineConfig[Value]
    	)
    return
    	TheValue

     

     

    The code will, of course, adjust itself automatically to the entries in the MachineConfig table.

  • Anonymous's avatar
    Anonymous
    Not applicable

    We still don't know if you need a measure or a calculated column...

    • rebrow31's avatar
      rebrow31
      Helper I

      Well that is because I do not know. I am not good on Power BI with this type of thing, which is why I am asking for some help. Maybe you could suggest which should be better?

  • I've managed to come up with this which works fine: 

     

    Shots = IF (Downtime[Machine] = "DCM01", IF(Downtime[Downtime] < 120, "0", IF(Downtime[Downtime] < 240, "1", IF(Downtime[Downtime] < 360, "2", IF(Downtime[Downtime] < 480, "3", IF(Downtime[Downtime] < 600, "4", IF(Downtime[Downtime] < 720, "5", IF(Downtime[Downtime] < 840, "6", IF(Downtime[Downtime] < 960, "7", IF(Downtime[Downtime] < 27000, "8"))))))))), IF(Downtime[Machine] = "DCM02", IF(Downtime[Downtime] < 300, "0", IF(Downtime[Downtime] < 600, "1", IF(Downtime[Downtime] < 900, "2", IF (Downtime[Downtime] < 1200, "3", IF (Downtime[Downtime] < 1500, "4", IF (Downtime[Downtime] < 1800, "5", IF (Downtime[Downtime] < 27000, "6")))))))))
     
    However I need to insert 2 more machines in there and it isn't letting me do this because IF function can only have 3 arguments. Which I get but how do I go round being able to put additional rules in for 2 more machines? 
    • Tanushree_Kapse's avatar
      Tanushree_Kapse
      Impactful Individual

      Hi rebrow31 ,
       Make use of variables to do that:

      Shots = 
      Var Machine 1= IF(Downtime[Downtime] < 120, "0", IF(Downtime[Downtime] < 240, "1", IF(Downtime[Downtime] < 360, "2", IF(Downtime[Downtime] < 480, "3", IF(Downtime[Downtime] < 600, "4", IF(Downtime[Downtime] < 720, "5", IF(Downtime[Downtime] < 840, "6", IF(Downtime[Downtime] < 960, "7", IF(Downtime[Downtime] < 27000, "8"))))))))), IF(Downtime[Machine] = "DCM02", IF(Downtime[Downtime] < 300, "0", IF(Downtime[Downtime] < 600, "1", IF(Downtime[Downtime] < 900, "2", IF (Downtime[Downtime] < 1200, "3", IF (Downtime[Downtime] < 1500, "4", IF (Downtime[Downtime] < 1800, "5", IF (Downtime[Downtime] < 27000, "6"))))))))

      Var Machine 2= conditions for machine 2
      Var Machine 3= conditions for machine 2

      Return  IF (Downtime[Machine] = "DCM01", Var Machine 1, IF (Downtime[Machine] = "DCM02",Var Machine 1,
       IF (Downtime[Machine] = "DCM03", Var Machine 3)))

       

       

       

      I hope this helps!

      • Anonymous's avatar
        Anonymous
        Not applicable

        Tanushree_Kapse 

         

        Again, please do not write code like this as it's completely unmaintainable and plain ugly.

    • Anonymous's avatar
      Anonymous
      Not applicable

      rebrow31 

       

      Your code is totally unmaintainable. By writing it like this you're shooting yourself in the foot. There is a much better way to write it.