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
Related
I am trying to make VBA write a formula into different cells that will find the maximum value for a Range decided by some variables. My variables I and J are (numbers/Integers).
Here is my code.
Sub AddMAX()
Dim I As Integer
Dim J As Integer
Dim L As Integer
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
For L = 5 To 4 + J
Worksheets(1).Cells(L, 4 + I).Formula = "=" & Max(Range(Cells(L, 4), Cells(L, 3 + I)))
Next L
End Sub
Have tried to re-write the second part (part behind the equal sign) several times. Usually I get the message Compile error: Sub or Function not defined and it marks the "Max". I thought Max (also tried with big letters) was an in-built function like SUM and so on.
I'm trying to make it write an Excel formula like this into the cells:
For I=2 and J=3:
Cell F5: =MAX(D5:E5)
Cell F6: =MAX(D6:E6)
Cell F7: =MAX(D7:E7)
i.e. I want a formula in the cells like I had wrote it in the cells manually to calculate max value, so that if the value in Cells D5, to D7 and E5 to E7 change, the new max value will be found without any scripts having to run.
Let me know if something is unclear.
You should not be putting Range and Cells in a formula string, they mean nothing to the Excel formula engine. You need the Address of the cells:
Dim I As Long
Dim J As Long
Dim L As Long
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
L = 5
With Worksheets(1)
.Range(.Cells(L, 4 + I), .Cells(4 + J, 4 + I)).Formula = "=MAX(" & .Cells(L, 4).Address(False, False) & ":" & .Cells(L, I + 3).Address(False, False) & ")"
End With
The formula is actually the same for all cells, which is why it is possible to assign it in one assignment for the entire range. It looks different in the A1 reference notation, but if you switch to R1C1 in the Excel settings, you will see they are the same. Which also means it is easier to create that formula using the R1C1 notation in the first place:
Dim I As Long
Dim J As Long
Dim L As Long
I = InputBox("Number of columns to check max value")
J = InputBox("Number of Rows to add formula inn and find max value of that row")
L = 5
With Worksheets(1)
.Range(.Cells(L, 4 + I), .Cells(4 + J, 4 + I)).FormulaR1C1 = "=MAX(RC[-" & I & "]:RC[-1])"
End With
But it would appear to me that you should instead use the Excel interface the intended way. Select the cells in which the MAX formula should be. Keeping the entire range selected, put the MAX formula into any of its cells as if you were creating it for just that cell, but instead of pressing Enter, press Ctrl+Enter.
You have to be careful to distinct between the part that is seen by VBA and the final formula.
If you write
Worksheets(1).Cells(L, 4 + I).Formula = "=" & Max(Range(Cells(L, 4), Cells(L, 3 + I)))
Max (and all the following stuff) is seen by the VBA-interpreter, not Excel. But there is no Max-function, and you get an (compiler)-error.
If you write
Worksheets(1).Cells(L, 4 + I).Formula = "=Max(Range(Cells(L, 4), Cells(L, 3 + I)))"
the VBA-interpreter sees the whole stuff as a string. It cannot take care about variables like L or I because is doesn't see them. So you end up with a formula that is exactly like you write it - and Excel (not VBA) will show you an error because it doesn't understand L or I.
What you need is a statement (in VBA) that creates a string that contains the actual values of your variables, and assign it to the cell.formula. I strongly advice that you first assign this to a string variable - it makes debugging much easier:
Dim formula As String
formula = "=Max(Range(Cells(" & L & ", 4), Cells(" & L & ", 3 + " & I & ")))"
Debug.Print formula
Worksheets(1).Cells(L, 4 + I).Formula = formula
Update: Sorry, I haven't looked to the content of the formula at all, of course the Range and Cells-objects are VBA objects. What you need in your formula is the address of the range, so change the line to
formula = "=MAX(" & Range(Cells(L, 4), Cells(L, 3 + i)).Address & ")"
Now VBA will create a Range and put the address into the formula string.
Could someone give me some pointers on how to write this formula right?
Sub WriteFormulaTextAndNumbersDependentOnI()
Dim xNumber As Integer
xNumber = InputBox ("Choose I")
For I = 1 To xNumber
Worksheets("Sheet1").Cells(1, 1 + I).Formula = "= & 2,10 + 0,01 * (I - 1)'" & Sheets(I + 1).Name & "'!B12"
Next I
End Sub
The point here is to write a name in different cells, with a calculated number (2.10 + 0.01*(I - 1)) and text from another sheet:
Lets say we have in Sheet2:
B12 = Hello World
Lets say we have in Sheet3:
B12 = You are cool!
We should then get in Sheet1:
I = 1 would give a value/text in cell B2, with the value/text: "2.10+0.01*(1-1) B12" = "2.10 Hello World"
I = 2 would give a value/text in cell C2, with the value/text: "2.10+0.01*(2-1) B12" = "2.11 You are cool!"
An so on.
Any suggestions?
Appreciate any suggestions
//GingerBoy
use:
Concatenate() worksheet function to mix numbers and text in the same string
Text() worksheet function to format a number to a string
as follows:
Worksheets("Sheet1").Cells(2, 1 + I).Formula = "=concatenate(TEXT(2.10 + 0.01*(" & I & "-1),""0.00""), "" "", " & Sheets(I + 1).Name & "!B12)"
see that:
I used Cells(2, 1 + I) to write in in B2, C2 ... as per your narrative
I used dots (.) as decimal separator: you may want to change all dots into commas as per your decimal separator conventions
I have a spreadsheet in which there are multiple rows that have three columns (K, L M) that contain text (inserted manually from a dropdown). The inserted text includes a 'score'. For the row shown in the image that score is 3 + 2 + 2 = 7.
What I'd like to be able to do is to have that score automatically calculated and shown in column N. I'm happy to do the score extraction given the text, but I'm completey unfamiliar with Excel's object model, and how to write a VBA macro that can be triggered across all of the rows. I assume it would be passed a range somehow, or a string designating a range, but how to do that is beyond me just now. Perhaps I just need a formula? But one that calls a function to strip non-numerical data from the cell?
Any help appreciated.
Put this formula in N2 cell and drag it all the way down.
=LEFT(K2, FIND("-", K2) - 2) + LEFT(L2, FIND("-", L2) - 2) + LEFT(M2, FIND("-", M2) - 2)
For more information see reference. It sum all numbers, that are present before the hyphen (-) in a cell.
Try:
N2 = LEFT(TRIM(K2),1) + LEFT(TRIM(L2),1) + LEFT(TRIM(M2),1)
As I said in comments, this solution does not scale so well if it is more than three columns and / or the scores are more than single digit [0-9]
A VBA solution to do all of your rows and enter the values into Column N:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your worksheet, amend as required
LastRow = ws.Cells(ws.Rows.Count, "K").End(xlUp).Row
'get the last row with data on Column A
For rownumber = 1 To LastRow 'loop through rows
For i = 11 To 13 'loop through columns
strValue = ws.Cells(rownumber, i).Value 'get text string from cell
pos = InStr(strValue, " -") 'find the dash - in cell
If pos > 0 Then 'if dash found
Value = Value + Val(Left(ws.Cells(rownumber, i).Value, pos - 1)) 'remove everything after number
End If
Next i
ws.Cells(rownumber, 14).Value = Value 'write value to column N
Value = 0
Next rownumber
End Sub
Suppose there are 3 columns. In 1 column number (a1), in the second name (b1), in the third description (c1). I want to make another 1 table, so that the data would spread to it, but with 1 condition. If in the 3 column, in one cell more than 500 characters, then continue to copy the data from the rows to the next cell. (For example, there is a line a2, b2, c2 In cell c2, 600 symbols are obtained, then the remaining characters are transferred to one cell, c3 and copy the text from cells a2, b2) Is it possible to trace it? To make, some counter, that he would count the symbols in the cell.
enter image description here
table
tabletest1
Well, i think this image will be self explanatory
First table contains your original data. Right upper one contains the results, and bottom one contains the formula
The formula =IF((LEN(C2) > 5);MID(C2;6;500);" ") checks the length of the text inside a cell, if its greater than 5 (you can modify this of course), then set the value of the cell to a substring (from 6th character) of the original text.
VB Macro
After some tries, i got a VB macro which makes that
Sub copyTable()
Dim colRange As Variant
colRange = Array(1, 2, 3) 'Columns where your data is'
Dim destColRange As Variant
destColRange = Array(5, 6, 7) 'Columns where you want data be copied'
n = UBound(colRange) - LBound(colRange)
i = 2 'Initial row'
newI = i
maxLen = 10 'Maximum size allowed in one cell'
While Not (Cells(i, colRange(0)) Is Nothing) And (Cells(i, colRange(0)) <> "")
Text = Cells(i, colRange(n))
Do
For j = 0 To n - 1
Cells(newI, destColRange(j)) = Cells(i, colRange(j))
Next j
Cells(newI, destColRange(j)) = Mid(Text, 1, maxLen)
Text = Mid(Text, maxLen + 1)
newI = newI + 1
Loop Until Len(Text) <= 0
i = i + 1
Wend
End Sub
Variables explanation
colRange: Indexes of columns with origin data
destColRange: Indexes of columns where data will be written
i: Initial row
maxLen: Maximum length allowed per cell
Note that this snippet only cares about size of the last cell, if any other has more length it will copy them as they are.
when you run it you got something like
I've never made a VB code, so don't be critic, it surely can be better
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.