I'm running into a (run-time error '1004': Application-defined or object-defined error) error while trying to write my first Excel VBA Macro. I've looked at similar questions on stack overflow and other sites, but my issue seems to be more basic than issues others are having.
Currently, I'm trying to take the data from two cells from one sheet and write them to another sheet. I understand that trying to find the column or row of a cell that I reference by cell or row is unnecessary, but eventually I will use for-loops and will substitute the specific cell references with variables.
Here are the two lines of code that I have:
Worksheets("Sheet2").Range("A1").Value = Worksheets("Sheet1").Range("A" & Worksheets("Sheet1").Range("B2").Row).Value
Worksheets("Sheet2").Range("B1").Value = Worksheets("Sheet1").Range(Worksheets("Sheet1").Range("B2").Column & "1").Value
The first line runs fine. It writes Sheet1's A2 to Sheet2's A1.
The second line does not run, does not write Sheet1's B1 to Sheet2's B1, references the error, and I'm not sure why.
Thank you for your time and help!
The .Columns property returns an integer, not a letter. Use the Range.Cells property if you want to define a range with a numerical row and numerical column.
Worksheets("Sheet2").Range("B1").Value = Worksheets("Sheet1").Cells(1, Range("B2").Column).Value
I suppose there is a larger purpose to this but as it sits, it is very verbose code.
your last lines from your question say that you want to fill Sheet2-A1 with Sheet1-A2 and Sheet2-B1 with Sheet1-B1
the most straightforward way is
Worksheets("Sheet2").Range("A1") = Worksheets("Sheet1").Range("A2")
Worksheets("Sheet2").Range("B1") = Worksheets("Sheet1").Range("B1")
I am a beginner at VBA just like you. You don't need to know everthing in VBA to make productive use of it. I made my first macro by RECORDING it, and it worked (but was hopelessly inefficient).
I had a problem similar to yours: looking up data on another worksheet. I created the following function:
Function GetMyNumber(C3ll)
MyCol = C3ll.Column
GetMyNumber = MyCol
End Function
To use it in a spreadsheet, just enter the formula into some cell, like D5,
=GetMyNumber(D5)
When you recalculate, the number 4 appears in cell D5. If you copy cell D5 into Cell F3, you will see in F3, =GetMyNumber(F3), and calculate will return a 6. Of course you can fill down or across, the argument is changed to the cell the formula is in. And if you want, you can offset with an argument referring to any cell.
Once you get this working, you can insert the code to do you matching and other tasks that make use of your column number MyCol to extract the number from the other worksheet. Remember, MyCol is an integer.
Hopes this helps.
Related
I am stuck...
I have a 100 Row sheet with 10 Columns. This list is broken into classes simply by inline headers. I have definitions of the blocks of data under each head, for example:
UNASSOCIATED A2 A19
HOSTS A21 A32
ROOF A34 A100
I compute those ranges as they may change from time to time. I need
first: Define Name of each group by formula
Second: From time to time select the defined group
I am unable to get a formula to work which will allow me to use the "Content" of the cell as opposed to the cell location to define these ranges.
I'm stuck.
Suggestions would be appreciated.
Regards,
RHD
This cannot be done in a cell formula. You'll need to create a macro (VBA) to do this. Essentially, what you need is to grab the value of a cell then use that value as if it were a cell address.
Take a look at the example macro below. If cell A1 contains the characters "B22", then x will become the value of A1 (which is "B22") and "test" will be written to cell B22. This cannot be done in with cell formulas.
Sub test()
Dim x As String
x = Range("A1").Value
Range(x).Value = "test"
End Sub
A good amount of adaptation will been needed to incorporate this technique, and you'll need to play with this a bit. Ping this community to help answer more specific questions as they come up.
I would like to put the below coding into a vba like a function. There is a bunch of data created already by VBA, and when the VBA does its work, then the following function should be run, but i dont know how to add to my vba so that the function always runs as long as data contains. The macro i created already puts the datasheet together, now instead of creating the below with lenthy codings, i just want my macro to run the below, like a man who clicks on the below right hand corner of the cell which contains the below function.
It should be something: Activesheet.ForulaR1C1 = "=RIGHT(AY4,LEN(AY4)-FIND(".",AY4))" something. Can someone help me? Thanks
ORIGINAL FUNCTION TO BE RUN "=RIGHT(AY4,LEN(AY4)-FIND(".",AY4))"
This is where I am at now:
Sub Project_numbers()
Dim j As Integer
Zorro = Range("AY" & Rows.Count).End(xlUp).Row
o = 4
Worksheets("MJE").Range("AF" & o).FormulaR1C1 = "=RIGHT(AE4,LEN(AE4)-FIND(".",AE4))"
o = o + 1
End Sub
You have a couple of problems here. The biggest is that you've got quotation marks in your formula. VBA reads these as the end of the string, so it's interpreting your formula as two separate text strings: =Right(AE4,LEN(AE4)-FIND( and ,AE4)), separated by a .. This isn't a structure VBA can do anything with, so it's going to fail at that point.
When you're inserting a formula with VBA that contains quotation marks, you need to use two quotes together to indicate that it's a literal quote mark that's part of the string, rather than the end of the string:
"=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
The second problem is that you're using the FormulaR1C1 method, which expects cell references to be given in R1C1 (row#column#) notation, rather than A1 notation, but then passing it a formula that uses A1 notation. Again, this is going to confuse the issue and produce errors.
I'm guessing you used the macro recorder to get the syntax, then inserted your own formula? The macro recorder, for some weird reason, loves to use the R1C1 reference style, but we can use a different method for written code.
The full line you need is:
Worksheets("MJE").Range("AF" & o).Formula = "=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
EDITED TO ADD:
With further information, specifically that you need the range referenced to change as you loop, you have some options on how to do it.
1. Use the R1C1 reference style
This allows you to include relative references in formulae easily. You'll use R to designate the formula's row, and C to designate its column; so a cell that referred to itself would simply be =RC. You can follow the R and C with numbers to designate specific rows and columns, so cell B2 would be =R2C2 - row 2, column 2. More usefully, you can use =R[#]C[#] to offset your formula by a certain amount.
In your formula, assuming it's always going to be looking at column AE but whichever row the formula is entered into, your line would be:
Worksheets("MJE").Range("AF" & o).FormulaR1C1 = "=RIGHT(RC31,LEN(RC31)-Find(""."",RC31))"
2. Build your formula from variables.
You already have a variable you can use, o, so we can combine that with the rest of the string to get the appropriate references. It's harder to read, though...
Worksheets("MJE").Range("AF" & o).Formula = "=RIGHT(AE" & o & ",LEN(AE" & o & ") - FIND(""."",AE" & o & "))"
Personally, I find this method rather cumbersome to work with, but it's an option.
3. Assign the formula to your entire range as a single operation
Personally, I prefer this option; I find it to be the neatest one. I'm assuming, from your formula, that your data starts on row 4, and you want the formula to go into every cell between AE4 and the end of your data, which is stored in Zorro. You can use this line to add the formula in one go:
Worksheets("MJE").Range("AF4","AF" & Zorro).Formula = "=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
The cell references will update automatically for each row. There's no need for a loop with this method - of course, if you're looping anyway, that may be no great saving.
I want to select a value from one sheet and put it in a cell on a different sheet.
My script determines the proper value but I cannot get the value into the sheet.
This function returns the !Value error on the 6th line of the following excerpt:
Function PrintTest(Cell)
Dim iRow As Integer
Dim bs As Worksheet
Set bs = ThisWorkbook.Sheets("By System")
iRow = Cell.Row
bs.Cells(iRow, 6).Value = "Hello World"
End Function
I also tried using .Text.
Note: In the actual Script the text will be seeded from the other sheet and I have it stored in a variable. I am not looking for a way to get the same text into many different cells.
Update: Cell is passed from an Excel spreadsheet as an empty cell G4. Row is defined as 4. To call the functions I have been typing "=PrintTest(G4)" in my Excel worksheet named "By System" .
Update 2: Scott Holtzman answered the question in a comment. You cannot write to cells from a UDF called from within a cell. The fix was to call it from a button.
Set a cell value with Cells(Row, Col).Value="Some text"
If your sheet is active you do not need to fully qualify the address. If you activate the sheet you can just use Cells all of the time. If you have to retrieve data from a different sheet then you will have to qualify the address with the sheet name, i.e. Sheets("My Sheet").Cells(Row, Col).Value.
Also your code has Row=Cell.Row, but you are not saying what cell is active. In that case you are getting some arbitrary value. So that is where your error is, probably. Cell.Row=????? Also Row is an excel word. Use something like intRow for your variable. For example intRow=25. Cells(intRow, 6).Value="My Cell". If the cursor is on a cell you can say intRow=ActiveCell.Row.
When you have a problem such as this set a break point in your code (in your example, the Set statement). Thenm run your code. When it stops at the set statement you can hit F8 to step through one line at a time and examine your variables. Then you will see if Row is really a number or just garbage.
Hope that helps
I was trying to insert a formula directly into a cell and have it reference the cells around it based on where it is placed (R1C1). I turned on the record macro feature in excel and edited a cell with the desired formula and hit enter. Excel provided me with the following function. The odd part about this, is this is the exact formula excel gave me, and when I try to run the function, it errors out with a "run time error '1004': Application-defined or object defined error.
Background on the use: The function itself is just for a budget I am creating and it uses a cell two columns over to decide whether to continue numbering or to create a subset of the number above (TR is notation for total request, so anything that is not a TR, is a subset of the total request, and will be labeled the last known number & 'A', 'B', etc)
ActiveCell.FormulaR1C1 = _
"=IF(RC[2]=""TR"",IF(R[-1]C[2]<>""TR"",IF(R[-2]C[2]<>""TR"",IF(R[-3]C[2]<>""TR"",IF(R[-4]C[2]<>""TR"",IF(R[-5]C[2]<>""TR"",IF(R[-6]C[2]<>""TR"",IF(R[-7]C[2]<>""TR"",""add more"",R[-7]C+1),R[-6]C+1),R[-5]C+1),R[-4]C+1),R[-3]C+1),R[-2]C+1),R[-1]C+1), IF(R[-1]C[2]=""TR"",IF(RC[2]<>""TR"",R[-1]C&""A"",R[-1]C+1),IF(R[-2]C[2]=""TR"",R[-2]C&""B"",IF(R[-3]C[2]=""TR"",R[-3]C&" & "(R[-4]C[2]=""TR"",R[-4]C&""D"",IF(R[-5]C[2]=""TR"",R[-5]C&""E"",IF(R[-6]C[2]=""TR"",R[-6]C&""F"",IF(R[-7]C[2]=""TR"",R[-7]C&""G"",""""))))))))"
Any help on this will be appreciated,
thanks
Edit:
I'm at work, and I cant respond in line, so I decided to try here: Below is the recorded macro as is.
Sub Macro7()
'
' Macro7 Macro
'
'
ActiveCell.FormulaR1C1 = _
"=IF(RC[2]="""","""",IF(RC[2]=""TR"",IF(R[-1]C[2]<>""TR"",IF(R[-2]C[2]<>""TR"",IF(R[-3]C[2]<>""TR"",IF(R[-4]C[2]<>""TR"",IF(R[-5]C[2]<>""TR"",IF(R[-6]C[2]<>""TR"",IF(R[-7]C[2]<>""TR"",""add more"",R[-7]C+1),R[-6]C+1),R[-5]C+1),R[-4]C+1),R[-3]C+1),R[-2]C+1),R[-1]C+1), IF(R[-1]C[2]=""TR"",IF(RC[2]<>""TR"",R[-1]C&""A"",R[-1]C+1),IF(R[-2]C[2]=""TR"",R[-2]C&""B"",IF(R[-3]" & _
"R"",R[-3]C&""C"",IF(R[-4]C[2]=""TR"",R[-4]C&""D"",IF(R[-5]C[2]=""TR"",R[-5]C&""E"",IF(R[-6]C[2]=""TR"",R[-6]C&""F"",IF(R[-7]C[2]=""TR"",R[-7]C&""G"","""")))))))))"
Range("C121").Select
End Sub
This is the recorded macro from the record macro feature.
The formula was designed in excel, and i'm attempting to reuse it inside a macro. the reason I didn't try a select case or anything like that is because this formula was designed to dynamically change based the cells around it. So if i add a line above it and insert a new budget line (this is for a budget as referenced above), the lines below it will change accordingly.
edit:ex of what it looks like in excel:
You have an error in the formula, that's why VBA isn't adding the formula.
I've pulled out the formula and tried to put it in manually and excel throws a message saying there is an error.
With all the to and fro on possible errors in the formula, it's clearly too unwieldy to debug easily, so here's an alternative:
=COUNTIF(E$16:E128,"TR")&IF(E128="TR","",IF(E127="TR","A",CHAR(CODE(MID(C127,2,1))+1)))
or in R1C1 format
=COUNTIF(R16C[2]:RC[2],"TR")&IF(RC[2]="TR","",IF(R[-1]C[2]="TR","A",CHAR(CODE(MID(R[-1]C,2,1))+1)))
And VBA code to add it to the Active Cell
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R2C[2]:RC[2],""TR"")& _
IF(RC[2]=""TR"","""",IF(R[-1]C[2]=""TR"",""A"",CHAR(CODE(MID(R[-1]C,2,1))+1)))"
It has the added benifit of not being limited to 7 levels (well, in practice limited to 26 levels, after which it will append some odd characters)
Note: the first cell reference R2C[2] may need to be adjusted to match the starting row of your data, eg if the first rank is in row 128 change it to R128C[2]
How it works:
Count the number of TR's in the table down to this row.
If the Type column is TR, return this count
Otherwise, if the Type in the row above is TR, append A
Otherwise, get the character off the end of the Rank in the row above, increment it to the next character and append it
Note: If the first Type is not TR you will get unexpected results down to the first TR
I'm not sure if this is even possible without going to VB, but I was trying to do it through conditional formatting. Basically I have a column (Column K) that will always be the same value (345) if there is a record entered in that row. Basically when I populate my reports I simply want the value (345) to be entered into Column K if there is any data in that row. I was trying to just use Column A as a reference. I was messing with =IF(ISTEXT(Col.A location),"345","") but that's getting nowhere. So, I'm looking for ideas outside of vba, but if there are no possibilities then vba is the way to go I suppose. :)
Assuming your data is in columns A to J, and that it starts in row 2, enter this in K2 and copy down as necessary:
=IF(COUNTA(A2:J2),345,"")
Edit: For a conditional formatting formula you don't need the "If" part, because the formatting is already ... conditional:
=COUNTA(A2:J2)
Will this work?
=IF(ISBLANK(A1),"","345")
This code works to tell whether column A has something in it or not COUNTA(INDIRECT("$A$"&ROW()))>0, but I don't think you can set the value of the cell using conditional formatting. But with conditional formatting you have to know ahead of time how far down your data is going to go unless you just put it in all the rows.
Why don't you just put it in your VBA code when you are copying, you can find out what the last row is then put the IF() formula in. You can use this code:
Dim r1 As Range
Set r1 = Range("K1")
r1.NumberFormat = "General"
r1 = "=IF(COUNTA(INDIRECT(""$A$""&ROW())>0,""345"","""")"
r1.AutoFill Destination:=Range(r1, r1.Offset(200))