Link to home
Start Free TrialLog in
Avatar of PastorDwayne
PastorDwayne

asked on

LPMAPITABLE QueryRows does not return all rows to SRowSet

Good-day,
I am having a problem with LPMAPITABLE::QueryRows not returning all available rows to the SRowSet object.  Here is a snippet of code that seems to work great for folders that are under 100 emails or so.  When trying to access a folder that has a large number of emails, the assert on the last line will fail. The QueryRows() does not seem to obtain all of the availible rows when trying to retreive many emails.

************************
  LPMAPIFOLDER pFolder = NULL;
    hr = HrMAPIOpenFolderEx(pDefMsgStore,
       '\\',
       Folder,
       &pFolder);
    if (FAILED(hr)) throw -1;

    // Get contents table.
    LPMAPITABLE pContentsTable = NULL;
     hr = pFolder->GetContentsTable(0, &pContentsTable);
    if (FAILED(hr)) throw -1;

    // Get row count
    ULONG ulRows = 0;
    hr = pContentsTable->GetRowCount(0, &ulRows);
    if (FAILED(hr)) throw -1;
     
    assert(ulRows > 0);

    // Get all rows
    SRowSet * pRowSet = NULL;

     hr = pContentsTable->QueryRows(ulRows,0 ,&pRowSet);
     
   assert(ulRows == pRowSet->cRows);
***********************************

I am guessing that I will need to call QueryRows again and somehow merge it to another SRowSet, but I'm not sure how to do this, (or if it is even possible).
Any help would be appriciated.
Thanks.
Avatar of Hermetic
Hermetic

Straight from the MSDN Library for GetRowCount:
Notes to Callers
Use GetRowCount to find out how many rows a table holds before making a call to the IMAPITable::QueryRows method to retrieve the data. If there are less than twenty rows in the table, it is safe to call QueryRows to retrieve the whole table. If there are more than twenty rows in the table, consider making multiple calls to QueryRows and limit the number of rows retrieved in each call.

According to the documentation, when you call QueryRows,
it sets an internal pointer.  You can call QueryRows again and it should just start from where you left off.
Avatar of PastorDwayne

ASKER

Would I have to create a new SRowSet pointer, or could I use the original one..  Using the example above, could you give a rough idea of how to implement this into my code?
It depends on exactly what you are doing with the rows but I will attempt an example:

---------------------------------YOUR CODE
   // Get row count
   ULONG ulRows = 0;
   hr = pContentsTable->GetRowCount(0, &ulRows);
   if (FAILED(hr)) throw -1;
   
   assert(ulRows > 0);

   // Get all rows
   SRowSet * pRowSet = NULL;
   
//---------CHANGES
   ULONG ulCurRows = 0;
   ULONG ulCumulativeRowCount = 0;
   do
   {
      hr = pContentsTable->QueryRows(20, 0 ,&pRowSet);
      //Do something with the rowset.
      //Whatever you do, it will have to store it's own
      //copy of the information because you are about
      //to free it.
      ulCumulativeRowCount += pRowSet->cRows;
      FreeProws(pRowSet);
   } while (pRowSet->cRows > 0)
   
  assert(ulRows == ulCumulativeRowCount);
//---------END CHANGES
***********************************
---------------------------------YOUR CODE
ASKER CERTIFIED SOLUTION
Avatar of Hermetic
Hermetic

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Hermetic; That seemed to do the trick...