Use the Position(text;searchString;start;occurrence) function to find if the word is in your string and where it starts.
next use the Left(text;numberOfCharacters) to select all of the string before the occurance of your word set numberof characters to Position -1
next use the WordCount(text) function to count how many words are in the new string which will be on less than your word position
the formula would end up as WordCount(Left(text;Position(text;searchString;start;occurrence)-1) )+1
WordCount(Left(" I have a apple.";Position(" I have a apple.";apple;1;1)-1) )+1
I have not tested this but I believe it will work.
Using a global to hold the varying word you are looking for, as Ian suggested, you could use:
Let ( [
pos = Position ( text ; gWord ; 1 ; 1 ) ;
prior = Left ( text ; pos - 1 ) ] ;
WordCount ( prior )
Keep in mind that you CAN get false positives and you should clearly decide the business rules, i.e. if you are looking for 'right' and there is a word rightful, it will identify it as a match and count words before it. But since you are looking for the count of words before this word, it should be fine.