UPDATE:
Thank you for your help thus far! That definitely worked.
I am wondering though if there is a way to add a loop function as well. What i would like it to do is to reference Column A of Worksheet 888 to identify the same value in Column A of 999, and sum the values in the last column of the sheet (keeping in mind that the last column may differ, thus allowing the macro to be more dynamic).
Dim LastRow, LastColumn As Long
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
LastColumn = Worksheets("888").Cells(1,
Columns.Count).End(xlToLeft).Column
For x= 1 To LastRow
Cells(x, 2).Value =
WorksheetFunction.SumIf(Worksheets("888").Range("A:LastRow"),
Worksheets("999").Range("A:LastRow"),
Worksheets("888").Range("LastColumn:LastColumn"))
Next c
I keep getting the error "Unable to get the SumIf property of the worksheet function class. Any thoughts on how to fix?
i don't really understand why do you want to use macro when formula can do the job
put below in C2 and drag down the formula should do the job
=SUMIF(Sheet2!F:F,A2,Sheet2!H:H)+SUMIF(Sheet3!J:J,A2,Sheet3!L:L)
but if you insist macro,
Worksheets("Sheet1").Range("C2").Value = "=SUMIF(Sheet2!F:F,A2,Sheet2!H:H)+SUMIF(Sheet3!J:J,A2,Sheet3!L:L)"
Worksheets("Sheet1").Range("C2:C7").FillDown
Related
Need a little help here.
In the "Data" Tab I want to copy values in column "c2:c1000" and paste in column "a1" of another Tab.
This is what i have so far,
Dim x As Long
Dim lastRow As Long
lastRow = Worksheet("Data").Cells(3, Columns.Count).End(xlUp).Column
For x = 1 To lastRow
If Worksheets("Sheet2").Cells(2, "A") = "" Then
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Range(1, "A")
Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
Else
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Cells(2,
Columns.Count).End(xlToLeft).Offset(, 1)
'Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss") --> can't figure how to increment this as this will need to be on the subsequent empty column
End If
Next
End Sub
Your help will be greatly appreciated!
Thank you.
Pasting values first into range A1 and down and then next time to cell B1 and so on, leaves no space for the timestamp to A1, B1 etc. So, I assume that you would like to paste the random values to row 2. So cells A1, B1, ... are left for the timestamp.
Inside the With statements we can refer to properties of the wsAudit so we can replace the "Worksheets("Audit")." reference with just "."
The column.count expression just checks the amount of columns in the worksheet.
The expression .Cells(2, Columns.Count) just points to last cell in the row 2.
The .End(xlToLeft).Column then looks from this column to left and is supposed to find the last not empty cell on this row. It's basically the same idea that in Excel's sheet you would go to cell XDF2 and hit CTRL+Arrow Left from keyboard.
But instead of activating the cell we just want to get the columns index number and then add 1 (the new column) and save it into variable. Now the new column is known.
The expression Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value is really the same as e.g. Range("B2:B1000"), but with this we can use the row and column index numbers instead. This is useful as the column number varies.
And as Samuel pointed out the copy paste operation can be avoided by setting the areas equal.
Dim wsAudit As Worksheet
Dim newColAudit As Long
Set wsAudit = Worksheets("Audit")
With wsAudit
newColAudit = .Cells(2, Columns.Count).End(xlToLeft).Column + 1
Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value = Worksheets("Data").Range("C2:C1000").Value
.Cells(1, newColAudit).Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
End With
Much like your LastRow* variable for your source sheet, create a LastColumn variable for your destination sheet, which will find the last used column the same way you are finding your last used row.
Like so:
Dim LastColumn As Long
LastColumn = Sheets("Audit").Cells(1, Columns.Count).End(xlToLeft).Column
Then use the variable like so:
Destination:= Worksheets("Audit").Cells(1, LastColumn)
It seems that your code contradicts your question too, in your question you explained the data will be written to the Audit sheet in row 1, using the next column each time but your code looks for values in row 2 in your If statement:
If Worksheets("Audit").Cells(2, "A") = "" Then is the same as If Worksheets("Audit").Range("A2") = "" Then.
If you mean to check the first row, change the 2 to 1.
To help improve your codes efficiency:
(Also see the link to 'how to avoid select' in that question):
You can achieve 'copy/paste' without actually using the 'copy' and 'paste' methods by assigning the value of one range to the other, as example, like so:
Worksheets("Audit").Cells(1, LastColumn).Resize(999, 1) = Worksheets("Data").Range("c2:c1000").Value
Note: Change the Resize Property rows to suit the source range (in this case you are wanting to move values from C2:C1000).
*The LastRow variable is a bit confusing, as it is looking for the last used column in row 3.
If it's meant to find a column, consider renaming it to avoid confusion later on in debugging.
If it's meant to find the last row, try like this:
LastRow = Worksheet("Data").Cells(Rows.Count, 1).End(xlUp).Row
having a bit of a problem and not sure how possible this is. I'm trying to get the last row number (not count) in a column and then use that number in a formula. The reference would be in the SUMIF(R[5] and R[6] statements. I want to change the R to reflect whatever the last row is.
Here is what I have and while it returns the row number I need I can't figure out how to define or use it in the formula. I'm not sure if this is even the best way to do it.
Any help in the right direction would be greatly appreciated!
Sub test()
Dim lrow As Long
lrow = ActiveSheet.Cells(Rows.count, 2).End(xlUp).Offset(1, 0).Select
Selection.Value = ActiveCell.Row - 1
ActiveCell.FormulaR1C1 = "=if(RC[-6]="""",if(RC[-8]=R[-1]C[-8],R[-1]C,SUMIF(R[5]C[-8]:R[6]C[-8],RC[-8],R[5]C[-11]:R[6]C[-11])),"""")"
End Sub
EDIT:
So the idea is to get the formula to look at the column labeled RD/SFC and anything that matches, for example if in RD/SFC row match 6605 we then add everything in the columns Est FNL sales to the end of the row and same for the $Ret Cost column. Currently trying to do that through the formula and put it in Column O.
Hope that helps explain a little bit more
may this help:
'To get the last row with data in a given column
Public Function lastRowInOneColumn(ByVal ws As Worksheet, ByVal givenCol As Long) As Long
With ws
lastRowInOneColumn = .Cells(.Rows.count, givenCol).End(xlUp).Row
End With
End Function
I have a table with column A containing incrementing numerical values, and column B being a bunch of names. I need to filter the table according the names, and have column C update with the difference between the value in column A in the current row and the cell above..
For example, I'd like to have something like this
which,
when filtered according to the Name column, should update the difference like so
I have tried to use SUBTOTAL function in a few different ways but to no avail. Ideally it'd update once the filter in the table is changed. I tried to do this in VBA but so far I've gotten macro that only filters with the hard-coded filter criteria.
Solutions in either excel formulas/python/vba are all welcomed and greatly appreciated!
I apologise in advance if this question isn't up to standards as Im new here :) Thank you in advance!
#JvdV: This is the outcome of me trying to implement your formula, This is after filtering.
REVISED ANSWER
So after your explenation I have looked into a formula that will give you the difference of the current row B-value minus the B-value of occurance of the A-value before that.
=IFERROR(B2-LOOKUP(2,1/($A$1:A1=A2),$B$1:B2),0)
Taking your sample data, it would look like this:
Then when you apply the filter, it would look like this:
So with this workaround you dont have the correct value when no filter is applied, but in this case I assumed you are interested in the difference when it IS filtered!
The formula is entered in cell C2 and dragged down.
EDIT
If this is not the answer you'r after and you DO need the values when it is not filtered, make use of a UDF like below:
Public Function LastVisibleCell(CL As Range) As Long
Dim RW As Long, X As Long
RW = CL.Row - 1
On Error GoTo 1
If RW > 1 Then
For X = RW To 1 Step -1
If ActiveSheet.Rows(X).EntireRow.Hidden Then
Else
LastVisibleCell = Cells(CL.Row, 2).Value - Cells(X, 2).Value
Exit For
End If
Next X
Else
1: LastVisibleCell = 0
End If
End Function
Call it from cell C2 like: =LastVisibleCell(A2) and drag down. When you apply your filter, the cells will update.
Beware, this will take ages to update on large datasets!
After 3 days of intense (albeit ineffective) Google-ing, I finally came across this answer also on stack overflow.
However, as I'm working on a large set of data (>150,000 rows), the method in the question uses too much memory. Using VBA to paste the formulas into visible cells only does not seem to alleviate the problem.
Sub CopyPasteFormula()
Dim Ws As Worksheet
Dim LRow As Long
Dim PasteRng As Range
Set Ws = Worksheets("Translated Data")
Ws.Range("$D$2:$D$200000").AutoFilter Field:=4, Criteria1:="<>-", Operator:=xlFilterValues
LRow = Ws.Range("D" & Rows.Count).End(xlUp).Row
Set PasteRng = Ws.Range("A3:A" & LRow).SpecialCells(xlCellTypeVisible)
Ws.Range("A3").Copy
PasteRng.PasteSpecial xlPasteFormulas
Application.CutCopyMode = False
End Sub
Above is my macro code to attempt reduce the memory use... Appreciate any feedback!
Sorry if there is a basic answer to this but I've been stumped on this for a while. I have a pivot table which I want to show the detail of each cell in the second to last row between column D and the second to last column. The formula I wrote to do this isn't doing anything and I am not 100% sure why (I know I wrote it to do a different range just wanted to get something simpler working). It could be that there is a problem with me defining the last column or I could just be completely on the wrong page with this. Ideally each new page it would create would be named as the value of cell I2 on that page as well. Please find my code below and thanks for your help.
'Define LastColumn
LastColumn = sht.Cells(2, .Columns.Count).End(xlToLeft).Column
'Define last row
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
For i = "D" To LastColumn
Range(LastRow & i).Select
With Selection
Selection.ShowDetail = True
End With
Next i
I am attempting to select a dynamic range of filtered data that spans from col. A: col. J without selecting the header (in row 1). From there I need to copy and paste it into a new sheet where I will manipulate it further, but I cannot come up with an efficient or functional way to do this. Based on some code I found on another forum I was able to select all of the "visable cells" in a single column, but I am running into issues trying to select the whole range. I am still very new to vba so forgive my syntax, but my code posted below was an attempt to itterate through Rows.Count and i which was an integer 1-10. If you have any advice on how to do this better and more efficiently I would really appreciate it.
Sub SelectVisibleInColD()
Dim lRow As Long, i As Integer
Set i = 1
Do While i <= 10
With ActiveSheet
lRow = .Cells(.Rows.Count, i).End(xlUp).Row
If lRow < 3 Then Exit Sub
.Cells(1, 1).Offset(1, 0).Resize(lRow - 1).SpecialCells(xlCellTypeVisible).Select
End With
i = i + 1
Loop
End Sub
You can select a range by using Range property of ActiveSheet. You already have the last row and you know that the header is in the first row, so your range starts from position A2 and goes to the last row of column J
ActiveSheet.Range("A2:J"&lRow).SpecialCells(xlCellTypeVisible)
If you want to copy this range, use Copy function like
yourRangeAsAbove.Copy
This function only moves the selection to memory, to paste it, build your destination range and call PasteSpecial function.
I came across this answer googling my issue for: deleting of filtered selection in vba.
However trying your answer &lRow gives me an runtime error 1004, application-defineed or object-defined error
I got around it with this
ActiveSheet.Range("A2:G" & Range("A" & Rows.Count).End(xlUp).Row).SpecialCells(xlCellTypeVisible).Delete
For those that may also get the same issue.