I have an excel table with one header row and one data body row. I want to count the data body rows. When I'm trying to check how many rows my table has with
Set myWorkSheet= ActiveWorkbook.Worksheets("Sheet1")
Set myTable= myWorkSheet.ListObjects("Table1")
countrows = myTable.ListRows.Count
countrows contains 0. If the has 2 or more rows, it gives the right row number. Why does it say 0 for one row ans is it the best way to count the rows or are there better ones?
EDIT:
Found out whats causing the problem. I use this lines to clear the table before i fill it again:
If tblChart.ListRows.Count >= 1 Then
myTable.DataBodyRange.Delete
End If
After that operation the table looks like I described it. Without it and modifying the table to look like I described the table it worked. But why is it causing this problem?
The ListObject property you are looking for is the .DataBodyRange.
Dim myWorkSheet As Worksheet, myTable As ListObject, countRows As Long
Set myWorkSheet = ActiveWorkbook.Worksheets("Sheet1")
Set myTable = myWorkSheet.ListObjects("Table1")
countRows = myTable.DataBodyRange.Rows.Count
Debug.Print countRows
A comprehensive list of the ListObject properties is available at: ListObject Interface.
Responding late in-case Google search brings user here:
I found this problem as well. DataBodyRange object does not exist unless there are two rows of data. Not just two empty rows, but two rows of data in at least one column.
What I have found to work reliably is to test if DataBodyRange exists:
If Not TableListObject.DataBodyRange is Nothing Then
Debug.Print "Data Rows Count=", TableListObject.DataBodyRange.Rows.Count
Else
Debug.Print "No Data in Table detected"
End if
Related
I have tried the following,
ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible).Rows.Count
However this always returns 1, I suspect is it because the data is within a table? Thanks
If your data is in a table, use a ListObject object:
ListObject object
(Excel)
Then count visible cells only in a single column of the data range:
Something like this should work:
Dim Mytable As ListObject
Set Mytable = ActiveSheet.ListObjects("Table1")
Debug.Print Mytable.DataBodyRange.Columns(1).SpecialCells(xlCellTypeVisible).Count
Set Mytable = Nothing
If your data is not a table object but just a range of cells then do:
Range("A1").CurrentRegion.Columns(1).SpecialCells(xlCellTypeVisible).Count - 1
ReplaceRange("A1") with a cell of your header row. And because this count will add also the header row itself, we must do -1 at the result of the count
I have a Table containing a list of Names.
I would like to update a secondary table to have headers that correspond to this list of names (starting from column 2).
Example if my original List contained a,b,c. I would like my secondary table to have column headers of "blank",a,b,c
With Range("Original Table[Names]")
Range("Secondary Table").HeaderRowRange.Value = .Value
End With
The above gives me errors, however, i can't seem to figure out how to solve this
Use Transpose, and Resize.
With Range("Original Table[Names]")
Range("Secondary Table").HeaderRowRange.Cells(2).Resize(,.Rows.Count).Value = Application.Transpose(.Value)
End With
Perhaps a personal preference, but I'd work with ListObjects here:
Dim origTable As ListObject
Set origTable = ThisWorkbook.Worksheets("insertname").ListObjects("Original Table")
Dim secTable As ListObject
Set secTable = ThisWorkbook.Worksheets("insertname").ListObjects("Secondary Table")
With origTable.ListColumns("Names").DataBodyRange
secTable.HeaderRowRange.Cells(2).Resize(,.Rows.Count).Value = Application.Transpose(.Value)
End With
Also, note that a column header can't be blank in a table.
So im currently working a table in excel that I have named Table1 with three columns (Column 1, Column 2 and Column 3). Ive been trying to count the used rows or populated rows inside the table using VBA but have had no luck.
Example 1:
UsedRows= Sheets ("Sheet1").ListObjects.("Table1[#Column 1]").UsedRange.ListRows.Count
Example 2 (This One Returns only all available rows)
UsedRows= Sheets ("Sheet1").ListObjects.("Table1[#Column 1]").ListRows.Count
I either want the populated or unpolulated row amount. Either of the two will work just fine. Remember this is a Table so End(xlUp) and End(xlDown) work a little bit different. Ive tried those too but I still get either the total rows available or the cells that are modified which is way more than what I have available.
Thanks for the help in adavanced whoever posts.
Sounds like you can use CountA, like this perhaps:
Dim myColumn As ListColumn
Set myColumn = Sheets("Sheet1").ListObjects("Table1").ListColumns("Column 1")
Dim UsedRows As Long
UsedRows = Application.CountA(myColumn.DataBodyRange)
Debug.Print UsedRows
If you don't have blank cells in other rows. The 3 doesn't need to be hard-coded, this is just the number of columns in your table.
Sub x()
Dim r As Range
Set r = ActiveSheet.ListObjects(1).DataBodyRange
With WorksheetFunction
MsgBox .CountBlank(r) / 3 'empty rows
MsgBox (r.Rows.Count - .CountBlank(r) / 3) 'non-empty rows
End With
End Sub
I am trying to create a Stacked Column Chart with the data in the table below.
I want to Select column A1:A9 and C1:F9. The Selection also needs to be adaptive to different column sizes (i.e, someone adds another Feature). The macro should also work for a table of data, anywhere in the Sheet. As long as the macro originates from the ActiveCell.
How do I not only Select until the column end, but also Select excluding the "Values" column. I am trying to use End and Offset, but I am not sure the best way to do it. And once again, I want to use it on a table that is anywhere in the sheet and then create a Stacked Column Chart from it.
Thanks for your help!
Try this code please. The idea is that you iteratively Union various ranges of the data based on the condition that the header is not 'Values'.
The working assumption is that the CurrentRegion of the ActiveCell will select your table data. Where the definition of CurrentRegion is 'The current region is a range bounded by any combination of blank rows and blank columns. ' - MSDN link
Then the code will append the first column to an output range. After that, the outer columns will only be appended to the output range if the header is not 'Values'.
Dim rngData As Range
Dim intCounter As Integer
Dim rngToSelect As Range
Set rngData = ActiveCell.CurrentRegion
Set rngToSelect = Range(rngData.Cells(1, 1), rngData.Cells(rngData.Rows.Count, 1))
For intCounter = 1 To rngData.Columns.Count
If rngData.Cells(1, intCounter).Value <> "Values" Then
Set rngToSelect = Union(rngToSelect, Range(rngData.Cells(1, intCounter), rngData.Cells(rngData.Rows.Count, intCounter)))
End If
Next intCounter
rngToSelect.Select
I am working with ListObject objects in VBA. In particular I am creating a table dynamically (variable number of rows and columns, and variable column headers). I have the need to sort the table's columns in ascending alphabetical order.
For instance if I have the table:
I want it to be sorted like so,
Is there any way to do this? I have tried to use the Range.Sort method but it seems that this is not allowed if the range is part of a ListObject.
I also tried to record a macro to find code, but found that when I right clicked the table to sort it, the selected range left the header out and I was not able to select the "Sort left to right" option...
Any ideas?
This seems to work. It takes the name of a table (e.g. "Table1"), converts it to a range, sorts it, then reconverts it to a table with the same name:
Sub SortByCol(tableName As String)
Dim sh As Worksheet
Dim myTable As ListObject
Dim myStyle As TableStyle
Dim myRange As Range
Set sh = ActiveSheet
Set myTable = sh.ListObjects(tableName)
Set myStyle = myTable.TableStyle
Set myRange = myTable.Range
myTable.Unlist
On Error Resume Next
myRange.Sort key1:=myRange.Rows(1), Orientation:=xlSortRows
If Err.Number > 0 Then Debug.Print "Range couldn't be sorted"
On Error GoTo 0
sh.ListObjects.Add(xlSrcRange, myRange, , xlYes).Name = tableName
sh.ListObjects(tableName).TableStyle = myStyle
End Sub
On edit: I added a bit of error handling around the sort method call. Experiments showed that my original code didn't preserve the style (if the table didn't have the default style then the result was a weird blend of the default style and the original table style). I added coded to save and then restore the original table style, but I don't know much about table formatting and might have missed some subtleties. At the very least, it seems to preserve the style if it was chosen from Excel's built-in list of table styles.