I am working with tables in Excel (ListObject). I apply filter via VBA on a table which work fine. I would like to read specific row (or row, col) from filtered table. I tried with SpecialCells which return a range of cells. But I would like to iterate as rows like listobject.listrows(N) where n is number of row. I didn't find any example. Of course I can iterate cell by cell and locate the the row via formula. But I wonder if exist a better way.
For instance: I would like filter a table with several criteria and update certain columns with a particular value.
I hope I am clear with my question.
thanks.
You can loop rows like this
Option Explicit
Sub test()
Dim rng As Range
With ActiveSheet.ListObjects(1).DataBodyRange
For Each rng In .SpecialCells(xlCellTypeVisible).Rows
Debug.Print rng.Address
Next rng
End With
End Sub
Related
I have a row of cells A1:G1 on Sheet2 and I want those values on Sheet1 columns A:G but only on visible rows. I know how to do it through selecting visible cells only and pasting value from Sheet2. But I have many rows and it is incredibly slow. I tried creating an array from cells A1:G1 on Sheet2 and making it a 2D array and then selecting range on Sheet1 and set value in the worksheet but I cannot make the code to work at all. What other ways would you suggest?
Dim Arr() As Variant
Dim 2DArr() As Variant
Sheet1.range(cells(1,8),cells(last_row,8). select
activecell.formulaR1C1="=AGGREGATE(3,5,#columnA)"
Arr = Sheet2.Range("A1:G5")
for i=1 to last_row
if cell(i,8)=1 then
2DArr(i)=Arr
End If
Next i
Sheet1.range("A1:G900000")=2DArr
I admit this is an annoying one: Excel VBA does not have a Visible property for its ranges. Instead it has a Hidden property which works exactly in the opposite way, as you can see from this simple example:
' instead of if RAnge(A1).Visible, you should do:
if NOT(RAnge(A1).Hidden)
We are looking to delete an entire section of rows (named range “Remove_Allowances_Credits”) when all values in the section (named range "Allowances_Credits_Range") are equal to “N/A”.
For example, we are looking to delete rows 156:171 when each value in C161:C170 equal “N/A”. How do I use application.worksheetFunction count and countif to accomplish this?
If Application.WorksheetFunction.Count(Range("Allowances_Credits_Range")) = Application.WorksheetFunction.Count(Range("Allowances_Credits_Range", "n/a")) Then
Workbooks(PharmacyPricingGuarantees2).Sheets("Pharmacy Pricing Guarantees").Range("Remove_Allowances_Credits").Delete
End If
I am getting an Error 1004
If Application.WorksheetFunction.Count(Range("Allowances_Credits_Range")) = Application.WorksheetFunction.Count(Range("Allowances_Credits_Range", "n/a")) Then
Workbooks(PharmacyPricingGuarantees2).Sheets("Pharmacy Pricing Guarantees").Range("Remove_Allowances_Credits").Delete
End If
To delete the named range "Remove_Allowances_Credits"
I am getting an error 1004
Not entirely sure what you are trying to achieve, so I added a few different methods.
Sub Examples()
'Might need to change Workbook reference to PharmacyPricingGuarantees2?
Dim ws As Worksheet: Set ws = Thisworkbook.Sheets("Pharmacy Pricing Guarantees")
If ws.Range("Allowances_Credits_Range").Cells.Count = WorksheetFunction.CountIf(ws.Range("Allowances_Credits_Range"), "n/a") Then
ws.Range("Remove_Allowances_Credits").ClearContents '<-- Clear the values?
ws.Range("Remove_Allowances_Credits").EntireRow.Delete '<-- Delete the rows?
ThisWorkbook.Names("Remove_Allowances_Credits").Delete '<-- Delete the named range?
End If
End Sub
Try the following:
If Application.WorksheetFunction.COUNTA(Range("Allowances_Credits_Range")) =
Application.WorksheetFunction.COUNTIF(Range("Allowances_Credits_Range"), "#N/A")) Then
Workbooks(PharmacyPricingGuarantees2).Sheets("Pharmacy Pricing Guarantees").Range("Remove_Allowances_Credits").Delete
End If
Firstly, you want to use COUNTA instead of COUNT for the first part. COUNT only counts numerical values. COUNTA counts all non-empty values (including #N/A).
Secondly, you want to use the COUNTIF function to count values = #N/A.
What I am doing is very simple - selecting a union of columns which contain numbers stored as text and converting them. Every time this runs, all even union numbered columns of data are getting cleared.
Union(Columns(19), Columns(22), Columns(25), Columns(28), Columns(31), Columns(34), Columns(37), Columns(40), Columns(43), Columns(46)).Select
With Selection
.Value = .Value
End With
I've looked though my entire code multiple times are cant figure why this is behaving so weird. any help is greatly appreciated.
The Value property of a discontiguous range only returns the first area of that range. When you then try and assign that value (array, in this case) back to a discontiguous range, you get strange results. For this particular case, every second column will get the value of the first cell in the first area.
You should loop through the areas in your range.
For each rArea in Selection.Areas
rarea.value2 = rarea.value2
Next rarea
Try to avoid using Select, and fully qualify your ranges. This makes things easier to diagnose and more robust...
Dim myRange As Range
With ThisWorkbook.Sheets("Sheet1")
Set myRange = Union(.Columns(19), .Columns(22), .Columns(25)) ' etc.
End With
Now if you're trying to convert text to numbers, you might be better off using the NumberFormat property as discussed here: What are .NumberFormat Options In Excel VBA?
Looping through range areas and number-formatting:
Dim area As Range
For Each area In myRange.Areas
area.NumberFormat = 0 ' for numbers, could still use area.Value = area.Value
Next area
I want to write a formula like =SUM(tab2!A:A) but instead use the column title of A which is say "count". How can I modify this to look more like: =SUM(tab2!"count")?
The reason I want to do this is because I copy and paste a spreadsheet from another source in tab2 and the column referring to "count" may be in a different column. I want the formula to give me the correct calculation as soon as I paste the new spreadsheet by automatically finding the column to sum up by title name.
I must be missing something because this seems like a very basic question and I can't find the answer anywhere...
Thanks for your help!
I like the idea of naming ranges proposed by #Doug, but if the issue is that you are dumping your data in [and you don't know in advance which column is going to be where] and would need to rename your range every time, there are other options - I suggest using OFFSET. OFFSET allows you to dynamically create a range, starting at a particular point and moving down/up / right/left for as many rows and columns as you determine.
In your case, you will need to combine that with a method for searching the columns to see which one says "Count". I am assuming that your column headings are always in row 1. If they aren't [or if they aren't always in row 2, or any row you know in advance]... you can get around that but then I'd recommend you try to make your data more uniform instead of creating unnecessary Excel workarounds.
In total your formula would look like this:
=SUM(OFFSET(A1,,MATCH("Count",1:1,0)-1,ROWS(A:A),1))
What this does is first determine which column the word "Count" is found in, in row 1. Then it subtracts 1 from that number - this now equals the number of columns to the right that it is, from column A. It uses offset to create a reference to that column, for all rows, and sums those rows together.
Check out the name manager for naming ranges :)
You didn't say whether you would consider a macro solution. If so, this may work.
If the sheet you are pasting into is Sheet2 and the sheet you want the result in is Sheet1, then this macro, if placed in the Worksheet_Activate event of Sheet1 will give you the result as soon as you click on the Sheet1 tab afetr pasting your data into Sheet2:
Private Sub Worksheet_Activate()
Dim r As Range
Dim rCol As Range
Dim rFound As Range
Dim ws As Worksheet
Dim lTotal As Long
Set ws = Sheet2
Set r = ws.Cells
Set rFound = r.Find("count")
If Not rFound Is Nothing Then
Set rCol = rFound.EntireColumn
lTotal = Application.WorksheetFunction.Sum(rCol)
End If
Cells(1, 1) = lTotal
End Sub
It does assume there is only one cell with the word "count" in it on Sheet2.
I'm trying to create a macro that will do the following:
Recognize my active cell(s) and select the entire table row(s) of
those cell(s). Cut all of those rows.
Paste them into another table on a different worksheet (at the end
of the table to add on to whatever is already there).
Return to the original worksheet and delete the now empty rows.
I have a decent understanding of VBA. I was able to select the entire row based on my active cell. But if I select multiple cells (eg, B4, B5, and B6), it would only select one row instead of all three. Additionally, I've been having trouble getting it to select only the Table Row, not the entire Row.
This is the first line of code I started out with. But it doesn't A: Select multiple rows or B: Select only the row cells of the table.
ActiveCell.EntireRow.Select
Any and all help would be greatly appreciated. Even just help on part of the above steps could help me.
Thank you!
Sub Tester()
Dim rng As Range
Set rng = Application.Intersect(Selection.EntireRow, _
Selection.Parent.ListObjects(1).Range)
If Not rng Is Nothing Then
'rng.Font.Color = RGB(255, 0, 0) 'do something with rng
End If
End Sub