would like to ask if there is a way to disregard 0 value when comparing?
to be specific i need to compare a value greater than zero if they are equal..and if so, a msgbox "" will appear ... to be honest i am not knowledgeable so i just used if statement... and need to compare 7 cells... i have to redundantly use if then statement for ever possible 0 and non zero combinations. (which ofc. alot)
example all zeroes will be neglected, if for instance cellA = 2 and CellB = 0 and CellC = 2 then it will show a msgbox because cellA an cellC is > 0 and have the same value(which is correct). but when i turned cellA = 0 and CellB = 0 and Cell3 = 0 ...it still showing a msgbox.. i was hoping that when all the cells turned 0 it will neglect the condition "if A = B, B = C then appear msgbox" but will consider the condition if it is > 0.
Advance thanks
This will do it:
Option Explicit
Sub msgBx()
'Set some vars
Dim sourceArr, dict As Object, j As Long, i As Long
'get data in memory = array
sourceArr = Sheet1.Range("A1:A7").Value2
'build a dict to compare quickly
Set dict = CreateObject("Scripting.Dictionary") 'create dictionary lateB
For j = 1 To UBound(sourceArr, 2) 'traverse source
dict(sourceArr(1, j)) = Empty
Next j
'check if key exists in dict and copy data
For j = 1 To UBound(sourceArr)
For i = 1 To UBound(sourceArr, 2)
If sourceArr(j, i) <> 0 And dict.Exists(sourceArr(j, i)) Then
MsgBox "gotya"
End If
Next i
Next j
End Sub
Related
I have a macro with counter for unique values that met specific conditions. As you can see on the image, I have list of unique values in column F. Macro checks, if value is listed in column AE (can contain duplicated lines) and checks if there is no "OB" in column AH. Then returns how many values it found in cell K2. But I need this counter to also list these values in column AD, but I am struggling to make it happen. I checked many forums and managed to crash Excel twice already. Any ideas how to achieve it?
Dim myTbl As range, mStr As String, Miss As Long, xCol As Variant
Set myTbl = Sheets("OB").range("AE2") '
xCol = "AH"
mStr = ""
Set myTbl = range(myTbl, myTbl.End(xlDown).Offset(0, 1))
xCol = Cells(1, xCol).Column - myTbl.Cells(1, 1).Column + 1
For i = 1 To myTbl.Rows.count
If myTbl.Cells(i, 1) <> "" Then
If myTbl.Cells(i, xCol) <> "OB" And InStr(1, mStr, "##" & myTbl.Cells(i, 1), vbTextCompare) = 0 Then
mStr = mStr & "##" & myTbl.Cells(i, 1)
Miss = Miss + 1
End If
End If
Next i
If Miss > 0 Then
range("K2") = Miss & " still active"
range("K2").Font.ColorIndex = 46
Else
range("K2") = "None"
range("K2").Font.ColorIndex = 10
End If
Please, test the next code. It, also, is able to return how many occurrences per each Value x have been found (if more than one per each exist):
Sub ExtractUniqueCondValues()
Dim sh As Worksheet, lastR As Long, arr, i As Long, dict As Object
Set sh = Sheets("OB")
lastR = sh.Range("AE" & sh.rows.count).End(xlUp).row
arr = sh.Range("AE2:AH" & lastR).Value
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(arr)
If arr(i, 4) <> "OB" Then dict(arr(i, 1)) = dict(arr(i, 1)) + 1
Next i
sh.Range("K2").Value = dict.count
sh.Range("AD2").Resize(dict.count, 1).Value = Application.Transpose(dict.Keys)
End Sub
About occurrences per each 'Value x' element, it can return in an adiacent column 'Value 2| 1 andValue 4` | 2, for your picture case... Of course, if it may have relevance for your purpose. The dictionary already keeps this data.
Maybe using formulas is an option for you? See column G where the formula in G2 is the following and copied down.
=IF(COUNTIFS(AE:AE,F2,AH:AH,"<>OB")>0,F2,"")
Using Count or Countifs may be an option instead of VBA.
I am working on an excel problem that I feel will have to be based off duplicates. Basically if duplicate values are found ("A:A") then somehow group them as a variable and only populate the matching rows if atleast 1 negative number exists in ("B:B"). The same will apply to non duplicates as well where they should only populate if a negative number exists in Column B but I feel that can be done easily via formula
I have tried a few things but the main problem is identifying the duplicates as their own variable. When I create a function that behaves purely off highlighted duplicates,this would apply to all duplicates regardless of their individual text. This would be much simpler if summed but that is not the case. Below is an example of what I am going for
Problem:
IDs Trades
US9128 -500
US9128 750
EU9133 900
GD2104 -300
GD2104 150
FG5454 200
Expected:
IDs Trades
US9128 -500
US9128 750
GD2104 -300
GD2104 150
Open to other routes to this problem
Suppose your data is in column(A:B),Starting form row(1)
Try this Macro
Option Explicit
Sub test_me()
Dim obj As Object
Dim x, k%
Dim R%, C%
R = 2: C = 4
Dim lr%: lr = Cells(Rows.Count, 1).End(3).Row
Dim i%, j%
Range("d2").CurrentRegion.ClearContents
Set obj = CreateObject("System.Collections.SortedList")
For i = 2 To lr
obj.Add Cells(i, 2).Value, Cells(i, 1).Value
For j = i + 1 To lr
If Cells(j, 1) = Cells(i, 1) Then
obj.Add Cells(j, 2).Value, Cells(j, 1).Value
End If
Next j
x = obj.Count
If x = 1 Then GoTo NEXT_I
With Cells(R, C)
.Value = obj.GetByIndex(0): .Offset(, 1) = obj.Getkey(0)
.Offset(1) = obj.GetByIndex(x - 1): .Offset(1, 1) = obj.Getkey(x - 1)
End With
R = R + 2
NEXT_I:
obj.Clear
Next i
Set obj = Nothing
End Sub
I have a code that searches an excel fill for the word distance, takes the value of the cell next to it, paste it into a new cell, then sums all the cells up. Which works great, but i now need to find a way to only sum ever even row number. Does that make sense?
Sub Distance_Check()
Dim DistanceCheck As String
Dim DistanceNumber As String
Dim DistanceSum As String
Dim DistanceTotal As String
DistanceCheck = MsgBox("Would you like to check the distance?", vbYesNo)
If DistanceCheck = vbYes Then
If IsArray(fname) Then Workbooks.OpenText fname(1)
i = 1
findStr = "Distance"
Set foundCel = Range("A:A").Find(what:=findStr)
If Not foundCel Is Nothing Then
firstAddress = foundCel.Address
Do
Range("J" & i).Value = foundCel.Offset(0, 1).Value
Set foundCel = Range("A:A").FindNext(foundCel)
i = i + 1
Loop While Not foundCel Is Nothing And foundCel.Address <> firstAddress
End If
Set wkbSourceBook = ActiveWorkbook
DistanceNumber = i - 2
DistanceSum = WorksheetFunction.Sum(Range(Cells(2, 15), (Cells(DistanceNumber + 1, 15))))
DistanceTotal = DistanceSum / DistanceNumber
If DistanceNumber = Cells(2, 12) Then
MsgBox ("No error found wihin distance")
Else
MsgBox ("Error found with distance")
End If
Else
End If
Call Save_Data
End Sub
Would the way youd go about this be using a for loop on the
cells(DistanceNumber(j,+1)
Where j = 0,
j = j +2 ,
Until j > DistanceNumber,
Would that work? If so how would you go about it?
Thanks
A quick way to step through a loop in the desired increments is to use the Mod operator which divides two numbers and returns any remainder (e.g. 7 mod 2 = 1, as two sixes fit into seven, leaving one).
You can use the row property of the range you identify with the Find method, and since you want to jump by two the modulo should be zero:
If foundcel.Row Mod 2 = 0 Then Range("J" & i).value = foundcel.Offset(0, 1).Value
That said, there is a 'built in' way to step through a loop if using a For loop like this
For x = 2 to 10 Step 2
' Do stuff
Next x
You can also use this method to step backwards, e.g.
For x = 100 to 0 Step -10
' Do stuff backwards!
Next x
I need to find the average of a number found in column F if a particular value is found in any of the other columns in the sheet.
For instance: I have the following in a range...
A B C D E F
Red Bill Jack Ruby Bill 250
Blue Ruby Ivan Raul Ted 350
Green Ted James Rick Ted 125
Red Ted Phil Ruby Bill 300
And in this worksheet, I want to find any instance of the name Bill and get the average of the number found in column F. In this case, the answer of 275 because Bill's name shows up in two rows. In the same respect, If I choose to look at Ted's numbers, the answer should be 258 because Ted's name shows up in three rows.
I would also appreciate if the formula would ignore any blank cells in the process of calculating the answer.
Thanks in advance!
I would use the function below, assuming that the data is placed in Sheet1.
Function my_average(strName As String) As Variant
Dim varArrayNames As Variant
Dim varValues As Variant
Dim dblInSum(1 To 4) As Double '~~> change to "1 To 40"
Dim lngCnt As Long
Dim strRow As String
Dim dblSum As Double
varArrayNames = Sheet1.Range("B1:E4").Value '~~> change to "B1:G40"
varValues = Sheet1.Range("F1:F4").Value '~~> change to "H1:H40"
For lngCnt = LBound(varArrayNames, 1) To UBound(varArrayNames, 1)
strRow = Join(WorksheetFunction.Index(varArrayNames, lngCnt, 0))
If InStr(strRow, strName) > 0 Then
dblInSum(lngCnt) = 1
End If
Next lngCnt
dblSum = WorksheetFunction.Sum(dblInSum)
If dblSum > 0 Then
my_average = WorksheetFunction.SumProduct(dblInSum, Application.Transpose(varValues)) / dblSum
Else
my_average = 0
End If
End Function
Testing:
Place =my_average("Bill") in any workbook (or a cell reference instead of "Bill").
Formulas:
Results:
Assuming the lookup value (Bill etc) is in cell C7, add the following formula in G1 then copy down for other rows.
=IF(ISERROR(MATCH($C$7,A1:E1,0)),"",F1)
Then do
=AVERAGE(G1:G4)
So if Bill is in any col a-e that number is taking into the ave... If so depending on your data size why not do this simply...:
Sub simplesearch()
cnt = 0
tot = 0
srchval = InputBox("What are we looking for?")
lr = Range("A1000000").End(xlUp).Row
For i = 1 To lr
For j = 1 To 5
If Cells(i, j).Value = srchval Then
tot = tot + Cells(i, 6).Value
cnt = cnt + 1
End If
Next j
Next i
If Not (cnt = 0) Then
MsgBox (tot / cnt)
Else
MsgBox ("0")
End If
End Sub
so Ive got programming knowledge but i need help with excel
i need to create a macro that checks for a specific value in a cell (e.g. begins with "01A") and if it finds it to check the cell underneath it for the same value. It should keep doing that until the value changes. I would also like it to calculate how many times it found that specific value (counta())
here is an example i would use if i were to do something similar in c
if (value = 01a){
amount ++
value + 1
}
any help is greatly appreciated
If you need to search only the first occurrance in a range, use:
Public Function FoundRec(Str As String, x As Range) As Integer
Application.Volatile
Dim i As Integer
Set c = x.Find(Str, after:=x.Item(x.Rows.Count), LookIn:=xlValues)
If c Is Nothing Then
FoundRec = 0
Exit Function
End If
For i = 1 To 9999
If c.Offset(i, 0).Value <> c.Value Then Exit For
Next
FoundRec = i
End Function
This function search the string Str in the range x :
=FoundRec("01A";A2:A16)
Return 0 if don't found.
If you need to search in the other occurrance, you can use:
Public Function FoundRecR(Str As String, x As Range, StartR As Integer) As Single
Application.Volatile
Dim i, e As Integer
Dim xx As Range
Set xx = x.Item(1)
For e = 1 To StartR
If e = 1 Then
Set c = x.Find(Str, after:=x.Item(x.Rows.Count), LookIn:=xlValues)
Else
Set c = x.Find(Str, after:=xx, LookIn:=xlValues)
End If
If xx.Row > c.Row Then ' Restart to Find ...
FoundRecR = -1
Exit Function
End If
If c Is Nothing Then
FoundRecR = 0
Exit Function
End If
For i = 1 To 9999
If c.Offset(i, 0).Value <> c.Value Then Exit For
Next
Set xx = c.Offset(i - 1, 0)
Next
FoundRecR = i
End Function
The function search the occurrance StartR of the string Str in the range x:
=FoundRecR("01A";A2:A16;1)
Return 0 if don't found and -1 if the occurrance it's to high (no other occurrance).
The After parameter it's necessary to force Excel to start from the first cell of the range, otherwise Excel ignore...