I have two integer values in 2 columns in excel. I need to retrieve these integers and form a ratio and then compare it with another ratio in another column.
For example, if the numbers are 2 and 3 in columns A1 & B1. I need to retrieve these values and form 2:3 in C1 and should compare if this is same as in D1 (with value 4:1).
How do i do it in VBA ?
I created a formula in C1 as =A1&":"&B1 and got the values in C1. However i am unable to compare this with the value in D1, and I am not sure how do I declare this variable in VBA ?
Kindly help me here.
You can try this ..
Private Sub Worksheet_Change(ByVal Target As Range)
Dim y As Integer
y = Target.Row
Select Case Target.Column
Case 1, 2 ' if col A
If IsEmpty(Cells(y, 1)) Or IsEmpty(Cells(y, 2)) Then
Cells(y, 3) = ""
Exit Sub
End If
Cells(y, 3) = "'" & Cells(y, 1) & ":" & Cells(y, 2)
Case 3 ' then compare
MsgBox IIf(Cells(y, 3) = Cells(y, 4), "Equal", "Not Equal")
End Select
End Sub
This use ' sign to avoid autoconvert value to time and for this you should have in D column with ' too ..
If D1 is formatted in the same way as C1 then a formula of =(D1=C1) would return TRUE or FALSE. In VBA this could be stored in a variable:
Dim blnSame As Boolean
blnSame = (Range("D1").Value = Range("C1").Value)
Based on the OPs further comment, an Excel formula would be:
=IF(Sheet1!C1=Sheet2!D1,"Win","Lose") ' or ,"Lose","Win"
(adjust the cell and sheet references as necessary) which could be copied down the column.
In VBA, a formula could be inserted into a range:
Worksheets("Sheet3").Range("E1:E10").Formula = _
"=IF(Sheet1!C1=Sheet2!D1,""Win"",""Lose"")"
If you want to loop down the column inserting the words "Win" or "Lose" then IMO you should study some VBA.
Related
I am trying to make a macro in VBA-Excel that allows me to generate a simple sum (using a + sign) in a specific cell; keeping all the numbers in the formula of the cell. I mean i need that the output formula "hold" the values/adding formulas that are in a certain range. The numbers should be added automatically to the + formula. An special restriction is that in the event that there is no number in a cell of the range, the formula should not incorporate "0".
For example The data shown below are to numbers or sums within a Range (A1:A7):
A1: 5
A2: 7,5 --> =5+2,5
A3:
A4: 1
A5: 1 --> =3-2
A6:
A7: 5,5
Where A2: =5+2,5 and A5: =3-2. The other terms are just numbers.
Range of the example = A1:A7
Formula Output of the macro on B1 (or Cells(1, 2)) should be:
=5 + 5 + 2,5 + 1 + 3 - 2 + 5,5 (20)
The pseudo code should be like:
for i = 1 to 7 -> Cells(1, 2).FormulaLocal = if Cell(i,1) is a number (or an existing adding formula with values), add to the current formula. if its blank or 0, skip to next i (or row).
Output: formula "= Value1(5) + formula2(5+2,5) + Skip0Value3() +
Value4(1) and so on..
I already tried the following code with partially positive results:
Sub summanual()
Dim i As Integer
Dim y As String
For i = 1 To 7
If Cells(i, 1) <> 0 Then
y = Cells(i, 1)
Cells(1, 2).FormulaLocal = Cells(1, 2).FormulaLocal & "+" & y
End If
Next i
If Cells(1, 2) <> 0 Then
Cells(1, 2).FormulaLocal = "=" & Cells(1, 2).FormulaLocal
Else
Cells(1, 2) = ""
End If
End Sub
This works only for positives values. Negatives values are added
like "+-" to the output formula.
The output formula only stores the results of the origin cell. Ex:
A2 is 5+2,5 but it is added like 7,5. It should be split. Same with
A5.
Is fine to declare "y" variable as String in this case?
Any other optimization? Maybe there is a completely different
approach with better and faster result? Just new with vba-excel
Any help would be appreciated
Thanks
I have two diferent excel formatted tables one near another. First table (green headers) is a table where I have to add some chemical formulas in Column A and Column B will be SUM of all compounds that I will add from second table (yellow headers), which represents Periodic System of Elements!
The formula that I am using in Table 2 (yellow headers) for calculating chemical compounds is this:
=C$2*MAX(IFERROR(IF(FIND(C$1&ROW($1:$99);MolM.[#[Mol. Formula]]);ROW($1:$99);0);0);IFERROR(IF(FIND(C$1&CHAR(ROW($65:$90));MolM.[#[Mol. Formula]]&"Z");1;0);0)) (CSE formula)
What and how I am usually doing this update of new compounds is that I am adding new chemical formulas in Column A manually (that is okay) and then dragging main formula in Table 2 (yellow header) to calculate all elements, and then SUM in column B for the main result!
My question is, is there a possibility to be more automated, just when I type new compound in Column A it will expand as normal table do, but also to auto-expand and calculate rest of compounds, without that I drag the formula manually..?
Hopefully this was clear enough.
Is there any possibility to make this happen? Is the only solution Power Query or?
I'm making a wild guess here.
Say that you write NH3 in A3, and then have it print I2 (value of "N") in I3, and C2 * 3 (value of "H" times 3, "H3") in C3. To then have B3 calculate the total value with =SUM() or similar.
You could have a VBA sub that looks for the value and prints this.
Here is a prototype of that:
Sub molFunc(chem As String, formRow As Long)
Dim i As Long, c As String, atoms As Range, a as Range
Set atoms = Range("C1", Cells(1, Columns.count).End(xlToLeft))
For i = 1 To Len(chem)
If Not Mid(chem, i + 1, 1) = UCase(Mid(chem, i + 1, 1)) Then
c = Mid(chem, i, 2)
i = i + 1
Else
c = Mid(chem, i, 1)
End If
For Each a In atoms
If a.Value = c Then
If IsNumeric(Mid(chem, i + 1, 1)) Then
a.Offset(formRow - 1).Value = a.Offset(1) * Mid(chem, i + 1, 1)
Else
a.Offset(formRow - 1).Value = a.Offset(1)
End If
End If
Next a
Next i
End Sub
Then you can call it from a Worksheet_Change event in the worksheet of your choice.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:A")) Is Nothing And Target.count = 1 Then
Application.EnableEvents = False
Call molFunc(Target.Value, Target.Row)
Application.EnableEvents = True
End If
End Sub
I'd like to find if any row in Column C matches any cells in Column A or B and print out 'yes' or 'no' in an adjacent cell if it does match. The match might not be exact, because an ID may be written as '12401' but the match in the column may be like 'cf[12401]', with the ID enclosed in brackets.
This is an example of what I might find in the table. The values in A and B columns originally came from another table but I'm trying to find all instances of where they might exist in the third column.
Excel Example:
If possible, I'd like to list the values themselves that matched in the column. But that part would be a nice extra while the other part is more important because there are around 6000 values in the middle column so it would take days by hand.
I've tried different things like this:
=IF(COUNTIF(C2,"*" & A6 & "*" ), "Yes", "No")
or
=IF(COUNTIF(C2,"*" & Length & "*" ), "Yes", "No")
these work for individual words or cells, but trying to check all the values in that column against the cell will return no. I've tried variations of SUMPRODUCT and others that I've found, but haven't been able to get something that works for multiple values.
Is there some function in Excel that will allow me to do this? Or maybe a way in VBA?
Here is some UDF you could use.
Dim MyArr As Variant, X As Double, LR As Double
Option Explicit
Public Function MatchID(RNG As Range) As String
With ActiveWorkbook.Sheets(RNG.Parent.Name)
LR = .Cells(Rows.Count, 1).End(xlUp).Row
MyArr = Application.Transpose(.Range(.Cells(2, 1), .Cells(LR, 1)))
For X = LBound(MyArr) To UBound(MyArr)
If InStr(1, RNG.Value, MyArr(X), vbTextCompare) > 0 Then
If MatchID = "" Then
MatchID = MyArr(X)
Else
MatchID = MatchID & ", " & MyArr(X)
End If
End If
Next X
End With
End Function
Public Function MatchCFNAME(RNG As Range) As String
With ActiveWorkbook.Sheets(RNG.Parent.Name)
LR = .Cells(Rows.Count, 1).End(xlUp).Row
MyArr = Application.Transpose(.Range(.Cells(2, 2), .Cells(LR, 2)))
For X = LBound(MyArr) To UBound(MyArr)
If InStr(1, RNG.Value, MyArr(X), vbTextCompare) > 0 Then
If MatchCFNAME = "" Then
MatchCFNAME = MyArr(X)
Else
MatchCFNAME = MatchCFNAME & ", " & MyArr(X)
End If
End If
Next X
End With
End Function
In D2 Ijust used =IF(F2<>"","YES","") and dragged it sideways and down.
I have a problem where I can't add numbers with decimals. Only numbers with no decimals.
I have written a code to sum up values from different cells. This work fine as long as the numbers are without decimals.
Here is my code:
Sub SumValues()
'This makro is made to add values together depending on
'x amount of Sheets in the workbook:
Application.ScreenUpdating = False
'A will sum up the values from each cell,
'depending on the amount of Sheets in the this Workbook:
A = 0
For I = 1 To ThisWorkbook.Sheets.Count
'Adding the values from cell E5 to Cells(5, 5 + (I - 1) * 3),
'with the distance 3 between each cell:
A = A + Cells(5, 5 + (I - 1) * 3)
Next I
'The values A that is added togheter from the cells, is now put in a cell:
Worksheets("Sheet1").Cells(1, 1).Formula = "=" & A & ""
Application.ScreenUpdating = True
End Sub
So for 3 number of sheets, "I" goes from 1 to 3.
So if my cells contain these numbers:
Cell(5,5) = 2
Cell(5,8) = 3
Cell(5,11) = 8
I get the sum in Cell(1,1) = 13
But if I have these values:
Cell(5,5) = 2,2
Cell(5,8) = 3
Cell(5,11) = 8
I get the "run-time error '9': Subscript out of range" Error message when running script.
Any suggestions?
Another question is if it is possible to get the formula into the cell I am adding up the values?
For Examlpe if I have 3 Sheets in my Workbook, it will sum up the values from Cell(5,5) , Cell(5,8) and Cell(5,11).
The sum is shown in Cell(1,1).
But all I get is the number, not the formula.
Is it possible to make the Cell show the formula "=E5+H5+K5"?
This last question might be a "fix" for the first question, if it is the separator "," that is making trouble, maybe?
Thanks
GingerBoy
Tested and working fine
Declare your variables
You need to qualify your objects with a worksheet
No need to toggle off Screen Updating here. You are just modifying one cell
This code will place the Value in A1 and the Formula in B1
Disclaimer:
Your code, and the code below, is subject to a potential Type Mismatch Error if you feed any cell with a non-numerical value into your loop. If there is some chance of any non-numerical cell being in the sum range, you can avoid the error by nesting something like the following inside your loop: If ISNUMERIC(Range) Then.
Sub SumValues()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim A As Double, i As Long, Loc As String
For i = 1 To ThisWorkbook.Sheets.Count
A = A + ws.Cells(5, (5 + (i - 1) * 3))
Loc = ws.Cells(5, (5 + (i - 1) * 3)).Address(False, False) & "+" & Loc
Next i
ws.Range("A1") = A
ws.Range("B1").Formula = "=" & Mid(Loc, 1, Len(Loc) - 1)
End Sub
I have numerical values entered in Row 1 from columns A to IA. I want to create a loop that compares one cell with the cell before it (aka Cell B1 to A1 or cell F to E). Let's use B1 and A1 as the example. It looks at the Value in Cell B1 and sees if it is greater then the value of the cell in A1. If it is greater then I want a + to be entered in the Cell B2. Also if B1 is < A1 put a - into Cell B2. I want the program to be able to loop this process so it does it for all the columns A-AI. Below is what I want want the program to do (not including the dashes and teh paranthesis around the positive and negative signs of course).
A B C D F
1 33.12 34.52 34.92 35.19 34.97
2 (+) (+) (+) (-)
I realize this task is easily performed in excel (not using VBA) but I am trying to learn VBA so I can perform much more complex tasks. I have written the basic code to do the simple task but I am not sure how to loop it so it will do this for all my cells!
Sub EnterFormula()
Dim x As Integer
Dim y As Integer
x = Worksheets("Sheet2").Range("C2").Value
y = Worksheets("Sheet2").Range("B2").Value
If x > y Then
Worksheets("Sheet2").Range("C4") = "+"
End If
End Sub
Ok So for the next part of My Program. It gets a touch more complicated. We move onto row 3. Row 3 is going to either have a U (for Up) or a D (for down) or nothing.
Let's Start at Column C. Column C1 has a value of 34.92, and C2 was given a + (as 34.92 was larger then the day before which was 33.02). Now we go to the first previous "+" WITH AT LEAST one opposite sign (in this case "-") in between. So in this case that is row A (one "-" inbetween under row B). Now if the Numerical Value in C1 (34.92) is larger then the numerical value in A (33.12) then we designate a "U" in C3. If it was NOT larger we would leave an empty cell in C3.
Let's move onto column D. Column D1 has a value of 35.19 which is greater then the C1 value of 34.92 and this is why D2 has a "+". Next we go to the first previous "+" WITH AT LEAST one opposite sign (in this case "-") in between. So in this case that is row A again. Since the numerical value in D1 (39.19) is greater then the numerical value in A1 (33.12) then D3 gets a U.
Moving onto Column F (32.97)...Note:I changed the value a little from the original F. 32.97 is LESS then 35.19 (D1) which is why F2 is a "-". Next we go to the first previous "-" WITH AT LEAST one opposite sign (in this case "+") in between. So in this case this is Row B (with two "+" signs in between). Now because we are dealing with "-" signs this time we look and see if the numerical value in F1 is LESS then the numerical value in B1...which it is, so a "D" is entered in F3. If F1 was larger then B1 then the cell would be left empty.
Onto Column G (35.21). This is greater then 32.97 (F1) and therefore gets a "+" in G2. Next we go to the first previous "+" WITH AT LEAST one opposite sign in between (in this case "-"). So in this case this is Row D (with one "-" in between). Since the numerical value of G1 is greater then that of D1 we designate a "U". If it was not greater we would leave the cell empty.
A B C D F G H I
1 33.12 33.02 34.92 35.19 32.97 35.21 35.60 35.90
2 (+) (-) (+) (+) (-) (+) (+) (+)
3 U U D U U U
Here is my code so far for this. I have added to my original code which was creating the "+" signs and "-" signs.
Sub Comparison()
Dim targetCell As Range
Dim targetSignCell As Range
Dim currentSign As String
Dim currentNumericalCell As Currency
' Find out what sign (+ or -) the current Cell has in it
currentSign = Worksheets("Sheet2").Range("H3").Value
'Variable to associate the numerical number above the current Cell
currentNumericalCell = Worksheets("Sheet2").Range("H2").Value
' Here we iterate through each cell in a specified range
' Since you know you want to start at B1 and go until E1,
' you can ues the following syntax to go through each cell
For Each Cell In Range("B2:H2")
' Get the value of the current cell with the .Value property
currentValue = Cell.Value
' Now get the value of the cell that is before it (column-wise)
previousValue = Cell.Offset(0, -1).Value
' Create a variable for our target cell
Set targetCell = Cell.Offset(1, 0)
' Here are the basic comparisons
If currentValue > previousValue Then
targetCell.Value = "+"
ElseIf currentValue < previousValue Then
targetCell.Value = "-"
ElseIf currentValue = previousValue Then
targetCell.Value = "="
Else
' Not sure how it would happen, but this
' is your catch-all in case the comparisons fail
targetCell.Value = "???"
End If
' Now go to the next cell in the range
Next Cell
'Alex starting to code
For Each Cell In Range("H3:B3")
' Find out what the sign is in the cell before it
previousSign = Cell.Offset(0, -1).Value
'Variable used to find the first cell with an
'Opposite sign as the current cell
oppositeSign = Cell.Offset(0, -2).Value
'Variable to associate the numberical number above the first Opposite Sign Cell
oppositeNumericalCell = Cell.Offset(-1, -2).Value
' Create a Variable for Target Cell
Set targetSignCell = Cell.Offset(1, 0)
If currentSign.Value = "+" And currentSign.Value <> previousSign.Value And oppositeSign.Value = currentSign.Value And currentNumericalCell.Value > oppositeNumericalCell.Value Then
targetSignCell = "U"
ElseIf currentSign.Value = "-" And currentSign.Value <> previousSign.Value And oppositeSign.Value = currentSign.Value And currentNumericalCell.Value < oppositeNumericalCell.Value Then
targetSignCell = "D"
Else
End If
Next Cell
End Sub
I agree with #JohnBustos that a formula would be much more efficient, however if this is indeed a learning exercise then here is a simple example that would do what you want:
Sub Comparison()
Dim targetCell As Range
' Here we iterate through each cell in a specified range
' Since you know you want to start at B1 and go until E1,
' you can ues the following syntax to go through each cell
For Each cell In Range("B1:E1")
' Get the value of the current cell with the .Value property
currentValue = cell.Value
' Now get the value of the cell that is before it (column-wise)
previousValue = cell.Offset(0, -1).Value
' Create a variable for our target cell
Set targetCell = cell.Offset(1, 0)
' Here are the basic comparisons
If currentValue > previousValue Then
targetCell.Value = "+"
ElseIf currentValue < previousValue Then
targetCell.Value = "-"
ElseIf currentValue = previousValue Then
targetCell.Value = "="
Else
' Not sure how it would happen, but this
' is your catch-all in case the comparisons fail
targetCell.Value = "???"
End If
' Now go to the next cell in the range
Next cell
End Sub
And if you were to do it as a formula, it could be something like this (entered into B2 and copied to the end of the range):
=IF(B1>A1,"+",IF(B1<A1,"-","="))
This compares the cell above the formula and the cell to the left of that cell and adds the appropriate symbol.
Assuming there are no empty cells in the range you want to work in, you could do it like this:
Range("b2").Select
Do Until IsEmpty(ActiveCell.Offset(-1, 0))
If ActiveCell.Offset(-1, 0).Value > ActiveCell.Offset(-1, 1).Value Then
ActiveCell.Formula = "+"
End If
If ActiveCell.Offset(-1, 0).Value < ActiveCell.Offset(-1, 1).Value Then
ActiveCell.Formula = "-"
End If
ActiveCell.Offset(0, 1).Select
Loop
If there are empty cells in the range then instead of 'do until' use
dim I
for I = 1 to ..
next I