10 outputs on single sheet

amkkhan

Board Regular
Joined
Dec 11, 2021
Messages
75
Office Version
  1. 2019
  2. 2016
Platform
  1. Windows
Here is the link to file
Situation here is similar to this one
Actually "ID" is the main Identity.
I am using Vlookup for calling students data and picture.
Actually these are students cards. For printing purpose,
All I want is10 cards to be printed on single page.

As you can see that output is very small size.
Page size must be A4 or legal.

I need a VB Script that would scroll ID's from Consolidated Sheets Column A and almost 1000 entries. If list becomes blank at any point it should stop.
And output must be a pdf file containing All provided students in the "Consolidated" sheet with 10 outputs on each page.

I have data of 34 students for example but it could be around 1000 or more ...
 
I think I understand what you're asking for, however your last post didn't really clarify anything or add further explanation.

It looks like each 'card' should be rotated by 90 degrees and then 10 cards (each card is cells A2:B9 on the "Cards" sheet) placed in a 2 columns x 5 rows 'grid' will fit onto one A4 page. If that's correct then try the macro below.

This proved quite tricky because I discovered that if you position a shape (a picture of a 'card') at (0,0) on a sheet - the first card needs to be at (0,0) - and rotate it 90 degrees, the width and height of the shape changes! The solution is to first position the shape well away from (0,0) so that rotating it doesn't change its width and height and then move it to the correct position. Furthermore, when the rotated shape is explicitly positioned at (0,0) its resultant Top property value is 0, but its Left is actually (Width - Height) / 2, not 0, and visibly the left side of the shape is on the exact left of the sheet, but the top of the shape is not at the top of the sheet, as it should be!

View attachment 105306

The shape is positioned and then adjusted by the following code:
VBA Code:
        'Set shape's correct position
      
        .Top = picPositionTop
        .Left = picPositionLeft
        .IncrementTop (picWidth - picHeight) / 2 'move up
        If picPositionLeft > 0 Then .IncrementLeft (picHeight - picWidth) / 2 'move right

View attachment 105307

VBA Code:
Public Sub Create_Cards_PDF()
  
    Dim PDFoutputFile As String
    Dim PDFsheet As Worksheet
    Dim currentSheet As Worksheet
    Dim r As Long, n As Long
    Dim cardRange As Range
    Dim picPositionTop As Single, picPositionLeft As Single
    Dim picShape As Shape
    Dim pageBreakCell As Range
    Dim gridlines As Boolean
  
    '2 cards per row x 5 rows per page gives 10 cards per page
    Const CardsPerRow = 2
    Const RowsPerPage = 5

    'Gap between rows and columns of cards on output PDF
    Const CardRowGap = 4
    Const CardColumnGap = 4
 
    PDFoutputFile = ThisWorkbook.Path & "\All cards with 10 cards per page.pdf"
      
    Application.ScreenUpdating = False
  
    'The single card is A2:B9 on the Cards sheet
  
    With Worksheets("Cards")
        Set cardRange = Worksheets("Cards").Range("A2:B9")
        .Select
        gridlines = ActiveWindow.DisplayGridlines
        ActiveWindow.DisplayGridlines = False  'turn off gridlines, otherwise they appear in the PDF
    End With

    With ActiveWorkbook
        Set currentSheet = .ActiveSheet
        Set PDFsheet = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
        ActiveWindow.DisplayGridlines = False
    End With
  
    picPositionTop = 0
    picPositionLeft = 0
  
    With Worksheets("Consolidated")

        n = 0
        r = 2
      
        While Not IsEmpty(.Cells(r, "A").Value)
                
            'Create a picture of the next card
          
            Worksheets("Cards").Range("B2").Value = .Cells(r, "A").Value
            cardRange.Copy
            With cardRange.Worksheet
                .Pictures.Paste
                Set picShape = .Shapes(.Shapes.Count)
            End With
          
            'Add the picture to the PDF sheet in the correct position
          
            Add_Card_Picture picShape, PDFsheet, picPositionTop, picPositionLeft
          
            n = n + 1
          
            If n Mod CardsPerRow = 0 Then
                'Set top position for next card on a new row
                picPositionTop = picPositionTop + picShape.Width + CardRowGap
                picPositionLeft = 0
            Else
                'Set left position for next card on the same row
                picPositionLeft = picPositionLeft + picShape.Height + CardColumnGap
            End If
          
            If n Mod CardsPerRow * RowsPerPage = 0 Then
                'All cards on a page so insert page break
                Set pageBreakCell = GetCellByPos(PDFsheet, 0, picPositionTop)
                'Debug.Print "Page break " & pageBreakCell.EntireRow.Address
                PDFsheet.HPageBreaks.Add Before:=pageBreakCell.EntireRow
                picPositionTop = pageBreakCell.Top
            End If
          
            r = r + 1
        Wend
      
    End With
  
    Application.PrintCommunication = False
    With PDFsheet.PageSetup
        .LeftMargin = Application.InchesToPoints(0.5)
        .RightMargin = Application.InchesToPoints(0.5)
        .TopMargin = Application.InchesToPoints(0.5)
        .BottomMargin = Application.InchesToPoints(0)
        .HeaderMargin = Application.InchesToPoints(0)
        .FooterMargin = Application.InchesToPoints(0)
    End With
    Application.PrintCommunication = True
  
    'Save PDF sheet as a .pdf file
  
    PDFsheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFoutputFile, _
        Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
  
    Application.DisplayAlerts = False
    PDFsheet.Delete
    Application.DisplayAlerts = True
  
    Worksheets("Cards").Select
    ActiveWindow.DisplayGridlines = gridlines  'restore gridlines setting
  
    currentSheet.Select
  
    Application.ScreenUpdating = True
  
    MsgBox "Created " & PDFoutputFile
 
End Sub


Private Sub Add_Card_Picture(picShape As Shape, destSheet As Worksheet, picPositionTop As Single, picPositionLeft As Single)

    Dim picWidth As Single, picHeight As Single
  
    'Cut source card shape and paste on PDF sheet
  
    picShape.Cut
    With destSheet
        .Select
        .Paste
        Set picShape = .Shapes(.Shapes.Count)
    End With
  
    With picShape

        picWidth = .Width
        picHeight = .Height
      
        'Set shape's position away from (0,0) so that rotating it 90 degrees does not change its width and height
      
        .Top = .Width
        .Left = .Height
      
        'Debug.Print "Before rotate top=" & .Top & ", left=" & .Left & ", width=" & .Width & ", height=" & .Height
      
        'Rotate shape 90 degrees to put card sideways
      
        .LockAspectRatio = msoTrue
        .Rotation = 90
      
        'Debug.Print "After rotate top=" & .Top & ", left=" & .Left & ", width=" & .Width & ", height=" & .Height
      
        'Set shape's correct position
      
        .Top = picPositionTop
        .Left = picPositionLeft
        .IncrementTop (picWidth - picHeight) / 2 'move up
        If picPositionLeft > 0 Then .IncrementLeft (picHeight - picWidth) / 2 'move right
      
        'Debug.Print "After reposition top=" & .Top & ", left=" & .Left & ", width=" & .Width & ", height=" & .Height
      
    End With

End Sub


Private Function GetCellByPos(ws As Worksheet, x As Single, y As Single) As Range
    With ws.Shapes.AddLine(x, y, x, y)
        Set GetCellByPos = .TopLeftCell
        .Delete
    End With
End Function
Thanks @John_w 😊,
I salute your skills
I shall be always great ful to you.
It worked exactly as you said. For the sake of information please guide me that isn't it possible that we output Page could be set as Horizontal instead of vertical.
I mean to say that is it possible to change page Orientation from portrait to landscape, then printing would be much easier.
 
Upvote 0
Add .Orientation = xlLandscape in the PageSetup code. The Add_Card_Picture routine should be simpler because you don't need to rotate the picture, and other changes to calculate the position of the next card would be needed.

I've spent long enough on this for a free help forum.
Thank you So much @John_w .It worked....
I am honestly great ful to you for your time and effort.
I owe you my dear....
Best wishes for you
 
Upvote 0

Forum statistics

Threads
1,216,119
Messages
6,128,941
Members
449,480
Latest member
yesitisasport

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top