Cần giúp đỡ về vấn đề xác định chiều cao của khổ giấy khi in (1 người xem)

  • Thread starter Thread starter bivily
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

bivily

Thành viên hoạt động
Tham gia
11/10/07
Bài viết
110
Được thích
26
Chào cả nhà GPE!

Mình có 1 sheet được thiết lập cùng in PrintArea = "$A$1:$H$46" và vùng này có thể thay đổi khi chèn thêm dòng nằm giữa 846.

Mình muốn khi in thì cố định chiều cao của các dòng từ 1 đến 7.
Các dòng từ 8 đến cuối bảng tính (như ví dụ này là 46) thì tự động thay đổi để in vừa trên 1 tờ giấy A4.

Ý tưởng của mình là tính chiều cao của PrintArea:
[GPECODE=vb]
With Sheet1.PageSetup
PrintAreaHeight = Sheet1.Range(.PrintArea).Height
End With
[/GPECODE]

Sau đó tính chiều cao của khổ giấy:
[GPECODE=vb]
With Sheet1.PageSetup
PaperHeight = IIf(.Orientation = xlPortrait, 297, 210) * (72 / 25.4) / (.Zoom / 100) - (.TopMargin + .BottomMargin)
End With
[/GPECODE]

Tiếp đến là so sánh PaperHeight với PrintAreaHeight để điều chỉnh chiều cao cho các dòng từ 8 đến 46.

Vấn đề ở đây là mình tính được PaperHeight < PrintAreaHeight nhưng vẫn in được toàn bộ PrintArea trên 1 trang A4. Mình nghĩ công thức tính PaperHeight ở trên có vấn đề nhưng mình tìm mãi không biết sai ở chổ nào?

Toàn bộ Code cho việc này như sau:
[GPECODE=vb]
Sub TestPrint()
Dim lngTableBe As Long, lngTableEn As Long
Dim PrintAreaBe As Long, PrintAreaEn As Long
Dim PrintAreaHeight As Double, PaperHeight As Double
Dim Delta As Double

lngTableBe = Sheet1.Range("BATDAU").Row
lngTableEn = Sheet1.Range("KETTHUC").Row - 1
Select Case Sheet1.HPageBreaks.Count
Case 0
With Sheet1.PageSetup
.FooterMargin = 0
.HeaderMargin = 0
Sheet1.Rows(lngTableBe & ":" & lngTableEn).RowHeight = 18
If .PrintArea <> "" Then
PrintAreaBe = Val(Split(Split(.PrintArea, ":")(0), "$")(2))
PrintAreaEn = Val(Split(Split(.PrintArea, ":")(1), "$")(2))
PrintAreaHeight = Sheet1.Range(.PrintArea).Height

PaperHeight = IIf(.Orientation = xlPortrait, 297, 210) * (72 / 25.4) / (.Zoom / 100) - (.TopMargin + .BottomMargin)
Delta = Round((PaperHeight - PrintAreaHeight) / (lngTableEn - lngTableBe + 1), 2)
PaperHeight = Round(PaperHeight, 2)

MsgBox "PrintArea" & vbTab & vbTab & ": " & .PrintArea & vbCrLf & _
"PrintAreaHeight" & vbTab & ": " & PrintAreaHeight & vbCrLf & _
"PaperHeight" & vbTab & ": " & PaperHeight & " (Tai sao PaperHeight < PrintAreaHeight nhung lai in duoc tren 1 trang giay?)" & vbCrLf & _
"PrintZoom" & vbTab & ": " & .Zoom & "%" & vbCrLf & _
"Delta Height" & vbTab & ": " & Delta
'Sheet1.Rows(lngTableBe & ":" & lngTableEn).RowHeight = 17 + Delta
End If
End With
Case 1

Case Else

End Select
End Sub
[/GPECODE]

Xin các cao thủ ra tay giúp đỡ.
 

File đính kèm

Lần chỉnh sửa cuối:
Vấn đề ở đây là mình tính được PaperHeight < PrintAreaHeight nhưng vẫn in được toàn bộ PrintArea trên 1 trang A4. Mình nghĩ công thức tính PaperHeight ở trên có vấn đề nhưng mình tìm mãi không biết sai ở chổ nào?
Mình trả lời cho câu hỏi này của bạn (chưa xét bất kì tính toán nào)
Nguyên nhân là do bạn đặt chế độ Page Setup Zoom 95%. Bạn thử đặt Zoom 100% xem kết quả như thế nào nhé.
 
Upvote 0
Mình trả lời cho câu hỏi này của bạn (chưa xét bất kì tính toán nào)
Nguyên nhân là do bạn đặt chế độ Page Setup Zoom 95%. Bạn thử đặt Zoom 100% xem kết quả như thế nào nhé.

Cám ơn bạn đã trả lời.
Mình đã thử trường hợp Zoom = 100% rồi nhưng không được. Vì đưa lên diễn đàn để hỏi nên mình làm luôn trường hợp tổng quát (để zoom 95%).
 
Upvote 0
Cám ơn bạn đã trả lời.
Mình đã thử trường hợp Zoom = 100% rồi nhưng không được. Vì đưa lên diễn đàn để hỏi nên mình làm luôn trường hợp tổng quát (để zoom 95%).
Hình như bạn chưa hiểu câu trả lời của tôi. Bạn hỏi
Vấn đề ở đây là mình tính được PaperHeight < PrintAreaHeight nhưng vẫn in được toàn bộ PrintArea trên 1 trang A4. Mình nghĩ công thức tính PaperHeight ở trên có vấn đề nhưng mình tìm mãi không biết sai ở chổ nào?
Có nghĩa là: tại sao khổ A4 nhỏ hơn kích thước vùng in mà vẫn in được toàn bộ vùng in trong khổ A4
=> Và tôi đã nói rõ rằng: nguyên nhân do bạn đặt chế độ Page Setup Zoom 95 %. Thì quá rõ rồi, bạn thử tính xem nếu PaperHeight < PrintAreaHeight nhưng nhân PrintAreaHeight * 95 % => sẽ có khả năng PaperHeight > PrintAreaHeight*95% nên bạn vẫn in được toàn bộ printArea trên khổ A4.
Nếu Code thì bạn có thể tham khảo cách làm sau và tuỳ biến
[GPECODE=vb]
Sub PrtArea()
Dim PArea As Range
Dim HConstArea As Double
Dim HPArea As Double, Hpage As Double, PZoom As Double
'Thiet lap vung in
Set PArea = Sheet1.Range("A1:H" & Sheet1.Range("A65536").End(3).Row)
ActiveSheet.PageSetup.PrintArea = PArea
'Do cao vung co dinh A1:H7
HConstArea = Sheet1.Range("A1:H7").Height
With Sheet1.PageSetup
'Do cao A4 theo kho doc, ngang
Hpage = IIf(.Orientation = xlPortrait, 297, 210)
'Do cao vung con lai = kho giay - vung co dinh
HPArea = Application.CentimetersToPoints(Hpage / 10) - .TopMargin + .BottomMargin
'Ty le thiet dat Zoom
PZoom = .Zoom
End With
'Thiet dat do cao cho vung con lai
Sheet1.Range("A8:A" & PArea.Rows.Count).EntireRow.RowHeight _
= Application.WorksheetFunction.RoundDown( _
((HPArea - HConstArea * PZoom / 100) / (PArea.Rows.Count - 6)) * 100 / PZoom, 2)
ActiveSheet.PrintPreview
End Sub
[/GPECODE]
 
Upvote 0
Cám ơn bạn đã nhiệt tình giúp đỡ. Đúng là mình đã chia cho Zoom sai vị trí. Mình đã lấy code của bạn và Test với cái bản tính mình đính kèm ở trên lúc Run nó cho kết quả là 2 trang (Có 1 dòng cuối cùng nằm ở trang thứ 2). Xem kỹ lại code của bạn mình thấy tại dòng 21 ((HPArea - HConstArea * PZoom / 100) / (PArea.Rows.Count - 6)) * 100 / PZoom, 2), mình nghĩ ở đây phải là ((HPArea - HConstArea * PZoom / 100) / (PArea.Rows.Count - 7)) * 100 / PZoom, 2) mới đúng. Những nếu sửa lại là 7 thì ở trang 2 lại có đến 2 dòng.

Thêm nữa, tại sao tại dòng 14 HPArea = Application.CentimetersToPoints(Hpage / 10) - .TopMargin + .BottomMargin lại là + .BottomMargin?

Bạn bỏ thêm chút thời gian nữa giúp mình luôn nha!
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn đã có những suy nghĩ tốt về lập trình, đó là 2 vấn đề tôi sai sót. Code tôi đã chú thích rất rõ và bạn có thể tự tuỳ biến cho hợp lý.
Mã:
Sub PrtArea()
    Dim PArea As Range
    Dim HConstArea As Double
    Dim HPArea As Double, Hpage As Double, PZoom As Double
    'Thiet lap vung in
    Set PArea = Sheet1.Range("A1:H" & Sheet1.Range("A65536").End(3).Row)
    ActiveSheet.PageSetup.PrintArea = PArea
    'Do cao vung co dinh A1:H7
    HConstArea = Sheet1.Range("A1:H7").Height
    With Sheet1.PageSetup
        'Do cao A4 theo kho doc, ngang
        Hpage = IIf(.Orientation = xlPortrait, 297, 210)
        'Do cao vung con lai = kho giay - vung co dinh
        HPArea = Application.CentimetersToPoints(Hpage / 10) - .TopMargin - .BottomMargin
        'Ty le thiet dat Zoom
        PZoom = .Zoom
    End With
    'Thiet dat do cao cho vung con lai
    Sheet1.Range("A8:A" & PArea.Rows.Count).EntireRow.RowHeight _
          = Application.WorksheetFunction.RoundDown( _
            ((HPArea - HConstArea * PZoom / 100) / (PArea.Rows.Count - 7)) * 100 / PZoom, 2)
    ActiveSheet.PrintPreview
End Sub
 
Upvote 0
Bạn đã có những suy nghĩ tốt về lập trình, đó là 2 vấn đề tôi sai sót. Code tôi đã chú thích rất rõ và bạn có thể tự tuỳ biến cho hợp lý.
[GPECode=vb]
Sub PrtArea()
Dim PArea As Range
Dim HConstArea As Double
Dim HPArea As Double, Hpage As Double, PZoom As Double
'Thiet lap vung in
Set PArea = Sheet1.Range("A1:H" & Sheet1.Range("A65536").End(3).Row)
ActiveSheet.PageSetup.PrintArea = PArea
'Do cao vung co dinh A1:H7
HConstArea = Sheet1.Range("A1:H7").Height
With Sheet1.PageSetup
'Do cao A4 theo kho doc, ngang
Hpage = IIf(.Orientation = xlPortrait, 297, 210)
'Do cao vung con lai = kho giay - vung co dinh
HPArea = Application.CentimetersToPoints(Hpage / 10) - .TopMargin - .BottomMargin
'Ty le thiet dat Zoom
PZoom = .Zoom
End With
'Thiet dat do cao cho vung con lai
Sheet1.Range("A8:A" & PArea.Rows.Count).EntireRow.RowHeight _
= Application.WorksheetFunction.RoundDown( _
((HPArea - HConstArea * PZoom / 100) / (PArea.Rows.Count - 7)) * 100 / PZoom, 2)
ActiveSheet.PrintPreview
End Sub
[/GPECode]

Một lần nữa, cám ơn bạn đã nhiệt tình giúp đỡ. Về mặt thuật toán mình thấy bạn đã hoàn toàn đúng. Nhưng có lẽ bác Bill không tính như chúng ta đang nghĩ hoặc bác ấy tính sai hay sao mà em dùng đoạn code trên chạy thử với các bảng tính của em nó ra sai mất tiêu. Em đính kèm cả file Excel và cái hình chụp vị trí còn sai luôn cho anh tham khảo. Qua mò mẫm em thấy rằng nếu bỏ luôn - .BottomMargin ở dòng 14, khi đó
[GPECODE=vb]HPArea = Application.CentimetersToPoints(Hpage / 10) - .TopMargin[/GPECODE]
thì lại cho kết quả gần đúng với các giá trị Zoom khác nhau trong trường hợp giá trị .BottomMargin không quá lớn (nhỏ hơn 2 cm).
 

File đính kèm

Upvote 0

Bài viết mới nhất

Back
Top Bottom