Selecting Range - excel

TL;DR:
I would like it so that the range A6:A? down is pasted into range B10:B?
I am trying to select a range of data to populate into another column. The range is coming from a table and is currently in range A6:A9, although this will extend.
The code that I am currently using is:
Sub Supplier_Names()
Dim wb As Workbook
Dim ws_Temp As Worksheet
Dim Supplier_Names As Range
Set wb = ThisWorkbook
Set ws_Temp = wb.Worksheets("Templates")
Set Supplier_Names = ws_Temp.Range("A6", Range("A6").End(xlDown))
ws_Temp.Range("B10") = Supplier_Names
End Sub
This works when I only select from range A6, but when I run it with the xlDown it does not enter any values into B10. It also does not come up with a debug box.
Any solutions would be great!
Cheers,

Using array is easy.
Sub Supplier_Names()
Dim wb As Workbook
Dim ws_Temp As Worksheet
Dim Supplier_Names As Range
Dim vDB As Variant
Set wb = ThisWorkbook
Set ws_Temp = wb.Worksheets("Templates")
With ws_Temp
Set Supplier_Names = ws_Temp.Range("A6", .Range("A6").End(xlDown))
vDB = Supplier_Names '<~~ use array
.Range("b10").Resize(UBound(vDB, 1)) = vDB
End With
End Sub
The following are the same. It doesn't matter which one is a character and which one is a range.
Dim rngDB As Range
Set rngDB = Range(Range("a1"), Range("a10"))
Set rngDB = Range("a1", "a10")
Set rngDB = Range("a1", Range("a10"))
Set rngDB = Range("a1:a" & 10)

Range("A1").End(xlDown) returns the default property which is Value.
So for example, your current range is A6:A9, if A9 has the word Test in it, your line becomes:
Set Supplier_Names = ws_Temp.Range("A6", "Test"). though it should be noted Excel/VBA seems smart enough to work out what you are wanting to do and does infact use the cell address reference)
You can use the Address property of Range to return the cell address that is found.
Like so:
Set Supplier_Names = ws_Temp.Range("A6", Range("A6").End(xlDown).Address)
Which would translate to:
Set Supplier_Names = ws_Temp.Range("A6", "$A$9")
I agree with #Dy.Lee answer that using an Array is a better way to do what you are wanting to do.
Like so:
Sub Supplier_Names()
Dim ws_Temp As Worksheet
Dim Supplier_Names_Array() As Variant
Set ws_Temp = ThisWorkbook.Worksheets("Templates")
With ws_Temp
Supplier_Names_Array = .Range("A6", .Range("A6").End(xlDown).Address)
.Range("B10").Resize(UBound(Supplier_Names_Array, 1)) = Supplier_Names_Array
End With
End Sub
http://www.cpearson.com/Excel/ArraysAndRanges.aspx is a great resource for learning about this method of using Arrays with the Worksheet.

I've introduced another range object to make it more readable:
Option Explicit
Sub Supplier_Names()
Dim wb As Workbook
Dim Temp As Worksheet
Dim Supp As Range
Dim Cust As Range
Set wb = ThisWorkbook
Set Temp = wb.Worksheets("Templates")
Set Supp = Temp.Range("A6")
Set Supp = Temp.Range(Supp, Supp.End(xlDown))
Set Cust = Temp.Range("B10")
Set Cust = Cust.Resize(Supp.Rows.Count, Supp.Columns.Count)
Cust.Value = Supp.Value
End Sub

Related

VBA: How to retrieve ListObject-Column-Count of given element in HeaderRowRange?

I am trying (and failing) to find a given string in the HeaderRowRange of a ListObject. I would like to pull the ListObject-Column Count (not the spreadsheet-column count). I am trying to address with using ".index", however, it is running into an error. What is wrong with the below code?
See screenshot to understand better my goal:
w/in the ListObject Column3 is the 3rd column, while w/in the worksheet it is column 6 (column F). I want the j in my code to be 3 (not 6).
Sub MWE()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("worksheet1")
Dim lo As ListObject: Set lo = ws.ListObjects("table1")
Dim j As Long: j = lo.HeaderRowRange.Find("Column3", LookIn:=xlValues, LookAt:=xlWhole).Index
End Sub
As I know the name of the column header, I can simply use this code to get the column count w/in the ListObject:
j= lo.ListColumns("Column3").Index
.Find returns a range object. Is this what you are trying?
Option Explicit
Sub Sample()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("worksheet1")
Dim lo As ListObject: Set lo = ws.ListObjects("Table1")
Dim aCell As Range
Set aCell = lo.HeaderRowRange.Find("Column3", LookIn:=xlValues, LookAt:=xlWhole)
If Not aCell Is Nothing Then
MsgBox aCell.Column
End If
End Sub
Alternatively you can also use Application.Match
Option Explicit
Sub Sample()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("worksheet1")
Dim lo As ListObject: Set lo = ws.ListObjects("Table1")
Dim j As Long: j = Application.Match("Column3", lo.HeaderRowRange, 0)
MsgBox j
End Sub
PS: You also have a typo in your code. Dim lo As listoject should be Dim lo As ListObject
EDIT
See screenshot to understand better my goal: w/in the ListObject Column3 is the 3rd column, while w/in the worksheet it is column 6 (column F). I want the j in my code to be 3 (not 6).
In such a case if your table doesn't start from Col A then you will have to do the range adjustment. Change MsgBox aCell.Column to MsgBox aCell.Column - lo.HeaderRowRange.Column + 1 in the first code.
Output
There are several way to access the column in listobject table other than hearderRow, hope you find it useful
Sub tt()
Dim tb1 As ListObject
Dim rcol As Range
Set tb1 = Sheet1.ListObjects("Table1")
Set rcol = tb1.ListColumns("Ctry").DataBodyRange
Debug.Print rcol(3).Value 'Hawaii
End Sub

How to copy a range to another worksheet with for each loop?

I would like to copy a range to an another worksheet and to insert before it 2 columns on the new worksheet. It doesn't copy the original range.
It works, if I copy to the same worksheet.
Set ws = ThisWorkbook.Sheets("Sh2")
Set ws2 = ThisWorkbook.Sheets("Sh3")
Set wb = ThisWorkbook
rowNum = ws.UsedRange.Rows.Count
For Each row In ws.Range("A1:A" & rowNum)
ws2.Range("A1:A" & rowNum).Offset(0, 0).Value2 = wb.Name
ws2.Range("A1:A" & rowNum).Offset(0, 1).Value2 = ws.Name
Next row
For Each cell In ws.UsedRange
cell.Offset(10, 2).Value2 = cell.Value2
Next cell
I expect the column "A" contains the name of active workbook, the "B" the name of active worksheet, the other rows comes the original content. Now, the filename and worksheet's name copied to the new worksheet, but the content not.
The direction you're headed with your code is close, hopefully this example can help. But first, please always use Option Explicit in your code.
In setting up your initial variables for the worksheets, using more descriptive variable names makes it more clear exactly which variable is intended to hold certain data. My example set up then is
Dim wb As Workbook
Dim srcWS As Worksheet
Dim dstWS As Worksheet
Set wb = ThisWorkbook
Set srcWS = wb.Sheets("Sh2")
Set dstWS = wb.Sheets("Sh3")
Next, you can create a variable to determine the range area of your source data:
Dim srcRange As Range
Set srcRange = srcWS.UsedRange
In the case where you want to create your first two columns to contain the workbook and worksheet names, you don't actually need a loop. By creating a Range of the size you need, a single statement will place the same value in all of the cells in that range. Therefore you can create your name columns in two statements using
dstWS.Range("A1").Resize(srcRange.Rows.Count, 1) = wb.Name
dstWS.Range("B1").Resize(srcRange.Rows.Count, 1) = srcWS.Name
I'll establish a destination range that starts in the third column, just to the right of the two name columns:
Dim dstRange As Range
Set dstRange = dstWS.Range("C1").Resize(srcRange.Rows.Count, _
srcRange.Columns.Count)
Then with the same idea, you can also copy the entire source range to your destination in a single statement as well:
dstRange.Value = srcRange.Value
And you're done.
Here is the whole example in a single block:
Option Explicit
Sub CopyMyRange()
Dim wb As Workbook
Dim srcWS As Worksheet
Dim dstWS As Worksheet
Set wb = ThisWorkbook
Set srcWS = wb.Sheets("Sh2")
Set dstWS = wb.Sheets("Sh3")
Dim srcRange As Range
Set srcRange = srcWS.UsedRange
dstWS.Range("A1").Resize(srcRange.Rows.Count, 1) = wb.Name
dstWS.Range("B1").Resize(srcRange.Rows.Count, 1) = srcWS.Name
Dim dstRange As Range
Set dstRange = dstWS.Range("C1").Resize(srcRange.Rows.Count, _
srcRange.Columns.Count)
dstRange.Value = srcRange.Value
End Sub

How create new sheets with specific names and copy specific values into new sheets

I have an excel file with a list of names(names.xlsm), I want to create another new excel file(separate.xlsx) with different sheets. The name of each sheet in separate.xlsx is a name in names.xlsx and the first cell of each sheet is the same name value.
'''VBA
Sub copy_name()
Dim MyCell As Range, MyRange As Range, ws As Worksheet
Dim mybook As Workbook
Set mybook = Workbooks("names.xlsm")
Set MyRange = mybook.Sheets("names").Range("A2:A6") 'eg. five names'
Dim target As Workbook
Set target = Workbooks("separate.xlsx")
i = 1
For Each MyCell In MyRange
Set ws = target.Worksheets.Add(After:=Worksheets(Worksheets.Count)) ' create new worksheet in target file
ws.Name = MyCell.Value ' renames the new worksheet
target.Sheets(MyCell.Value).Cells(1, 1) = MyCell 'copy the value of Mycell to target sheets
i = i + 1
Next
Set mybook = Nothing
Set target = Nothing
End Sub
'''
Here is my code. It keeps showing errors and I do not know how to debug.
You can create the worksheet and name it in one line. No need to create it and then name it.
You need to fully qualify your objects
I am assuming that the workseets with the same name as in the names.xlsm do not exist in separate.xlsx. If it does then you will have to handle that separately.
Is this what you are trying?
Option Explicit
Sub Sample()
Dim wbNames As Workbook, wbSep As Workbook
Dim rng As Range, aCell As Range
Set wbNames = Workbooks("names.xlsm")
Set wbSep = Workbooks("separate.xlsx")
Set rng = wbNames.Sheets("Names").Range("A2:A6")
For Each aCell In rng
With wbSep
.Sheets.Add(After:=.Worksheets(.Worksheets.Count)).Name = aCell.Value
.Worksheets(aCell.Value).Cells(1, 1).Value = aCell.Value
End With
Next
End Sub

How to copy named range from one workbook to another workbook in specific cell?

Below is my original code. I am trying to change my code so that add/delete new columns/rows won't affect the new created workbook. I decided to use the name range to avoid the code crushed. (I know how to create the new range in the Name manager) Anyone knows how to adjust the code?
Dim WS As Worksheet
Dim Rng As Range
Dim myWs As Worksheet
Set myWs = ThisWorkbook.Sheets("MASTER")
Set Rng1 = myWs.Range("A1:AJ4")
Set Rng2 = myWs.Range("A85:AJ104")
Application.Workbooks.Add
Set WS = Application.ActiveSheet
Rng1.Copy Destination:=WS.Range("A1:AJ4")
Rng2.Copy Destination:=WS.Range("A5:AJ50")
You need to dim each workbook and worksheet you will be using.
Dim wb1 as Workbook, wb2 as Workbook, ws1 as Worksheet, ws2 as Worksheet
Dim xrow as long, arrData() as variant
Set wb1 = Workbooks("Book1")
Set ws1 = wb1.Worksheets("Sheet1")
Set wb2 = Workbooks("Book2")
Set ws2 = wb2.Worksheets("Sheet2")
Note that this only works if you have both workbooks open.
Also I would recommend copying the data from each cell to an array, instead of copying a range. I get less errors this way.
ApplicationScreenUpdating = False
ws1.Activate
'where n is the number of rows you want to copy
for x = 1 To n
arrData[x - 1] = ws1.Cells(x, 1).value
next x
ws2.Activate
for i = 1 to n
ws2.Cells(i, 1).value = arrData[i - 1]
next i
ApplicationScreenUpdating = True

Paste from advanced filter

I am stuck on a line and don´t know how to solve the error. I´m dividing the lines in a list by filtering different names with an advanced filter and copying the data in individual sheets, but got stuck on a line, the last one before the Next: "newWS.Range("A1").Paste". I get error 1004 from debugging:
Private Sub loopfilter()
Dim thisWB As Workbook
Dim filterws As Worksheet
Dim howto As Worksheet
Dim advfilter As Range
Dim Postenws As Worksheet
Dim VersandRange As Range
Dim rng As Range
Dim Name As String
Set thisWB = ThisWorkbook
Set filterws = thisWB.Sheets("Filtro")
Set howto = thisWB.Sheets("How to")
Set advfilter = filterws.Range("A1:AK2")
Set Postenws = thisWB.Sheets("Alle gemahnten Posten (2)")
Set VersandRange = howto.Range("J2", Cells(Rows.Count, "j").End(xlUp))
Dim newWS As Worksheet
For Each rng In VersandRange
filterws.Range("AK2") = rng.Value
Application.CutCopyMode = False
Postenws.Range("A1").CurrentRegion.AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=advfilter, _
CopyToRange:=filterws.Range("A5"), _
Unique:=False
filterws.Range("a5").CurrentRegion.Copy
Set newWS = thisWB.Sheets.Add
newWS.Name = rng.Value
newWS.Range("A1").Paste
Next
End Sub
Any idea why its not working?
Thanks
Try this (also made a sheet reference to your definition of Versandrange). Paste is not a method of the range object.
Private Sub loopfilter()
Dim thisWB As Workbook
Dim filterws As Worksheet
Dim howto As Worksheet
Dim advfilter As Range
Dim Postenws As Worksheet
Dim VersandRange As Range
Dim rng As Range
Dim Name As String
Set thisWB = ThisWorkbook
Set filterws = thisWB.Sheets("Filtro")
Set howto = thisWB.Sheets("How to")
Set advfilter = filterws.Range("A1:AK2")
Set Postenws = thisWB.Sheets("Alle gemahnten Posten (2)")
Set VersandRange = howto.Range("J2", howto.Cells(Rows.Count, "j").End(xlUp))
Dim newWS As Worksheet
For Each rng In VersandRange
filterws.Range("AK2").value = rng.Value
Application.CutCopyMode = False
Postenws.Range("A1").CurrentRegion.AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=advfilter, _
CopyToRange:=filterws.Range("A5"), _
Unique:=False
Set newWS = thisWB.Sheets.Add
newWS.Name = rng.Value
filterws.Range("a5").CurrentRegion.Copy newWS.Range("A1")
filterws.Range("a5").CurrentRegion.clearcontents
Next
End Sub

Resources