VBA Working with Tables and Loops - excel

Create a VBA loop to re-size all of the tables in an Excel project.
A list of table names is stored in the "Tlist" named range
This code all works if the table names are written in.
The code works in this loop for the column count, but on the second reference of x , the re-size, I get an error of 'subscript out of range'
Hovering over the second x on debug, Excel seems to read it in right, but I can't get it to re-size the table Something to do with the list object function not supporting the text in the loop? Or am I doing this loop wrong and need to define x differently? Any help greatly appreciated.
Sub RSizeTables()
Dim rr As Integer
Dim cc As Integer
Dim x As Range
Dim £Table As Range
Set £Table = Range("Tlist")
For Each x In £Table
rr = 2
cc = Range(x).Columns.Count
With Sheets("Data").ListObjects(x)
.Resize .Range.Resize(rr, cc)
End With
Next x
End Sub

This code will resize all tables to two rows:
Sub ResizeAll()
Dim ws As Worksheet
Dim lo As ListObject
'If you only have tables in one sheet, use this
Set ws = Sheets("Data")
'Else this:
'For Each ws in Sheets
For Each lo In ws.ListObjects
lo.Resize lo.Range.Resize(2)
Next lo
'Next ws
End Sub
If you need to loop only the tables in TList, this will do the job:
Sub ResizeTList()
Dim varTableName As Variant
For Each varTableName In Range("TList")
With Sheets("Data").ListObjects(varTableName)
.Resize .Range.Resize(2)
End With
Next varTableName
End Sub

Related

Create Named Range for Each Sheet, Store those Named Ranges in a list or array, and then Delete the named Ranges

I have a fairly unique situation that I hope to solve with a series of macros. I regularly work with large workbooks (>100 tabs), for which I would like to be able to navigate between sheets quickly while in cell edit mode. This is obviously challenging, as cell edit mode seems to block most VBA code. I have found a solution to this, which is to create a named range in cell a1 on each sheet in the workbook.
The next goal is to store these named ranges in a list, sheet, or an array, so that later on I can run another macro that will leverage this list/sheet/array to delete all of those named ranges located in cell a1 on each sheet. Understandably, this is likely a roundabout problem that can be solved in various ways, many of those much simpler. However, due to the nature of my work, this seems to be the most straight-forward solution. Below I will detail the code that I have written, for the 3 parts (likely 3 separate macros).
First macro (create named ranges)
Sub NamedRange()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim rng As Range
For Each ws In ActiveWorkbook.Worksheets
ws.Activate
With ActiveWindow
Set rng = ws.Range("A1")
ActiveWorkbook.names.Add Name:=Replace(ws.Name, " ", "_"), RefersTo:=rng
End With
Next
Application.ScreenUpdating = True
End Sub
Second macro (store named ranges. I opted to store them in a new sheet that will also be deleted with the named ranges, but if this can be done in an array or list, that would be better)
Sub ListSheets()
Dim ws As Worksheet
Dim x As Integer
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "namedranges"
x = 1
Sheets("namedranges").Range("A:A").Clear
For Each ws In Worksheets
Sheets("namedranges").Cells(x, 1) = ws.Name
x = x + 1
Next ws
End Sub
Third macro (delete named ranges, this is the only one that does not work at all, the others are functional - albeit inefficient)
Sub DeleteNamedRanges()
Dim strArray() As String
Dim TotalRows As Long
Dim i As Long
Dim strName As Variant
TotalRows = Rows(Rows.Count).End(xlUp).Row
ReDim strArray(1 To TotalRows)
For i = 1 To TotalRows
strArray(i) = Cells(i, 1).Value
Next
i = strName
For Each strName In strArray
strName.Delete
Next
End Sub
Any help is much appreciated, I've been struggling with this issue for a while and it would be a huge help to get this rolling. If I can provide any additional color, I am happy to follow up, once again, thanks so much!
You should not write the names to the workbook but to each sheet:
Option Explicit
Const CheckName As String = "RememberMe"
Sub DoNames()
Dim g As Worksheet
DeleteNames
For Each g In Worksheets
g.Names.Add CheckName, g.Range("a1")
Next g
' Example: Now you can get every name by sheet:
For Each g In Worksheets
Debug.Print g.Names(CheckName).RefersToRange.Address
Next
' Your Code
DeleteNames
End Sub
Sub DeleteNames()
Dim g As Worksheet
On Error Resume Next ' Lazy but ok here
For Each g In Worksheets
g.Names(CheckName).Delete
Next g
End Sub
A solution on Workbooknames?
Option Explicit
Sub DoNames()
Dim g As Worksheet
DeleteNames
For Each g In Worksheets
ActiveWorkbook.Names.Add g.Name & "_todel", Range("a1")
Next g
End Sub
Sub DeleteNames()
Dim n As Name
On Error Resume Next ' Lazy but ok here
For Each n In ActiveWorkbook.Names
If n.Name Like "*_todel" Then n.Delete
Next
End Sub

Use named range to loop through sheets

I have a named range compiled of 30 string values. Each of the string values is also used as the name of a sheet. I was wondering if it would be possible to loop through each string in the range to edit it's respective sheet. I've gone through some trial and error but am still stuck. Any help would be greatly appreciated.
Option Explicit
Sub NamedRanges()
Dim ws As Worksheet
Dim rng As Variant
rng = Sheets("Teams").Range("TeamList_Full")
For Each ws In rng
ws.Range("A36").Value2 = 2
Next ws
End Sub
You can do it like this:
Sub NamedRanges()
Dim c As Range
For Each c In ThisWorkbook.Worksheets("Teams").Range("TeamList_Full").Cells
ThisWorkbook.Worksheets(c.Value).Range("A36").Value2 = 2
Next c
End Sub
Since you appear to be targeting the same cell on each sheet, you can also achieve your aim by avoiding a loop
Sub NamedRanges()
Dim sh As Worksheet, rng As Range
Set rng = Worksheets("Teams").Range("TeamList_Full")
Set sh = Worksheets(rng.Cells(1).Value2)
sh.Range("A36").Value2 = 2
Worksheets(WorksheetFunction.Transpose(rng.Value2)).FillAcrossSheets sh.Range("A36")
End Sub

What is the proper syntax to reference a table by index number in a VBA script

I'm trying to put together a very simple VBA script to clear cell contents within a specified table column range ([Front Straddle]:[Front Option]), of all tables within a specified worksheet. This script will only live within the "VolJump" worksheet, which contains an arbitrary number of identically formatted, differently named tables. Because of this, I felt the best approach was to reference the tables by the index number.
This is where I'm running into issues with the proper referencing/nesting within the 'Range' function, shown below. Any help is greatly appreciated.
Sub ClearCells()
Dim i As Long
Dim sh As Worksheet
Set sh = ThisWorkbook.Worksheets("VolJump")
If sh.ListObjects.Count > 0 Then
For i = 1 To sh.ListObjects.Count
Range("Activesheet.ListObjects(1)[[Front Straddle]:[Front Option]]").Select
Selection.ClearContents
Next i
End If
End Sub
Clear Contents of Table Columns Range
Option Explicit
Sub ClearCells()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("VolJump")
Dim tbl As ListObject
For Each tbl In ws.ListObjects
ws.Range(tbl.Name & "[[Front Straddle]:[Front Option]]").ClearContents
Next tbl
End Sub
Just using the ListObjects:
Sub ClearColumns()
Dim lo As ListObject
Dim ColNum1 As Long, ColNum2 As Long
For Each lo In ThisWorkbook.Worksheets("Sheet1").ListObjects
'Get the index numbers of the start and end columns.
ColNum1 = lo.ListColumns("Front Straddle").Index
ColNum2 = lo.ListColumns("Front Option").Index
'Resize the range from the start column to the end column and clear it.
lo.DataBodyRange.Columns(ColNum1).Resize(, ColNum2 - ColNum1 + 1).ClearContents
Next lo
End Sub

Formula into Excel Table using VBA

I want to insert the following formula into the third column of my Excel Table "Transactions". If I enter it manually, it works, but if I try to enter it using a subroutine I get the Error 1004. Not sure how to solve this. Here is a code snippet:
Sub test3()
Dim ws As Worksheet
Dim lo As ListObject
Dim lCol As ListColumn
Set ws = ThisWorkbook.Worksheets("Transactions")
Set lo = ws.ListObjects(1)
Set lColName = lo.ListColumns(3)
lColName.DataBodyRange.Formula = "=IFERROR(INDEX(Staff[CREDENTIALS],MATCH([#[Staff, Last Name]],LastName,0)),"")"
End Sub
All I really need to do is to put the formula into the first row of the table (row 2) in the third column "Staff, Credentials". It is pulling from another Excel Table "Staff".
I believe the issue is coming from your formula (I know you mentioned it works when you manually enter it however when I try I'm getting an error), try changing [#[Staff, Last Name]] to Staff[Last Name]
Also, you'll need to escape the "" in the IFERROR formula, the below code should work:
Sub test3()
Dim ws As Worksheet
Dim lo As ListObject
Dim lCol As ListColumn
Set ws = ThisWorkbook.Worksheets("Transactions")
Set lo = ws.ListObjects(1)
Set lColName = lo.ListColumns(3)
lColName.DataBodyRange.Formula = "=IFERROR(INDEX(Staff[CREDENTIALS],MATCH(Staff[Last Name],LastName,0)),"""")"
End Sub

Copy from one ListObject to another VBA

More a question of writing nice VBA code here, since it technically works. I have a simple task - I need to copy data from one ListObject (2 columns from 4-column table) and add it to the end of another 2-column table (and have the Excel table autoexpand).
I created Range Trans_log, for addressing those 2 columns I need to copy. I'm targeting the newly created ListRow through newrow, in order not to accidentially paste data somewhere in the middle of the table.
However is there a neater way to do this, instead of using With, .Activate and ActiveCell ?
Sub Copy()
Dim newrow As ListRow
Set newrow = ActiveSheet.ListObjects("Log").ListRows.Add
ActiveSheet.Range("Trans_log").Copy
With newrow
.Range(1).Activate
ActiveCell.PasteSpecial xlPasteValues
End With
End Sub
You can do something like this - directly assign the values instead of copy/paste
Sub Copy()
Dim newrow As ListRow
With ActiveSheet
Set newrow = .ListObjects("Log").ListRows.Add()
newrow.Range.Value = .Range("Trans_log").Value
End With
End Sub
EDIT: for copying multiple rows
Sub Copy()
Dim rw As Range
Dim newrow As ListRow
Dim lst As ListObject, sht As Worksheet
Set sht = Sheets(1)
Set lst = sht.ListObjects("Log")
'loop over rows in named range
For Each rw In sht.Range("Trans_log").Rows
'only copy rows with data
If Application.CountA(rw) > 0 Then
Set newrow = lst.ListRows.Add()
newrow.Range.Value = rw.Value
End If
Next rw
End Sub

Resources