Use of RANDOM / RANDOMIZE

This is kind a embarising, but I need your help in using random and RANDOMIZE. My customer has close to 2000 different items. Most of them, are real items, in boxes in the warehouse. Using AD it is crutial that measurements and cross references are correct, and using E-ship, weights are important when rate shopping. I have created a report, that we want to use for radomly pick a handfull of items for checking. The report has the fields that I need, but - and heres my question - I want Navision to pick these items for me. But how do I do that best?. First I thought of doing something in this direction:


NoOfItems := Item.Count;

REPEAT
  NoOfItemsToSkip := random(round(NoOfItems/2,1));
  for i := NoOfItemsToSkip downto 1 do begin
    if item.next = 0 then
    Item.find('-'); 
  end; 
  if not Item.MARK then begin
    Item.MARK(TRUE);
    Selected += 1;
  end;
UNTIL Selected = NoToSelect;

However I am afraid that this will be way to slow, compared to what you get. You are going to do a complete read in the Item table several times. Does anyone have a better way of doing it? Using 2.60 on Native database //Henrik Helgesen -: KISS::Keep it Simple, Stupid :- Edited by - hhelgesen on 2001 Nov 05 20:50:25

I would create a Temp Item record,

//Decide how many items you want to pick

TotalNoOfItems := Item.Count;
NoOfItems := random * TotalNoOfItems;

//then just start picking:

item.find('-');
Item2.copy(item);
for i := 1 to noofitems do begin
  Repeat
    item.copy(item2); // I think this is faster than always doing 
                      // item.find('-') or item.get(Item2."no.");
    Item.next(random * TotalNoOfItems);
    TempItem := Item;
  until TempItem.insert;
end;

might work. PS I am not sure if it is just me, but whilst typing just now I realized that F3 and F4 do not work. _________________________ David Singleton Navision Consultant since 1991 dmks22@home.com___________

quote:


David singleton wrote: would create a Temp Item record, //Decide how many items you want to pickTotalNoOfItems := Item.Count; NoOfItems := random * TotalNoOfItems; //then just start picking: item.find(‘-’); Item2.copy(item); for i := 1 to noofitems do begin Repeat item.copy(item2); // I think this is faster than always doing // item.find(‘-’) or item.get(Item2.“no.”); Item.next(random * TotalNoOfItems); TempItem := Item; until TempItem.insert; end;


Another way for doing it with a temporary table its: // Set the system to create a new set of random numbers: RANDOMIZE; // Initializate variables: CLEAR (TempItem); CLEAR (Item); TempItem.RESET; TempItem.DELETEALL; CLEAR (MaxItemsNumber); // Set the number of items we’re going to get MaxItemsNumber := random (round(Item.Count / 2,1)); // Set the items where to search : all in begining // We loose some time for regaining it later. if (Item.FIND(‘-’)) THEN REPEAT Item.MARK (TRUE); UNTIL (Item.NEXT = 0); Item.MARKEDONLY(TRUE); WHILE (TempItem.COUNT < MaxItemsNumber) DO BEGIN Item.FIND(‘-’); Item.NEXT (ROUND (RANDOM(Item.COUNT),1)); // After getting a new item // we put in the temporary list TempItem.INIT; TempItem.TRANSFERFIELDS(Item); TempItem.INSERT; // and remove it from the list of availables ones. // as it’s set marked only to true Item.MARK(FALSE); END; If you don’t want to use temporary tables, you can just keep an counter and just show the items you’ve marked when finished (it will just read 1 times and a half the items…). The MarkedOnly can help you in this kind of problems by using it in the opposite way: instead of marking the choosen items, unmark the discarded ones after marking all. Regards, Alfonso Pertierra (Spain)apertierra@teleline.es

The following algorithm will randomly mark SampleSize records in the item table.


  TotalItems := Item.COUNT;
  RecordNo := 1;
  RecordsMarked := 0;
  LastRecordMarked := 1;

  Item.FIND('-');
  RANDOMIZE;
  WHILE (RecordNo <= TotalItems) AND (RecordsMarked < SampleSize) DO BEGIN
    IF RANDOM(TotalItems + 1 - RecordNo) <= (SampleSize - RecordsMarked) THEN BEGIN
      Item.NEXT(RecordNo - LastRecordMarked);
      Item.MARK(TRUE);
      LastRecordMarked := RecordNo;
      RecordsMarked += 1;
    END;
    RecordNo += 1;
  END;
 

The basic idea is to run through the records in the item table. The (n + 1)st record is marked with probability (SampleSize - RecordsMarked) / (TotalItems - n). This only requires one pass through the item table and will usually terminate prior to passing all the item records. Exactly SampleSize records will be marked and the probability that any given record will be marked is SampleSize / TotalItems. I have marked the records but they could just as easily be copied to a temporary table.