Smartsheet - How to find total number of pages in a sheet? - smartsheet-api

I want to get all the records on a sheet by page with such query https://api.smartsheet.com/2.0/sheets/{sheetId}?rowsModifiedSince={date}&pageSize=20&page=10
But response hasn't totalPages or similar parameter. How to find a total number of pages in a sheet?
Of course, I can check the number of rows on the current page. If it is equal to the 'pageSize' parameter then the next sheet exists. This does not seem to be correct as on the sheet can be a multiple of the number of rows.

The Get Sheet response contains a totalRowCount parameter that specifies the total number of rows in the sheet. You can calculate the total number of pages (i.e., the total number of Get Sheet requests that you'll need to submit to retrieve all rows in the sheet) by dividing the totalRowCount value by the pageSize value you're specifying in the request query string, and rounding the result up to the next whole number.
For example, if:
Your request specifies pageSize=20 (e.g., https://api.smartsheet.com/2.0/sheets/{sheetId}?pageSize=20&page=1).
And the value of the totalRowCount parameter in the Get Sheet response is 105.
This means you'll need to submit 6 Get Sheet requests (each one specifying pageSize=20) to have retrieved all rows in the sheet (because totalRowCount/pageSize = 105/20 = 5.25, rounded up to the next whole number is 6). Each of the first 5 responses (pages) would contain 20 rows, and the 6th response would contain the remaining 5 rows.
** UPDATE #1 **
If you're specifying a query string parameter (e.g., rowsModifiedSince) then the strategy above won't work -- because the value of totalRowCount always indicates the total number of rows in the sheet, which is not necessarily equal to the number of rows that meet the criteria you've specified via the query string parameter(s). In that case, you can just continue submitting Get Sheet requests, incrementing the value of the page parameter each time, until you receive a response where the rows property is an empty array (as shown in the response example below) -- this indicates that the previous page you requested was the final page of results.
{
"id": 3932034054809476,
...
"rows": []
}
** UPDATE #2 **
Unfortunately I'm seeing inconsistent behavior from Smartsheet with the approach described above.
If the last page with results is a full page of results, then the response to the request for the next page of results will return an empty rows[] array. e.g., if 4 rows meet the criteria I specify, and I specify pageSize=2 in each request -- then the first two pages will each contain 2 rows and the third page (i.e., request issued with pageSize=2&page=3 in the query string) will return an empty rows[] array.
However, if the last page with results is not a full page of results, then the response to the request for the next page of results returns the last page of results again. e.g., if 3 rows meet the criteria I specify, and I specify pageSize=2 in each request -- then the first page contains 2 rows, the second page contains 1 row, and the third page (i.e., request issued with pageSize=2&page=3 in the query string) will contain the same rows that were in the previous/last page of results -- i.e., the same 1 row that was returned for page=2.
Unfortunately, this means you may have to resort to doing something like keeping track of the row id values that you receive in each response (and if you get a response that contains a row id you've received previously, this would indicate that the page you requested previously was actually the final page of results).

Related

Do not print a particular field on first page of the report

I am working on crystal reports. I want to avoid printing a field on the first page of the report, but print it on rest of the pages. I am also resetting the page number at group level. So if I suppress the field on page 1 it also suppresses on the page where the new group starts and the page number is reset to 1, which I don’t want.
If the field is suppressed on this condition:
RecordNumber = 1
it should behave like you want, i.e. it's not shown on the very first page, regardless of the CR page numbering.
Note: this one will only work if the second record started on page 1, too.
If I'm understanding your question correctly, it sounds like you are using a formula to suppress the field when PageNumber = 1, and it is suppressing the field on the first page of the report, but when you get to the next record in the group the page number resets to 1 and the field is suppressed again, when you want it to be shown.
I would try updating the suppression formula to the following.
PageNumber = 1 AND GroupNumber = 1
If you have multiple levels of grouping in your data, things can get a little interesting though. The GroupNumber function does not allow you to specify which group it is enumerating and instead returns record number for the inner most group that the function is contained within.

Print Multiple Copies of Record Crystal Reports

I have a report that is only one record, however, the user specifies how many times it needs printed, let's say 10. Each time it prints it prints 4 of the same report. Like this, Page 1 x 4, Page 2 x 4, Page 3 x 4, etc. With 10 copes their will be 40 pages altogether.
Update:
I was able to get all the pages I needed based on the values the user inputs. So if there are 10 pallets I have 40 pages of labels, which is correct. Now the control number part that needs to be displayed. It is kind of like a page number but every 4 pages the number needs to increment by 1. I assume I can use WhilePrinterRecords and some how increment, but I am still new to Crystal and unfamiliar with it.
Example:
Page 1: Control number 1
Page 2: Control number 1
Page 3: Control number 1
Page 4: Control number 1
Page 5: Control number 2
Page 6: Control number 2
Page 7: Control number 2
Page 8: Control number 2
This would continue until there is no more pages to print.
if you want 4 copies for each label, what you could do is create 4 sections on the report with the same info. Make sure that you assign the label size to each page(e.g. 4x6). e.g. if you have that info on your header, create PHa, PHb, PHc and PHd, same for details or PF.
don't know if this could work for you, but at least is a recommendation. You can create suppressed sections with the same info(e.g. 10 sections) and create a parameter that control that suppress condition defaulted in 4. If the user what to print 5, it will enable section 5th, same if want to print 3 it will suppress the 4th.
Upadte: how to get the increment:
place a formula on your page footer like below one. It will return value when gets an integer and suppress it when is equal to 0(right click on it, number tab, customize, suppress if 0).
if pagenumber = Ceiling(pageNumber,4) then numbervar page := page +1
then place another formula on your PF as well like below one and suppress it when pagenumber = Ceiling(pageNumber,4) so it won't show when the other has value and put one overlapping the other to get the value in the same place.
if {1st formula} <> 0 then numbervar page1 := {1st formula};
page1 + 1
2nd Update:
Because is a label and your details are acting as a new page do this:
create a new detail section, so you will have details a and b and place your formulas on details b
I have used additional tables for such tricks; these tables must be linked to report to multiply main query results. Some care has to be taken to not allow multiple users printouts to mix.
Example, assuming your report query has some unique id to link and your user/session has also some unique id:
you create table cr_special(reportid int, userid int, ctlnumber int)
you design report, linked to this table by reportid and filtered by userid; changing ctlnumber field is taken from your special table
before printing, you delete all records with reportid/userid combo and insert new ones
you print report, giving userid as parameter
Say you want to print 10 reports with increasing numbers - then you insert 10 records into your special table with ctlnumber increasing from 1 to 10.
Variation of this solution is to use some other non-related table, like our all-dates-containing dates table :)
Both of these solutions are ugly, but they usually work.
Another approach is to use some stored procedure to return these sequential numbers as records and link your report to such procedure; Crystal Reports and stored procedures do not behave always well however.

How to detect the last page before the header record changes

I need to place in the header of a crystal report, the number 0 or 1.
1 if the page is the last page of the current record, else 0.
i.e I have multiple records that each have a varying number of detail lines. Each record starts on a new page with a repeating header. If the detail lines span more than one page, I need to write a 1 on the last page of the record header and a 0 on every other page header.
I've tried using the following in a formula field to detect the next record's primary key
iif((Next({primary_key}) = {primary_key}), '0', '1')
but I think this will always return 1 because it's checking the next record and not the next page's record.
Any help would be appreciated.

Group Page Totals and Carried Forward Totals

I have googled a lot about this but found nothing useful. This has been asked before here but noone has responded.
I have a tablix that presents grouped data with an amount column:
Tablix (data)
Name (group)
Amount (rows)
If the "Name" group spans more than one page I want to show a page total for the sum of the amounts present on the first page. On the next page the carried forward total of the previous page must be shown.
I have tried many things, especially with my custom assembly (like keeping a dictionary with the total of each group and in the footer of the report try to show the total etc). The thing that really messes up any implementation is the order where report's header, body and footer are "executed".
Any ideas or suggestions?
Due to:
The fact that there is no way to get whether one instance of the grouped data are split in more than one page at the detail level (so that the carried forward total can be shown below the repeated column headers)
The page header and footer are always "evaluated" after the body elements
You can only reference on ReportItem in the expressions used in the page header and footer
You cannot make changes to the body elements from the page header or footer (mostly because of the point above)
You cannot extend the tablix control to add your own functionality
I decided to go with showing the group page total in the footer, storing it and the picking it up to show it to the next page.
This is done by having a cumulative total column using
= IIf(RunningValue(Fields!AmountDC.Value, Sum, "Group1") <> Sum(Fields!Amount.Value, "Group1"), code.SetTotal(RunningValue(Fields!Amount.Value, Sum, "Group1")), Nothing)
which for the last detail row is setting it to "Nothing"
In the footer a textbox picks up the last value of that cumulative total field.
= code.SetTotal(Last(ReportItems!CumTotal.Value))
and stores the current total in a private field in the embedded code.
Private running As Double = 0
Public Function SetTotal(ByVal val As Double) As Double
running = val
Return val
End Function
Public Function GetTotal() As Double
Return running
End Function
And last in the page footer the stored total is picked up
= code.GetTotal()
It is too simple, but still it is the closest I could get with what I have after many trials!
Try this post ...separating pages answers..
This is not a direct answer but if youy get creative and separate the page using the sql or use a running total , this could get you started.
However to answer your question its not a feature in ssrs.

Finding the number of column in a table

I would like to know how to tell the number of columns in a table created in iReport. The variable COLUMN_COUNT returns the number of rows, but I want to know the number of columns.
Does anyone know how to do?
The quotes from JasperReports Ultimate Guide:
BUILT-IN REPORT VARIABLES
COLUMN_NUMBER
This variable contains the current column number. For example, on a report with three
columns, the possible values are 1, 2, and 3. The variable restarts from 1 and runs up to
the defined number of columns for each page in the generated document.
COLUMN_COUNT
This variable contains the number of records that were processed when generating the
current column.
PAGE_NUMBER
This variable’s value is its current page number. At the end of the report-filling process,
it will contain the total number of pages in the document. It can be used to display both
the current page number and the total number of pages using a special feature of
JasperReports text field elements, the evaluationTime attribute. You can see this
happening in most of the samples. Check the /demo/samples/jasper sample for an
example.
REPORT_COUNT
After finishing the iteration through the data source, this report variable contains the total
number of records processed.
PAGE_COUNT
This variable contains the number of records that were processed when generating the
current page.
GroupName_COUNT
When declaring a report group, the engine automatically creates a count variable that
calculates the number of records that make up the current group (that is, the number of
records processed between group ruptures).
The name of this variable is derived from the name of the group it corresponds to,
suffixed with the _COUNT sequence. It can be used like any other report variable, in any
report expression, even in the current group expression, as shown in the BreakGroup
group of the /demo/samples/jasper sample).