I think so, and from this POV it is not even required to change the sources at all.
Without the index parameters the values are inserted according to the order in the parameter list of the Format command. With the index parameters you instruct Format() to use them in a different order. The only important thing is that you keep the type and count of the parameters.
Example:
resourcestring
RSErrorMsg = 'Error #d (%s)';
var
msg: String;
errCode: Integer;
errText: String;
...
errCode := 512;
errText: 'Disk full'
msg := Format(RSErrorMsg, [errCode, errText]); // --> 'Error #512 (Disk full)'
Here the first parameter passed is the integer errCode (--> %d for integer), the second parameter is the string errText (--> %s). If you want the errText to appear before the errCode just translate the RSErrMsg to 'Error "%1:s" (code: %0:d)' because the integer parameter is at index 0, the string parameter at index 1 of the parameter list in the square brackets.
'Error %s (code %d)' will not work because the first parameter to be used should be astring but above code has an integer as first parameter, the same arguments holds for the second parameter.
'Error %2:s (code %0:d)' will not work either because %2:s refers to a third parameter which does not exist.
'Error %d' or 'Error %1:s', however, will work because it is not required to refer to all parameters passed to Format().