No expert here, but I’ll take a shot. Please forgive if I assume incorrectly.
You can directly control the arm :
Adjust speed slower maybe, watch they don’t strain motors. And as Foster said, reverse one motor if they face away from each other, also may have to change signs (in power) to ensure up and down is correct. This will get them going.
To hit exact height, a bumpSwitch, the timer, or the motor encoder can be used. Encoder example:
You need to start the program with the arm down. (Or, I have sometimes added a 2 second “down” before the first reset. Don’t want to strain/stall the motors too long, though).
There is some overshoot. Values can be found by trial and error (be ready to turn it off). Or you can show encoder on bot’s LCD using “displayMotorValues” added to the first (direct control) example, and plug those values into the second example. You may need to flip the “greater or equal to” and “less than or equal to”).
Where you get the encoder value:

BrakeMode might help (needs SuperUser menus under “Window>Menu Level” or in RobotC prefs).

This is from memory, I will retest it myself later today.
Also as an aside, the “moveMotorTarget” is relative, so will move from current position when button pressed. You can use that if you reset the encoder each button push (or use math limits on encoder values) to avoid multiple “ups” without a “down”. There is also the danger of an “up” in the middle of a “down” causing overshoot. Also there may be some wandering of set points.
Using “setMotorTarget” is absolute, (though they use the word “relative” confusingly in the help file) and would work. It can be used in the above examples without the “stopMultipleMotors” on the two motors. I have wondered about differences between “setMotorTarget” vs. “setMultipleMotors” plus “stopMultipleMotors” when using encoders.
BTW, bot pics can help, and if you show us code you’ve got so far, that always helps.