Array of worksheet variable - arrays

As per documentation, I can define array of worksheets like below
Dim sheetsArray As Sheets
Set sheetsArray = ActiveWorkbook.Sheets(Array("Sheet1", "Sheet2"))
But what happens if my worksheets are dynamically created and pointed by pointer variable like below? How can I make an array of them so that I can loop through them to do same activity?
Dim tempsheet1 As Worksheet
Dim tempsheet2 As Worksheet
Set tempsheet1 = Sheets.Add
Set tempsheet2 = Sheets.Add
Dim sheetsArray As Sheets
Set sheetsArray = ActiveWorkbook.Sheets(Array(tempsheet1, tempsheet2)) ' Doesn't work
For Each msheets In sheetsArray
With msheets
DO SOMETHING
End With
Next msheets

Since you should specify sheet names in Array, change
Set sheetsArray = ActiveWorkbook.Sheets(Array(tempsheet1, tempsheet2))
to
Set sheetsArray = ActiveWorkbook.Sheets(Array(tempsheet1.Name, tempsheet2.Name))

Related

Create array of worksheets not variant

I would like to create an array of type worksheet, not variant, then populate the array using the Array function and finally pass the array to the worksheet.copy function to crate a new workbook of the worksheets in the array variables.
The following code works but none of the arrays are of type worksheet and two of the example arrays are populated with the worksheet names.
Dim wbkThis As Workbook
Dim wstX As Worksheet
Dim wstY As Worksheet
Dim wstZ As Worksheet
Dim arrWSA As Variant
Dim arrWSB() As Variant
Dim arrWSC(1 To 3) As Variant
Cancel = True
Set wbkThis = ThisWorkbook
Set wstX = wbkThis.Worksheets("SheetX")
Set wstY = wbkThis.Worksheets("SheetY")
Set wstZ = wbkThis.Worksheets("SheetZ")
ReDim arrWSA(1 To 3) As Variant
ReDim arrWSB(1 To 3) As Variant
arrWSA = Array(wstX, wstY, wstZ)
arrWSB = Array(wstX.Name, wstY.Name, wstZ.Name)
arrWSC(1) = wstX.Name
arrWSC(2) = wstY.Name
arrWSC(3) = wstZ.Name
arrWSA(1).Copy
Worksheets(arrWSB()).Copy
Worksheets(arrWSC()).Copy
While you can create an array of worksheets, it won't work to copy them all at once (though you could copy them in a loop). An array of names is the way to go if you want to copy multiple sheets at once.
Sub CopySheets()
Dim shtCount As Long: shtCount = Worksheets.Count
Dim X As Long
Dim arrSheets() As Worksheet: ReDim arrSheets(1 To shtCount)
For X = LBound(arrSheets) To UBound(arrSheets)
Set arrSheets(X) = Worksheets(X)
Next X
' Worksheets(arrSheets).Copy After:=Worksheets(shtCount) 'This won't work.
For X = LBound(arrSheets) To UBound(arrSheets)
arrSheets(X).Copy After:=Worksheets(shtCount) 'this will
Next X
Dim arrShtNames() As String: ReDim arrShtNames(1 To shtCount)
For X = LBound(arrShtNames) To UBound(arrShtNames)
arrShtNames(X) = Worksheets(X).Name
Next X
Worksheets(arrShtNames).Copy After:=Worksheets(shtCount) 'this will as well
End Sub

Delete all contents except for first row for specific sheets in Excel

Please assist. I have this code here and it works for first sheet however, does not execute in the 2nd sheet. I think i'm missing a sheet syntax. thanks.
Dim arrSheets As Variant, sht As Variant
arrSheets = Array("tl_1", "tl_2")
For Each sht In arrSheets
Sheets(sht).UsedRange.Offset(1).ClearContents
Next sht
My 2 cents: do not rely on worksheet names. Instead, work with their (Name) property as seen from the Visual Basic Editor. Note that you can give significant names yourself instead of the default Sheet1..N ones. This way, your code will survive modifications to the names as seen from Excel, in the tabs at the bottom.
Option Explicit
Public Sub DoTheClearThing()
Dim loopVariant As Variant
Dim loopWorksheet As Excel.Worksheet
Dim worksheetsToConsider As Variant
'Use the (Name) property, as seen from the Visual Basic Editor, of the worksheets you're interested in.
'The array below is not a string array; it is an array of worksheet objects.
worksheetsToConsider = Array(TL_1, TL_2)
'The For's variable must be a Variant; you can then Set it to a variable of the Worksheet type and enjoy Intellisense.
For Each loopVariant In worksheetsToConsider
Set loopWorksheet = loopVariant
loopWorksheet.UsedRange.Offset(1).ClearContents
Next
End Sub
Here's what the worksheets' (Name) properties look like in my test Excel workbook:
From within your workbook's code, you can directly interact with worksheet objects using their (Name) property. Avoid ThisWorkbook.Worksheets("tl_1").SomeMethod and directly go with TL_1.SomeMethod. By the way, a worksheet's (Name) property can be read by code using its CodeName property.
Option Explicit
'This will do something to your target sheets,
'just make sure your "something" is what you want
Dim N As Long
Dim wsName As String
'Optional if included
For N = 1 To ThisWorkbook.Sheets.Count
wsName = ThisWorkbook.Worksheets(N).Name
If wsName = "tl_1" or wsName = "tl_2" Then
ThisWorkbook.Worksheets(N).UsedRange.Offset(1).ClearContents
Else 'Do Nothing
End If
Next N
Note: This is very worksheet name dependent and users can change those if you are not the only user. You may want to CodeName your sheets (properties Explorer and change the Name) then pull the CodeName.
You can use an array to hold the sheets names but it seems like more trouble than its worth unless you are going to load the names into the array.
-WWC
Worksheet.UsedRange does not always return the correct address. Consider the results of the test below:
Test Used Range
Sub Test()
Application.ScreenUpdating = False
Dim cell As Range, target As Range
Debug.Print "Data Range", "|"; "UsedRange"
Debug.Print String(24, "_")
With Worksheets.Add
Set target = .Range("B2:D2")
target.Value = 1
Debug.Print target.Address, "|"; .UsedRange.Address
End With
With Worksheets.Add
.Range("A1:G10").Interior.Color = 65535
Set target = .Range("B2:D2")
target.Value = 1
Debug.Print target.Address, "|"; .UsedRange.Address
End With
End Sub
Clear Non-Headers
Sub ClearNonHeaderRows()
Dim arrSheets As Variant, sht As Variant
Dim cell As Range
arrSheets = Array("tl_1", "tl_2")
For Each sht In arrSheets
With Worksheets(sht).UsedRange
Set cell = .Find("*", .Cells(1, 1))
If Not cell Is Nothing Then
cell.Offset(1).Resize(.Cells.Rows.Count - cell.row + .Cells(1, 1).row).EntireRow.ClearContents
End If
End With
Next sht
End Sub

use array to add and name new sheets

I need to create a given number of sheets, depending on the amount of names in a List. The sheets need to have the same name as the string value in every cell inside the list/array. So far my code, which is not working:
Private Sub loopfilter()
Dim VersandRange As Range
Dim rng As Range
Dim Name As String
Set VersandRange = Range("J2", Cells(Rows.Count, "j").End(xlUp))
For Each rng In VersandRange
rng.Value = Name
Worksheets.Add
ActiveSheet.Name = Name
Next
end sub
Thanks!
Would this not work?
For Each rng In VersandRange
Worksheets.Add
ActiveSheet.Name = rng.Value
Next

Copy and paste with array macro excel

Can anybody help me edit? I want to copy from column to another workbook column using array.
The range inside the array is the Alphabet of the column i want to copy/paste.
Sub setting2()
Dim wb As ThisWorkbook
Dim here As Workbook
Dim there As Workbook
Dim source() As Variant
Dim log() As Variant
Dim LastRowHere() As Integer
Dim LastRowThere() As Integer
'Open both workbooks first:
Set here = Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting2.xlsm")
Set there =Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting3.xlsm")
Windows("Setting.xlsm").Activate
source() = Array(Sheets("Sheet1").Range("E11"), Range("E12"), Range("E13"), Range("E14"), Range("E15"), Range("E16"),Range("E17").Value)
Windows("Setting.xlsm").Activate
log() = Array(Sheets("Sheet1").Range("J11"), Range("J12"),Range("J13"),Range("J14"), Range("J15"), Range("J16"), Range("J17").Value)
Windows("Setting2.xlsm").Activate
LastRowHere() = Array(Sheets("Sheet1").Rows.Count, source().End(xlUp).Row)
Windows("Setting3.xlsm").Activate
LastRowThere() = Array(Sheets("Sheet1").Rows.Count, log()).End(xlUp).Row
For i = 1 To LastRowHere()
LastRowThere(1) = there.Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count.log(1)).End(xlUp).Row
For k = 1 To LastRowThere()
'here.Sheets("Sheet1").Cells(i, k).Copy Destination:=there.Sheets("Sheet1").Cells(i, k)
here.Sheets("Sheet1").Rows(i).Columns(source(1)).Copy Destination:=there.Sheets("Sheet1").Rows(k + 1).Columns(log(1))
Next k
Next i
End Sub
Your problem is source().End(xlUp).Row. You're trying to use it as a range - which it's not. That is giving you the error.
You'd be better to populate your array by using a loop. And, unless you really want to carry the cell formatting across to the destination sheet, better not to use Copy since then you don't have to activate the destination sheet.
Not sure if the code below exactly fits your need. I wasn't sure of the purpose of log() array so I've left it out. The below copies the values of a single column from Source sheet to Destination sheet.
'Open both workbooks first:
Set here = Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting2.xlsm")
Set there =Workbooks.Open("C:\Users\jesslynn\Desktop\macro\Setting3.xlsm")
SourceCol = 5 'Column E from your example
Set SourceSht = here.Sheets(1)
Set DestnSht = there.Sheets(1)
With SourceSht
'Get last cell in the column
LastRow = .Cells(.Rows.Count, SourceCol).End(xlUp).row
End With
With DestnSht
'Get last cell in the column
DestnLastRow = .Cells(.Rows.Count, SourceCol).End(xlUp).row
End With
'Loop through all cells (assumes row 1 is header)
For r = 2 to LastRow
'Assign value from Source to Destination sheet
i = i + 1
DestnSht.Cells(DestnLastRow + i, SourceCol) = SourceSht.Cells(r, SourceCol)
Next
Try this.
I assume you need copy the value from range E11 to E17 and J11 to J17
Option Explicit
Dim CurrentWorkbook As Workbook
Dim SourceWorkbook As Workbook
Dim DestWorkbook As Workbook
Dim CurrentWorksheet As Worksheet
Dim SourceWorksheet As Worksheet
Dim DestWorksheet As Worksheet
Sub setting2()
Dim SourceLastRow As Long
Dim DestLastRow As Long
Set CurrentWorkbook = ActiveWorkbook
Set CurrentWorksheet = CurrentWorkbook.ActiveSheet
Set SourceWorkbook = Workbooks.Open("C:\Users\lengkgan\Desktop\Testing\MyData1.xlsx") 'change to your path
Set DestWorkbook = Workbooks.Open("C:\Users\lengkgan\Desktop\Testing\MyTemplate.xlsx") 'change to your path
Set SourceWorksheet = SourceWorkbook.Sheets(1)
Set DestWorksheet = DestWorkbook.Sheets(1)
SourceLastRow = SourceWorksheet.Cells(Rows.Count, "E").End(xlUp).Row
DestLastRow = DestWorksheet.Cells(Rows.Count, "J").End(xlUp).Row + 1
SourceWorksheet.Range("E11:E17").Copy Destination:=DestWorksheet.Range("E" & DestLastRow + 1) 'Change to the column you want
SourceWorksheet.Range("J11:J17").Copy Destination:=DestWorksheet.Range("J" & DestLastRow + 1) 'Change to the column you want
End Sub

Excel VBA: Write 2D array to another worksheet

I have a VBA function that creates a 2D array res. I'd like to write the array data to another worksheet, not the current worksheet the function is executed from. This should be pretty straightforwards but i'm new to VBA.
The code ends on the last line without an error message or writing any data.
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Output")
Dim out As Range
Set out = ws.Range("A1")
out.Resize(UBound(res, 1), UBound(res, 2)).Value = res
Your existing code should work.
Does Res actually contain data?
Sample below that populates an array, checks if it is more than one cell, then dumps back to the worksheet.
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim rng1 As Range
Dim res
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Input")
Set ws1 = wb.Worksheets("Output")
Set rng1 = ws.Range("A1:B10")
If rng1.Cells.Count > 1 Then
res = rng1.Value2
ws1.[a1].Resize(UBound(res, 1), UBound(res, 2)).Value2 = res
End If

Resources