none
Overrunning pages? RRS feed

  • Question

  • again, with the Word 2007 and the printing of a test form.

    I'm using a 2 column table to print questions top to bottom (as opposed to side by side).

    I'm keeping track of the 'current' page with a variable, and when the next row added causes us to move to another page, what SHOULD happen is that it triggers moving to the 2nd column.

    This works fine for the first 2 pages - after that, it almost seems to be acting like it's not seeing the new pages, yet it prints the correct page number in the footer.  Here comes the best part.  If I step through the code, it works beautifully.  It's when I turn it loose to run like it would be running in production I get this behaviour.

    I'm using oDoc.Sections[1].Range.Information(3) to keep track of pages.

     

    Any ideas for what is going on?

    Dorris

    Thursday, December 15, 2011 4:55 PM

Answers

  • Hi Dorris

    As I'm not conversant with FoxPro, and this is a lot of code, my trying to wade through it isn't going to be much good. And for obvious reasons, I have no way to test it.

    Have you tried the other two approaches?

    <<And, I'm sorry, but the idea that merging one row's cells merges the rest of the table strikes me as counter-intuitive. >>

    I didn't say it merge the entire table. I said it destroys the grid, in that not all rows and columns have the same number of cells. It's just the way Word is, so you have to deal with it.

    One more thought. I have no idea how big this table is getting. But as soon as Word has to calculate page layout for a table, things can slow down quite a bit. Possibly, breaking the table up for the text sections can have other, positive effects...


    Cindy Meister, VSTO/Word MVP
    Friday, December 16, 2011 4:40 PM
    Moderator

All replies

  • Hi Dorris

    Why not use:

    oDoc.Content.Information(4)?

    Or

    oDoc.ComputeStatistics(2)


    Cindy Meister, VSTO/Word MVP
    Thursday, December 15, 2011 5:23 PM
    Moderator
  • What's the difference between the three commands - and will that stop the 'overrun'?

    and one more question, then I'll leave you alone, at a certain point, I need to print some directions for the next section of the test.  Simple, right?  oTab.Cells.Merge and print the directions.  The problem is coming up when I add the next row and suddenly oTab.Rows[nRow].Range.Cell[2] doesn't exist, even though oTab.Columns.Count reports 2 columns.  Most confusing and most frustrating.

     

    Dorris

    Thursday, December 15, 2011 9:08 PM
  • Hi Dorris

    <<What's the difference between the three commands - and will that stop the 'overrun'?>>

    At a technical level, I simply don't know. Certainly, Information(4) returns all the pages in the document whereas the option you've been using refers only to the current selection. It's quite likely that the current selection isn't moving (since I don't see all your code, I can only guess!), so the number wouldn't change. If that's the case then it ought to stop the overruns.

    Information is very, very old (WordBasic left-over); ComputeStatistics is newer. Beyond that, I'd normally expect it to give the same result as Information(4).

    In any case, I can't guarantee my suggestion will stop the overruns as I can't know what's causing them - too little information.

    As soon as you merge cells within a table, you can no longer effectively work with individual cells because you've destroyed the "grid". Again, I don't have much information about what your result must be, but my inclination would be to split this to a new table, with text between.

    If that's not allowed, an effective workaround could be to make all the table cells except the one in which the text is required very narrow. Either at the far right, if the text should be left-aligned or to either side, giving a centered effect.


    Cindy Meister, VSTO/Word MVP
    Friday, December 16, 2011 7:16 AM
    Moderator
  • Here is the code:
    #Define CR Chr(10)
    
    
    Select Val(b.seq) As qstnum, b.cat, a.script, a.stem, a.respa, a.respb, a.respc, a.respd,;
      b.itmnum, a.scriptim From convatc a, dupwk b;
      WHERE a.itmnum = b.itmnum;
      INTO Cursor testbook;
      ORDER By qstnum
    
    ** Create instance of Word
    oApp = Createobject("word.Application")
    ** Create New Document
    oDoc = oApp.Documents.Add()
    oDoc.TextLineEnding = 1  && wdCROnly
    
    oApp.ActiveDocument.PageSetup.TopMargin = oApp.InchesToPoints(1)
    oApp.ActiveDocument.PageSetup.BottomMargin = oApp.InchesToPoints(1)
    oApp.ActiveDocument.PageSetup.rightMargin = oApp.InchesToPoints(1)
    oApp.ActiveDocument.PageSetup.leftMargin = oApp.InchesToPoints(1)
    
    * Set up Doc Footer
    oApp.ActiveDocument.Sections[1].footers[1].pagenumbers.Add()
    oApp.ActiveDocument.Sections[1].footers[1].pagenumbers[1].Alignment = 1
    * Set up header
    rHdr = oApp.ActiveDocument.Sections.First.Headers.Item[1].Range
    rHdr.Text = ""
    rHdr.Font.Name = "Courier New"
    rHdr.Font.Size = 10.5
    rHdr.InsertAfter("ENGLISH COMPREHENSION LEVEL EXAMINATION" + CR)
    rHdr.InsertAfter("Form " + m.testnum + CR)
    
    *Set Document Font name And size
    DocRange = oDoc.Range()
    DocRange.Font.Name = 'Courier New'
    DocRange.Font.Size = 10.5
    DocRange.ParagraphFormat.LineSpacingRule = 0  && wdLineSpaceSingle
    DocRange.ParagraphFormat.KeepTogether = .T.
    DocRange.ParagraphFormat.KeepWithNext = .T.
    ** go to beginning of section
    DocRange.Text = ""
    DocRange.InsertAfter(CR + "PART I - LISTENING" + CR)
    DocRange.InsertAfter("Directions for items 1-56.  You will hear statements or ")
    DocRange.InsertAfter("questions on the tape.  Select the best answer and mark your ")
    DocRange.InsertAfter("answer sheet, a, b, c, or d.  DO NOT WRITE ON THE TEST BOOKLET." + CR)
    ** go to bottom of section
    DocRange.Collapse(0)
    
    
    *oApp.Visible = .T.
    
    
    ** Set up Table for rest of Document
    oTab = oDoc.Tables.Add(DocRange, 1, 2)
    oTab.Rows.allowbreakacrosspages = .F.
    oTab.AllowAutoFit = .F.
    oTab.Rows.SetHeight(oApp.InchesToPoints(1.2),1)
    oTab.Rows.SetMarginBottom(10)
    oSec = oDoc.Sections[1]
    SectionCnt = 2
    nRow = 0
    ** Set "Last Page"
    mcurpage = oSec.Range.Information(3)
    maxRow = 0
    HoldRow = 1
    ShortSection = .F.
    ** print cat 40 - print next set of instructions, print cat 41,
    *Scan while !eof('prtfile')
    Scan While cat < '50'
      mcat = cat
      Scan While cat = mcat
        nRow = nRow + 1
        oRow = oTab.Rows[nRow].Range()
        orow.cells[1].range.paragraphformat.linespacing = 10
        Store '' To fblock, line1, line2, line3, line4, line5
        If Empty(stem)    && just the responses
          line1 = Iif(qstnum < 10,' ' + Alltrim(Str(qstnum)), Alltrim(Str(qstnum)));
            + '. a) ' + Alltrim(respa) + CR
          line2 = Space(4) + 'b) ' + Alltrim(respb) + CR
          line3 = Space(4) + 'c) ' + Alltrim(respc) + CR
          line4 = Space(4) + 'd) ' + Alltrim(respd)
        Else
          line1 = Iif(qstnum < 10,' ' + Alltrim(Str(qstnum)), Alltrim(Str(qstnum)));
            + '. ' + Alltrim(stem) + CR
          line2 = Space(4) + 'a) ' + Alltrim(respa) + CR
          line3 = Space(4) + 'b) ' + Alltrim(respb) + CR
          line4 = Space(4) + 'c) ' + Alltrim(respc) + CR
          line5 = Space(4) + 'd) ' + Alltrim(respd)
        Endif
        fblock = line1 + line2 + line3 + line4 + line5
        ** If we've 'run off the page' - time to move to column 2
        ** maxRow holds end of this page row
        ** HoldRow holds "next row to print"
        ** mCurPage holds current page
    if oSec.Range.Information[3] = 3
    susp
    endif
        If oSec.Range.Information(3) <> mcurpage
    wait window "Now Printing page " + alltrim(str(mCurPage)) timeout 3
          maxRow = nRow -1
          nRow = HoldRow
          mcurpage = oSec.Range.Information(3)
        Endif
        If maxRow <> 0
          oRow = oTab.Rows[nRow].Range()
          orow.cells[2].range.paragraphformat.linespacing = 10
          oRow.Cells(2).Range.InsertAfter(fblock)
        Else
          oRow = oTab.Rows[nRow].Range()
          orow.cells[1].range.paragraphformat.linespacing = 10
          oRow.Cells[1].Range.InsertAfter(fblock)
          ** This keeps us from adding to many blank rows, which will
          ** cause new pages when we don't want them
          If oTab.Rows.Count - nRow <= 0
            oTab.Rows.Add()
          Endif
        Endif
        ** going to new page.  Check to see how many questions left in
        ** this section.  If < 6, need to split between the two columns
    
        If nRow = maxRow
          If (56 - qstnum <= 6) Or (66 - qstnum <= 6)
            ShortSection = .T.
          Endif
          HoldRow = maxRow + 1
          maxRow = 0
          If oTab.Rows.Count - nRow <= 0
            oTab.Rows.Add()
          Endif
        Endif
        If ShortSection
    susp    
          ** The rest needs to happen in this section, 'splitting' the questions that are left
          ** between two columns
          Do Case
          Case 56 - qstnum <= 6
            LastRow = nrow + Round((56 - qstnum)/2,0)
            LastQst = 56
          Case 66 - qstnum <= 6
            LastRow = Round((66 - qstnum)/2,0)
            LastQst = 66
          Endcase
          HoldRow = nRow
          skip
          Scan While qstnum <= LastQst
            nRow = nRow + 1
            Store '' To fblock, line1, line2, line3, line4, line5
            If Empty(stem)    && just the responses
              line1 = Iif(qstnum < 10,' ' + Alltrim(Str(qstnum)), Alltrim(Str(qstnum)));
                + '. a) ' + Alltrim(respa) + CR
              line2 = Space(4) + 'b) ' + Alltrim(respb) + CR
              line3 = Space(4) + 'c) ' + Alltrim(respc) + CR
              line4 = Space(4) + 'd) ' + Alltrim(respd)
            Else
              line1 = Iif(qstnum < 10,' ' + Alltrim(Str(qstnum)), Alltrim(Str(qstnum)));
                + '. ' + Alltrim(stem) + CR
              line2 = Space(4) + 'a) ' + Alltrim(respa) + CR
              line3 = Space(4) + 'b) ' + Alltrim(respb) + CR
              line4 = Space(4) + 'c) ' + Alltrim(respc) + CR
              line5 = Space(4) + 'd) ' + Alltrim(respd)
            Endif
            fblock = line1 + line2 + line3 + line4 + line5
            If maxRow <> 0
              oRow = oTab.Rows[nRow].Range()
              orow.cells[2].range.paragraphformat.linespacing = 10
              oRow.Cells(2).Range.InsertAfter(fblock)
            Else
              oRow = oTab.Rows[nRow].Range()
              orow.cells[1].range.paragraphformat.linespacing = 10
              oRow.Cells[1].Range.InsertAfter(fblock)
              ** This keeps us from adding to many blank rows, which will
              ** cause new pages when we don't want them
              If oTab.Rows.Count - nRow = 0
                oTab.Rows.Add()
              Endif
            Endif
            If nRow = LastRow
              maxRow = 1
              nRow = HoldRow
            Endif
          Endscan
          nRow = LastRow
        Endif
      Endscan
      ** add another row, if needed
      If oTab.Rows.Count - nRow = 0
        oTab.Rows.Add()
      Endif
      nRow = nRow + 1
      If mcat = '40'
        oRow = oTab.Rows[nRow].Range()
        oRow.Cells.Merge()
        oRow.Cells[1].Range.InsertAfter("Directions for items 57-66.  " + ;
          "You will hear conversations or persons giving information.  " + ;
          "Select the best answer and mark your answer sheet, a, b, c, or d." + CR)
      Endif
      ** add another row, if needed
      If oTab.Rows.Count - nRow = 0
        oTab.Rows.Add()
      Endif
    Endscan
    ** Finished with cats 40 and 41.
    If oTab.Rows.Count - nRow = 0
      oTab.Rows.Add()
    Endif
    nRow = nRow + 1
    oRow = oTab.Rows[nRow].Range()
    oRow.Cells.Merge()
    oRow.InsertAfter(CR+ "THIS IS THE END OF THE LISTENING PART OF THE TEST." + CR)
    oRow.InsertAfter(CR + "PART II - READING" + CR)
    oRow.InsertAfter(CR + "Directions for items 67-100.  Select the best answer and mark " + ;
      "your answer sheet, a, b, c, or d.  DO NOT WRITE ON THE TEST BOOKLET." + CR)
    Scan While !Eof()
      nRow = nRow + 1
      Store '' To fblock, line1, line2, line3, line4, line5
      line1 = Iif(qstnum < 10,' ' + Alltrim(Str(qstnum)), Alltrim(Str(qstnum)));
        + '. ' + Alltrim(stem) + CR
      line2 = Space(5) + 'a) ' + Alltrim(respa) + CR
      line3 = Space(5) + 'b) ' + Alltrim(respb) + CR
      line4 = Space(5) + 'c) ' + Alltrim(respc) + CR
      line5 = Space(5) + 'd) ' + Alltrim(respd)
      fblock = line1 + line2 + line3 + line4 + line5
      oRow = oTab.Rows[nRow].Range()
      oRow.Cells[1].Range.InsertAfter(fblock)
      If oTab.Rows.Count - nRow = 0
        oTab.Rows.Add()
      Endif
      nRow = nRow + 1
      oRow = oTab.Rows[nRow].Range()
      oRow.Cells.Merge()
    Endscan
    If oTab.Rows[nRow].islast
      oTab.Rows.Add()
      nRow = nRow + 1
    Endif
    oRow = oTab.Rows[nRow].Range()
    oRow.Cells.Merge()
    oRow.InsertAfter( "THIS IS THE END OF THE TEST" + CR)
    
    ** save and exit
    
    

    And, I'm sorry, but the idea that merging one row's cells merges the rest of the table strikes me as counter-intuitive. 

     

    Anyway,  what appears to be happening is that once we pass page 3, the line    If oSec.Range.Information(3) <> mcurpage is not resolving to true <i>unless I'm stepping through the code</i>.  If I'm stepping through the code, everything works just fine.



    Friday, December 16, 2011 3:51 PM
  • Hi Dorris

    As I'm not conversant with FoxPro, and this is a lot of code, my trying to wade through it isn't going to be much good. And for obvious reasons, I have no way to test it.

    Have you tried the other two approaches?

    <<And, I'm sorry, but the idea that merging one row's cells merges the rest of the table strikes me as counter-intuitive. >>

    I didn't say it merge the entire table. I said it destroys the grid, in that not all rows and columns have the same number of cells. It's just the way Word is, so you have to deal with it.

    One more thought. I have no idea how big this table is getting. But as soon as Word has to calculate page layout for a table, things can slow down quite a bit. Possibly, breaking the table up for the text sections can have other, positive effects...


    Cindy Meister, VSTO/Word MVP
    Friday, December 16, 2011 4:40 PM
    Moderator