That's correct. 0x6a contains the offset from the start of the file to the effects list (which may be separated into any number of abilities), and 0x20 into the ability structure is the index of the start of the effects for this ability (for a spell with no global effects, the first ability would have 0, the second would have the number of effects of the first ability, etc.). So your calculation would be fx_off + ab_fx_index * 0x30 to find the effects list for the ability you're working with.
SAY will work. What you're trying to do is exactly what it's designed for. You can also use it in places where you'd normally write an strref but don't want to look up the actual strref (say if you had to use the string "Imoen"; if you don't want to find an occurrence of Imoen in dialog.tlk, you can just use SAY where ~Imoen~ instead of WRITE_LONG where strref and WeiDU will gladly find the first "Imoen" string in dialog.tlk and write the strref of that string).