What I would recommend with regards to area loops is this:
As you loop through the areas for the first time.
Store a reference to the area on the module in association with the areas index in the module.
Eg: (Pseduo-code)
int i = 0;
while (Area == Valid)
{
SetLocalObject(oModule,"Area_"+IntToString(i),Area);
i++;
Area = NextArea();
}
SetLocalInt(oModule,"MAX_AREAS",i);
What this means is that you can then later refer to those areas - without having to do a costly loop.
This becomes important if you end up having 500+ areas - as looping through 500-700 areas just so you can pick one at random, is a costly and wasteful exercise.
int iRandom = RandomNumber(0,i);
object RandomArea = GetLocalObject(oModule,"Area_"+IntToString(iRandom));
What Meaglyn said about looping twice to keep the area list accurate stands true.
If you use plugins such as nwnx_Areas - then the area list you store on the module will become out of date when the new area is added.
It wont affect your ability to interact with those areas (unless they were destroyed), but you just wont be able to access newly added areas unless you do the loop/harvest step again.
I recommend doing these costly loops infrequently.
Eg: OnModLoad
OnClientExit (only if there are no characters left in the module)