Here is a simple vi that should do what you want. Since this is a subvi, and is called periodically, I see no reason for the outer while loop. It runs only once anyway. I suppose you were using it before because of shift registers. My attached version does not use shift registers. It simply waits until the IR beam is broken, then it checks the metal detector and causes the proper string to be placed onto the queue, then it waits for the IR beam to be unbroken. Now the subvi is done. I like to keep the delays in the while loops just so that the CPU can do other things while waiting for the IR beam action.
A problem might arise if you are wanting to do other things while waiting for the IR beam action. If so, then a whole new strategy is needed. You might want to use an event structure. The IR beam change can be the event. Inside the IR beam change event, put a case structure to check the IR Beam boolean. In the case of the beam being broken, put the code to enqueue the string. In the other case, do nothing. When the beam is broken, the event will fire and the string will be queued. When the beam becomes unbroken, the event will fire and nothing else will happen. The next part that comes around will repeat the event sequence. You can then do other things while waiting for the next event.
This whole strategy is based on the fact that the metal detector is still activated by a metal part when the IR beam gets broken. If this is not so, then a new strategy is needed. According to what you described, the metal detector is still activated when a metal part breaks the IR beam, so this should work.