I have a form in MS Access that allows users to enter data they collect from the field and that form also has the option to compile all of the information into a formal report. The report contains a cover sheet and a table of contents as well as leaves section header pages for additional documents to be attached when printed out/exported.
There are 2 things that execute before their processes are actually finished:
One subroutine creates many formatted tables but the tables only get created with the appropriate data, the formatting does not apply right away and as a result, the formatting finally kicks in once the document is done typing and will delete any extra pages. This is affecting the second problem.
Since the page numbering for each page is not the same, sections are used so that each page can have a unique footer with the page number included in that. A loop is used to run through the document and unlink all headers and footers from the previous ones. It then starts from the beginning of the document and moves from footer to footer and writes the page number. That code is below:
While Not Selection.Information(wdActiveEndPageNumber)
If Selection.Information(wdActiveEndPageNumber) = (Section_Page + 1) Then
Selection.TypeText "Page: " & (pgNum + Section_Length)
pgNum = pgNum + Section_Length
Else
Selection.TypeText "Page: " & pgNum
End If
pgNum = pgNum + 1
ActiveWindow.ActivePane.View.NextHeaderFooter 'move to the next page's footer
Wend
The problem that I am having with this section of code is that the Selection does not always move to the next footer fast enough and as a result footers that belong on the next page sometimes cram onto the same page as another footer and the footer looks something like "Page: 5Page: 6" rather than "Page: 5" on one and "Page: 6" on the next.
Please do not suggest the built in Word page numbering - I shortened the code here, there are anywhere between 3 and 7 sections that need spacing. I think if there was a way to get the code to execute asynchronously that block of code will work.
A stop-gap measure would be to insert one (or several) line(s) of
DoEvents
after the change and before ActiveWindow....NextHeaderFooter. That command yields execution to the OS. That may give Word the time it needs to catch up.
Of course, you would do better to avoid using ActiveWindow... altogether and iterate through the sections with a For loop.
Related
I need to create a report and export it to .docx that shows the page number and total number of pages in the first page header (e.g. "1 of 5") and only show the page number in the header for all other pages (e.g. "2", "3").
What I've tried so far
Creating 2 text boxes in the header and setting their visibility to "=Globals!PageNumber=1" and "=not Globals!PageNumber=1" or "=Globals!OverallPageNumber=1" and "=not Globals!OverallPageNumber=1".
Both text boxes either exist on all pages or don't exist at all.
Setting the header to not print on the first page, adding only the page number to the header and adding a text box with the expression code.PageNumber & " of " & code.TotalPages to the top of the report body and adding
Function PageNumber() As String
Return Me.Report.Globals!PageNumber.ToString()
End Function
Function TotalPages() As String
Return Me.Report.Globals!TotalPages.ToString()
End Function
to report code, because you can't use global variables in report body. But the text box in the body always shows "1 of 1" no matter how many pages there are.
Is there something I did wrong in my attempts that I don;t understand?
Is there another way of achieving the result I need?
I'm not sure which version of ssrs I'm using but solutions that work with any version would help me a lot.
Add your header then add a textbox to the header and set the expression to this.
="Page " &
Globals!PageNumber &
IIF(Globals!PageNumber = 1,
" of " & Globals!TotalPages,
"")
This will show "Page 1 of 5" on the first page and then just "Page 2" etc on subsequent pages.
So I'm having some difficulties with this code. I know it's obnoxiously wordy, but every attempt I made to turn some of these form references into variables to save space ended with me having even less functionality than before.
Basically what I've done so far is create a navigation form with several tabs, one to create a ticket, one to resolve/edit a ticket, and one to search the tickets. The search tab is basically a continuous form that updates based on the search criteria I enter. My goal is that when I click on the ticketID for each record, it will take me to the selected record on the Resolve/Edit Ticket page (on that page I have a combo box [called cboGoToRecord] where you can select the record you want).
I have a hyperlink in place that takes the user to the Resolve/Edit page and code that works ONLY when the line I've denoted with four asterisks (for clarity) is replaced with
rst.FindFirst "ticketID =" & [some number].
When I do that, the results are as expected. If I leave it as it is below, every record looks up the first record (A Debug.print check shows that the value of this field is apparently always 1...) So I guess what I need to figure out is how do I access the ticketID hyperlink's value so that I can put it on that line and make my code function effectively? I apologize if this is overly detailed but figured too much was better than not enough.
Private Sub ticketID_Click()
'Takes user from Search Tickets to Resolve/Edit Issues tab
DoCmd.BrowseTo acBrowseToForm, "frmResolveIssues", "frmBrowseTickets.NavigationSubform"
On Error Resume Next
Dim rst As Object
Set rst = Forms!frmBrowseTickets!NavigationSubform.Form.RecordsetClone
[Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value = [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
****rst.FindFirst "ticketID =" & [Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value
Forms!frmBrowseTickets!NavigationSubform.Form.Bookmark = rst.Bookmark
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
End Sub
Edit:
After altering my form to add a separate hyperlink and referencing the static ticketID, I have concluded that everything I thought was true was not. Finding the value of a hyperlink was NOT the problem. The problem is that my ticketID value truly does insist on being one, and I have no clue how to fix that.
When this works:
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
then also check out:
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value
As June7, I never use the Navigation form. It complicates everything too much.
I'm struggling with a problem in SSRS. I have created a customer invoice that is looking good in report viewer however, it needs to be set to print in a certain way.
There are 4 main elements to this report.
Header, this needs to repeat on every other page if the invoice details + footer do not fit on the first page.
Invoice details, this needs to repeat on every other page if the invoice details and footer do not fit on the first page.
Footer, this needs to repeat on every other page if the invoice details and footer do not fit on the first page.
Back of page (payment details, like a bank statement), this needs to repeat on every other page without the header, invoice details or footer.
Is this even possible? If not, the end user has accepted that the first 3 parts of the invoice to repeat as necessary and just the last page to be the payment details.
Thanks in advance
Getting the Report Header and Footer to repeat on every page should be pretty straight forward.
Now if you have some additional information outside of the report content you wish to repeat on every page you could do the following:
As you are probably already aware, when using a Tablix it's possible to repeat table header rows on each page . This can be used to our advantage by adding Tablix with a single column and making it span the size of the page, in both the header and data rows you add rectangles so it acts like the report body. In the header row you can add any data/text you wish to repeat on the next pages.
Now as you want the back-side of the pages to have text on them, you probably don't want this to repeat on every page. Because the back of the pages is always the same static data, you could simply generate your report the way it's set up right now and insert the static page between the pages of the report.
To achive the last part you could use some code like this:
String inputFilePath1 = #""; //back of page
String inputFilePath2 = #""; //report
String outPutFilePath = #""; //final report
PDFDocument doc1 = new PDFDocument(inputFilePath1);
PDFDocument doc2 = new PDFDocument(inputFilePath2);
// Get a page from the first document. -> back of page
PDFPage page = (PDFPage)doc1.GetPage(0);
for(int i = 1; i <= doc2.PageCount; i++)
{
if (i % 2 == 1)
{
// Insert the page to the second document at specified position.
doc2.InsertPage(page, i);
}
}
// Output the new document.
doc2.Save(outPutFilePath)
This is the part of the code for paging(when you see page 1,page 2...at the bottom).The $_SERVER[QUERY_STRING] is used to copy what was searched on previous page so that page number 2 displays results for same query.
The problem is that on page 2 the "query string" is added with page number &page=2 so when you click for page 3 the $_SERVER[QUERY_STRING] copies the query(which i need to be copied,eg. ?search=salad)and the page number(which is unnecessary),it looks like this &page=2&page=3
Is there any good way to do this?...it would be nice if something could change only the number of page instead copying whole word.
<a href='$_SERVER[PHP_SELF]?$_SERVER[QUERY_STRING]?start=$back'><font face='Verdana' size='2'>PREV</font></a>
$query = http_build_query(array('page' => $num) + $_GET);
printf('Prev', $_SERVER['PHP_SELF'], $query);
This uses the $_GET array, which contains all the values of $_SERVER['QUERY_STRING'] in a neat array, "overwrites" the page value of that array, then re-assembles it into a URL-encoded query string.
I have a table displaying results from a database, and I am adding some paging/navigation buttons to it, such as 'prev', 'next', etc. These are being constructed for now as submit input buttons that are wrapped with a form tag and some hidden inputs to pass the needed querystring values back to the page itself, which means each form and element in the form should have an ID attribute.
Now, I'd love to add the navigation to both the top and bottom of the table, so I've modularized the navigation generation into a single routine I call whenever needed. This of course leads to duplicate form and element IDs in the page when there is more than one navigation bar included.
I've thought of passing some 'count' parameter to the routine so that when generating the HTML it could append that value to the IDs, and there are other solutions, such as using a global counter (ugly), etc, but I thought I'd poll the crowd and see what others have done in this situation.
Thanks,
Paul
Of the solutions you have thought of thus far, I would suggest the tactic that you mention first in the last paragraph. Passing a query string variable and loading X number of records including the number passed (doing error checking of course to make sure that some sneaky user doesn't try to put random characters in the query string) would resolve your issue.
Another option (since you are obviously doing codebehind for loading from the DB) is to create a session variable and assign the value to that when the links are clicked and use it to generate the list.
For both instances, when the page loads you can take the current value being passed and add X (number of rows in results shown +1) and change the value passed by the links.
I recently made a paginator myself, but approached it in a totally different way. I used php to generate the numbers, and each number (page) had a tag with an href that was mywebsite.php?page=x. That way you can use a get method, grab the page number from the url, and loop through as many times as you want for the number of pages displayed.
As they say, there is more than one way to skin a cat. I prefer the url passing method because I can stay away from forms and ID's in their entirety, making it so that the paginator can go wherever I decide to slap it in (and however many times).
Here's a snapshot of how I went about generating it. Hope it gives you some ideas!
/*PAGE NUMBERS*/
// ceil rounds a decimal up to the next integer
$pages=ceil(($totalrows-1)/$tablesize); //we subtract 1 from total rows because it counts 0
//(int) typecasts the $pages variable, so that it is divisible by an integer (ceil makes it a float)
$pages=(int)$pages;
//displays all the pages with their links
//if page count is less than 7 (the full paginator), display all pages
if($pages<=7){
for($i=1;$i<=$pages;$i++){
print "<a class='pages";
//add class current_page if necessary
if($page==$i){print " current_page";}
print "' href='index.php?page=";
print $i. "'>"." $i</a> "." "." ";
}
//if page count is more than 7
}else{
//if page # is less than 4, display pages up to 7, so that there are always 7 pages available (makes the buttons not jump around)
if($page<=4){
for($i=1;$i<=7;$i++){
print "<a class='pages";
//add class current_page if necessary
if($page==$i){print " current_page";}
print "' href='index.php?page=";
print $i. "'>"." $i</a> "." "." ";
}
//if page # is less than 4 away from the end, display pages $pages-7
}elseif($page>=$pages-3){
for($i=$pages-6;$i<=$pages;$i++){
//8,9,10,11,12,13,14,15
print "<a class='pages";
//add class current_page if necessary
if($page==$i){print " current_page";}
print "' href='index.php?page=";
print $i. "'>"." $i</a> "." "." ";
}
//if it's in between the ends, do this
}else{
for($i=1;$i<$pages+1;$i++){
//limit the number of visible pages to 7
if(($i>=$page-3)&&($i<=$page+3)){
print "<a class='pages";
//add class current_page if necessary
if($page==$i){print " current_page";}
print "' href='index.php?page=";
print $i. "'>"." $i</a> "." "." ";
}
}
}
}
There might have been some confusion it seems over what I was looking for, but in a nutshell, a simple way to avoid the duplicate ID issue when using a form-based paging solution that can be displayed multiple times on the same page (above and below tabular data, for example). My solution is to model it after the PHPMyAdmin paging, in that I simply remove the IDs for the form elements for now and reference the data being passed via the name attribute, which allows for duplicates.