A Structured project is the best way to go, It allows you to create functions & blocks you can call multiple times & saves you programming the same code many times.
It actually still creates the equivalent of a single block of ladder, however by using the same instance of a function block it actually passes the values for input parameters to temporary memories (these are actually M & D registers in the higher limits (so don't use them as set in the compiler settings) jumps over the end instruction runs the code, passes any output variables to temporary memories & jumps back to the main program where the output memory is updated.
A function block with 2 input parameters & one output parameter in code goes:
Load D200 Transfer D4000 (temporary memory)
Load D201 transfer D4001
Call P2000 (pointer to function)
L D4002 T D202 (move result to D202)
ju P400 (Pointer)
rest of code
FEnd (End of ladder)
Transfer D 4002
So it's really like one block of code but as the FEND instruction is the end of what would be the ladder scan, function blocks are code in an area that is not normally scanned but can be jumped to & returned many times.
It allocates the temporary memory addresses and pointers at compile time .
Very useful if you have say many motors or valves with auto/manual & status information in a program, you write the function once then call it for as many you require but use the same instance name i.e. Motor_Control., if you use a different instance it creates a subroutine for every one & increases amount of memory used.