[1] There needs to be a sanity check that you're not asking for something you can't have. For example:

_GenerateRandomNoRepeat(12, 4, 10)

Will presumably never return.

[2] It would be nice to be able to pass a seed through to the function for initialization of the Random function. This would allow the same array to be generated twice using the same seed. Always useful to be able to generate the same "random" sequence twice

[3] I'm not convinced the algorithm is as efficient as it could be when, for example, I call it with:

_GenerateRandomNoRepeat(52, 1, 52)

Getting the last number could take a very long time. In those cases, it might be better to create an array containing all the possible numbers 1 to 52, shuffling the array and then returning the first X numbers as appropriate. Obviously this is not an efficient algorithm for:

_GenerateRandomNoRepeat(2, 1, 10000)

So perhaps there could be some logic in order to choose the best way forward.