VBA Nested Iferror in If function while looping - excel

I've only started using VBa and I keep getting an Expected: end of statement error.
I'm not sure what the issue is. I need the vba to loop an if statement with a vlookup and an iferror. I can't set the range because the list will be dynamic.
The more I try to fix the code myself the more messy it gets. I've scoured the internet for help.
Any and all help would be appreciated.
The formula is running on the MasterData tab and pulling from the DataDrop tab.
Sub COAB()
Dim i As Range
Set i = Sheets("MasterData").Range("D2")
Dim i2 As Range
Dim i3 As Range
Set i2 = Sheets("MasterData").Range("W2")
Set i3 = Sheets("MasterData").Range("X2")
Dim MasterData As Worksheet
Dim DataDrop As Worksheet
Set MasterData = ThisWorkbook.Sheets("MasterData")
Set DataDrop = ThisWorkbook.Sheets("DataDrop")
Do Until IsEmpty(i)
i2 = "=IFERROR(IF(VLOOKUP(" & MasterData.Range("D2").Address(0, 0) & ","
& DataDrop.Range("A:C") & ",3,FALSE)" <> "NULL" & ", & ""Charged Off"" & ","
& "Active "),"& Active")"
i3 = "=IFERROR(VLOOKUP(RC[-20],'DataDrop'!A:C,2,FALSE),0)"
Set i = i.Offset(1)
Set i2 = i2.Offset(1, 0)
Set i3 = i3.Offset(1, 0)
Loop
End Sub
The formula in one column should be =IFERROR(IF(VLOOKUP(D2,DataDrop!A:C,3,FALSE)<>"NULL","Charged Off","Active ")," Active")
And the other column should be =IFERROR(VLOOKUP(D2,DataDrop!A:C,2,FALSE),0)

No need for a loop, just get the last row based on Column D, and write the formulas to the entire range in question in one go. Also, quotation marks within formulas need to be doubled up.
Sub COAB()
With ThisWorkbook.Sheets("MasterData")
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
.Range(.Range("W2"), .Range("W" & lastRow)).Formula = _
"=IFERROR(IF(VLOOKUP(D2,DataDrop!A:C,3,FALSE)<>""NULL"",""Charged Off"",""Active ""),"" Active"")"
.Range(.Range("X2"), .Range("X" & lastRow)).Formula = _
"=IFERROR(VLOOKUP(D2,DataDrop!A:C,2,FALSE),0)"
End With
End Sub

Related

VBA macro concatenate 2 columns in new column

I want to create a macro that inserts new column with column name (BL & Container) and then concatinates 2 column in newly inserted column.
In this column I named BL & Container is a new column added my macro.
Further I want the macro to concatenate the values present in column H and F macro should find column H and F by column name and concatenate the them in to newly inserted column I.
My codes below
Sub insert_conc()
Dim ColHe As Range
Dim FindCol As Range
Dim con As String
Dim x As Long
Set FindCol = Range("1:1") 'Looks in entire first row.
Set ColHe = FindCol.Find(what:="BL/AWB/PRO", After:=Cells(1, 1))
With ActiveWorkbook.Worksheets("WE")
ColHe.Offset(0, 1).EntireColumn.Insert
ColHe.Offset(0, 1).Value = "WER"
'x = Range("A" & Rows.Count).End(xlUp).Row
con = "=H2&""-""&F2"
ColHe.Resize(x - 1).Formula = con
End With
Application.ScreenUpdating = True
End Sub
[![Error in code][3]][3]
In this code line " con = "=H2&""-""&F2"" please advise how do I update column nameinstead of H2 and F2 macro should find columna H2 and F2 header name and then concatinate the values in newly inserted column I BL & container. Please advise.
Please, use the next adapted code:
Sub insert_conc()
Dim sh As Worksheet, x As Long, ColHe As Range
Dim FindCol As Range, con As String, firstCell As Range
Set sh = Worksheets("LCL")
x = sh.Range("A" & sh.rows.count).End(xlUp).row
Set FindCol = sh.Range("1:1") 'Looks in entire first row.
Set ColHe = FindCol.Find(what:="BL/AWB/PRO", After:=sh.cells(1, 1))
ColHe.Offset(0, 1).EntireColumn.Insert
ColHe.Offset(0, 1).value = "BL & Container"
Set firstCell = ColHe.Offset(1, -2) ' determine the cell to replace F2
con = "=" & ColHe.Offset(1).Address(0, 0) & "&" & firstCell.Address(0, 0)
ColHe.Offset(1, 1).Resize(x - 1).Formula = con
End Sub
It is also good to know that using With ActiveWorkbook.Worksheets("LCL") makes sense only if you use it in the code lines up to End with. And your code did not do that... It should be used before, in order to deal with the appropriate sheet, even if it was not the active one.

If value matches from list, insert corresponding value below

Attempting to write some vba but not having much luck. I have column A with a whole list of values that I am counting and looping through. For Each value in column A, there can be a match in range C:D. If a value in column A matches a value in column C. I want to insert the corresponding value in column D below the Column A value. I am not too certain on what my IF then statement should look like. I have my counter and loop... I am just unsure where to go with the middle portion of the code.
Sub SetListOrder()
Dim wp As Worksheet
Dim ef As Long
Set wp = Workbooks("Packing Slip FIXED").Worksheets("Locate Order")
ef = wp.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To ef
IF (UNSURE WHAT TO PLACE HERE!) THEN
Next i:
End Sub
Edit: adding sample data
Sample Data screenshot
In this example, I would like to insert a new row under the value in "A" where A=C. ie. Range in column "A" = Range in Column "C". I would like to then insert the value from "D". The new order in rows 4-6 would be:
Range
Order Group 1
2604291
I already have written the code to manually move my sheets around to follow the specific order once I am able to get the names in said order.
I agree with #BigBen that the simpler approach would be to insert a formula in column D that only replicates the column A value when a match is detected. Such a formula would probably look like the following -
=IF($A1=$C1,$A1,"")
This would be copied into cell D2 of your column and copied down as far as needed.
However, if you did want to achieve this with VBA and I have noted you used the word insert a value (as opposed to simple enter a value or copy & paste a value) then this could be your approach -
Sub SetListOrder()
Dim wp As Worksheet
Dim ef As Long
Dim i As Long
Set wp = Workbooks("Packing Slip FIXED").Worksheets("Locate Order")
ef = wp.Range("A" & Rows.Count).End(xlUp).Row
For i = ef To 1 Step -1
If wp.Range("A" & i).Value = wp.Range("C" & i).Value Then
wp.Range("D" & (i + 1)).Insert xlShiftDown
wp.Range("D" & (i + 1)).Value = wp.Range("A" & i).Value
Else
End If
Next i
End Sub
This approaches the problem in reverse by going up your column instead of going down. Note that by inserting your data, will cause each previous value to move down as well. If you don't want this, then simply erase the .Insert line and it will enter the value instead of inserting a cell.
Modify the below code and use:
Formula:
=IFNA(VLOOKUP(A1,$C$1:$D$5,2,0),"Missing")
VBA Code:
Option Explicit
Sub test()
Dim rngSearch As Range, rngFound As Range
Dim LastRowA As Long, LastRowC As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRowA = .Cells(.Rows.Count, "A").End(xlUp).Row
LastRowC = .Cells(.Rows.Count, "C").End(xlUp).Row
Set rngSearch = .Range("C1:D" & LastRowC)
For i = 1 To LastRowA
Set rngFound = rngSearch.Find(.Range("A" & i).Value, LookIn:=xlValues, Lookat:=xlWhole)
If Not rngFound Is Nothing Then
.Range("B" & i).Value = .Range("D" & rngFound.Row).Value
Else
.Range("B" & i).Value = "Missing"
End If
Next i
End With
End Sub
Result:

VBA to Create Dynamic Named Ranges

I am trying to create named ranges of cells named after the top left cell in each range. This shows what I mean:
Here, I want to have 4 named ranges (Names A, Names B, Names C, Names D) so I can reference them. Is there a way to have excel look for any cell in Column B that starts with "Names" and have it cut off the range when it hits the next cell that starts with "Names"? I apologize if this is not possible, I am still new to excel and not sure if this is doable. Any help is appreciated!
This is a quick thrown together script to provide the idea of how to approach this. By no means is it pretty, but does show the steps. This can be a lot more complexly written, ie to work with all cells, not start after the first instance of names (See Range("B3") for start, and Range("B4") for starting the looping of cells)
Sub DefineRanges()
Dim rngStart As Range
Set rngStart = Range("B3")
Dim NamedRangeCount As Integer
NamedRangeCount = 0
Dim NameRangeName As String
Dim LastRow As Integer
For Each cell In Range("B4:B18")
If LCase(Left(cell.Value, 5)) = "names" Then
NameRangeName = "Name_" & NamedRangeCount
ActiveWorkbook.Names.Add Name:=NameRangeName, RefersToLocal:=Range(rngStart.Address & ":D" & cell.Row - 1)
Set rngStart = Range("B" & cell.Row)
NamedRangeCount = NamedRangeCount + 1
End If
LastRow = cell.Row
Next
NameRangeName = "Name_" & NamedRangeCount
ActiveWorkbook.Names.Add Name:=NameRangeName, RefersToLocal:=Range(rngStart.Address & ":D" & LastRow)
End Sub

Can i put a formula in an IF THEN Else statement?

In the linked table, I would like to populate column H with a formula. The formula to be used is dependent on the value in column F. Each day, the number of rows and the number of possible values in column F can change. I thought vba would be the best approach to set this up but I'm having trouble with the code. Would this even be the way to start the code?
Sub Macro4()
Dim lastRow As Long
lastRow = Range("H" & Rows.Count).End(xlUp).Row
Label = Range("F2") = "AUD/JPY"
I made up formulas for column H, but you should be able to apply this pattern with whatever formulas you need entered.
Sub Macro4()
Dim lastRow As Long
Dim xCell As Range
lastRow = Range("H" & Rows.Count).End(xlUp).Row
For Each xCell In Range(ActiveSheet.Range("F2"), ActiveSheet.Range("F2").End(xlDown))
Select Case xCell.Value
Case "AUD/JPY"
ActiveSheet.Cells(xCell.Row, "H").Formula = "=G" & xCell.Row & "/E" & xCell.Row
Case "AUD/USD"
ActiveSheet.Cells(xCell.Row, "H").Formula = "=2*G2"
'''Case etc... write other cases you need to handle
End Select
Next
End Sub

VBA Copy and Paste

So I have a VBA that is suppose to copy the on the "data" sheet and paste it on the "Internal Use" via searching a cell on cell in the "Internal Use" I'm not getting an error it is just not doing it and it after I run the macro it just stays on the "data" sheet.
What am I missing?
Sub CommandButton2_Click()
Worksheets("Internal Use").Activate
project = Range("C4")
Worksheets("data").Activate
nr = Range("A" & Rows.Count).End(xlUp).Row
For Row = 2 To nr
If Range("F" & Row) = Worksheets("Internal Use").Range("C4") Then
Range("Q" & Row) = Worksheets("Internal Use").Range("C7")
End If
Next Row
End Sub
Hard to tell what you're trying to do. Let me know if this is what you want.
Sub CommandButton2_Click()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim nr As Long
Dim project As Variant
Set ws1 = ThisWorkbook.WorkSheets("Internal Use")
Set ws2 = ThisWorkbook.WorkSheets("data")
project = ws1.Range("C4").Value2
With ws1
nr = .Range("A" & .Rows.Count).End(xlUp).Row
For r = 2 To nr
If .Range("F" & r) = project Then
ws2.Range("Q" & r) = .Range("C7")
End If
Next
End With
End Sub
Ricardo,
Your code is working fine. Question is what are you trying to accomplish? If you are trying to paste on 'Internal Use' sheet, you need to activate it. I have added a line to activate it. Please be more specific on what you want to accomplish.
Sub CommandButton2_Click()
Worksheets("Internal Use").Activate
project = Range("C4")
Worksheets("data").Activate
nr = Range("A" & Rows.Count).End(xlUp).Row
Worksheets("Internal Use").Activate
For Row = 2 To nr
If Range("F" & Row) = Worksheets("Internal Use").Range("C4") Then
Range("Q" & Row) = Worksheets("Internal Use").Range("C7")
End If
Next Row
End Sub
You want to populate column Q on the data sheet with the value from Worksheet Internal Use cell C7, whenever column F on the same row is equal to cell C4.
I have to say that that's easily solvable with a formula using index match or a conditional formula like =If(F2='Internal Use'!$C$4,'Internal Use'!$C$7,"") (Just paste in column F). At least this is what your code currently more or less does or seems to want to achieve.
That said let's take a look at your code:
First of all avoid .Activate, it's unnecessary overhead. This will activate the worksheet. (By the way, the last .activate you use, is on the data worksheet, hence it stays there) Next you store C4 in an undeclared variable called project that you never use.
Next you reference the cells everywhere in the loop again. This means there is huge overhead on accessing and reading out these cells. Lastly you do this in a loop; I assume this is to avoid filling up any of the other rows.
To make your code work, you could use:
Sub CommandButton2_Click()
Dim project as string
Dim writeValue as string
Dim lr as long
Dim wr as long
project = Worksheets("Internal Use").Range("C4").value
writeValue = Worksheets("data").Range("C7").value
lr = Range("A" & Rows.Count).End(xlUp).Row
With Worksheets("data")
For wr = 2 To lr
If .Range("F" & wr).value = project Then
.Range("Q" & rw).value = writeValue
End If
Next wr
End With
End Sub
This will do the trick.
Neater would be to avoid the for loop and testing all cells. Two options are putting the entire F and Q columns into arrays and loop through those simultaniously while altering the Q-array before dumping the values back in the sheet, or use a Find-algorithm such as Chip Pearons FindAll: http://www.cpearson.com/excel/findall.aspx

Resources