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
Related
In my Workbook i have an Array which stores machines. With a button i am able to add some machines to the array.
The final array is used in three other buttons, each button is on a different worksheet. My question now is, how do i store the array global with its changing value?
this is my code for adding some value to the array:
Private Sub Add_Machine_Click()
Dim ws As Worksheet
Dim lastrow As Long
Dim Machine() As Variant
Dim DataRange As Range
Set ws = Worksheets("MachineTemplate")
lastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row
Set DataRange = ws.Range("A1:A" & lastrow)
Set Cell = DataRange.Find(What:=ComboBox1.Value, LookIn:=xlFormulas, lookat:=xlWhole)
If Cell Is Nothing Then
ws.Range("A" & lastrow + 1) = ComboBox1.Value
End If
ReDim Machine(DataRange.Cells.Count)
For Each Cell In DataRange.Cells
Machine(x) = Cell.Value
x = x + 1
Next Cell
End Sub
Right now i use the same code for the other three buttons. is there a way i can store this code as global?
I allready tried it in the WorkbookSheet like this:
Option Explicit
Public Machine() As Variant
Public ws As Worksheet
Public lastrow As Long
Public DataRange As Range
ws = Worksheets("MachineTemplate")
lastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row
Set DataRange = ws.Range("A1:A" & lastrow)
ReDim Machine(DataRange.Cells.Count)
x = 0
For Each Cell In DataRange.Cells
Machine(x) = Cell.Value
x = x + 1
Next Cell
But i know that this is totally wrong.
You do not need a Global Array for this. Since you are using Redim without Preserve, then it means it is getting initialzed everytime from the range DataRange
Also to create the array, you do not need to loop trough it everytime. You can directly create a 2D array in one line
Dim Machine as Variant
Machine = DataRange.Value
You may also want to see VBA Arrays And Worksheet Ranges
I usually avoid using Global variables. They get reset very easily during runtime if an error happens.
Try as I might I cannot correct a "Subscript out of Range" error that the code below is throwing on the last line of code below when I try to expand the size of an array with Redim Preserve. Any ideas as to what might be wrong?
Sub Demo()
'Set Excel variables
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim wsCluster As Worksheet: Set wsCluster = wb.Worksheets("Cluster")
Dim initialK As ListObject: Set initialK = wsCluster.ListObjects("k")
'Set Array variables
Dim kArray() As Variant
ReDim kArray(1 To initialK.DataBodyRange.Rows.Count, 1 To initialK.DataBodyRange.Columns.Count)
kArray = initialK.DataBodyRange
'Set Other variables
Dim coordResults As Variant, kResults As Variant, addKs As Variant, dupeArray As Variant
Dim transferLat As Double, transferLong As Double, potDupeCount As Long, expandK As Long, nextAvailK As Long
'Run the assignment function once, then loop through average/assign functions
coordResults = Assign(coordArray, kArray)
For i = 1 To 3
kResults = Average(coordArray, kArray, coordResults)
coordResults = Assign(coordArray, kArray)
Next i
'Run the radius function
addKs = AdjustForRadius(coordArray, kResults, coordResults)
'Add the new, deduped centroid data to the kResults array
expandK = UBound(addKs, 1) + UBound(kArray, 1)
ReDim Preserve kArray(1 To expandK, 1 To 3)
End Sub
The functions are working properly. The "expand" variable is good.
I have tested everything I know.
Jake
I want to use an array of strings that will replace the Worksheet object inside my loop, but I cant seem to figure it out.
If I declare SheetX as Variant, then I get the Object Required Error
If I declare SheetX as Object, then I get Compile Error: For Each variable on arrays must be variant
Sub DeleteAllData()
'SheetsArray = ["BalanceSheetTransposed", "IncomeStatementTransposed", "CashflowStatement"]
Dim SheetsArray(0 To 2) As Variant
Dim SheetX As Object
SheetsArray(0) = "BalanceSheetTransposed"
SheetsArray(1) = "IncomeStatementTransposed"
SheetsArray(2) = "CashflowStatement"
For Each SheetX In SheetsArray
lastrow = SheetX.Cells(Rows.Count, 1).End(xlUp).Row
lastcolumn = SheetX.Cells(1, Columns.Count).End(xlToLeft).Column
SheetX.Range("A2", Cells(lastrow, lastcolumn)).ClearContents
Next SheetX
End Sub
Out of my head 'cause I don't have Excel in this machine. Loop through the strings and set worksheet object.
Sub DeleteAllData()
Dim SheetsArray(0 To 2) As String
Dim SheetX As Worksheet
Dim name as String
SheetsArray(0) = "BalanceSheetTransposed"
SheetsArray(1) = "IncomeStatementTransposed"
SheetsArray(2) = "CashflowStatement"
For Each name In SheetsArray
set SheetX = ActiveWorkbook.worksheets(name)
lastrow = SheetX.Cells(Rows.Count, 1).End(xlUp).Row
lastcolumn = SheetX.Cells(1, Columns.Count).End(xlToLeft).Column
SheetX.Range("A2", Cells(lastrow, lastcolumn)).ClearContents
Next
End Sub
Your major problem was that you were trying to treat the strings stored in the array as if they were worksheets, but they are just strings.
The simplest way to get around it is to use Worksheets(SheetsArray) to return the worksheets that have the names you want to use, and then loop through those worksheets:
Sub DeleteAllData()
Dim SheetX As Worksheet
Dim lastRow As Long
Dim lastColumn As Long
Dim SheetsArray(0 To 2) As Variant
SheetsArray(0) = "BalanceSheetTransposed"
SheetsArray(1) = "IncomeStatementTransposed"
SheetsArray(2) = "CashflowStatement"
'An alternative to the previous 4 lines would be
'Dim SheetsArray As Variant
'SheetsArray = Array("BalanceSheetTransposed", _
' "IncomeStatementTransposed", _
' "CashflowStatement")
'Loop through the worksheets referred to in the array
For Each SheetX In Worksheets(SheetsArray)
With SheetX ' avoids some typing
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Existing code would have had issue with the unqualified Cells
'reference in the following line. You should always qualify Cells
'to specify which sheet you mean, because it defaults to
'ActiveSheet.Cells
.Range("A2", .Cells(lastRow, lastColumn)).ClearContents
End With
Next SheetX
End Sub
The Array has to be passed to the Sheets object :
Sub DeleteAllData()
Dim ws As Worksheet
For Each ws In Sheets(Array("BalanceSheetTransposed", "IncomeStatementTransposed", _
"CashflowStatement"))
s.UsedRange.Offset(1).ClearContents
Next
End Sub
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
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