Excel VBA code to copy and paste table rows to PowerPoint until specific row height is met - excel

I already have a working code that copies a table from Excel to PowerPoint and creates more slides and tables (splits the large table into multiple ones) if the sum of the row heights reaches a certain threshold in Excel:
Sub PowerPointTableSplit()
Dim rng As Range
Dim PowerPointApp As Object
Dim myPresentation As Object
Dim mySlide As Object
Dim myShape As Object
Dim lCol As Long
Dim lRow As Long
Dim LastRow As Long
Dim i As Long
Dim j As Integer
Dim rngH As Range
Dim wss As Worksheet
Set wb = Workbooks("Automation Tool.xlsm")
Set ws = wb.Sheets("630")
Set rngH = ws.Range("A1:AB1") 'Header Row (same for all tables)
LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
With ws.Range("A1:AB" & LastRow)
.Font.Name = "Arial"
.Font.Size = 6
End With
ws.Range("A1:A" & LastRow).EntireRow.AutoFit
i = 2
Set wss = wb.Worksheets.Add
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
Set myPresentation = PowerPointApp.ActivePresentation
'Loop through excel table and cut it after X rows to make it fit on PowerPoint, Copy & Paste table
'wss is a temporary excel sheet to store every X rows (will be deleted at the end)
Do While i <= LastRow
Z = 1 'counter to check row height in excel
RowHeight = 0
Do Until RowHeight > 600
RowHeight = RowHeight + ws.Rows(Z).Height
Z = Z + 1
Loop
j = Application.Min(i + Z, LastRow)
Union(rngH, ws.Range("A" & i, ws.Range("AB" & j))).Copy
wss.Range("A1").PasteSpecial Paste:=xlPasteColumnWidths
wss.Range("A1").PasteSpecial Paste:=xlPasteValues
wss.Range("A1").PasteSpecial Paste:=xlPasteAllUsingSourceTheme
sld.Shapes.PasteSpecial DataType:=ppPasteHTML, Link:=msoFalse
wss.Range("A1:AB" & j - i + 2).Copy
Set sld = myPresentation.Slides.Add(myPresentation.Slides.Count + 1, ppLayoutBlank)
i = j + 1
Loop
'Delte temporary excel sheet wss as not needed anymore
Application.DisplayAlerts = False
wss.Delete
Application.DisplayAlerts = True
Set wss = Nothing
End Sub
After this I am using a code to strech the table in PowerPoint to the whole available space on the slide, this also makes it tricky for me to get the real row height in PowerPoint using the code above as I would have to check the real height after streching the table.
Sub AutoFitTables()
Dim s As Slide
Dim oSh As Shape
Dim oTbl As Table
Dim lRow As Long
Dim lCol As Long
ScreenUpdating = False
For Each s In ActivePresentation.Slides
'ActivePresentation.Slides(Slide.SlideIndex(s)).Select
ActivePresentation.Slides(s.SlideIndex).Select
For Each oSh In s.Shapes
If oSh.HasTable Then
oSh.Left = 0 * 28.3
oSh.Top = 1.5 * 28.3
oSh.Width = 33.867 * 28.35
oSh.ZOrder msoSendToBack
Set oTbl = oSh.Table
For lRow = 1 To oTbl.Rows.Count
For lCol = 1 To oTbl.Columns.Count
With oTbl.Cell(lRow, lCol).Shape
.TextFrame.TextRange.Font.Name = "Arial"
.TextFrame.TextRange.Font.Size = 6
.TextFrame2.VerticalAnchor = msoAnchorMiddle
oTbl.Rows(lRow).Height = 0.5
End With
Next lCol
Next lRow
End If
Next oSh
Next s
ActivePresentation.Slides(1).Select
End Sub
However, since I still want to copy a much wider table, the format in the table shifts as soon as I copy it into PowerPoint, so that the table is too large to be seen completely, the code does not work.
I already have an idea, but the implementation fails. I want to copy the table row after row and after each copy check the total row height in PowerPoint and jump to the next page if the row height of 450 is reached. For this the following code comes into question:
sld.Shapes(X).Table.Rows(Y).Height 'with X and Y looping
I would be thankful for any help and hints.

Related

How to setup a conversion from Excel Table to PowerPoint Presentation

I would like to create a presentation based on data sorted in rows:
That, in the PowerPoint, would appear as this
But I am having difficulties understanding the correct syntax to properly have this done inside PowerPoint, rather than the Excel where the data comes from: how to declare/deal with the range of cells that become each a slide and in each of them of how to fill the relative placeholder, or "transposed/cut" place in table. I have looked everywhere, the very few pages/articles I found are not clear and overall short of explanation. I am stuck at the very beginning of this as I don't know how to set up the variable range of cells or if it should be an array to split later in different ranges, I would know how to continue, once I understood how to link Excel to PowerPoint Layouts/Slides/Objects.
I know I have to set a counter for each step, i.e. on for the change in Section #, in in the Slide # etc., mostly I find not clear how to translate the different parts of the table in rows and then section of rows.
EDIT: With code I have come up so far, this was the most helpful resource I could find. However I have the problem I was mentioning before: I do I swap the row I have left to columns in the table? How do I change them in a Range?
I referenced Excel for PowerPoint as from the original code, but the selection does no get recognized in POwerPoint (as said above, I would like to use it in PPT, not in Excel) . However, it works only in Excel, I have an error at For Each DataRow In DataRange.Rows variable not set when running as pptm. (reciprocal Libraries enabled in both programs).
From Excel, I can populate the title and the heading (so "AAA" and "aa") but I do not know how to progress in the cells, transposing the values for some columns and then restart.
Update:
I added a variable for the the columns of the source, but I am not sure how to deal with it. I'm so close but I don't know how to finish it. I introduced the variable FirstRowToColumn as range (columns E to the Excel screenshot below, that would become the first column of the tabel in PowerPoint), but I don't know how to declare this and the others range and paste them into the table. Could someone please teach me this or point to the solution, am I at least close ?
Edit2: added, with which I would copy the range and paste transposed, but it says the area is different.
Edit3: I can paste, I have to fix the counter to have the table in each slide, but the question of how to transpose remains and on top of that how to write the values in the Powerpoint table.
Edit 4:
I am trying a new way, by pasting in the Object placeholder id, but I saee nothing appearing in the table.
Sub General_Namer_For_Slides_And_Shapes()
Dim AnySlide As Slide
Dim AnyShape As Shape
Set AnySlide = Application.ActivePresentation.Slides(1)
For Each AnyShape In AnySlide.Shapes
Debug.Print "Application.ActivePresentation.Slides(1) AnySlide.Shapes AnyShape.Name " & AnyShape.Name & " AnyShape.Id "; AnyShape.Id '''names of each shape and their id '''removed " Slide " & AnySlide.SlideID&;
Next
Debug.Print "ActivePresentation.Slides(1).CustomLayout.Name " & ActivePresentation.Slides(1).CustomLayout.Name & " ActivePresentation.Slides(1).CustomLayout.Index " & ActivePresentation.Slides(1).CustomLayout.Index&;
Debug.Print " There are " & ActivePresentation.SlideMaster.Design.SlideMaster.CustomLayouts(4).Shapes.Count & " shapes in the Layout slide (SlideMaster View)"
'Debug.Print "ActivePresentation.Designs(4).Name = " & ActivePresentation.Designs(1).SlideMaster.CustomLayouts(4); ""
'Debug.Print " ActivePresentation.Designs.Name" & ActivePresentation.SlideMaster.Shapes.Placeholders. & ; ActivePresentation.Designs(4).Index; " & ActivePresentation.Designs(4).Index "
End Sub
Set NewTable = sld.Shapes.AddTable(12, 4)
FirstRowToColumn.Cells.PasteSpecial Paste:=-4163, Transpose:=True
to
Sub LoopRowsSelectedXCLToPPT()
Dim xlApp As Object
Dim xlWorkBook As Object
Dim xlSheet As Object
Dim DataRange As Range 'used
Dim DataRow As Range 'used
Dim DataCol As Range 'used
Dim PPTrng As Range ''cloning here the above to use in PowerPoint
Dim ShpRng As ShapeRange ''cloning here the data raw as range of shapes i could create later
Dim ShpCll As Shape
Dim AppPPT As PowerPoint.Application
Dim Pres As PowerPoint.Presentation
Dim sld As PowerPoint.Slide
Dim AppXCL As Excel.Application 'repeated the same as above with Excel as argument
Dim InputSheet As Excel.Worksheet
Set AppPPT = GetObject(, "PowerPoint.Application")
Set Pres = AppPPT.ActivePresentation
Set AppXCL = GetObject(, "Excel.Application")
Set InputSheet = AppXCL.ActiveSheet
Dim RowCounter As Integer
Dim ColCounter As Integer
Dim iRow As Integer
Dim iColumn As Integer
Dim FirstRowToColumn As Range
Dim SecondRowToColumn As Range
RowCounter = 0
ColCounter = 0
Set DataRange = Selection
For Each DataRow In DataRange.Rows
RowCounter = RowCounter + 1
Set sld = Pres.Slides.AddSlide(Pres.Slides.Count + 1, Pres.SlideMaster.CustomLayouts(4))
sld.Shapes.Title.TextFrame.TextRange.Text = DataRow.Cells(3, 3)
sld.Shapes.Placeholders(4).TextFrame.TextRange.Text = DataRow.Cells(3, 4)
' For Each DataCol In DataRange.Columns
ColCounter = ColCounter + 1
Set FirstRowToColumn = DataRange.Range(Cells(RowCounter + 1, 5), Cells(RowCounter + 1, 10))
FirstRowToColumn.Copy
Set NewTable = sld.Shapes.AddTable(12, 4)
sld.Shapes.Placeholders(4).TextFrame.TextRange.Text = FirstRowToColumn.Cells(1, 5)
' FirstRowToColumn.Cells(1, 10) =
' With sld.Shapes.Placeholders
' NewTable.Range(1,1)
'
'
' End With
' With sld.Shapes.Paste.SpecialPaste:=-4163, Transpose:=True
Next DataRow
Debug.Print RowCounter
Debug.Print ColCounter
End Sub
You may have to finesse the details but this works for me:
Sub LoopRowsSelectedXCLToPPT()
Const TABLE_COLS As Long = 5 '# of columns in PPT tables
Const BLOCK_SIZE As Long = 5
Dim Datarange As Range, rw As Range, rng As Range, i As Long, col As Long
Dim ppApp As PowerPoint.Application, pres As PowerPoint.Presentation
Dim sld As PowerPoint.Slide, newTable As PowerPoint.Table
On Error Resume Next
Set ppApp = GetObject(, "PowerPoint.Application")
Set pres = ppApp.ActivePresentation
On Error GoTo 0
If pres Is Nothing Then
MsgBox "Destination presentation must be open in PowerPoint", vbCritical
Exit Sub
End If
Set Datarange = Selection
For Each rw In Datarange.Rows
Set sld = pres.Slides.AddSlide(pres.Slides.Count + 1, _
pres.SlideMaster.CustomLayouts(2))
Set newTable = sld.Shapes.AddTable(BLOCK_SIZE, TABLE_COLS).Table
col = 0
Set rng = rw.Cells(5).Resize(1, BLOCK_SIZE) 'first BLOCK_SIZE cells starting from Col E
Do While Application.CountA(rng) > 0 'while have any data in `rng`
col = col + 1
If col > TABLE_COLS Then Exit Do 'ran out of columns in the PPT table...
For i = 1 To BLOCK_SIZE 'fill column # col
newTable.Cell(i, col).Shape.TextFrame2.TextRange.Text = rng.Cells(i).Value
Next i
Set rng = rng.Offset(0, BLOCK_SIZE) 'next block of cells to the right
Loop
Next rw
End Sub

Excel Macro Not stopping at last row

I have a macro that is building a bubble chart and for each row in the dynamic range it is creating a new series in the bubble chart. I tested the last row calculation was finding the actual last row both manually on the worksheet and with a quick macro to find the last row and display in a message box. So the macro for building the bubble chart is finding the last row correctly. The problem is that the macro is adding in blank series anyway beyond the last row. The macro is adding 10 generic series after the last row.
Macro below:
Sub bubble()
'
' bubble Macro for bubble chart
'
Dim Lastrow As Long, ws As Worksheet, wsRD As Worksheet, wsChart As Worksheet
Dim cht As ChartObject, currRow As Integer
Dim ch As Shape, SeriesNum As Integer
On Error GoTo ExitSub
For Each ws In ActiveWorkbook.Sheets
If Left(ws.Name, 12) = "Raw Data SEA" Then
Set wsRD = ws
End If
If Left(ws.Name, 10) = "SEA bubble" Then
Set wsChart = ws
End If
Next ws
Lastrow = wsRD.Cells(Rows.Count, 1).End(xlUp).Row
Set ch = wsChart.Shapes(1)
ch.Name = "SEACht"
SeriesNum = 1
For currRow = 2 To Lastrow
ch.Chart.SeriesCollection.NewSeries
ch.Chart.FullSeriesCollection(SeriesNum).Name = wsRD.Cells(currRow, 1)
ch.Chart.FullSeriesCollection(SeriesNum).XValues = wsRD.Cells(currRow, 2)
ch.Chart.FullSeriesCollection(SeriesNum).Values = wsRD.Cells(currRow, 4)
ch.Chart.FullSeriesCollection(SeriesNum).BubbleSizes = wsRD.Cells(currRow, 3)
SeriesNum = SeriesNum + 1
Next currRow
'Format Legend
ch.Chart.PlotArea.Select
ch.Chart.SetElement (msoElementLegendBottom)
ActiveWorkbook.Save
'Format X and Y axes
ch.Chart.Axes(xlCategory).Select
ch.Chart.Axes(xlCategory).MinimumScale = 0
ch.Chart.ChartArea.Select
ch.Chart.Axes(xlValue).Select
ch.Chart.Axes(xlValue).MinimumScale = 0
Application.CommandBars("Format Object").Visible = False
ActiveWorkbook.Save
' Format datalabels
ch.Chart.ApplyDataLabels
ch.Chart.FullSeriesCollection(1).DataLabels.Select
ch.Chart.FullSeriesCollection(1).HasLeaderLines = False
Application.CommandBars("Format Object").Visible = False
ActiveWorkbook.Save
' Add charttitle
'
ch.Chart.SetElement (msoElementChartTitleAboveChart)
ch.Chart.Paste
ch.Chart.ChartTitle.Text = _
"Properties operating exp - RSF and Building Age Factors"
ActiveWorkbook.Save
ExitSub:
End Sub
Thanks in advance for any help.
Checked that the last row calc was actually finding the last row to make sure that was not the issue. Tried recording the process again to see if I missed anything. I didn't see anything that was obvious to change.
Too long for a comment and maybe not the source of your problem, but NewSeries returns the added series, so you can do this and skip the SeriesNum counter:
Dim rw as Range
For currRow = 2 To Lastrow
Set rw = wsRD.Rows(currRow)
With ch.Chart.SeriesCollection.NewSeries
.Name = rw.Cells(1)
.XValues = rw.Cells(2)
.Values = rw.Cells(4)
.BubbleSizes = rw.Cells(3)
End With
Next currRow

Pasting a large table into separate slides by Excel VBA

I would like to paste a table from excel to power point using VBA. However, as I have dynamic range therefore I would like to create slides with 15 rows only for better visualization. For example, it will paste row 1 to row 15 into slide number 1 then row 1, and row 16 to row 29 into slide number 2 and so on. Here row 1 is the header of the table. I have attached the code where I can create only one slide. I would highly appreciate if anyone can help me.
Sub SortingandSlidecreation()
Dim pptName As String
Dim ppt As PowerPoint.Application
Dim myPres As PowerPoint.Presentation
Dim slds As PowerPoint.Slides
Dim sld As PowerPoint.slide
Dim pptextbox As PowerPoint.Shape
Dim oLayout As CustomLayout
Dim wb As Workbook
Dim ws As Worksheet
Dim y As Workbook, LastRow&
Dim r As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("SortedTable")
'This will open a PowerPoint template (I didn't attach the function)
pptName = openDialog()
Set ppt = CreateObject("PowerPoint.Application")
Set myPres = ppt.Presentations.Open(pptName)
Set slds = myPres.Slides
' creating slides at the end of the template
Set sld = slds.Add(myPres.Slides.Count + 1, ppLayoutBlank)
'Here data is selected for pasting
Set r = ThisWorkbook.Worksheets("SortedTable").Range("A1:L" & LastRow)
r.Copy
sld.Shapes.PasteSpecial DataType:=0
sld.Shapes(1).Top = 100
sld.Shapes(1).Left = 100
'Here title of the table is added
Set pptextbox = sld.Shapes.AddTextbox(msoTextOrientationHorizontal, 22, 60, 700, 60)
With pptextbox.TextFrame
.TextRange.Text = "Summary of Current Projects"
.TextRange.Font.Bold = msoTrue
.TextRange.Font.Name = "Arial(Headings)"
.TextRange.Font.Size = 20
.TextRange.Font.Color.RGB = RGB(0, 51, 102)
End With
End Sub
Remove your current definition of LastRow. Then delete everything after your Set slds = myPres.Slides line and paste this code instead.
Dim LastRow as Long, i as Long, j as Integer, rngH as Range, wss as Worksheet
LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Set rngH = ws.Range("A1:L1") 'Header Row
i = 2
Set wss = wb.Worksheets.Add
Do While i <= LastRow
j = Application.Min(i + 13, LastRow)
Union(rngH, ws.Range("A" & i, ws.Range("L" & j))).Copy Destination:= wss.Range("A1")
Set sld = slds.Add(myPres.Slides.Count + 1, ppLayoutBlank)
wss.Range("A1:L" & j-i+2).Copy
sld.Shapes.PasteSpecial DataType:=0
sld.Shapes(1).Top = 100
sld.Shapes(1).Left = 100
'Here title of the table is added
Set pptextbox = sld.Shapes.AddTextbox(msoTextOrientationHorizontal, 22, 60, 700, 60)
With pptextbox.TextFrame
.TextRange.Text = "Summary of Current Projects"
.TextRange.Font.Bold = msoTrue
.TextRange.Font.Name = "Arial(Headings)"
.TextRange.Font.Size = 20
.TextRange.Font.Color.RGB = RGB(0, 51, 102)
End With
i = j + 1
Loop
Application.DisplayAlerts = False
wss.Delete
Application.DisplayAlerts = True
Set wss = Nothing
End Sub

Copy all rows with unique values to new worksheets including header's rows

I'm trying to fix the code to copy all rows based on unique values in a column to new worksheets
1. The table has a header in the range A1:CM4 that also includes a small picture
2. The last row contains a SUM formulas for each column C:CM
Trying to get:
1. Create new worksheets for each unique values in a column A (copy all appropriate rows, some cells are empty) including the header (A1:CM4) with the picture
3. Name new worksheets based on unique values (can be long names with spaces and commas: "aaaaa and bbbb, cccc")
4. The last row should contain SUM formulas and formatting for each column C:CM
I have a code that does part of the job (creates new sheets with unique values), but still struggling to fix next issues:
1. Doesn't copy all header (now copies only 1st row out of 4)
2. Doesn't keep/copy the last row with SUM formulas
3. Doesn't name a worksheet if the unique value is like: "aaaaa and bbbb, cccc" (less important)
Sub unique_data()
Dim RCount As Long
Dim Sht As Worksheet
Dim NSht As Worksheet
Dim I As Long
Dim TRrow As Integer
Dim Col As New Collection
Dim Title As String
Dim SUpdate As Boolean
Set Sht = ActiveSheet
On Error Resume Next
RCount = Sht.Cells(Sht.Rows.Count, 1).End(xlUp).Row - 1
Title = "A1"
TRrow = Sht.Range(Title).Cells(1).Row
For I = 5 To RCount
Call Col.Add(Sht.Cells(I, 1).Text, Sht.Cells(I, 1).Text)
Next
SUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To Col.Count
Call Sht.Range(Title).AutoFilter(1, CStr(Col.Item(I)))
Set NSht = Nothing
Set NSht = Worksheets(CStr(Col.Item(I)))
If NSht Is Nothing Then
Set NSht = Worksheets.Add(, Sheets(Sheets.Count))
NSht.Name = CStr(Col.Item(I))
Else
NSht.Move , Sheets(Sheets.Count)
End If
Sht.Range("A" & TRrow & ":A" & RCount).EntireRow.Copy NSht.Range("A1")
NSht.Columns.AutoFit
Next
Sht.AutoFilterMode = False
Sht.Activate
Application.ScreenUpdating = SUpdate
MsgBox "All done!", vbExclamation
End Sub
Would be very grateful for any help!
I managed to fix my code and get the correct results (still have some issues with naming spreadsheets as some names are rather long and excel does not take them to name the tabs), but anyways here is what the code is doing:
1. Creates new spreadsheets and copies appropriate rows based on unique values in a certain range (A5:..) of the main sheet
2. Renames new spreadsheets based on unique values
3. Copies all header's rows (4) to new spreadsheets
4. Copies the last row with SUM formulas and adjust the sum range for each spreadsheets based on the number of returned records
5. Formats new spreadsheets
I hope someone can use this code to solve similar puzzles or maybe make it more efficient.
Sub unique_data()
Dim RCount As Long
Dim Sht As Worksheet
Dim NSht As Worksheet
Dim I As Long
Dim Col As New Collection
Dim SUpdate As Boolean
Dim Lrow As Long
Dim NShtLR As Long
Set Sht = ActiveSheet
On Error Resume Next
RCount = Sht.Cells(Sht.Rows.Count, 1).End(xlUp).Row - 1
Lrow = Sht.Cells(Sht.Rows.Count, 1).End(xlUp).Row
For I = 5 To RCount
Call Col.Add(Sht.Cells(I, 1).Text, Sht.Cells(I, 1).Text)
Next
SUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To Col.Count
Call Sht.Range("A5").AutoFilter(1, CStr(Col.Item(I)))
Set NSht = Nothing
Set NSht = Worksheets(CStr(Col.Item(I)))
If NSht Is Nothing Then
Set NSht = Worksheets.Add(, Sheets(Sheets.Count))
NSht.Name = CStr(Col.Item(I))
Else
NSht.Move , Sheets(Sheets.Count)
End If
Sht.Range("A5:A" & RCount).EntireRow.Copy NSht.Range("A5")
Next
Sheets.FillAcrossSheets Sht.Range("1:4")
For Each NSht In Worksheets
If Not NSht.Name = "MainReport" Then
NSht.Select
NShtLR = NSht.Cells(Sht.Rows.Count, 1).End(xlUp).Row + 1
Sht.Range("A" & Lrow).EntireRow.Copy NSht.Range("A" & NShtLR)
NSht.Range("C" & NShtLR).Formula = "=SUM(C5:C" & NShtLR - 1 & ")"
Range("C" & NShtLR).Copy Range("C" & NShtLR & ":CM" & NShtLR)
Rows("4:4").RowHeight = 230
Columns("A:A").ColumnWidth = 28
Columns("B:B").ColumnWidth = 29
Columns("C:C").ColumnWidth = 3
Columns("D:CB").ColumnWidth = 3.5
Columns("CC:CM").ColumnWidth = 4
NSht.Shapes.Range(Array("Picture 1")).Select
Selection.ShapeRange.IncrementLeft -3.6
Selection.ShapeRange.IncrementTop 47.4
Rows.EntireRow.Hidden = False
ActiveWindow.Zoom = 70
End If
Next
Sht.AutoFilterMode = False
Sht.Activate
Application.ScreenUpdating = SUpdate
MsgBox "All done!", vbExclamation
End Sub

Change column width and row height of hidden columns and rows (remaining hidden): Excel VBA

I have a macro which changes column width and row height of all the worksheets in my excel workbook, however, this macro is not making the changes in the hidden rows and column.
Please suggest how should I modify my code so that it should change the column width and row height of hidden rows and columns and keep them hidden?
Sub rowcolactivesheetb()
Dim exworkb As Workbook
Dim xlwksht As Worksheet
Dim lastrow1 As Long
Dim lastcolumn1 As Long
Dim firstrowDB As Long
With ActiveSheet
lastrow1 = .Cells(Rows.Count, "A").End(xlUp).Row
lastcolumn1 = .Cells(1, Columns.Count).End(xlToLeft).Column
.Range(.Cells(1, 1), .Cells(lastrow1, lastcolumn1)).Select
With Selection.SpecialCells(xlCellTypeVisible)
.ColumnWidth = 10.2
.RowHeight = 9.4
End With
End With
End Sub
Edit
I have implemented Wolfie's method below, but am now getting
Run-time error 91, Object variable or With block variable not set.
on this line:
' Z is a number, my loop variable for looping over each sheet
rng = ActiveWorkbook.Sheets(Z).Range(Sheets(Z).Cells(1, 3), Sheets(Z).Cells(lastrow1, lastcolumn1))
The below code is fairly straight-forward, and commented for further details. Steps:
Loop through rows and columns in the used range, note which ones are hidden.
Unhide everything and resize
Loop back through rows and columns, hiding those which were hidden before
Code:
Sub rowcolactivesheetb()
' Resizes all rows and columns, including those which are hidden.
' At the end, hidden rows and columns remain hidden.
Dim n As Long
Dim hiddencols() As Long
Dim hiddenrows() As Long
Dim rng As Range
Application.ScreenUpdating = False
With ThisWorkbook.ActiveSheet
' Set up range variable and true/false hidden arrays
' We don't need to find last row/col, just used UsedRange
Set rng = .UsedRange
ReDim hiddencols(rng.Columns.Count)
ReDim hiddenrows(rng.Rows.Count)
' Get hidden/visible status of each row and column
For n = 0 To UBound(hiddencols)
hiddencols(n) = rng.Columns(n + 1).Hidden
Next n
For n = 0 To UBound(hiddenrows)
hiddenrows(n) = rng.Rows(n + 1).Hidden
Next n
' Unhide all
rng.EntireColumn.Hidden = False
rng.EntireRow.Hidden = False
' resize all
rng.ColumnWidth = 10.2
rng.RowHeight = 9.4
' Re-hide rows/cols
For n = 0 To UBound(hiddencols)
rng.Columns(n + 1).Hidden = hiddencols(n)
Next n
For n = 0 To UBound(hiddenrows)
rng.Rows(n + 1).Hidden = hiddenrows(n)
Next n
End With
Application.ScreenUpdating = True
End Sub
Lastly a note on With, you should not start a second With block unless it is for an object within the first one. But really you could have ditched the (undesirable) Select using that fact anyway...
With ActiveSheet
lastrow1 = .Cells(Rows.Count, "A").End(xlUp).Row
lastcolumn1 = .Cells(1, Columns.Count).End(xlToLeft).Column
With .Range(.Cells(1, 1), .Cells(lastrow1, lastcolumn1)).SpecialCells(xlCellTypeVisible)
.ColumnWidth = 10.2
.RowHeight = 9.4
End With
End With
Edit:
With respect to your follow up error, you must use the Set command when assigning a Range object to a variable. So your code should be
Set rng = ActiveWorkbook.Range("...
You don't have to use Set for fundamental variable types (Strings, Integers, etc)

Resources