An FB is a function that "remembers", or "keeps score" of its last operations.
Both FCs and FBs can hold parameters (IN, OUT, IN-OUT and TEMP), it allows the re-use of the blocks with different calling environments. But FBs have an extra type of parameter: STATIC not available in FCs.
When you call an FB, you are required to generate an instance DB (IDB) that accompanies this particular call of an FB; this DB contains all the STATIC parameters of the FB, and these are available at any time by any other block in your program. You could do this with an FC, a general DB and MOVE instructions that would write results of the FC program in that DB. With an FB it is automatic.
Instead a DB, I used a MW.
Seems to be lacking some information/understanding here.
What is a FB?
A FB is a block which can have a instance DB connected to it. When you create IN/OUT/IN_OUT/STAT variables, then that FB will require an instance DB to work. This instance DB will be generated automatically when you call the FB. Your editor will ask you whether it should create it or not in most cases.
NOTE: a FB without IN/OUT/IN_OUT/STAT variables does not need a DB and one will
NOT be created for it.
The IN/OUT/IN_OUT data you supply to the FB will be copied to the instance DB. This is why you can leave these parameters empty. Because zero is a valid value.
In your case if you use MW10 as an IN_OUT parameter with a FB, the data from MW10 will be copied to the instance DB at the start of the block. And then copied from the instance DB to MW10 at the end of the block.
TEMP data, or L-data is
NOT stored in the DB. This is a data block shared among all other blocks.
What is a FC?
A FC is a block that contains logic. It has no DB linked to it. When you call it no DB will be created.
So what about the IN/OUT/IN_OUT parameters? Well when you use these parameters with a FC, they are created as pointers. If you use MW10 as an IN_OUT then the FC will use #INOUT1 as a pointer directly to MW10 and will read/write directly to MW10 when #INOUT1 is referenced in the code. And this is the reason why FC's must have all their parameters filled in at all times. Because a null-pointer is not accepted.
Because there is no DB linked to a FC it doesn't have any STAT variables.
So how does one achieve FB functionality with a FC?
Manually. You have to manually create a DB with the correct data structure. You'll have to write the code to copy the data to/from the DB.
Code:
OPN DB[#IN1] // This opens DBxx, where xx is the value of #IN1
L #IN2 // Loads the value of #IN2
T DBW0 // Transfers it to DBxx.DBW0 where xx is the value of #IN1
... some more code ...
OPN DB[#IN1] // Opens DBxx again in case you've referenced another DB somewhere else in the code
L DBW2 // Loads value of DBxx.DBW2
T #OUT1 // Transfers it to #OUT1 parameter
The code calling this FC might look like:
Code:
CALL FC1
IN1 := 20 // Opens DB20 within the FC
IN2 := MW10
OUT1 := MW20
In this case MW10 = DB20.DBW0 and MW20 = DB20.DBW2
Achieving the same while using a FB would look like:
Code:
CALL FB1, DB20
IN1 := MW10
OUT1 := MW20
Done. No additional coding required within the FB.