Background:
I have an array of 7 x 30 cells to loop through. For each of the 30 columns (Dim j), I am looping through rows (Dim i) 1 to see if a value is present and if so start copying the range of rows 2 through 7.
In attempting to use (e.g.):
Sheets("NAME").Range(Cells(i+1,1),Cells(i+7,1)).Copy
I am getting a 1004, Application-defined or object-defined error, that I have been able to alleviate using:
Sheets("NAME").Range("A" & i+1 & ":A" & i+7 & ").Copy
Error on line from my code:
Sheets("RM").Range(Cells(i + 6, 2), Cells(i + 13, 2)).Copy
Issue:
This has worked for items with known columns, but I am unsure how to proceed for a variable column, as well. I know that this doesn't work:
Sheets("NAME").Range(Cells(i+1,j),Cells(i+7,j)).Copy
I would need to find a way to fit this Range model without Cells to work for j, a variable column.
Question:
Is there a way to make this work using Range without using Cells?
My only guess is the following, which I believe uses incorrect syntax:
Sheets("NAME").Range(Columns(j) & i+1 & ":" & Columns(j) & i+1).Copy
Any help would be appreciated!
Edit: added the error 1004 name to this Issues section.
Try prefacing your Cells( call with the sheet i.e. Range(Sheets("Sheet1").Cells(1, 1), Sheets("Sheet1").Cells(2, 2))
When you omit the sheet in a call to Cells or Range then it will default to a reference to the currently selected sheet, so if you're calling Sheets(Unselected Sheet).Range(Cells(1, 1)) it gets confused between which sheet you're referring to.
Related
This question already has answers here:
Excel VBA, getting range from an inactive sheet
(3 answers)
Closed 7 years ago.
I am attempting to store the value of an 8 x 1 range into a range of identical dimensions, but on another sheet in the workbook. This would be easy except that my script is looping through different ranges of these same dimensions and I need to store them all on the second sheet. Currently my code looks like this:
Sheets("Sheet1").Range(Cells(i, 2), Cells(i + 7, 2)).Value = Sheets("Sheet2").Range("OriginalData").Value
Where "i" is the variable being used as the iterator in the loop.
This code throws an error "Error 1004 "Application-defined or Object-defined error"". Can someone explain what I'm doing wrong, and how to properly define range objects dynamically in this fashion?
Your problem is that the Cells inside the Sheets("Sheet1").Range don't know that they are supposed to belong to Sheets("Sheet1").
with Sheets("Sheet1")
.Range(.Cells(i, 2), .Cells(i + 7, 2)) = _
Sheets("Sheet2").Range("OriginalData").Value
end with
'alternate
Sheets("Sheet1").Range("B" & i).Resize(8, 1) = _
Sheets("Sheet2").Range("OriginalData").Value
The With ... End With statement allows you to definitively pass the parent worksheet into both .Range and .Cells with the prefix period (aka full stop).
Would a copy and paste work? I'm not sure of the specifics of your data but seems like a copy and paste would work better.
So like
Sheets("Sheet1").Range("x:x").Copy Sheets("Sheet2").Range("x:x")
I am using VBA to write formulas in an MS Excel sheet. When I copy the formula to the cell manually it works but when I use the line below it gives me a run-time error:
'1004': Application-defined or object-defined error.
ActiveSheet.Cells(Row + 3, Column + i).Formula = "=SUMPRODUCT(--(OFFSET(endResourceNaam;2;0):OFFSET(endResourceNaam;1000;0)=$A" & Row + 1 & ");--(OFFSET(endResourceNaam;2;4):OFFSET(endResourceNaam;1000;4)=$E" & Row + 1 & ");OFFSET(endResourceWeek;2;" & ColumnLetter(Column - 1) & "$1):OFFSET(endResourceWeek;1000;" & ColumnLetter(Column - 1) & "$1))"
The (first in loop) string generated is:
=SUMPRODUCT(--(OFFSET(endResourceNaam;2;0):OFFSET(endResourceNaam;1000;0)=$A6);--(OFFSET(endResourceNaam;2;4):OFFSET(endResourceNaam;1000;4)=$E6);OFFSET(endResourceWeek;2;O$1):OFFSET(endResourceWeek;1000;O$1))
I tested the formula by printing it from the VBA code and than copy/pasta that to the cell. That way I know for certain that the generated string is actually correct. From what I have learned there is some kind of protection build into VBA that makes sure that when I try to write a formula the formula is correct and working. There might be something in that protection that is keeping me from writing the formula to a cell.
Is there any solution for me to write the desired formula to a cell using VBA?
My bet is because it's an array formula, you should use the FormulaArray property.
ActiveSheet.Cells(Row + 3, Column + i).FormulaArray =
Jeeped gave the correct answer to my problem, replace the semi-colon list seperators with EN-US commas. Below actually works without a problem:
ActiveSheet.Cells(Row + 3, Column + i).Formula = "=SUMPRODUCT(--(OFFSET(endResourceNaam,2,0):OFFSET(endResourceNaam,1000,0)=$A" & Row + 1 & "),--(OFFSET(endResourceNaam,2,4):OFFSET(endResourceNaam,1000,4)=$E" & Row + 1 & "),OFFSET(endResourceWeek,2," & ColumnLetter(Column - 1) & "$1):OFFSET(endResourceWeek,1000," & ColumnLetter(Column - 1) & "$1))"
I have not tried the FormulaArray method since this already solved my problem.
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.
I'm trying to do "vlookup" with 2 different criteria(Column A and G values) using "Index" and "Match" functions.
and here is the line i used for the Excel command.
=INDEX(Database!A:KG,MATCH(1,(Database!A:A='TempSheet'!A2)*(Database!G:G='TempSheet'!G2),0),10)
How would I do it with VBA? It's keep giving me the error message "Compile error: Expected end of statement".
Selection= _
"=Index(DB.Range("A:KG"), Match(1, (DB.Range("A" = Temp.Range("A" & i).Value)) * (DB.Range("G" = Temp.Range("G" & i).Value)), 0), 10)"
Thanks
Every time you use a spreadsheet formula inside a VBA code, you need to precede it with <Excel.WorksheetFunction.> or <Application.WorksheetFunction.>.
For example:
Application.WorksheetFunction.Match
instead of Match only.
I have had little luck getting array formulas to work correctly via VBA, and use the 'IFERROR' as a workaround like so:
=IFERROR(VLOOKUP(A1, Database!A:Z,1,FALSE),VLOOKUP(B1, Database!A:Z,1,FALSE))
This function will attempt to match A1, and in case of a #VALUE error, it will match B1.
To get this kind of formula populated on a sheet in VBA, you can loop down your sheet using the '.formula' approach.
' get length of source data
Dim RowCount As Long
RowCount = ThisWorkbook.Sheets("Database").Cells(Rows.Count, 1).End(xlUp).Row
' now starting from row 2 to preserve headings
For i = 2 To RowCount
ThisWorkbook.Sheets("Summary").Cells(i, 1).Formula = "=IF(ISERROR(SEARCH(""ISO"",V" & i & ")),""Order type not supported"",""Transit"")"
ThisWorkbook.Sheets("Summary").Cells(i, 6).Formula = "=IFERROR(TEXT(VLOOKUP(B" & i & ",Database!A:N,7,FALSE),""dd-mmm-yyyy HH:MM AM/PM""),"""")"
Next
Not exactly what you were after, but hope it helps!
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...