How do I populate the same column using the text parameters from other columns? - excel

I'm creating a macro document that pulls information from several columns and places that information in assigned buckets in one specific column.
I made the first portion of the code work where it populated no recovery required into the selected column but I do not think it accurately populated the results and I cannot get the second if statement to run.
Sub DecisionTree()
Dim cell As Range
Dim Member_state As String
Dim NO_DR As String
NO_DR = "No Recovery Required"
Dim i As Integer
For i = 1 To 14000 'ActiveSheet.Rows.Count
If ActiveSheet.Cells(RowIndex:=i, ColumnIndex:="D").Value = "Arkansas" Then
ActiveSheet.Cells(RowIndex:=i, ColumnIndex:="K").Value = NO_DR
Else
If ActiveSheet.Cells(RowIndex:=i, ColumnIndex:="E").Value = 1 Then
ActiveSheet.Cells(RowIndex:=i, ColumnIndex:="K").Value = "One"
End If
End If
Next
End Sub
I would like answers for why my if statements are not properly calculating and how I can add other if statements to populate the same column

As far as I can see I only ajusted your code a bit and used ElseIf but your code should work. This is how you could escalate your criterias:
Option Explicit
Sub DecisionTree()
Dim cell As Range
Dim Member_state As String
Dim NO_DR As String
Dim ws As Worksheet 'Declare and use worksheet/workbook references
Set ws = ThisWorkbook.Sheets("SheetName") 'change this to the name of the worksheet you are working on
NO_DR = "No Recovery Required"
Dim i As Long, LastRow As Long 'always long, in case your data exceeds 32k rows and anyways working with 32bits will force it to long.
With ws 'this will allow you to use the reference without writting it
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'this calculate the last row with data, in this case on column A (1)
For i = 1 To LastRow
If .Cells(i, "D") = "Arkansas" Then 'You don't need to write rowindex and column index, just their values.
.Cells(i, "K") = NO_DR 'also, you don't need to specify .Value to change it's value
ElseIf .Cells(i, "E") = 1 Then 'You can use ElseIf statement instead using else, so you can use as many as you need
.Cells(i, "K") = "One"
ElseIf .Cells(i, "J") = "Cat" Then 'another statement
.Cells(i, "K") = "Cat"'Your code
End If
Next
End With
End Sub

It's throwing an error that the object range failed after changing some of the content and a type mismatch for "YES". ElseIf .Cells(i, "EP") = True Then 'You can use ElseIf statement (issue line)
Sub DecisionTree()
Dim cell As Range
Dim NO_DR As String
Dim YES As Boolean
Dim ws As Worksheet 'Declare and use worksheet/workbook references
YES = True
Set ws = ThisWorkbook.Sheets("Napa Data") 'change this to the name of the worksheet you are working on
NO_DR = "No Recovery Required"
Dim i As Long, LastRow As Long 'always long, in case your data exceeds 32k rows and anyways working with 32bits will force it to long.
With ws 'this will allow you to use the reference without writting it
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'this calculate the last row with data, in this case on column A (1)
For i = 1 To LastRow
If .Cells(i, "J") = "8-RTO No Recovery,RPO No Recovery" Then 'You don't need to write rowindex and column index, just their values.
.Cells(i, "FI") = NO_DR 'also, you don't need to specify .Value to change it's value
ElseIf .Cells(i, "EP") = True Then 'You can use ElseIf statement instead using else, so you can use as many as you need
.Cells(i, "J") = "Vendor"
ElseIf .Cells(i, "EF") = "Boulder" Or "Silver" Or "Nap" Or "Irma" Or "Budlign" Or "Sheffield" Then 'another statement I have to add an if statement consisting of like 6 factors
.Cells(i, "J") = "Enabled/Present" 'Your code
End If
Next
End With
End Sub

Related

Loops works, but causes program to freeze

I have this small piece of code.
Sub FillRemainingDates()
Dim SearchRange As Range
Set SearchRange = Sheets(1).UsedRange.Columns(11)
Dim cell As Range
For Each cell In SearchRange
If cell.Value = vbNullString And cell.Offset(0, 9).Value = cell.Offset(1, 9).Value Then
cell = cell.Offset(1, 0).Value
End If
Next
End Sub
Its goal is to attribute a value to a cell in a column depending on the value of a cell a row below:
The macro "works" in the sense that it does what I expect it to do, but whenever I run it it causes the program to become unresponsive and freeze for a long time.
I think I'm missing something in the loop and it's causing the program to fall into an infinite loop or have to deal with more data than necessary.
You should use an array to work on - and then write that back to the sheet.
Sub FillRemainingDates()
'ASSUMPTION: data start in column A
'>>> change the names according to your project
Const colNameOfColumn11 As Long = 11
Const colNameOfColumn20 As Long = 20
Dim arrSearch As Variant
arrSearch = Worksheets(1).UsedRange
Dim i As Long
Dim varValue As Variant '>>>> change type according to your values
For i = 1 To UBound(arrSearch, 1) - 1 ' don't check last row
varValue = arrSearch(i, colNameOfColumn11)
If varValue = vbNullString And _
arrSearch(i, colNameOfColumn20) = arrSearch(i + 1, colNameOfColumn20) Then
arrSearch(i, colNameOfColumn11) = arrSearch(i + 1, colNameOfColumn11)
End If
Next
Worksheets(1).UsedRange.Value = arrSearch
End Sub

VBA Index Match with a loop with two conditions

I hope that someone could help me with an index match formula that is made using a loop and storing the results data on the column.
Let's say that my data is following to make it simple:
We have an employee column and a salary column. I want to find all the salary options for HR employees.
I would like to store automatically all the results found on the column J (Researched input is in column I). And I want to finish the loop after not finding any new values.
Here is the data:
My initial code is down below without a loop to go down on the range:
Sub test()
Dim oCell As Range
Dim i As Long
i = 1
Do While Worksheets("Sheet1").Cells(i, 9).Value <> ""
Set oCell = Worksheets("Sheet1").Range("A:A").Find(What:=Worksheets("Sheet1").Cells(i, 9))
If Not oCell Is Nothing Then Worksheets("Sheet1").Cells(i, 10) = oCell.Offset(0, 1)
i = i + 1
Loop
End Sub
The problem stems from two main things:
The .Find range you are searching is the entire column A, which is then set to a .Range object (oCell). However, from my VBA understanding the .Find method cannot apply the cell address of each instance of the string/search parameter you are looking for. It will only apply the cell address of the first one it finds. To set a .Range object of non-contiguous rows you could use UNION function.
The .Find(What:= ... is set to a dynamic range which moves down column I as the loop continues. This means it will never find a match because it is searching the preceding column.
Here is a suggested solution, which hopefully you can adapt to your real world data:
Option Explicit
'
Sub test()
Dim oCell As Range
Dim i As Long
i = 1
Do While Worksheets("Sheet1").Cells(i, 2).Value <> ""
' Included as a sense check when stepping through your code to confirm loop is on correct cell
'Debug.Print Cells(i, 2).Address
'Debug.Print Cells(i, 2).Value
'Debug.Print "NEXT"
Set oCell = Worksheets("Sheet1").Range("A1:A10").Find(What:="HR")
If Not oCell Is Nothing Then Worksheets("Sheet1").Cells(i, 3) = oCell.Offset(0, 1)
i = i + 1
Loop
End Sub
Try this:
Option Explicit
Sub test()
Dim i As Long
Dim wb as Excel.Workbook
Dim ws as Excel.Worksheet
i = 2 ' we don't need the header
set wb = ActiveWorkBook
set ws = wb.Sheets("Sheet1") ' or wb.Sheets(1)
Do While ws.Cells(i, 1) <> ""
If ws.Cells(i,1) = "HR" then
ws.Cells(i, 3) = ws.Cells(i,2)
End If
i = i + 1
Loop
End Sub
Tested and found working

Looping for a value in a userform textbox

I was trying to write a basic loop that finds a unique value in a specific column in my worksheet. I believe that I have declared my variables properly. However, when I attempt to run my code, it gives me an overflow error. All I want is for my macro to be able to loop through my data set until it finds the specific ID Number.
Below is my Code for facilitated viewing:
Sub Macro1()
Dim FirstRow As Range
Dim LastRow As Range
Dim R As Long
FirstRow = Worksheets("Petrobras").Range("V2")
LastRow = Worksheets("Petrobras").Cells(Rows.Count, 22).End(xlUp).Select
R = TXTOPPNUM_Insert.Value
For R = FirstRow To LastRow
Worksheets("Petrobras").Cells(Rows.Count, 22).Find(R, , , Lookat:=xlWhole).Select
Next R
End Sub
Here is what may help:
Sub Macro1()
Dim FirstRow As Long
Dim LastRow As Long
Dim R As Long
Dim tempStore As New collection ' collection is initialized with .Count = 0
Dim uniqueValue As Variant
' is that needed?
'R = TXTOPPNUM_Insert.Value
With Worksheets("Petrobras")
FirstRow = .Cells(2, 22).row ' set first row
LastRow = .Cells(Rows.Count, 22).End(xlUp).row ' set last row
For R = FirstRow To LastRow ' there's an actual loop
If Application.WorksheetFunction.CountIf(range(.Cells(FirstRow, 22), .Cells(LastRow, 22)), .Cells(R, 22).Value) = 1 Then ' don't think that I have to explain how does the CountIf works
tempStore.Add .Cells(R, 22).Value ' if the CountIf of value = 1 then adding this value to a collection
End If
Next
If tempStore.Count > 1 Then ' if collection contains more that 1 value - means that there is not one unique value
MsgBox "There is more then 1 unique value"
Else
uniqueValue = tempStore(1) ' if collection contains 1 value - assign the unique value variable
End If
End With
End Sub
Also, look carefully to this article and this one.
To keep your code simple, you can use a one-liner that can be activated using a Button_Click on your userform; just add this line of code to the Button_Click macro. Type the value you are looking for into the textbox and click the button.
ThisWorkbook.Sheets("Petrobras").Range("V2", Range("V" & Rows.Count).End(xlUp)).Find(What:=Me.TXTOPPNUM_Insert.Value).Select

Type mismatch error with a if then statement

I am trying to write a If then statement that cant take out the rows on my worksheet that have been declined or void. So I am trying to get it to look into a Column then delete the rows with those values.
If Columns("K:K") = "Declined" Or "Void" Then
Selection.Delete Shift:=x1Up
End If
You'll instead need to loop through your range. One way to do it is:
Sub t()
Dim rng As Range, curCel As Range
Dim i As Long
Set rng = Range("K1:K100") ' Change as needed
For i = rng.Cells(rng.Rows.Count, 1).Row To rng.Cells(1, 1).Row Step -1
Set curCel = Cells(i, rng.column)
If curCel.Value = "Declined" or curCel.value = "Void" Then
curCel.EntireRow.Delete
End If
Next i
End Sub
you can loop through your cells and remove the rows. I would fully qualify your sheet and try to avoid using ActiveSheet. In the example below we are going from the bottom to the top so not to revisit cells twice or adjust the increment counter.
Dim i As Long
Dim iUsedRange As Long
iUsedRange = ActiveSheet.UsedRange.Rows.Count
For i = iUsedRange To 1 Step -1
If ActiveSheet.Cells(i, 11).Value = "Declined" Or ActiveSheet.Cells(i, 11).Value = "Void" Then
ActiveSheet.Cells(i, 11).EntireRow.Delete Shift:=xlUp
End If
Next i

Check if cell is text and if so, delete row

UPDATE:
Data set is made of strings that are number though (I don't get it) -> I can do all the math stuff with them as with regular numbers.
Problem is I need to separate cells that look like this "186.85" and cells that look like this "1.76 Dividend".
====================
I need a loop to check row by row if the cell contains some text (word "dividend" specifically) or if it's just number. If it is a text, then delete it and move to the next row.
It does some deleting BUT it wipes like 50 rows of data almost every time (I have only two text populated rows in this particular data set). These rows are numbers.
Dim i As Long
i = 2
Do
If WorksheetFunction.IsText(Sheets("Data").Cells(i, 5)) = True Then
If Not Worksheets("Data").Cells(i, 5).Value = "" Then
Worksheets("Data").Rows(i).Delete
End If
End If
i = i + 1
Loop Until i = 100
I expected to loop through the data and delete the entire row if a cell contains text.
This code so far deletes things kinda randomly.
The below has been updated to a dynamic range. This will not need modification regardless of how many rows your sheet has.
More importantly, deleting rows inside a loop will cause your range to shift at every deletion. The way around this is to loop backwards
OR, even better..
Don't delete cells inside your loop. Every time your criteria is met, you force an action (deletion). Instead, gather up all of the cells to be deleted inside your loop and then delete the entire collection (Union) all at once outside of the loop. This requires 1 action in total rather 1 action per text instance
Sub Looper()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1") '<-- Update sheet name
Dim i As Long, LR As Long
Dim DeleteMe As Range
LR = ws.Range("E" & ws.Rows.Count).End(xlUp).Row
For i = 2 To LR
If WorksheetFunction.IsText((ws.Range("E" & i))) Then
If Not DeleteMe Is Nothing Then
Set DeleteMe = Union(DeleteMe, ws.Range("E" & i))
Else
Set DeleteMe = ws.Range("E" & i)
End If
End If
Next i
If Not DeleteMe Is Nothing Then DeleteMe.EntireRow.Delete
End Sub
Try something like this:
Sub test()
Dim i As Long
For i = 100 To 2 Step -1
With ThisWorkbook.Worksheets("Data")
If WorksheetFunction.IsText(.Cells(i, 5)) = True Then
If Not .Cells(i, 5).Value = "" Then
.Rows(i).EntireRow.Delete
End If
End If
End With
Next i
End Sub
You can use SpecialCells with xlCellTypeConstants-2... No need for a loop. See Range.SpecialCells method (Excel) and XlSpecialCellsValue enumeration (Excel)
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
'~~> Change this to the relevant sheet
Set ws = Sheet1
With ws
On Error Resume Next
Set rng = .Columns(5).SpecialCells(xlCellTypeConstants, 2)
On Error GoTo 0
If Not rng Is Nothing Then rng.EntireRow.Delete
End With
End Sub
Thank you all for quick responses and effort.
I managed to get this solution working with InStr() function:
''loop through the Data and remove all rows containing text (Dividend payments which we don't need)
Dim i As Long
Dim ws As Worksheet
Dim searchText As String
Dim searchString As String
i = 2
Set ws = Sheets("Data")
Do Until ws.Cells(i, 2).Value = ""
searchText = "Dividend"
searchString = ws.Cells(i, 2).Value
If InStr(searchString, searchText) Then
ws.Rows(i).Delete
End If
i = i + 1
Loop

Resources