Pad single-digit numbers with a zero - vba

I have a loop like this to save sheets as CSV files but my first 9 sheets are name liked sinani-01 ... sinani-09 (not like sinani-1 ... sinani-9). How I can concatenate a 0 only before numbers less than 10?
Sub Adder()
Dim animal As String
Dim i As Integer
For i = 1 To 120
animal = "sinani-" & i
Sheets(animal).SaveAs "E:\Data\CSV\" & animal & ".csv", xlCSV
Next i
End Sub

VBA has a Format() function that you can use to pad numbers.
animal = "sinani-" & Format$(i, "00")
This will pad single-digit numbers with a 0. Your two- and three-digit numbers will continue to work as expected.

In the fifth line use the Format function like this:
animal = "sinani-" & Format(i, "#00")
The # means optionally a digit (i.e. present only if there are that many digits in i), 0 means definitely a digit, whereby leading zeros are used if i hasn't got enough digits.

Concatenate with a leading series of zeroes and peel off as many digits from the right-hand side as you need.
animal = "sinani-" & Right("00" & i, 2)
'alternate for many leading zeroes (e.g. DUNS number)
animal = "sinani-" & Right(String(9, "0") & i, 9)

Replace & i by & IIF(i < 10,"0","") & i
On edit: Even though in this case Format provides a cleaner solution than IIF, the IIF trick has some other uses in tweaking output. For example, if you wanted to inform the user how many cells were found which satisfy some condition you could use something like
MsgBox n & "cell" & IIF(n <> 1,"s","") & " found"
to gracefully handle plural vs. singular endings

Related

VBA USING TWO DIFFERENT RESULT USING countif VARIABLE

Good Evening
I have a problem on VBA ​I have a variable as countif
Dim Y As Integer
Y = Application.WorksheetFunction.CountIf(Worksheets("Calc_Giac").Range("I11:EZ11"), ">0")
So If I use the variable in a formula
Range("B21").Formula = "=SumIF((I11:EZ11), "">0"") / (" & Y & ")"
The value is correct
But if use in a condition the result is the variable*-1
If ("(" & Y & ")" > 0) Then
Range("L19") = "(" & Y & ")"
Else
Range("L19") = "HELLO"
End If
Any Idea about it?
First: You have a strange if-condition. Let's assume that Y has the value 3 as a result of your CountIf: "(" & Y & ")" resolves in a String "(3)". After that, you check if the string "(3)" is greater that 0. That makes no sense. Try
If Y > 0 then
Second: You write the String "(3)" into a cell. Now depending on how the cell is formatted, either you have "(3)" (as String) in the cell (when the cell is formatted as Text), or Excel tries to convert the string "(3)" into a number. However, numbers in Excel that are entered with brackets are interpreted as negative numbers (try it by entering "(3") into a cell manually. Use:
Range("L19").Value = 3
However, within the formula, =SumIF((I11:EZ11), "">0"") / (3), the (3) is just part of the calculation and the brackets tells Excel to evaluate anything within the brackets first before continuing the calculation. As 3 is already evaluated, there is nothing to do so the brackets are ignored.

VBA Excel set variable on 2digit after the comma

I want to set a result with 2 digits after the comma.
Is there any fast way to do this please ?
Because I need first to look for the result.
(If positif : add "+", negatif let the "-" and null "make it on 0.00)
Dim VariationX as Single
VariationX = 0,5
If VariationX >= 0.01 Then
VariationXString = "+" & VariationX
ElseIf VariationX = 0 Then
VariationXString = "0,00"
End If
VariationXString = Replace(VariationXString, ",", ".")
In this exemple
The result will be "+0.5"
But I want "+0.50" because in some case, the VariationX could be "10,50", "1,20", "-2.8" or simply "1". And I always need to have 2 digit after the comma.
Was going to use InStr, Len and Mid, but this would make a lot of line just for this.
Sorry to be boring, but this looks like a job for a custom number format...
Number formats are structured like so: [positive];[negative];[zero];[text]. So you want something like this:
"+"#,##0.00;"-"#,##0.00;#,##0.00
I get 0.00 for any zero value, +0.50 for 0.5, and -0.25 for -0.2463.
The representation of a value is different from that value. If you want to be able to use 0.5 in calculations, having it stored as "+0.50" is going to cause headaches - but having it stored as 0.5 and represented as +0.50 won't break anything.
If the presentation concern needs to be addressed in code (e.g. if you want that formatted string value to show up in some form's TextBox), then you can use the Strings.Format function to get the same result:
Public Function PrettifyVarianceFigure(ByVal value As Double) As String
PrettifyVarianceFigure = Strings.Format$(value, _
IIf(value > 0, "+", vbNullString) & _
"0" & Application.International(xlDecimalSeparator) & "00")
End Function
You can convert back to /round-trip to a Double by using the standard conversion functions*:
Debug.Print CDbl(PrettifyVarianceFigure(0.42)) ' outputs 0.42
*I doubt CDbl will handle a non-dot decimal separator though, so you might need to make a Strings.Replace call first.

Passing a variable into Left(string, VariableHere) not working

I have a data import file that has dates on it without a comma (i.e. January 1 2015). Excel won't recognize this as a date, and I need to work with these dates to find other dates (i.e. Date + Length of trip to find the last day of the trip, etc.)
I'm trying to use VBA to accomplish this and have the logic down but I'm encountering an error.
I'm taking the length of the date (January 1 2015), the 5 right characters (2015), the left of the whole length minus the 5 right characters(JANUARY 1), and then combining these variables with a comma inserted: Left(value-5) & ", " & Right(value, 5)
I'm using this code:
'correct date from JANUARY 1 2000 to JANUARY 1, 2000 so excel can recognize as date
LengthTrpDpt = Len(wb1.Sheets("BL Import").Cells(ioi, TrpDepCol)) 'length of date
LengthRightTrpDPt = Right(wb1.Sheets("BL Import").Cells(ioi, TrpDepCol), 5) 'finds right 5 of date " 2015"
NewListedDate = Left(wb1.Sheets("BL Import").Cells(ioi, TrpDepCol), LengthTrpDpt - 5) & ", " & LengthRightTrpDPt
The problem is with the NewListedDate variable. I can change the part LengthTrpDpt - 5 to a number and it works fine. For some reason I can't have an equation here though. I tried perform the equation in a separately saved variable (LengthMath = LengthTrpDpt - 5) and using LengthMath instead, but that doesn't work either.
LengthTrpDpt works fine and MsgBox's the correct number. Any ideas? Thanks!
You should just Split() the date string to get your three parts, then piece them back together however you'd like:
Dim a
a = Split(wb1.Sheets("BL Import").Cells(ioi, TrpDepCol))
NewListedDate = a(0) & " " & a(1) & ", " & a(2)
Use Range.TextToColumns method on the column of text-that-look-like-dates.
with worksheets("Sheet1").columns(1) '<-change this to reflect the actual worksheet and column
.TextToColumns Destination:=.cells(1,1), DataType:=xlFixedWidth, FieldInfo:=Array(0, 3)
end with
The 0 tells T2C that it should just put everything back into the original column. The 3 is the MDY TextFileColumnDataTypes property.
imho, it is ALWAYS better to work with numbers and dates rather than a string representation approximating them.

How to parse this specific type of data in excel VBA?

I have a bunch of different sets of engineering measurements in the format:
77.170 (+/- 0.025)
And I need to split it into the first number, which is the nominal value, and the number in the parenthesis, the tolerance. Not sure exactly how to do this in excel VBA. I was thinking I would use the Split function with a space delimiter, giving me the first number, then the unnecessary characters, then the tolerance, but the tolerance will include a parenthesis. How could I get rid of just that parenthesis, and will what I just suggested even work? Thanks!
Consider:
Sub dural()
s = "77.170 (+/- 0.025)"
s2 = Replace(Replace(Replace(s, " ", ""), "+/-", ""), ")", "")
ary = Split(s2, "(")
MsgBox ary(0) & vbCrLf & ary(1)
End Sub
Use Text to Columns and a formula.
Go to Data--->Text to Columns. Choose delimited and choose Space as your delimiter. This should split the text string into something like:
ColA |ColB|ColC
77.170|(+/-|0.025)
Column C is a bit funky, so let's just grab everything but the last character.
In column D put this:
=LEFT(C1,LEN(C1)-1)
Finally, you should get:
ColA |ColB |ColC |ColD |
77.170|(+/- |0.025)|0.025|
I would use a combination of instr() and mid to get what you need. For example
measurments="77.170 (+/- 0.025)"
mid(measurements,1,instr(measurements," "))
trim(mid(measurements,instr(measurements,"-")+1,instr(measurements,")")-instr(measurements,"-")-1))
or, to combine,
measurments="77.170 (+/- 0.025)"
mid(measurements,1,instr(measurements," ")) & " " & trim(mid(measurements,instr(measurements,"-")+1,instr(measurements,")")-instr(measurements,"-")-1))
Try using a combination of InStr(), Left(), Right().
Get the index/position of the '(' using InStr and then extract the characters using Left and Right. If you want to get the final data as a double or a Long use CDbl() or CLng() respectively.
For getting text out of other text consider using Regular Expresions.
To use them in VBA you will need in Reference 'VBScript_RegExp_55' library.
The reason why you might want to do that is because following code returns whatever first two numbers show up in your text( it can be modified to be much smarter than that), regardless of other text around it.
Dim Regex As RegExp
Dim Matches As MatchCollection
Set Regex = New RegExp
Regex.Pattern = "\d*\.\d*"
Regex.Global = True
Set Matches = Regex.Execute("77.170 (+/- 0.025)")
MsgBox (Matches(0).Value & " " & Matches(1).Value)
Assuming s is your measurement string, here is the most direct way:
v = Split(Left(s, Len(s) - 1), " (+/- ")
That's it. Now v(0) holds the nominal value and v(1) holds the tolerance.

Matching both \d and \. in a regular expression

I'm trying to match any combination of float numbers with a regular expression in VBA inside of Microsoft Word.
Example:
<text="">
<text="1">
<text="2">
<text="3">
<text="3.5">
<text="4">
<text="44">
I've tried the following patterns:
regex.Pattern = "<text=" & Chr(34) & "\d*\.*\d*" & Chr(34) & ">"
regex.Pattern = "<text=" & Chr(34) & "[\d\.]*" & Chr(34) & ">"
What's interesting is neither of these patterns will match the 44 either.
from the regex tester site,
Positive Integers --- ^\d+$
Negative Integers --- ^-\d+$
Integer --- ^-{0,1}\d+$
Positive Number --- ^\d*\.{0,1}\d+$
Negative Number --- ^-\d*\.{0,1}\d+$
Positive Number or Negative Number - ^-{0,1}\d*\.{0,1}\d+$
to test for the empty result being valid, and assuming all positive numbers, you would end up with
regex.Pattern = "<text=" & Chr(34) & "\d*\.{0,1}\d*" & Chr(34) & ">"
Let's break it down. A floating point number has two parts, integral and decimal. There are some choices on the format:
Here is pattern for a pretty common notation:
regex.Pattern = "<text=" & Chr(34) & "(-?\d+(\.\d+)?)?" & Chr(34) & ">"
Some choices:
Do you want to support omitting the integral part? (e.g. '.001')
Use * instead of + in the first number match: (-?\d*(\.\d+)?)?
Do you want to support leading zeros? (e.g. 000.)
This is gonna be more tricky :)
Do you want to support decimal point without decimal part? (e.g. '12.')
Then add ? after the decimal point match: (-?\d*(\.?\d+)?)?
Is the decimal part mandatory?
Remove the very last ?: (-?\d*(\.?\d+))?