Cool, what a great question!!   Unfortunately, the answer is no. For a couple of reasons.

First, you forgot the "STR"

Second, the STR portion of the SERIN2 command, grabs the number of bytes to receive at the start of execution, and doesn't check to see if it's changed later on.

If you look at the .ASM file generated for this line it looks something like this... (comments added by me)
Code:
; SERIN2~1.BAS	00018	serin2 Rx,16780,[WAIT("!"),str BytesIn\BytesIn[0]\"~"]
	SERIN2DPIN?T	_Rx             // PIN to use _Rx
	SERIN2MODE?C	0418Ch          //  Mode 16780

	LABEL?L	L00001	
	SERIN2WAIT?CL	021h, L00001    // wait for "!"

	SERIN2COUNT?B	_BytesIn        // Number of bytes to receive
	SERIN2CHAR?C	07Eh            // terminating character
	SERIN2STRC?B	_BytesIn        // Get the String
However, I think this might work.

SERIN2 Rx,16780,[WAIT("!"),BytesIn[0], STR BytesIn[1]\BytesIn[0]\"~"]

Code:
; SERIN2~1.BAS	00020	serin2 Rx,16780,[WAIT("!"),BytesIn[0], str BytesIn[1]\BytesIn[0]\"~"]
	SERIN2DPIN?T	_Rx             // PIN to use _Rx
	SERIN2MODE?C	0418Ch          // Mode 16780

	LABEL?L	L00002	
	SERIN2WAIT?CL	021h, L00002    // wait for "!"

	SERIN2?B	_BytesIn        // get number of bytes in packet

	SERIN2COUNT?B	_BytesIn        // STR byte count
	SERIN2CHAR?C	07Eh            // terminating character
	SERIN2STRC?B	_BytesIn + 00001h  // Get the STR

<br>