Do Until Selection Value equals the For Each value - excel

I'm currently trying to use a Do Until within a For each but I'm having a problem. What I'm trying is to Do Until selection value equals the value selected for the For each section in the following code:
Private Sub Copiar()
Dim Eselect As Variant
Dim vItem As Variant
Dim Col As Integer
Eselect = Array(CBE1.Value, CBE2.Value, CBE3.Value, CBE4.Value, CBE5.Value)
For Each vItem In Eselect
Range("C2").Select
Do Until Selection.Value = vItem.Value
Selection.Offset(0, 1).Select
Loop
Col = ActiveCell.Column
Columns(Col).Copy
Sheets(2).Active
Range("A1").Select
If Range("A1") = "" Then
Columns(Col).Copy
Else
Do Until Selection.Value = ""
Offset.Selection(0, 1) = Selection.Value
Loop
Columns(Col).Copy
End If
Next
End Sub
The problem is specifically where is says "Do Until Selection.Value = vItem.Value" because I can't use vItem.Value and I don't know what I should use for to search until it find the value that For Each has selected. (I'm obviously just learning VBA).
The whole idea is for it to search a specific value (multiple times, one for each ComboBox Value: CBEi) in a row and return the column, then copy that column on another sheet.
Any help would be appreciated.
Vicente.

Related

Repeat the loop with variables (Row Lines) incrementing by 1

I'm pretty new to VBA and struggling with a loop.
I'm doing a report that copies certain cells from an excel sheet to a new one ("Report").
How do I manage to increment the variables by +1 so that it checks and copies cell B3,B4,B5... to B3,B4,B5... on the report sheet? (and so on...)
Appreciate your help, thank you!
Sub CopyRow()
'Return to Sheets("CS15 Download"), Find Last Row and LastRow = that row
Sheets("CS15").Select
Range("A8").Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 1).Range("A1").Select
Selection.End(xlUp).Select
LastRow = ActiveCell.Row
Dim ObjDes As Variant
Const Lvl As Integer = 1
ObjDes = Range("Q1").Value
'Variables to be copied
Dim ComNum As Integer
ComNum = Range("F3").Value
Dim Description As Variant
Description = Range("G3").Value
'Target Cells in Report Sheet
Dim ReportComNum As Integer
ReportComNum = Sheets("Report").Range("B2")
Dim ReportDescription As Variant
ReportDescription = Sheets("Report").Range("C2")
'Variables to Check
Dim Level As Variant
Level = Range("B3").Value
'Select the first Component Number
Range(ComNum).Select
'Do Until LastRow is reached
Do While ActiveCell.Row < LastRow + 1
'If the Level Is 1 Then
If Range("B3").Value = Lvl Then
'Copy the ComNum and Description into B2/C2 of Report Sheet
ReportComNum.Value = Range(ComNum).Value
ReportDescription.Value = Range(Description).Value
'Select Next Row
ActiveCell.Offset(1, 0).Range("A1").Select
'If Level is not 1, but the ObjDes starts with "BDS" Then
ElseIf Range("B3").Value > Lvl And InStr(1, ObjDes, "BDS") = 1 Then
'Copy the ComNum and Description into B2/C2 of Report Sheet
ReportComNum.Value = Range(ComNum).Value
ReportDescription.Value = Range(Description).Value
'Select Next Row
ActiveCell.Offset(1, 0).Range("A1").Select
'If not, go to next row
Else
ActiveCell.Offset(1, 0).Range("A1").Select
End If
Loop
End Sub
There are multiple ways to address worksheet cells in vba. It looks from your code that you were using the range object and it's addressing scheme of letter/number (i.e. B3,B4,B5...). That is valid and the range object is very powerful.
However, when working with individual cells and trying to write iterative code over a worksheet I find that the Cells(Row,Col) method is easier for me to use. It addresses all rows and columns with integer values and fits well into a for..next loop.
This code goes in the source worksheet object. It iterates over rows 3 to 5 and over column 2 (column B). Sets the same cell range in the "Report" worksheet with the current value plus 1. Changing the range of operation just requires change the values on the for statement. Those can even be parametrized and passed into the function. The Option Explicit forces the declaration of all variables.
Some good MS docs on addressing worksheet values
Hope that helps..
Option Explicit
Private Sub CopyIt()
Dim Row, Col
For Row = 3 To 5
For Col = 2 To 2
Sheets("Report").Cells(Row, Col) = Me.Cells(Row, Col) + 1
Next
Next

For Loop statement VBA Excel 2016

Proper syntax Match and If not isblank
I need some assistance with creating a loop statement that will determine the range start and end where a particular criteria is met.
I found these statements on the web and need help to modify them to loop thru two different worksheets to update a value on 1 of the worksheets.
This one has an issue returning True or False value for the Range when I want to pass the actual named range for look up where this field = Y, then returns the value from another column. I original tried using Match and If is not blank function. But that is very limiting.
See the previous post to see what I am trying to accomplish - I know I will need to expand the code samples and probably will need help with this modification.
Sub Test3()
Dim x As Integer
Dim nName As String
Sheets("BalanceSheet").Select
nName = Range("qryDifference[[Validate Adjustment]]").Select
Debug.PrintnName
' Set numrows = number of rows of data.
NumRows = Range(nName, Range(nName).End(xlDown)).Rows.Count
' Select cell a1.
' Establish "For" loop to loop "numrows" number of times.
For x = 1 To NumRows
' Insert your code here.
MsgBox"Value found in cell " & ActiveCell.Address
' Selects cell down 1 row from active cell.
ActiveCell.Offset(1, 0).Select
Next
End Sub
This is what I have so far - this is giving me and issue with
ActiveCell.Offset(4, 0).Select
nAgentNo = Range("qryDifference[[agtno]]").Value
nValidate = Range("ryDifference[[Difference]]").Value
Debug.Print nAgentNo
Debug.Print nValidate
Type mismatch error on the above.
Sub Revised_AgentAmount()
Dim myRange As Range
Dim i As Long, j As Long
Dim nAgentNo As String
Dim nValidate As Long
Sheets("BalanceSheet").Select
Set myRange = Range("qryDifference[[Validate Adjustment]]")
For i = 1 To myRange.Rows.Count
For j = 1 To myRange.Columns.Count
If myRange(i, j).Value = "Y" Then
ActiveCell.Offset(4, 0).Select
nAgentNo = Range("qryDifference[[agtno]]").Value
nValidate = Range("ryDifference[[Difference]]").Value
Debug.Print nAgentNo
Debug.Print nValidate
End If
Next j
Next i
End Sub
In your first statement you declare nName as a String then try to select it. You would need to declare it as a Range if you are going to use it as a Range object.
I found solution elsewhere with a if statement instead of the for loop.
=IF([#agtno]=B24,[#[agt_amt]],SUMPRODUCT((Balance!$B$2:$B$7=[#agtno])*(Balance!$F$2:$F$7="Y")*Balance!$E$2:$E$7)+[#[agt_amt]])

VBA: Detecting value in cell with dropdown list

I am having some trouble detecting the value in a cell with a dropdown list.
When I am running the below code, it only gives me the value 0 in column I. Column H contains a number of Dropdown lists (made by data validation), which value can either be Yes or No:
Sub DropDownlistValue()
Dim Holidays As Worksheet
Dim Checkbox_RowCount As Long
Dim HolidayCount As Long
Set Holidays = ThisWorkbook.Sheets("Visning")
Checkbox_RowCount = Holidays.Cells(Holidays.Rows.Count, "H").End(xlUp).Row
For HolidayCount = 2 To Checkbox_RowCount
If Not IsEmpty(Holidays.Range("H" & HolidayCount)) Then
Holidays.Activate
Holidays.Range("H" & HolidayCount).Select
If ActiveCell = "YES" Then
ActiveCell.Offset(0, 1) = 1
Else
ActiveCell.Offset(0, 1) = 0
End If
End If
Next HolidayCount
End Sub
Thanks in advance.
What you possibly need is the change in this line:
If ActiveCell = "YES" Then
into
If Ucase(ActiveCell) = "YES" Then
One more tip- move this line:
Holidays.Activate
before/outside your loop.

vba: Figure out if a changing range is blank

I have two spreadsheets, one contains programs and one projects. I use D loops to look at projects, within programs, within countries. I am trying to figure out if a set of cells for each project is blank. I have tried a few things. In the case below sustTrue should stay at 0 if rangeVar is blank for all the projects, but it does not. Please help!
Sub NO_Sheet()
Sheets("Program_FINAL").Select
Range("C2").Select ' C column is country
Dim IndicatorLineIterator
Do Until IsEmpty(ActiveCell) ' loop until country is blank
IndicatorLineIterator = 61
Dim PRGNum
PRGNum = ActiveCell.Offset(0, -2).Value ' Identify the program number
Sheets("Project_FINAL").Select
Range("A2").Select ' A column is the project number
Dim rangeVar, sustTrue
sustTrue = 0
Do Until IsEmpty(ActiveCell) ; loop until Project number is blank
If PRJNum = ActiveCell.Value Then
'rangeVar = ("O" & ActiveCell.Row & ":S" & ActiveCell.Row)
rangeVar = Range(ActiveCell.Offset(0, 14) & ":" & ActiveCell.Offset(0, 17))
If Not IsEmpty(rangeVar) Then
sustTrue = sustTrue + 1
MsgBox (sustTrue)
End If
End If
ActiveCell.Offset(1, 0).Select
Loop
End If
'Sheets(SheetADPName).Range("M16").Value = sustTrue
Sheets("Program_FINAL").Select
ActiveCell.Offset(1, 0).Select
Loop
End Sub
I kept working on it and the following worked for me. There is probably a more streamlined way to do this, but this works!
If Not ActiveCell.Offset(0, 14) = "" Or Not ActiveCell.Offset(0, 15) = "" Or Not ActiveCell.Offset(0, 16) = "" Or Not ActiveCell.Offset(0, 17) = "" Then
sustTrue = sustTrue + 1
MsgBox (sustTrue)
End If
Your rangeVar is not a range object.
Strongly type your variables:
Dim rangeVar as Range
Dim sustTrue as Long 'Or As Integer
Dim cl as Range
Then use the Set keyword to assign object variables and instead of concatenating, we can just list the two cells separated by a comma, and this will create the range:
Set rangeVar = Range(ActiveCell.Offset(0, 14), ActiveCell.Offset(0, 17))
Further, you can't reliably use the IsEmpty on a range array, only a single cell or other simple data type. You can get around this by iterating the range:
For each cl in rangeVar.Cells
If Not IsEmpty(cl.Value) Then
sustTrue = sustTrue + 1
End If
Next
MsgBox (sustTrue)
The IsEmpty function may not be a foolproof way to do this check. But the rest of the logic above should help. Let me know if you have trouble with the IsEmpty part.
Another alternative would be to simply subtract the number of blanks from the total number of cells in that range (again, may not be 100% reliable if the cells aren't "truly" blank...)...
sustTrue = rangeVar.Cells.Count - rangeVar.SpecialCells(xlCellTypeBlanks).Cells.Count
RangeVar is a range object. You would need to do Isempty(RangeVar.Value)
I think this has been answered already here: Using VBA to check if below cell is empty

How do I reference a cell in Excel through a variable and access all its properties in Visual Basic?

I am working on a Macro in Excel that needs to iterate through an entire column and find clusters of non-zero data, add up the data and store the result near the mentioned cluster. Then it continues down the column looking for other clusters and doing the same thing.
That being said, I am trying to store a reference to the "target" cell (where the addition of the cluster will be stored) in a variable, and then using that variable to access the "value" property of the cell so that I can make changes to it.
Here's the code:
Sub addNonZeroes()
Dim targetCell
' Select cell E5, *first line of data*.
Range("E5").Select
' Set Do loop to stop when an empty cell is reached.
Do Until IsEmpty(ActiveCell)
If ActiveCell.Value <> 0 Then
targetCell = ActiveCell.Offset(1, 0)
Do Until ActiveCell.Value = 0
'ERROR OCCURS HERE
targetCell.Value = ActiveCell.Value + targetCell.Value
ActiveCell.Offset(0, 1).Select
Loop
End If
' Step down 1 row from present location.
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Source of the code error
The error occur because your targetCell is not really defined.
You should:
define your variable and type it
use the Set keyword to assign an object
Here is your code adapted:
Sub addNonZeroes()
Dim targetCell As Range
' Select cell E5, *first line of data*.
Range("E5").Select
' Set Do loop to stop when an empty cell is reached.
Do Until IsEmpty(ActiveCell)
If ActiveCell.Value <> 0 Then
Set targetCell = ActiveCell.Offset(1, 0)
Do Until ActiveCell.Value = 0
'ERROR OCCURS HERE
targetCell.Value = ActiveCell.Value + targetCell.Value
ActiveCell.Offset(0, 1).Select
Loop
End If
' Step down 1 row from present location.
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Using Select and Offset is a bad idea
Yet, you should consider not using Select and Offset because this is very slow.
A better way would be this kind of loop:
Dim c As Range
For Each c in Range("E5:E100")
If c.Value <> 0 Then
'do whatever
End If
Next c
Using range to array is a very VBA way
Note that you can use a Variant to store every value of a range into an array, something like this:
Dim arr As Variant, i As Integer
arr = Range("E5:E100").Value
For i = LBound(arr , 2) To UBound(arr , 2)
'check for any empty value
Next i
See this thread for more examples: Array from Range in Excel VBA

Resources