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
Related
I have a workbook with dynamic log sheet that performs calculations on data entered by the user. I would like specific dynamic columns copied from this log sheet to another sheet in the workbook for graphing purposes. This copy would only be for values and mainly is done to make it easier to run a final macro for producing a XY scatter plot. However, I am getting an object error and am not sure why this is happening. Thank you in advance for any and all help. Could you please help me figure out the best way to accomplish this task? Here is my current VBA:
Sub UpdateCharts()
Dim sourceSheet As Worksheet
Dim targetSheet As Worksheet
Dim sourcelRow As Long
Dim targetlRow As Long
Set sourceSheet = ThisWorkbook.Worksheets("Inventory Log")
Set targetSheet = ThisWorkbook.Worksheets("Tables")
sourcelRow = sourceSheet.Cells(Rows.Count, 1).End(xlUp).Offset(-1, 0).Row
targetlRow = targetSheet.Cells(Row.Count, 6).End(xlDown).Offset(1, 0).Row
sourceSheet.Cells(sourcelRow, 1).Copy
targetSheet.Cells(targetSheet, 6).PasteSpecial xlPasteValues
End Sub
There are several errors/typos in your code:
you should always use explicit referencing
Row and Rows are two different commands
to retrieve the last row you should always use the same function
you don't need to copy/paste values - you can write them directly to
You could e.g. use this function to retrieve the last row of a sheet and columnIndex:
Public Function getLastRow(ws As Worksheet, columnIndex As Long) As Long
With ws
getLastRow = .Cells(.Rows.Count, columnIndex).End(xlUp).Row
End With
End Function
Then your code would look like this
Sub UpdateCharts()
Dim sourceSheet As Worksheet
Dim targetSheet As Worksheet
Dim sourcelRow As Long
Dim targetlRow As Long
Set sourceSheet = ThisWorkbook.Worksheets("Inventory Log")
Set targetSheet = ThisWorkbook.Worksheets("Tables")
sourcelRow = getLastRow(sourceSheet, 1)
targetlRow = getLastRow(targetSheet, 6) + 1 'adding 1 row to have the next empty row
targetSheet.Cells(targetlRow, 6).Value = sourceSheet.Cells(sourcelRow, 1).Value
End Sub
I want to know the code for inserting specified cells ranges below. For example, if I have a table with values from A2:F2, I want to create a code, which inserts a row below (i.e. A3:F3) and so on as and when the procedure is run. I want to insert rows only for specified range, not full row.
Sub InsertCells()
Dim ws As Worksheet
Dim LastRow As Long
Dim FirstHeaderCell As Range
Dim LastHeaderCell As Range
Set ws = ThisWorkbook.Sheets("sheet1") 'change here to your needs
Set FirstHeaderCell = ws.Range("A2") 'change here to your needs
Set LastHeaderCell = ws.Range("C2") 'change here to your needs
With ws
LastRow = FirstHeaderCell.Rows.End(xlDown).Row + 1
.Range(.Cells(LastRow, FirstHeaderCell.Column), .Cells(LastRow, LastHeaderCell.Column)).Insert xlShiftDown
End With
End Sub
You may not have merged cells under your table.
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
I am trying to copy a row from another worksheet to the last row of my data tracking sheet.
I get application defined or object defined error.
Sub Macro1()
Dim i As Integer
Dim A As Integer
Range("A20:AB20").Select
Selection.Copy
Application.WindowState = xlNormal
Windows("master tracking sheet.xlsm").Activate
i = Worksheets("Recieved Results").cells(Rows.Count, 1).End(xlUp).Row
A = i + 1
Selection.End(A).Select
Range(A).Select
ActiveSheet.Paste
End Sub
You don't need to use things like Select or Activate. As you can declare things as objects in VBA, you can use this to perform most actions in without having to use any of that. Try the code below:
Sub CopyFromOneSheetToAnother()
Dim oCopyFromWS As Worksheet: Set oCopyFromWS = ThisWorkbook.Worksheets("Sheet3") '<- Change the sheet name to the sheet you want to copy from
Dim oCopyToWS As Worksheet: Set oCopyToWS = ThisWorkbook.Worksheets("Sheet4") '<- Change the sheet name to the sheet you want to copy to
Dim iLR As Long: iLR = oCopyToWS.Cells(oCopyToWS.Rows.Count, 1).End(xlUp).Row + 1
oCopyFromWS.Range("A20:AB20").Copy oCopyToWS.Range("A" & iLR)
End Sub
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