VBA Coding: What does .ListObjects actually do? - vba

I am trying to alter some code for a post-processing of data excel template.
The previous code is using arrays which I will admit I am new to, I have tried to work out what
.ListObjects
does?
Here is the code that I am currently sulking over...
Sub DefineLists()
Dim sheetArr(1 to 5) as Worksheet
Dim tblArr(1 to 5) as ListObject
'set array of sheet names
Set sheetArr(1) = Sheets("All Data")
Set sheetArr(2) = Sheets("Day")
Set sheetArr(3) = Sheets("Evening")
Set sheetArr(4) = Sheets("Night")
Set sheetArr(5) = Sheets("Weekend")
'set array of table names
Set tblArr(1) = sheetArr(1).ListObjects("tblAllData")
Set tblArr(2) = sheetArr(2).ListObjects("tblDayData")
Set tblArr(3) = sheetArr(3).ListObjects("tblEveData")
Set tblArr(4) = sheetArr(4).ListObjects("tblNightData")
Set tblArr(5) = sheetArr(5).ListObjects("tblWeekendData")
End Sub
I am just desperately trying to work out what the second set of "set" statements are doing!
The sheets also have some rather complex formulas (=blahblahblah) written in the cells, so is the .ListObjects creating an array where it stores all of those formulas?

ListObjects: A Collection of ListObjects
ListObject: A table on a worksheet
A Slice of your code
sheetArr(1): Sheets("All Data")
.ListObjects("tblAllData"): A refernce to a ListObject named tblAllData
sheetArr(1).ListObjects("tblAllData"): Refers to a table named "tblAllData: on the Worksheet names "All Data"

ListObjects is the collection of ListObjects on a sheet (Documentation here) Basically, this set of Set calls is assigning the Table array index positions to the specific ListObjects referenced by those names on the sheet. (FYI, that array is not a list of table names, but a list of the actual Table ListObjects themselves)

You are declaring an array of individual ListObject objects with Dim tblArr(1 to 5) as ListObject (note singlular form of ListObject).
Later you are setting each element of the array to a particular ListObject from the ListObjects collection (note plural form). This is all of the ListObjects on the worksheet identified by the previously set sheetArr element. The individual object is identified from the ListObjects collection by the table name ; e.g. tblAllData or tblDayData.

Related

VBA code help, issue with ranges [duplicate]

This is part of a larger code, but this snippet isn't working. I'm trying to just set two cells equal to each other, but it's not working. When I use the .Range("v1_copy"), the code runs, but when I name that range and place it as a variable (myCopyRange), the code doesn't run and I get the error: Compile error: Method or data member not found. Any help would be appreciated!
Sub copy_paste_test()
Dim myCopyRange As Range
Dim myPasteRange As Range
Dim myWS1 As Worksheet
Dim myWS2 As Worksheet
Set myWS1 = Sheets("Sheet1")
Set myWS2 = Sheets("Sheet2")
myCopyRange = Range("v1_copy")
myPasteRange = Range("v1_paste")
'myWS2.Range("v1_paste").Value = myWS1.Range("v1_copy").Value
' This line works, but the below line doesn't
myWS2.myPasteRange.Value = myWS1.myCopyRange.Value
' This should be the exact same, just substituting the variable, but doesn't work
End Sub
You're missing the Set keyword for your Range object reference assignments to myCopyRange and myPasteRange.
But for retrieving a named range, the best place to go if you want fully explicit code that does what it says and says what it does, is to dereference the Name from the appropriate Names collection.
If the names are workbook-scoped, qualify with a Workbook object - here a book object variable, but depending on needs ActiveWorkbook or ThisWorkbook work just as well:
Set myRange = book.Names("name").RefersToRange
If the names are worksheet-scoped, qualify with a Worksheet object - here a sheet object variable, but ActiveSheet works just as well:
Set myRange = sheet.Names("name").RefersToRange
That way the code won't break if the workbook is renamed, or if the user changes the "tab name" of the sheet. It won't break as long as the name exists in the queried Names collection.
'myWS2.Range("v1_paste").Value = myWS1.Range("v1_copy").Value
' This line works, but the below line doesn't
myWS2.myPasteRange.Value = myWS1.myCopyRange.Value
' This should be the exact same, just substituting the variable, but doesn't work
This should be the exact same - no. myWS1.myCopyRange is illegal: myWS1 is a Worksheet object: the Worksheet interface doesn't have a myCopyRange member, hence method or data member not found.
Since myCopyRange is a Range object, it knows about its Parent which is the Worksheet it belongs to: there's no need to qualify it... and there's no need to dereference it again either - this is enough:
myPasteRange.Value = myCopyRange.Value
Range will only apply to the currently active worksheet unless you add the Worksheet reference at the time of assignment (not at the time usage as you have done).
Since you are access a different worksheet, your second assignment will fail.
myCopyRange = myWS1.Range("v1_copy")
myPasteRange = myPasteRange = Range("v1_paste")
See the Range Object Documentation:
When it's used without an object qualifier (an object to the left of
the period), the Range property returns a range on the active sheet
... Use the Activate method to activate a worksheet before you use the
Range property without an explicit object qualifier
If you are trying to refer to NamedRanges and not a name held in a VBA variable, you need to change the way you are accessing the range.
Workbook-scope NamedRanges do not use worksheet reference - since they don't apply to a worksheet, they apply at the workbook level. If you need to add a qualifier, you add the workbook:
Range("MyBook.xls!MyRange")
If you are referring to Worksheet-scope NamedRange, you need a qualifier, but it goes inside the quotations:
Range("Sheet1!Sales")
Properly create ranges by using Set and don't refer to worksheets before them. Workbook-scoped ranges don't need to be tied to any worksheet.
Sub copy_paste_test()
Dim myCopyRange As Range
Dim myPasteRange As Range
Set myCopyRange = Range("v1_copy")
Set myPasteRange = Range("v1_paste")
Range("v1_paste").Value = Range("v1_copy").Value
'myPasteRange.Value = myCopyRange.Value
End Sub

Convert a string sheet to an object sheet VBA

I would like to convert an array which contains the name of my sheets, but as Object and not as String
For example, I have this :
arr=(Sheet01, Sheet02, Sheet03)
When I add a Watches on my array, I get the type Variant/Object/Sheet01 and that's I need for.
But I would like to not hardcoding my namesheet and use a Range like :
arr = Worksheets("Data").Range("NameSheet")
But when I use this solution I get the type Variant/Variant but I need the object type for after use something like :
Set SheCurrent = arr(i)
Is there possible to do something like that ? Thanks for the help and sorry for the approximate english
This is one way to convert a array of strings into an array of worksheet objects:
Sub WhatsInAName()
arr = Array("Sheet1", "Sheet2", "Sheet3")
Dim oArr(1 To 3) As Worksheet
i = 1
For Each a In arr
Set oArr(i) = Sheets(a)
i = i + 1
Next a
End Sub
Worksheets are part of a Workbook. Every workbook has a collection of worksheets that you can access either by name of by number. If you write Worksheets("Data"), it accesses the worksheet "Data" of the current active workbook.
So the simple answer would be
Set SheCurrent = worksheets(arr(i))
But I would advice to read a little bit about how to deal with Workbooks and Worksheets in VBA, for example 10 ways to reference Excel workbooks and sheets using VBA. As a general advice, you should (nearly) never assume a specific workbook to be active.

Create a range using named cells

I need to create a range using named cells in vba.
So far I have the following which is not working;
Dim pasteRange As Range
Set pasteRange = Range(firstRow, 11)
pasteRange.Value(11) = slabTemplateSheet.Range("slabTemp").Value(11)
Where firstRow is an Integer. slabTemplateSheet refers to a worksheet and slabTemp is a named range in said sheet.
I thought it would be fairly simple as my paste range is only 1 row and 11 columns (i.e 11 cells in a row) but I can't get it to work.
In your answer, presuming there is one, could you also please give me the ability to paste multiple rows and columns, so for instance if slabTemp refers to A1:F16
Edit: I didn't make it clear what I am trying to do.
I have a named range called slabTemp in the worksheet slabTemplateSheet. In another sheet I want to copy that range, including the formatting, and paste it. I heard that using the copy/paste function was slow so I found the property above that supposedly does the same thing but is faster (i haven't tested it). Source, Durgesh's answer here: fast way to copy formatting in excel
In the new sheet I need to paste it into a range which is to be created (this is what i don't know how to do)
So Range(firstRow, 11) refers to the integer saved as firstRow (a row number) and 11 is the column number. But this doesn't work.
I guess my question, is how do i create a range using names rather than say Range("A1:G6") so instead Range(firstRow1:secondRow:6)
Thanks Again!
Here's a working example.
Public Sub CopyRange()
'Define the Copy Range
Dim CopyRange As Range: Set CopyRange = Range("MyCustomRange")
'Define the range to Paste Value to
Dim PasteRange As Range: Set PasteRange = Range("MyOtherCustomRange")
'Move the Copy Range into the Paste Range
'You don't need to specify the sheet name, the Defined named holds that information
'Important: The ranges should be the same size, otherwise you may get an error
PasteRange.Value() = CopyRange.Value()
End Sub
About how to create a Named Range (worksheet scope, not for Workbook per your code), use the code below. Not sure what are you trying to achieve in this line:
pasteRange.Value(11) = slabTemplateSheet.Range("slabTemp").Value(11)
Anyway, this is the code for the Named Range:
Sub UseNamedRange()
Dim slabTemplateSheet As Worksheet
Dim pasteRange As Range
Set slabTemplateSheet = Sheets("Sheet1")
' create the Named Range "slabTemp" (Named Range for Worksheet)
' you can manualy (or with variables) modify the Range("A1:F16")
slabTemplateSheet.Names.Add "slabTemp", Sheets("Sheet1").Range("A1:F16")
Set pasteRange = slabTemplateSheet.Range("slabTemp")
End Sub
It doesn't seem like you are trying to transfer the xlRangeValueXMLSpreadsheet XlRangeValueDataType enumeration of the cells; rather it sounds like you want 11 cells in a row.
with slabTemplateSheet.Range("slabTemp")
pasteRange.Resize(1, 11) = .Cells.Resize(1, 11).Value
end with

Referencing multi-sheet named range in VBA

I have a named range in Excel that I am trying to clear using VBA.
The problem with the range is that spans across multiple sheets and I am not sure how to properly reference the named range in VBA since it covers multiple sheets.
The Named Range "Counts" is set to Workbook scope with the following cell references:
=Sheet1!$A$1, Sheet2!$A$1, Sheet3!$A$1
When clearing a named range where it only has cells referenced on one sheet I use the following:
ThisWorkbook.Sheets("Sheet1").Range("Counts").ClearContents
I have tried the following but neither seemed to work.
ThisWorkbook.Range("Counts").ClearContents
and
Range("Counts").ClearContents
The last gives me a global error.
Instead of a range that goes across multiple sheets (which does not work, as we have established), you need a worksheet scoped range in each sheet.
When defining a range name you can set its scope to workbook or the current sheet. This way you can have the same range name in many sheets.
Use VBA to loop through all worksheet, access the ws.Range("TheRangeName") on the current sheet and clear its contents.
That's a cleaner approach.
I would write something that displays the names and you can use that to remove it...
In the immediate window:
For i = 1 to names.count:Debug.print i, Names(i).RefersTo, Names(i).name:next
You can then either use th name or the index to remove the particular name you want.
Hope that helps.
Rory Archibald states on his website post about named ranges that: A Range object can only refer to cells on one worksheet. You cannot refer to cells on different sheets with one Range object.
So I am unable to accomplish what I was wanting but I should be able to just create multiple named ranges and just clear them one at a time.
I was able to complete the code for this as follows with inspiration from teylyn
Public Sub ClearRanges()
'Checks if named Range exists on sheet if it does then clear contents
Dim ws As Worksheet
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
If Len(ws.Range("Counts").Name) <> 0 Then
ws.Range("Counts").ClearContents
End If
Next ws
Application.DisplayAlerts = True
End Sub

Excel vba macro how to create an empty Range variable object

As the question says, how to create an empty range variable object:
tested with the code below it cannot insert a new cell/range from a different source (workbook/worksheet).
Public Sub test()
Dim Sheet As Worksheet
Dim t As Range
Set Sheet = ActiveWorkbook.Sheets(1)
Sheet.Activate
Set t = Sheet.Range("A1:A1")
t.Delete
t.Insert
End Sub
the above code gives me the object required exception. How do we create an empty Range and populate it with cells from another source or at least a custom made cell to be inserted in the Range?
similar to how an array object is capable or in a gridview where we can create a row/column/cell object instantiate it and give values to it and add it to gridview, like how you do it in asp.net/c# winforms?
After you have deleted a Range you cannot refer to it because it does not exist. The address A1 of course still exists but now points to a different range.
You can clear a range or overwrite it with new data or copy a range from somewhere and paste it somewhere else.
BTW inserting ranges can be very time-expensive ...