I'm trying to sum a variable range of data starting at row 3. sortedRow is the row # of the end of the data. lColumn is the last column used as a number.
I'm trying to sum the data in row 1, column H - lColumn.
I need to have the formula calculate the sum of column G, then iterating on referenced column by the current iteration (which will be columns h through x)
I've taken Scott Craner's advice and edited my code as
Dim lColumn As Long
lColumn = ActiveSheet.Cells(3, Columns.Count).End(xlToLeft).Column
sortedRow = Cells(Rows.Count, "D").End(xlUp).Row
Dim i As Integer 'iterated column sum cell
For i = 8 To lColumn
Cells(1, i).Value =Application.WorksheetFunction.SumIfs(Range(Cells(3,7),
Cells(sortedRow, 7)), Range(Cells(3, i), Cells(sortedRow, i)), 1)
Next i
The cells are not being updated with their values though.
It feels like I'm missing something really obvious with actually applying the number to the cell. I thought the above would do it.
added lColumn declaration because of issue with the formula being applied
added sortedRow declaration.
basically this. But with variable column lengths and number of columns.
It didn't matter for Column H that there was "#VALUE" in the volume column. So I assume it doesn't matter for the other columns.
Any help would be appreciated!
You have problems here.
("$G3:$G" & sortedRow, i & "3:" & i & sortedRow, 1)
("$G3:$G" & sortedRow & "," & i & "3:" & i & sortedRow, 1)
But you still have issues in there. If i=4 and sortedRow=12 let's say, this is what you would have.
(G3:G12,43:412, 1)
So you need to fix your Criteria_range1. I'm not clear from your question what you want the criteria to be.
Here is info on the arguments. https://msdn.microsoft.com/en-us/library/office/ff193011.aspx
The issue was resolved after fixing #VALUE cells in the sumifs columns I was trying to add. I made a conditional statement that set all errors to equal zero. This allowed the loop to function.
Related
Looking to automate the insertion of a VLOOKUP formula in a cell.
When recording the macro I instruct it to populate the columns below with the same formula. Works great, however, there is an issue when the table that the VLOOKUP searches through changes (more or less rows).
As it's recorded, the VLOOKUP drops down to the final row in the table (273). However, I want to set it up so that it will go down to the very last row. Meaning that I can run the script on tables of varying numbers of rows.
Selected columns will remain the same.
Range("AJ2").Select
ActiveCell.FormulaR1C1 = _
"=VLOOKUP(RC[-20], Previous!R2C2:R273C22,17,FALSE)"
try this:
With Worksheets("Previous")
Range("AJ2").FormulaR1C1 = _
"=VLOOKUP(RC[-20], Previous!R2C2:R" & .Cells(.Rows.Count, 2).End(xlUp).Row & "C22,17,FALSE)"
End With
where:
Range("AJ2")
will implicitly reference the ActiveSheet
.Cells(.Rows.Count, 2).End(xlUp).Row
will reference "Previous" worksheet, being inside a With Worksheets("Previous")- End With block
#nbayly said it, plenty of posts on this. Infact i have provided an answer to this before here:
How to Replace RC Formula Value with Variable
below is slightly modified for a dynamic range, which is what i believe you are looking for
For j = n To 10 Step -1
If Cells(j, 1).Value = "" Then
Cells(j, 1).Formula = "=VLookup(RC20,Previous!R2C2:R273C22,17,FALSE)"
End If
Next j
remember to define j as long and n=sheets("sheetname)".cells(rows.count,1).end(xlup).row
replace 10 in j = n to 10 with the starting row number
I'm trying to lookup an ID from column I, in column A.
Dim x As Long
lr = Worksheets("Risk Explorer greeks").Cells(Rows.Count, "I").End(xlUp).Row
Range("J2:J2" & lr).FormulaR1C1 = "=VLOOKUP(RC[-1], R1C1:R50000C1, 1, False)"
I have ~40,000 values in column J, however when I run this code it populates down to cell 237,000.
How can I look up column J where it has a value, and not lookup loads of blank cells?
Alternatively is there a faster way to do this lookup rather than the above formula?
You're appending the number 37000 to the string "J2:J2", which gives you "J2:J237000".
Replace Range("J2:J2" & lr) with Range("J2:J" & lr). You should be good to go.
I'm using INDEX and MATCH functions to pull data which is concatenated string of G2 and H2 from column D (sorry I don't have enough points to attach pic). Column D has INDEX(column A and column B) and columns A and B have values till 12th row. MATCH is working fine giving me the position as 6 on the worksheet. But when I use this in VBA code as shown below,INDEX is working in the VBA code (can be seen through MsgBox) but MATCH function which would allot value to the variable 'check' isn't working. I have been breaking my head for really long. Need help from experts here. Somebody please tell me where am I going wrong?
Sub testindex()
Dim check As Long
Set sh = Sheets("Sheet1")
For j = 1 To 11
'Index value is correctly shown
MsgBox "Index Value=" & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2)
'Cells(7, 4)=ISA737775 same as G2&H2
MsgBox "Cells(7,4)=" & Cells(7, 4)
check = Application.WorksheetFunction.Match(Cells(7, 4), Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2), 0)
Next j
End Sub
Thanks
Match expects the second paramater to be in the form of a range. When you call match through VBA that range actually needs to be a range object, not just some string like "A1:A12" or whatever it is that your concatenated Index formulas output.
At any rate, you are iterating already, so why not just call those values directly instead of pulling their values through Index?
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j), 0)
Which is writing the same exact thing but without having to use a taxing INDEX function in VBA to do it. Note that this still won't work because the second parameter of match is still just a string which is a concatenated value from Column A and Column B. You could convert to a range by sticking them in the range object with:
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range(sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j)), 0)
I'm assuming that the values in A and B are actual cell names that when concatenated will make a range. Like when j=1 then the it would be like check=Match(Cells(7,4), sh.Range("G2:H50"), 0) or something...
I writing a macro within which I need to autofill some rows with formulas, across multiple columns.
The number of columns is fixed, but each time the macro runs, the number of rows is variable. I use the "record macro" function and the current macro only ever fills my rows to row 16. Below is the code:
Range("D3:P3").Select
Selection.AutoFill Destination:=Range("D3:P16")
I obviously need to change the "P16" to something dynamic.
I have tried to use the following:
Dim LR As Long
LR = Range("D3:P3" & Rows.Count).End(xlUp).Row
Range("B3:P3").AutoFill Destination:=Range("B3:P" & LR)
I am unsure whether the "Dim LR as Long" has to be placed at the very beginning of my macro - or can it just be placed anywhere?
I am getting an error anyway with what i attempted above giving me an "autofill selectio error" (sorry i cant remember the exact error message.
Would someone be able to point me in the right direction?
LR can be declared anywhere before where you first use it, but it's best to do it at the beginning. Your range for LR is incorrect.
LR = Range("D3:P3" & Rows.Count).End(xlUp).Row
Should be
LR = Range("D3:P3").End(xlUp).Row
You should use xlDown if you are trying to find the end of a range BELOW D3:P3
LR = Range("D3:P3").End(xlDown).Row
Would give you the last row with data in all columns D:P in it below D3:P3
I think you're looking for this:
LR = Range("D3:P" & Rows.Count).End(xlUp).Row
but note that this finds the last row with any content in Column D - if there are later rows with content in Cols E-P but not in Col D then those rows will be ignored.
So I used the information provided to me and managed to get the following:
Dim LR As Long
LR = Range("C3:P" & Rows.Count).End(xlDown).Row
Range("D3:P3").AutoFill Destination:=Range("D3:P" & LR)
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$D$2:P" & LR), , xlYes).Name = _
"Table10"
This allowed me to count the number of rows that had already been populated in column "C", and then take the formulas that already existed in cells D3:P3 and autofill them down through the range until the last populated row of column C.
I then used that structure to make the whole range a table, in this case named "Table10".
Great stuff guys - your help allowed me to get exactly what I wanted. Thanks
I have a macro which inserts a number of rows depending on user input in Excel 2007. Everything works but I still have a minor issue. I want to copy the complete formatting from the row above. It only works for some cells in the row.
Here is the code for insertion:
Rows("B:B").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Is it possible to change it?
best, US
I am not sure exactly how you are inserting your rows, but if you insert the row below an existing one, it will by default take on the formatting of the row above it, at least it does when you use this type of syntax:
Range("B2").EntireRow.Offset(1, 0).Insert
In this example, it will insert a row below B2 and the format (say, B2's row is highlighted yellow) will be yellow as well. It might have to do with the fact that this type of inserting specifies exactly under which row to insert.
For those that don't want to inherit formatting from parent range use .cells().
.rows(2).insert will inherit formatting while .cells(2).insert will not.
The answer is the first comment.
New code:
Rows(CStr(InsRowNumber - 1) & ":" & CStr(InsRowNumber - 1)).Copy
Rows(CStr(InsRowNumber) & ":" & CStr(InsRowNumber)).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Dim j As Long, r As Range
j = InputBox("type the number of rows to be insered")
Set r = Range("A4")
Do
Range(r.Offset(1, 0), r.Offset(j, 0)).EntireRow.Insert
Set r = Cells(r.Row + j + 1, 1)
If r.Offset(1, 0) = "" Then Exit Do Loop