|
-
Feb 13th, 2003, 05:03 AM
#1
Thread Starter
Fanatic Member
Urgent ListView problem - Unresolved
Hi all...
Here is some code which I use to print and align listviews in the package...
VB Code:
Option Explicit
Public Event MaxYReached(ByVal CurrentY As Double, ByRef oPrinter As Object, ByRef bRePrintHeader As Boolean)
Public Event Progress(ByVal oNextListItem As ListItem, ByRef oPrinter As Object, ByRef bRePrintHeader As Boolean, ByVal lTotalLines As Long, ByRef bCancel As Boolean)
Private mlFromX As Long
Public Sub PrintListview(lvListview As ListView, Optional ByVal oPrinter As Object, Optional ByVal bLines As Boolean = False, Optional ByVal bBlackAndWhite As Boolean = True, Optional ByVal MaxY As Double, Optional ByVal lFromX As Long)
Dim oListItem As ListItem
Dim oSubItem As ListSubItem
Dim oColumnHeader As ColumnHeader
Dim iCounter As Integer
Dim lPrevY As Long
Dim sCorrectPrintText As String
Dim bRePrintHeader As Boolean
Dim bCancel As Boolean
mlFromX = lFromX
If oPrinter Is Nothing Then
Set oPrinter = Printer
End If
With oPrinter
.Font = lvListview.Font
Call PrintHeader(lvListview, oPrinter)
.CurrentY = .CurrentY + .TextHeight(" ") + (.TextHeight(" ") / 2)
For Each oListItem In lvListview.ListItems
bRePrintHeader = False
RaiseEvent Progress(oListItem, oPrinter, bRePrintHeader, lvListview.ListItems.Count, bCancel)
If bCancel Then
Exit For
End If
If bRePrintHeader Then
Call PrintHeader(lvListview, oPrinter)
End If
Set oColumnHeader = lvListview.ColumnHeaders(1)
lPrevY = .CurrentY
'oPrinter.Line (.CurrentX, .CurrentY)-(.CurrentX + oListItem.Width, .CurrentY)
.CurrentY = lPrevY
.CurrentX = .CurrentX - oListItem.Width
Select Case oColumnHeader.Alignment
Case lvwColumnLeft
.CurrentX = mlFromX + oListItem.Left + 60
Case lvwColumnRight
.CurrentX = mlFromX + oListItem.Left + oListItem.Width - .TextWidth(oColumnHeader.Text) - 120
Case lvwColumnCenter
.CurrentX = mlFromX + oListItem.Left + ((oListItem.Width - .TextWidth(oListItem.Text)) / 2)
End Select
.ForeColor = IIf(bBlackAndWhite, vbBlack, oListItem.ForeColor)
If oListItem.Width > 15 Then
sCorrectPrintText = Trim$(oListItem.Text)
If .TextWidth(sCorrectPrintText) > oColumnHeader.Width - 60 Then
Do Until Not .TextWidth(sCorrectPrintText & "...") > (oColumnHeader.Width - 120)
sCorrectPrintText = Mid$(sCorrectPrintText, 1, Len(sCorrectPrintText) - 1)
Loop
sCorrectPrintText = sCorrectPrintText & "..."
End If
Debug.Assert sCorrectPrintText = Trim$(oListItem.Text)
oPrinter.Print sCorrectPrintText; 'Because of some weird bug there has to be oPrinter before this
' If i dont add the oPrinter i get a syntax error
End If
.CurrentY = lPrevY
For Each oSubItem In oListItem.ListSubItems
Set oColumnHeader = lvListview.ColumnHeaders(oSubItem.Index + 1)
Select Case oColumnHeader.Alignment
Case lvwColumnLeft
.CurrentX = mlFromX + oColumnHeader.Left + 60
Case lvwColumnRight
.CurrentX = mlFromX + oColumnHeader.Left + oColumnHeader.Width - .TextWidth(oSubItem.Text) - 120
Case lvwColumnCenter
.CurrentX = mlFromX + oColumnHeader.Left + ((oColumnHeader.Width - .TextWidth(oSubItem.Text)) / 2)
End Select
.ForeColor = IIf(bBlackAndWhite, vbBlack, oSubItem.ForeColor)
If oColumnHeader.Width > 15 Then
sCorrectPrintText = Trim$(oSubItem.Text)
If .TextWidth(sCorrectPrintText) > oColumnHeader.Width - 120 Then
Do Until Not .TextWidth(sCorrectPrintText & "...") > (oColumnHeader.Width - 120) Or (sCorrectPrintText = "")
sCorrectPrintText = Mid$(sCorrectPrintText, 1, Len(sCorrectPrintText) - 1)
Loop
sCorrectPrintText = sCorrectPrintText & "..."
End If
oPrinter.Print sCorrectPrintText;
End If
.CurrentY = lPrevY
Next
.CurrentY = .CurrentY + oListItem.Height
If .CurrentY > MaxY Then
RaiseEvent MaxYReached(.CurrentY, oPrinter, bRePrintHeader)
If bRePrintHeader Then
Call PrintHeader(lvListview, oPrinter)
.CurrentY = .CurrentY + .TextHeight(" ") + (.TextHeight(" ") / 2)
End If
End If
Next
End With
End Sub
Public Sub PrintHeader(lvListview As ListView, oPrinter As Object)
Dim lPrevY As Long
Dim oColumnHeader As ColumnHeader
Dim sCorrectPrintText As String
With oPrinter
For Each oColumnHeader In lvListview.ColumnHeaders
If oColumnHeader.Width > 60 Then
lPrevY = .CurrentY
Select Case oColumnHeader.Alignment
Case lvwColumnLeft
.CurrentX = mlFromX + oColumnHeader.Left + 60
Case lvwColumnRight
.CurrentX = mlFromX + oColumnHeader.Left + oColumnHeader.Width - .TextWidth(oColumnHeader.Text) - 120
Case lvwColumnCenter
.CurrentX = mlFromX + oColumnHeader.Left + ((oColumnHeader.Width - .TextWidth(oColumnHeader.Text)) / 2)
End Select
.FontUnderline = True
If oColumnHeader.Width > 15 Then
sCorrectPrintText = Trim$(oColumnHeader.Text)
If sCorrectPrintText <> "" Then
If .TextWidth(sCorrectPrintText) > oColumnHeader.Width - 120 Then
Do Until Not .TextWidth(sCorrectPrintText & "...") > (oColumnHeader.Width - 120) Or (sCorrectPrintText = "")
sCorrectPrintText = Mid$(sCorrectPrintText, 1, Len(sCorrectPrintText) - 1)
Loop
sCorrectPrintText = sCorrectPrintText & "..."
End If
oPrinter.Print sCorrectPrintText;
End If
End If
.FontUnderline = False
.CurrentY = lPrevY
End If
Next
End With
End Sub
The code works fine, but only for the first page! Once all the data has filled the first page... it goes mad. All other remaining fields print on seperate pages! It needs to stop after a certain amount of data, in order to go over to another page.
Any quick idea's please, PLEASE?
Regards,
Paul.
Last edited by VisionIT; Feb 13th, 2003 at 05:31 AM.
-
Feb 13th, 2003, 05:56 AM
#2
You need a varible, say lngLine, which tracks what line it's printing on, then when this gets to 50 (Max line per page), it resets it'self to one and you then need to call Printer.newPage...does that make sense?
Woka
-
Feb 13th, 2003, 06:01 AM
#3
Thread Starter
Fanatic Member
Perfect sense M8y...
But how i'm supposed to include it into that code... i still need to find. Damn good idea though M8, cheers.
Regards,
Paul.
-
Feb 13th, 2003, 06:15 AM
#4
Here's my print code for the SGrid from vbAccelerator...
VB Code:
Private Function Print_Results(grdPrint As vbalGrid)
Dim intHeader As Integer
Dim intMargin As Integer
Dim intPageNo As Integer
Dim intPrintRow As Integer
Dim intCounter As Integer
Dim intColumns As Integer
Dim intColumnWidth() As Long
Dim intColumnID() As Integer
Dim strOutput As String
Dim intGridWidth As Integer
Dim sngRatio As Single
Dim intXpos As Integer
Dim intPosition As Integer
Dim intRow As Integer
Dim intLinesPerPage As Integer
Dim blnIcon As Boolean
On Error GoTo ErrorHandler
Printer.ScaleMode = vbTwips
Printer.PaperSize = vbPRPSA4
Printer.Orientation = vbPRORLandscape
Printer.FontName = "Arial"
intMargin = 500
intHeader = 1500
intLinesPerPage = 45
With grdPrint
For intCounter = 1 To .Columns
If .ColumnVisible(intCounter) And Trim(.ColumnHeader(intCounter) & "") > "" Then
intGridWidth = intGridWidth + (.ColumnWidth(intCounter) * Screen.TwipsPerPixelX)
End If
Next intCounter
sngRatio = ((Printer.Width - 2000) / intGridWidth)
For intCounter = 1 To .Columns
If .ColumnVisible(intCounter) And Trim(.ColumnHeader(intCounter) & "") > "" Then
intColumns = intColumns + 1
ReDim Preserve intColumnWidth(1 To intColumns)
ReDim Preserve intColumnID(1 To intColumns)
intColumnWidth(intColumns) = (.ColumnWidth(intCounter) * Screen.TwipsPerPixelX) * sngRatio
intColumnID(intColumns) = intCounter
End If
Next intCounter
End With
intPrintRow = 0
intPageNo = 0
For intRow = 1 To grdPrint.Rows
intPrintRow = intPrintRow + 1
If intPrintRow = 1 Then
intPageNo = intPageNo + 1
Printer.FontSize = 12
Printer.FontBold = True
Printer.FontUnderline = False
Printer.CurrentX = intMargin - 300
Printer.CurrentY = intHeader - 1000
Printer.Print Me.Caption
Printer.FontSize = 7
Printer.FontBold = False
Printer.CurrentY = intHeader - 600
Printer.CurrentX = intMargin - 300
Printer.Print "Page " & intPageNo & " of " & ((grdPrint.Rows - (grdPrint.Rows Mod intLinesPerPage)) / intLinesPerPage) + IIf((grdPrint.Rows Mod intLinesPerPage) > 0, 1, 0)
intXpos = 0
Printer.FontBold = True
Printer.FontUnderline = True
For intCounter = 1 To intColumns
Printer.CurrentY = intHeader
If intCounter > 1 Then
intXpos = intXpos + intColumnWidth(intCounter - 1)
End If
Printer.CurrentX = intXpos + intMargin
strOutput = grdPrint.ColumnHeader(intColumnID(intCounter))
intPosition = Len(strOutput)
Do While Printer.TextWidth(Left(strOutput, intPosition)) > intColumnWidth(intCounter)
intPosition = intPosition - 1
Loop
If intPosition < Len(strOutput) Then
strOutput = Left(strOutput, intPosition - 2) & "..."
End If
If grdPrint.ColumnAlign(intColumnID(intCounter)) = ecgHdrTextALignCentre Then
Printer.CurrentX = Printer.CurrentX + (intColumnWidth(intCounter) - Printer.TextWidth(strOutput)) / 2
End If
Printer.Print strOutput
Next intCounter
Printer.Print
End If
Printer.FontUnderline = False
Printer.FontBold = False
intXpos = 0
For intCounter = 1 To intColumns
Printer.CurrentY = intHeader + 250 + (Printer.TextHeight("H") * 1.1 * intPrintRow)
If intCounter > 1 Then
intXpos = intXpos + intColumnWidth(intCounter - 1)
End If
Printer.CurrentX = intXpos + intMargin
If grdPrint.Cell(intRow, intColumnID(intCounter)).IconIndex > 0 Then
blnIcon = True
strOutput = ""
Else
blnIcon = False
strOutput = grdPrint.CellFormattedText(intRow, intColumnID(intCounter))
End If
intPosition = Len(strOutput)
Do While Printer.TextWidth(Left(strOutput, intPosition)) > intColumnWidth(intCounter)
intPosition = intPosition - 1
Loop
If intPosition < Len(strOutput) Then
strOutput = Left(strOutput, intPosition - 3) & "..."
End If
If blnIcon Then
If grdPrint.ColumnAlign(intColumnID(intCounter)) = ecgHdrTextALignCentre Then
Printer.CurrentX = Printer.CurrentX + (intColumnWidth(intCounter) - Printer.TextHeight("H")) / 2
End If
Printer.PaintPicture ilsImages.ItemPicture(ilsImages.ItemKey(grdPrint.Cell(intRow, intColumnID(intCounter)).IconIndex + 1)), Printer.CurrentX, Printer.CurrentY, Printer.TextHeight("H"), Printer.TextHeight("H")
Else
If grdPrint.ColumnAlign(intColumnID(intCounter)) = ecgHdrTextALignCentre Then
Printer.CurrentX = Printer.CurrentX + (intColumnWidth(intCounter) - Printer.TextWidth(strOutput)) / 2
End If
Printer.Print strOutput
End If
Next intCounter
If intPrintRow = intLinesPerPage And intRow < grdPrint.Rows Then
intPrintRow = 0
Printer.NewPage
End If
Next intRow
Printer.FontBold = True
Printer.CurrentY = Printer.CurrentY + 400
strOutput = grdPrint.Rows & " Helpdesk Requests"
Printer.CurrentX = (Printer.Width - Printer.TextWidth(strOutput) - intMargin) / 2
Printer.Print strOutput
Printer.EndDoc
Exit Function
ErrorHandler:
Call MsgBox("Failed to print." & vbCr & Err.Number & " : " & Err.Description, vbCritical, "Printer Error")
Exit Function
End Function
The varibles are intLinePerPage and intPrintRow...think you can figure how it works 
if you need help give me a shout...
Woka
-
Feb 13th, 2003, 06:17 AM
#5
The above code formats the grid correctly, prints icons and truncates text (that is to long) and adds '...' to the end of it 
Woka
-
Feb 13th, 2003, 07:53 AM
#6
Thread Starter
Fanatic Member
User-defined type not defined on this line...
Private Function Print_Results(grdPrint As vbalGrid)
Damnit
Any idea's, or is there just a line I could add to the existing code perhaps?
Regards,
Paul.
-
Feb 13th, 2003, 08:00 AM
#7
Woka's code is not using a listview, but vbAccelerator's SGrid.
I think your problem is caused by one of the
.CurrentY = lPrevY
lines. If the first page is full, the printer switches to the next page, and cannot go back. The line I mentioned causes the printer to go to the last Y position on the new page instead.
You need to add some code that compares the Y position to the paper's height, and if needed inserts a Printer.NewPage. Don't rely on the printer to go to a new page, you should do it yourself.
-
Feb 13th, 2003, 08:10 AM
#8
p, my code is for SGrid, not a ListView, however, the functionality is still exactally the same. Just look at how lngPrintRow is used to set a new page and work out what line you are printing on...
-
Feb 13th, 2003, 08:45 AM
#9
Thread Starter
Fanatic Member
Right...
I understand exactly how the code is working... but the currentY variable you mentioned doesn't monitor line numbers.
Even if I add my own code to search through it, it keeps doing it every damn time!
Getting a bit sick of VB now 
Regards,
Paul.
-
Feb 13th, 2003, 08:50 AM
#10
CurretY is the the Y co-ordinate on the paper where I am going to print text...
VB Code:
If intPrintRow = intLinesPerPage And intRow < grdPrint.Rows Then
intPrintRow = 0
Printer.NewPage
End If
intPrintRow is the one that records what line I am up to for that page...so if intprintRow = intLinePerPage (max Lines) then it resets and Printer.NewPage is called...
You should be merely looking for how the intprintRow varible is used, and nothing more...
Woka
-
Feb 13th, 2003, 10:03 AM
#11
Thread Starter
Fanatic Member
Thanks for all the help M8....
My heads killing me, and i'm far from programming mood! I'll perhaps look at it again 2moro. It seriously looks like crap to me at the moment, and I coded it!
If i remember correctly... it looked that way anyway! 
If anyone invents a quick-fix button, please inform me!
Annoying part... is I can perfectly understand the code you've placed, but can't physically place it into the format! I need a headache pill or 5! 
Regards,
Paul.
-
Feb 13th, 2003, 05:19 PM
#12
Thread Starter
Fanatic Member
Ok... headache's gone, back to work!
Anyone else got any ideas where to stick the printer.newpage line in all my code?
Regards,
Paul.
-
Feb 14th, 2003, 04:15 AM
#13
It's not hard to transgfer those few varibles across.
I Have...
VB Code:
For intRow = 1 To grgGrid.Rows
Next intRow
You have...
VB Code:
For Each oListItem In lvListview.ListItems
Next oListItem
SO...add the following...
VB Code:
Dim lngPrintRow As Long
Dim lngRow As Long
Dim lngMaxRows As Long
lngMaxRows = 40 'This varible sets how many listitems to display per page...setting this too large may cause a few problems with page positioning :(
For Each oListItem In lvListview.ListItems
If lngPrintRow = 0 Then
PrintHeader lvListview, oPrinter 'I am assuming this prints the column headers on the page...
End If
lngPrintRow = lngPrintRow + 1
lngRow = lngRow + 1
'All the rest of your code...
If lngPrintRow = lngMaxRows And lngRow < lvListItem.ListItems.Count Then
Printer.NewPage
lngPrintRow = 0
End If
Next oListItem
That will print on multiple pages, and add the columns to the top of each page. The code I added includes special text and font formatting, but I stripped that out to make it slightly simpler...
Hope this helps.
Woka
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|