VBA Excel 2013 Finding specific string length and adding a value - vba

I am trying to write a macro to find if a cell has 5 numeric values and if it does, I need to add a 0 at the end.
My macro already has some steps in it.
For example
Cell BZ2 = 9.48E+00
My macro finds the decimal point and replaces it with 94811E-5
I need to add a Zero in this case, because there are 5 numeric values, AND only when the last three characters are E-5.
Expected result is 948110E-5.
I am using a number stored as text.
Can anyone help me out?
Sub TextFormat()
Dim c As Range
Dim d As Range
For Each c In Sheets("order_export").Range("F2:F10000").Cells
If StrComp(Right(c.Value, 1), "R", vbTextCompare) = 0 Then
c.Offset(0, -1).Value = c.Offset(0, -1).Value & "R"
c.Value = Left(c.Value, Len(c.Value) - 1)
End If
Next c
For Each d In Sheets("order_export").Range("BZ2:BZ10000").Cells
If InStr(1, d.Value, ".", vbTextCompare) > 0 Then
d.NumberFormat = "#"
d.Value = Replace(d.Value, ".", "")
d.Value = d.Value & "E-5"
End If
Next d
End Sub

using this conditional
if isNumeric(left(text,5)) AND right(text,3) = "E-5" then
'add zero
text = left(text,5) & "0" & right(text, len(text) - 5)
end if
will add the 0 after the first 5 if the first 5 characters are numeric and the last 3 are e-5. the left function takes the first 5 characters. the isNumeric checks if they are numeric. and then the rest, takes the first 5 characters, puts a 0, and then the right takes all characters starting from the right going up till length - 5 (we already have the first 5 characters)
edit
as pointed out, if there is already a 0, like 123450E-5 then an extra would be added.
add ANd len(text) = 8 so that it only adds the 0 if there are 8 characters.

Excel doesn't short circuit so for coding efficiency it is better to break an AND into IF's with the most likely errors first, then the breaches
Also never using the variant functions Left and Right use string functions Left$ and Right$ instead
This link is an excellent resource re coding optimisation.
Re-cutting the earlier answers would be something like this:
c = "94811E-5"
If Len(c) = 8 Then
If IsNumeric(Left$(c, 5)) Then
If Right$(c, 3) = "E-5" Then c = Left$(c, Len(c) - 3) & "0" & Right$(c, 3)
End If
End If
MsgBox c

Related

Issue with Replace function when editing strings

So currently I am trying to update an old excel file's macro codes so that we can use it with a new program. Though I am new to VB I know some C++ and Java from college so I was able to get just about everything working but this section of code. So basically, we are converting excel information to .CVS and when we do the conversion seems to give some of the information three quotation marks on either side instead of the single set like it is listed in the excel document.
To make a simple fix I just added this extra set of code to search each string for quotation marks and remove all but a single set. Instead it seems to just continue replacing sections of the entire string until there is only 1 quotation mark left...do y'all know what the issue might be?
I know this is some poorly written code especially since I havent moved on to fix the infinite loop BUT the main concern right now is just how I am misusing the Replace function.
For X = 1 To 56
String2 = Sheets(1).Cells(X, 1)
Z = 1
Do While Z <> Len(String2)
If Mid(String2, Z, 1) = Chr(34) Then
If Mid(String2, Z + 1, 1) = Chr(34) Then
String2 = Replace(String2, """", "", Z, 1)
' Replace(String2, Char(34) + Char(34), "", Z, 1)
Sheets(1).Cells(X, 1) = String2
Z = 1
Else
Z = Z + 1
End If
Else
Z = Z + 1
End If
Loop
Next
The File Information being altered:
"MH 7 to Tipton1",7.942,1,1,0.22
4.9,1,18.8
"SINGLE CABLE",15,206.8
""--""",0,0 ^^ This is a string that gets eaten by the Replace
function after a few loops. It continues till (",0,0") Previous
strings were not altered in operation.
0,"""--""",0,"""H""","""--""",100,21.1
0,"""--""",0,"""VU""","""U""",200,5.1
5.1,"""U""",0,"""N""","""--""",0,0
0,"""--""",0,"""H""","""--""",100,21.4
0,"""--""",0,"""VU""","""U""",200,6.5
0,"""--""",0,"""VD""","""U""",100,11.5
0,"""--""",0,"""N""","""--""",0,0
0,"""--""",0,"""VU""","""U""",100,11.5
0,"""--""",0,"""VD""","""U""",100,11.5
0,"""--""",23.1,"""N""","""--""",0,0
0,"""--""",0,"""VU""","""U""",100,3.6
0,"""--""",0,"""VD""","""U""",100,3.6
0,"""U""",120.8,"""N""","""--""",0,0
0,"""--""",0,"""H""","""--""",12,30.9
"Test4.pll"
I cant quite tell from your question but if all you are trying to do is replace triple quotes and with single quotes then you can remove the entire do loop and just put
string2=replace(string2,"""""""","""")
inside the for loop to replace contents of the entire string rather than just each character.
So
For X = 1 To 56
String2 = Sheets(1).Cells(X, 1).value
String2 = Replace(String2, """""""", """")
Sheets(1).Cells(X, 1).value = String2
Next
or even
For X = 1 To 56
Sheets(1).Cells(X, 1).value = Replace(Sheets(1).Cells(X, 1).value, """""""", """")
Next
EDIT
You'll also want to use .value for getting the cell value

How can I insert variable into formula in VBA

Can anyone solve this?
Sub test
Dim i as integer
For I = 1 to 10
ActiveCell.Offset(0, 2).Formula = "=Sum(E15,&i&)"
Next I
End Sub
your actual goal is unclear
you may want to start form this code
Sub test()
Dim i As Integer
For i = 1 To 10
cells(i, 4).Formula = "=Sum(E" & i & ":E15)"
Next
End Sub
and adjust it to your needs, knowing that:
it currently writes in cells "D1:D10"
since cells(i, 4) references a cell in 4th column (i.e.: column "D") 4 and i row, and we're inside a loop where i is looping through 1 to 10
so if:
you want to reference a different column then just change 4 to the proper column index
you want to reference a different row then just change i to the proper row index (may be some i+2 if you need to iterate through 1 to 10 but start writing from row 3)
the formula written in those cells is:
=SUM(E1:E15) in D1,
=SUM(E2:E15) in D2,
....
=SUM(E10:E15) in D10.
so just change "=Sum(E" & i & ":E15)" to your actual needs
You're close, trying to use ampersands (&) to concatenate strings.
ActiveCell.Offset(0, 2).Formula = "=Sum(E15," & i & ")"
Use the ampersands between strings to merge them, not inside strings.

Excel VBA: Find first value in row larger than 0 and sum over following 4 cells

As a complete beginner to VBA Excel, I would like to be able to do the following:
I want to find the first value larger than 0 in a row, and then sum over the following 4 cells in the same row. So
Animal1 0 0 1 2 3 0 1
Animal2 3 3 0 1 4 2 0
Animal3 0 0 0 0 0 1 0
Results in
Animal1 7
Animal2 11
Animal3 1
Is this possible?
(Your problem description didn't match your examples. I interpreted the problem as one of summing the 4 elements in a row which begin with the first number which is greater than 0. If my interpretation is wrong -- the following code would need to be tweaked.)
You could do it with a user-defined function (i.e. a UDF -- a VBA function designed to be used as a spreadsheet function):
Function SumAfter(R As Range, n As Long) As Variant
'Sums the (at most) n elements beginning with the first occurence of
'a strictly positive number in the range R,
'which is assumed to be 1-dimensional.
'If all numbers are zero or negative -- returns a #VALUE! error
Dim i As Long, j As Long, m As Long
Dim total As Variant
m = R.Cells.Count
For i = 1 To m
If R.Cells(i).Value > 0 Then
For j = i To Application.Min(m, i + n - 1)
total = total + R.Cells(j)
Next j
SumAfter = total
Exit Function
End If
Next i
'error condition if you reach here
SumAfter = CVErr(xlErrValue)
End Function
If your sample data is in A1:H3 then putting the formula =SumAfter(B1:H1,4) in I1 and copying down will work as intended. Note that the code is slightly more general than your problem description. If you are going to use VBA, you might as well make your subs/functions as flexible as possible. Also note that if you are writing a UDF, it is a good idea to think of what type of error you want to return if the input violates expectations. See this for an excellent discussion (from Chip Pearson's site - which is an excellent resource for Excel VBA programmers).
ON EDIT: If you want the first cell greater than 0 added to the next 4 (for a total of 5 cells in the sum) then the function I gave works as is, but using =SumAfter(B1:H1,5) instead of =SumAfter(B1:H1,4).
This is the one of the variants of how you can achieve required result:
Sub test()
Dim cl As Range, cl2 As Range, k, Dic As Object, i%: i = 1
Set Dic = CreateObject("Scripting.Dictionary")
For Each cl In ActiveSheet.UsedRange.Columns(1).Cells
For Each cl2 In Range(Cells(cl.Row, 2), Cells(cl.Row, 8))
If cl2.Value2 > 0 Then
Dic.Add i, cl.Value2 & "|" & Application.Sum(Range(cl2, cl2.Offset(, 4)))
i = i + 1
Exit For
End If
Next cl2, cl
Workbooks.Add: i = 1
For Each k In Dic
Cells(i, "A").Value2 = Split(Dic(k), "|")(0)
Cells(i, "b").Value2 = CDec(Split(Dic(k), "|")(1))
i = i + 1
Next k
End Sub
Here is what I would use, I dont know any of the cell placement you have used so you will need to change that yourself.
Future reference this isnt a code writing site for you, if you are new to VBA i suggest doing simple stuff first, make a message box appear, use code to move to different cells, try a few if statments and/or loops. When your comftable with that start using varibles(Booleans, string , intergers and such) and you will see how far you can go. As i like to say , "if you can do it in excel, code can do it better"
If the code doesnt work or doesnt suit your needs then change it so it does, it worked for me when i used it but im not you nor do i have your spread sheet
paste it into your vba and use F8 to go through it step by step see how it works and if you want to use it.
Sub test()
[A1].Select ' assuming it starts in column A1
'loops till it reachs the end of the cells or till it hits a blank cell
Do Until ActiveCell.Value = ""
ActiveCell.Offset(0, 1).Select
'adds up the value of the cells going right and removes the previous cell to clean up
Do Until ActiveCell.Value = ""
x = x + ActiveCell.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Offset(0, -1).ClearContents
Loop
'goes back to the begining and ends tallyed up value
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 1).Value = x
'moves down one to next row
ActiveCell.Offset(1, 0).Select
Loop
End Sub

Subtract two columns, with each other as a condition, and append values

I need to subtract two columns from a large array and see which ones are positive and of those positive values I need to find the positive values row and append a few things onto that value.
Here is the general concept I'm thinking so far
While < 8000
if (cell(i,1).Value - cell(i,2) > 0)
print in another sheet cell(i,3).value (cell(i,2).Value-cell(i,4)) cell.value(i,4)
for example...
suppose I have something like this
[2 2 hi yo]
[3 2 go mo]
this macro would return "go 1 mo" in another sheet.
Sub Leaves()
Dim i As Integer
Dim g As Integer
Dim Quantity As Integer
Dim Executed As Integer
Dim Leaves As Integer
i = 1
g = 1
Do While i < 8000
Quantity = Worksheets("Sheet1").Cells(i, 3).value
Executed = Worksheets("Sheet1").Cells(i, 5).value
Leaves = Quantity - Executed
If Leaves > 0 Then
Worksheets("Sheet2").Cells(g, 1).value = _
Worksheets("Sheet1").Cells(i, 9).value & _
Worksheets("Sheet2").Cells(i, 2).value & _
Leaves & Worksheets("Sheet2").Cells(i, 3).value
g = g + 1
End If
i = i + 1
Loop
End Sub
The above code gives me a Type mismatch error.
It is helpful if you say what line is throwing an error. Also, one should strive to create a Minimal, complete, and verifiable example. The effort to do so often resolves the question before you need to post it.
The code itself seems fine and it runs for me (on an empty workbook) with no type mismatch. Thus, the problem must be with your assumptions about the spreadsheet.
Either of the lines
Quantity = Worksheets("Sheet1").Cells(i, 3).value
Executed = Worksheets("Sheet1").Cells(i, 5).value
will trigger a type mismatch if the corresponding value can't be converted to an integer. This could happen, for example, if one of the cells contains a string (other than something like "1") or an error value such as #N/A or #Value!.
The line which begins
Worksheets("Sheet2").Cells(g, 1).value = _
will throw a type mismatch if one of the values being concatenated can't be converted to a string. An error value in one of the cells is the most likely culprit. If this is the case and for some reason you actually want to create a string that includes substrings which look like e.g. "#N/A" then you could use the Text property of those cells rather than Value.

Excel VBA Match function not working

I'm using INDEX and MATCH functions to pull data which is concatenated string of G2 and H2 from column D (sorry I don't have enough points to attach pic). Column D has INDEX(column A and column B) and columns A and B have values till 12th row. MATCH is working fine giving me the position as 6 on the worksheet. But when I use this in VBA code as shown below,INDEX is working in the VBA code (can be seen through MsgBox) but MATCH function which would allot value to the variable 'check' isn't working. I have been breaking my head for really long. Need help from experts here. Somebody please tell me where am I going wrong?
Sub testindex()
Dim check As Long
Set sh = Sheets("Sheet1")
For j = 1 To 11
'Index value is correctly shown
MsgBox "Index Value=" & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2)
'Cells(7, 4)=ISA737775 same as G2&H2
MsgBox "Cells(7,4)=" & Cells(7, 4)
check = Application.WorksheetFunction.Match(Cells(7, 4), Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2), 0)
Next j
End Sub
Thanks
Match expects the second paramater to be in the form of a range. When you call match through VBA that range actually needs to be a range object, not just some string like "A1:A12" or whatever it is that your concatenated Index formulas output.
At any rate, you are iterating already, so why not just call those values directly instead of pulling their values through Index?
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j), 0)
Which is writing the same exact thing but without having to use a taxing INDEX function in VBA to do it. Note that this still won't work because the second parameter of match is still just a string which is a concatenated value from Column A and Column B. You could convert to a range by sticking them in the range object with:
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range(sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j)), 0)
I'm assuming that the values in A and B are actual cell names that when concatenated will make a range. Like when j=1 then the it would be like check=Match(Cells(7,4), sh.Range("G2:H50"), 0) or something...