I am attempting to insert an IF formula using a macro and I can't seem to get the syntax correct. Trying to insert quotes has me confused, attempting to insert "" I have to use """"".
This is the IF function I need to insert
=IF(P14&Q14&R14<>"","<>","")
The macro creates a new row every time it is called, therefore the next formula inserted under it would be
=IF(P15&Q15&R15<>"","<>","")
I get the next empty row using
iRow = ws.Cells.Find(What:="*", SearchOrder:=xlRows,
_ SearchDirection:=xlPrevious, LookIn:=xlValues.Row + 1
Yet using this insert method and syntax I get a type mismatch error.
.Cells(iRow, 3).Value = "=IF(P" + iRow + "&Q" + iRow + "&R" + iRow + "<>"""""," + ""<>"",""""")"
Can someone please advise as to why I am receiving a type mismatch error?
Thanks for your help!
Firstly, do not use + for concatenation. Use &. In some particular cases, you may have problems.
Secondly, it is good to use .Formula instead of .Value...
And the formula string should be:
.Cells(iRow, 3).Formula = "=IF(P" & iRow & "&Q" & iRow & "&R" & iRow & "<>""""," & """<>"","""")"
Five """"" makes sense only at the end of the string... Four to double the existing one and the fifth for string termination.
You could use:
.Cells(iRow, 3).Value = Replace("=IF(PX&QX&RX<>"""",""<>"","""")", "X", iRow)
Related
I've just created a brand new macro. Took function down below from internet (all credits goes to trumpexcel.com), code down below
Function CONCATENATEMULTIPLE(Ref As Range, Separator As String) As String
Dim Cell As Range
Dim Result As String
For Each Cell In Ref
Result = Result & Cell.Value & Separator
Next Cell
CONCATENATEMULTIPLE = Left(Result, Len(Result) - 1)
End Function
Then I proceed to extract data from various columns and into the one (my table is 20 rows x 10 columns)
Sub conact_data()
Dim i As Integer
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Cells(i, "M").Value = Cells(i, "A").Value & " " & _
Cells(i, "B").Value & " / " & Cells(i, "D").Value & "; "
Next i
End Sub
Thanks to that I've got combined data from column A, B and D, so its 20 rows. All I want to do now is to concatenate data from M2:M21 using CONCATENATEMULTIPLE function therefore I try various approach (I want this huge line in P2 cell) like :
Cells(2, 16).Value = CONCATENATEMULTIPLE (M2:M21, " ")
or
Range("P2") = "CONCATENATEMULTIPLE (M2:M21, " ")"
I don't really know how to apply that
Secondly, I'd like withdraw the Cells(i, "B").Value as percentage. Can I do that in one line like Cells(i, "B").NumberFormat="0.00%".Value (which is not working for me obviously) else I need to copy column B into another column with number format and then combine the new column, properly formatted instead of column B?
Thanks in advance
Percent format: Range("B" & i).NumberFormat = "0.00%"
CONCATENATEMULTIPLE
In VBA, CHR(32) = " "
In Excel, CHAR(32) = " "
With that being said...
'Value
Range("P2").Value = CONCATENATEMULTIPLE(Range("M2:M21"), CHR(32))
'Formula
Range("P2").Formula = "=CONCATENATEMULTIPLE(M2:M21, CHAR(32))"
You should really qualify all of your ranges with a worksheet
Say your workbook has 10 sheets. When you say Range("P2"), how do we (VBE) know what sheet you mean? Objects need to be properly qualified. Sometimes this is not a huge issue, but when you are working across multiple sheets, not qualifying ranges can lead to some unexpected results.
You can qualify with a worksheet a few ways.
Directly: ThisWorkbook.Sheets("Sheet1").Range("P2").Copy
Or use a variable like so
Dim ws as Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("P2").Copy
Now there is no room for ambiguity (potential errors) as to the exact location of Range("P2")
First of all, remove your ConcatenateMultiple() code, and instead use Excel worksheet function CONCAT(), which takes a range and a delimiter as parameters.
Here is how you can handle the percentage issue and supply a default for non-numeric items. I've also cleaned up the way you reference your data range.
Sub concat_data()
Dim rngRow As Range, vResult As Variant
Const DEFAULT = 0 'Can also be set to a text value, eg. "Missing"
For Each rngRow In [A2].CurrentRegion.Rows
If IsNumeric(rngRow.Cells(, 4)) Then vResult = rngRow.Cells(, 4) * 100 & "%" Else vResult = DEFAULT
Range("M" & rngRow.Row) = rngRow.Cells(, 1) & rngRow.Cells(, 2) & "/" & vResult & ";"
Next
[M2].End(xlDown).Offset(1).Formula = "=CONCAT(M2:M" & [M2].End(xlDown).Row & ",TRUE,"" "")"
End Sub
I'm not a fan of hard-coding range references, like the [A2] or Range("M"), but will leave that for another time.
I have to calculate the difference between the values of 2 columns(firstCol and lastCol) and set those differences in a different column(NextColumn). The row count keeps changing, so I have to calculate the rowCount before calculating the difference. I'm trying to write a loop using Range so that the difference can be calculated but it doesn't seem to work.
For i = 3 To lastRow
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).FormulaR1C1 = "=Range(Cells(i, firstCol),Cells(i,firstCol)).Value - Range(Cells(i, lastCol),Cells(i,lastCol)).Value"
Next i
Any help would be greatly appreciated!
Thank you
Nick
For any input of "i" into the formula, you need to use " & i & " when using using a formula="", such as:
"=A" & i & "+B" & i
When you change to just a formula that doesn't input a formula to the cell (math happens in VBA), you can ignore the Excel formatting and "" blocking, such as:
= Cells(i,"A").Value + Cells(i,"B").Value
Make sure to use your loop variable where appropriate, so that you would have an outcome in a loop like:
Dim i as Long
For i = 1 to 10
Cells(i,"C").Formula = Cells(i,"A").Value + Cells(i,"B").Value
Next i
Why looping ? Unless I misunderstood the question, something like this should do the trick:
Range("X3:X"& lastrow).Formula = "=C3-D3"
The formula will adjust.
vba needs to be outside the quotes and you do not need the loop:
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).Formula = "=" & Cells(3, firstCol).Address(0, 0) & "-" & Cells(3, lastCol).Address(0, 0)
No loop needed. Excel will change the relative references as needed.
I am trying to copy some 8-digit numbers to use in a SQL search.
The SQL query gave me errors and after some debugging I found that the string doesn't contain all the data. It seems that after 25 or so numbers my for loop stops entering data as if the string is full.
Thanks for the help...
Lots = ""
For iRow = 2 To 500
If IsEmpty(Sheets("Filtered Data").Cells(iRow, 2)) Then Exit For
Lots = Lots & ",'" & Sheets("Filtered Data").Cells(iRow, 2).value & "'"
Next iRow
Lots = "(" & Mid(Lots, 2, Len(Lots) - 1) & ")"
you should post your data raising the errors
as for while you can consider the following code to build-up the string exploiting Join() function
Dim Lots As String
With Worksheets("Filtered Data") '<--| change "Filtered Data" with your actual worksheet name
With .Range("B2", .Cells(.Rows.Count, 2).End(xlUp)) '<-- consider its column "B" cells from row 2 down to last non empty one
Lots = "('" & Join(Application.Transpose(.Value), "','") & "')" '<-- build up the string
End With
End With
this assumes that all non empty cells in column "B" are contiguous (i.e. non blank cells in between non blank ones), but it can be easily modified should this not be the case
Your code works fine. Presumably you have an empty cell in the column which is making it exit the loop....
I have the following string "123 - 456789". What I am trying to do is find a way to only capture the remaining characters after the second space - "456789" - regardless the length of the string.
I have the follow set of code:
For leftLoop = 2 To leftNumberOfCells
Range("A" & iRow) = Split(Range("B" & iRow).Value, " ")
Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)
iRow = iRow + 1
Next leftLoop
The code line "Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)" is what I tried, among other ways (from searching online, but I can't seem to get it to work.
I have two questions:
Does someone know what the correct code should be? and...
Can I reference the cell where the string is located and replace it in that same cell after doing the mid function without having to temporarily put it into another cell and copy and paste it back? For example, my string "123 - 456789" is in cell B2, is there a way to code it so I can reference cell B2 and simultaneous replace the cell B2 with "456789" and not having to place it in another cell then copy and paste it back into B2. I hope you get what i'm asking.
Thanks for you help!
This addresses part 2.
Sub strings()
Dim replace As String
Dim bCell As Range
For leftLoop = 2 To leftNumberOfCells
Set bCell = Range("B" & iRow)
replace = Mid(bCell, InStr(bCell, "-") + 2, 100)
Range("B" & iRow) = replace
iRow = iRow + 1
Next leftLoop
End Sub
Try this:
result = Split(TextToSplit, " ", 3)(2)
Split(TextToSplit, " ", 3) will split the text on spaces, returning a zero-based array. The last argument 3 limits the splitting to 3 portions: before the first space, between the first and second space, and everything else. The (2) at the end of the statement returns the last element of the array.
Hope that helps
I am trying to select an entire row in a different sheet and then copy the row to the sheet I am currently in with a macro. The code works fine if the Rows() sub is passed integers hardcoded but when I put a variable I get the "Select method of Range class failed" error. here is the code I have:
Sheets("BOM").Select
Rows(copyFromRow & ":" & copyFromRow).Select
Selection.Copy
Sheets("Proposal").Select
Rows(copyToRow & ":" & copyToRow).Select
ActiveSheet.Paste
copyToRow = copyToRow + 1
Rows(copyToRow & ":" & copyToRow).Select
Application.CutCopyMode = False
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
if instead i used :
Rows("52:52").Select
Selection.Copy
it works fine, but when the variable is there, the error occurs.
Thanks
I just tested the code at the bottom and it prints 16384 twice (I'm on Excel 2010) and the first row gets selected. Your problem seems to be somewhere else.
Have you tried to get rid of the selects:
Sheets("BOM").Rows(copyFromRow).Copy
With Sheets("Proposal")
.Paste Destination:=.Rows(copyToRow)
copyToRow = copyToRow + 1
Application.CutCopyMode = False
.Rows(copyToRow).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
Test code to get convinced that the problem does not seem to be what you think it is.
Sub test()
Dim r
Dim i As Long
i = 1
r = Rows(i & ":" & i)
Debug.Print UBound(r, 2)
r = Rows(i)
Debug.Print UBound(r, 2)
Rows(i).Select
End Sub
I solved the problem for me by addressing also the worksheet first:
ws.rows(x & ":" & y).Select
without the reference to the worksheet (ws) I got an error.
Saw this answer on another site and it works for me as well!
Posted by Shawn on October 14, 2001 1:24 PM
var1 = 1
var2 = 5
Rows(var1 & ":" & var2).Select
That worked for me, looks like you just have to keep the variables outside the quotes and add the and statement (&)
-Shawn
The key is in the quotes around the colon and &, i.e. rows(variable & ":" & variable).select
Adapt this:
Rows(x & ":" & y).select
where x and y are your variables.
Some other examples that may help you understand
Rows(x & ":" & x).select
Or
Rows((x+1) & ":" (x*3)).select
Or
Rows((x+2) & ":" & (y-3)).select
Hopefully you get the idea.
You need to add quotes. VBA is translating
Rows(copyToRow & ":" & copyToRow).Select`
into
Rows(52:52).Select
Try changing
Rows(""" & copyToRow & ":" & copyToRow & """).Select
One needs to make sure the space between the variables and '&' sign.
Check the image. (Red one showing invalid commands)
The correct solution is
Dim copyToRow: copyToRow = 5
Rows(copyToRow & ":" & copyToRow).Select
mycell = ActiveCell
r = mycell.Row
c = mycell.Column
Range(Cells(r, c), Cells(r + 100, c)).Select