1

I'm fetching company names and other data from QB file with the following code using QB-SDK:

public IList<CustomerModelQB> GetAllCustomer(string fromName = "a", string toName = "z", bool IsActiveOnly = true)
{
    RequestMsgSet.ClearRequests();
    ICustomerQuery CustomerQueryRq = RequestMsgSet.AppendCustomerQueryRq();

    if (IsActiveOnly)
    {
        if (CustomerQueryRq != null)
                CustomerQueryRq.ORCustomerListQuery.CustomerListFilter.ActiveStatus.SetValue(
                ENActiveStatus.asActiveOnly);
    }
    else
        CustomerQueryRq.ORCustomerListQuery.CustomerListFilter.ActiveStatus.SetValue(ENActiveStatus.asAll);


    //Set field value for FromName
    CustomerQueryRq.ORCustomerListQuery.CustomerListFilter.ORNameFilter.NameRangeFilter.FromName.SetValue(fromName);
    //Set field value for ToName
    CustomerQueryRq.ORCustomerListQuery.CustomerListFilter.ORNameFilter.NameRangeFilter.ToName.SetValue(toName);

    CustomerQueryRq.IncludeRetElementList.Add("FullName");
    CustomerQueryRq.IncludeRetElementList.Add("AccountNumber");

    ResponseMsgSet = SessionManager.DoRequests(RequestMsgSet);

    return WalkCustomerQuery(ResponseMsgSet);
}

I looked at the iterator and tried some code..

iterator

It seems that it is fetching initial data like fetch first one thousand records and that's it... The logic will be like fetch first few records of data, than the next few records and so on until the total of the records fetched.... But unfortunately QB SDK is not giving this facility, as it is only letting me to fetch the first few records and that's all...

What I actually want to do is:

I have few 100k records in my QB company file and I would like to fetch first few records (like ten thousand records) than move to the next 10 thousand records, and than next 10 thousands and so on... until all the records fetched.

Although am able to do this with ORNameFilter, TotalBalanceFilter and some other filters but I want to do this like first 10 thousand records than next 10 thousand, and so on until total of the records from my company file.

This is actually continuation of this SO question.

Is there any way around to do this?

James Z
  • 12,209
  • 10
  • 24
  • 44
Softhmak.
  • 131
  • 9
  • Yes, with QBSDK, you can with iterator. But I think intuit suggest batch of 100 records. We can success do it for a total 6,000-7,000 records. If you want for many batch fo 10 thousand, it will be very long! Which object type you want to get from QB? – DanB Oct 30 '18 at 01:26
  • Can you please post the code to do so like 100 records iterations. I want to get XML of FullName and AccountNumber only of first 100 records and than next 100 and so on... till the total of the records. – Softhmak. Oct 30 '18 at 01:34
  • I have an example with QBFC. QBFC use behind QBXML, but I don't use directly QBXML. Do you want my example? – DanB Oct 30 '18 at 13:16
  • Yes please show your example. – Softhmak. Oct 30 '18 at 23:07

1 Answers1

1

Here our code to get invoices from date range. It use QBFC.

    public List<tbInvoiceHeader> GetInvoices(DateTime? fromDate, DateTime? toDate, bool fromModifiedDate, string invoiceNumber)
    {
        var invoices = new List<tbInvoiceHeader>();

        IMsgSetRequest requestMsgSet;
        IMsgSetResponse responseMsgSet;

        requestMsgSet = GetLatestMsgSetRequest();
        requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;

        IInvoiceQuery invoiceQuery = requestMsgSet.AppendInvoiceQueryRq();
        IInvoiceFilter invoiceFilter = invoiceQuery.ORInvoiceQuery.InvoiceFilter;

        if (!string.IsNullOrEmpty(invoiceNumber))
        {
            invoiceFilter.ORRefNumberFilter.RefNumberFilter.RefNumber.SetValue(invoiceNumber);
            invoiceFilter.ORRefNumberFilter.RefNumberFilter.MatchCriterion.SetValue(ENMatchCriterion.mcStartsWith);
        }
        else
        {
            if (fromDate.HasValue)
            {
                if (!fromModifiedDate)
                {
                    invoiceFilter.ORDateRangeFilter.TxnDateRangeFilter.ORTxnDateRangeFilter.TxnDateFilter.FromTxnDate.SetValue(fromDate.Value);
                }
                else
                {
                    invoiceFilter.ORDateRangeFilter.ModifiedDateRangeFilter.FromModifiedDate.SetValue(fromDate.Value, asDateOnly: true);
                }
            }

            if (toDate.HasValue)
            {
                if (!fromModifiedDate)
                {
                    invoiceFilter.ORDateRangeFilter.TxnDateRangeFilter.ORTxnDateRangeFilter.TxnDateFilter.ToTxnDate.SetValue(toDate.Value);
                }
                else
                {
                    invoiceFilter.ORDateRangeFilter.ModifiedDateRangeFilter.ToModifiedDate.SetValue(toDate.Value, asDateOnly: true);
                }
            }
        }

        invoiceFilter.MaxReturned.SetValue(iterationNumber); // Set max returns element.
        invoiceQuery.iterator.SetValue(ENiterator.itStart);
        invoiceQuery.IncludeLinkedTxns.SetValue(true);
        invoiceQuery.IncludeLineItems.SetValue(true);   
        invoiceQuery.OwnerIDList.Add("0");              // To include customs fields

        responseMsgSet = mySessionManager.DoRequests(requestMsgSet);
        do 
        {
            //Step 5: Interpret the response
            IResponseList rsList = responseMsgSet.ResponseList;

            //Retrieve the one response corresponding to our single request
            IResponse response = rsList.GetAt(0);

            if (response.StatusCode == 0) //We have one or more invoices-> show them
            {
                IInvoiceRetList invoiceList = response.Detail as IInvoiceRetList;
                int maxCnt = invoiceList.Count;

                if (invoiceProgressEvent != null)
                {
                    invoiceProgressEvent(new ProgressEvent() { Count = maxCnt, RemainingCnt = response.iteratorRemainingCount, Invoices = invoices });
                }

                //for logging only
                //XmlDocument doc = new XmlDocument();
                //doc.LoadXml(responseMsgSet.ToXMLString());
                //XmlNodeList nodes = doc.SelectNodes("//InvoiceRet");
                for (int ndx = 0; ndx < maxCnt; ndx++)
                {
                    //var xmlText = nodes[ndx].InnerXml;
                    IInvoiceRet invoiceRet = invoiceList.GetAt(ndx);
                    invoices.Add(GetInvoiceHeaderDetail(invoiceRet));
                }
            }

            if (response.iteratorRemainingCount > 0)
            {
                invoiceQuery.iteratorID.SetValue(response.iteratorID);
                invoiceQuery.iterator.SetValue(ENiterator.itContinue);
                responseMsgSet = mySessionManager.DoRequests(requestMsgSet);
            }
            else
            {
                //This cause The iteratorID "..." is not valid.
                //invoiceQuery.iteratorID.SetValue(response.iteratorID);
                //invoiceQuery.iterator.SetValue(ENiterator.itStop);
                //responseMsgSet = mySessionManager.DoRequests(requestMsgSet);
                break;
            }
        } while (true);

        return invoices;
    }
DanB
  • 2,022
  • 1
  • 12
  • 24
  • Does iterator only work when searching for a range of dates? it will work if we search for TxnIDs? let's say 400 TxnIDs and I set iterator MaxReturned to 100 ? – DanielRamiz Feb 03 '23 at 16:24