Changing decimal separator in VBA - vba

I've written simple code in VBA (and seen questions here and here and none of these solutions work).
Dim toString As String
toString = cell.Value & "_"
If (InStr(toString, ",")) Then
toString = Replace(toString, ",", ".")
toString = Trim(toString)
cell.Value = " " + Left(toString, (Len(toString) - 1))
End If
Unfortunately, instead of string with dot separator, excel gives me double with comma in cell.Value. What curious is, when I exchange this whitespace with "_", it converts f. ex. 12,3 into _12.3. How can I fix it?
P.S. I add "_" at the end to ensure that toString will remain String.

I've had this issue before. You need to change the formatting of the cell before you write to it.
Application.Workbooks("Book1").Sheets("Sheet1").Range("A1:A100").NumberFormat = "#"
After that line runs you can simply write to the column like this:
Cells(1,1).Value = "12.3"
Excel will keep the string formatting and not convert it to a double.
Hope this helps.

Related

VBA InStr With ~

I'm trying to extract a date from a cell that is not in standard date format.
The Cell in Question has the string "10/9~10/13" in it.
I know this because I initially find the suspect cell by using a Range.Find function. (I tried .Value, .Value2, and .Text here to no avail).
text = .UsedRange.Find("~~").Value
If I use debug.Print text then
debug.Print text
10/9_10/13
Interestingly enough the ~ disappears. However, debug.Print also reveals this strange behavior.
d = InStr(1, "10/9_10/13", "_", vbTextCompare)
5
d = InStr(1, text, "_", vbTextCompare)
0
I thought perhaps text isn't a string?
debug.Print TypeName(text)
String
If you could explain why VBA is exhibiting this apparently inconsistent behavior that would be very useful.
As you have seen AscW returns -162, you can use that value to find the unicode char in vba
I put your data in D1 and then I ran:
Sub dural()
Dim dCell As String, txet As String
dCell = Range("D1").Value
Debug.Print dCell
txet = ActiveSheet.UsedRange.Find("~~").Value
Debug.Print txet
End Sub
(I used txet rather than text to avoid any confusion with the Property of the same name) and got:
Is it possible that what you have is not tilda but some other unicode character that looks like tilda?

Inputbox is not accepting double number VBA excel

I have a declaration like number= InputBox("Number for:", "Number:"), number is declared as Dim number As Double but when I enter a double number, for example 5.4, into the Inputbox and transmit it into a cell, the cell shows me 54, it deletes the point.
How can I fix this?
THX
If you want to detect which settings your Excel uses for the Decimal seperator, try the code below:
MsgBox "Excel uses " & Chr(34) & Application.DecimalSeparator & Chr(34) & " as a decimal seperator"
if you want to change it to ., then use the line below:
Application.DecimalSeparator = "."
Unfortunately, VBA is horrible at handling differences in decimal seprators. In your case, you should probably use a comma (,), instead of a punctuation/dot (.).
Edit: Using the Application.DecimalSeparator method, it now works regardless of regional settings. Be aware though, it seems to cause some issues if you change the comma separator settings for Excel (it seems that VBA somewhat ignores this setting). If you do not change that however, the example should work in all other cas
Sub GetNumberFromInputBox()
Dim val As String
Dim num As Double
'Get input
val = InputBox("Number for:", "Number:")
Debug.Print Application.DecimalSeparator
If IsNumeric(val) Then
'Try to convert to double as usual
num = CDbl(val)
'If the dot is removed automatically, then
'you will se a difference in the length. In
'those cases, replace the dot with a comma,
'before converting to double
If Len(val) <> Len(num) Then
If Application.DecimalSeparator = "," Then
num = CDbl(Replace(val, ".", ","))
Else
num = CDbl(Replace(val, ",", "."))
End If
End If
'Pring the number
Debug.Print "You selected number: " & num
Else
'If its not a number at all, throw an error
Debug.Print "You typed " & val & ", which is not a number"
End If
End Sub

Removing leading and trailing semicolons from a text in a cell

Suppose in a cell sometime text looks like
;ABCD;EFGH
;;ABCD;EFGH;
How to remove semicolon only from beginning and end. The outcome should be
ABCD;EFGH
I'm sure there's a better way to do this, but it works!
Public Function SplitSemiColon(s As String) As String
While Left(s, 1) = ";"
s = Mid(s, 2)
Wend
While Right(s, 1) = ";"
s = Left(s, Len(s) - 1)
Wend
SplitSemiColon = s
End Function
Place the code in a new module and use the function on the worksheet like this (for example):
=SplitSemiColon(A1)
If there are no spaces, another alternative can be to convert them to spaces, trim, and convert back:
=Substitute(Trim(Substitute(A1,";"," "))," ",";")
TRIM removes extra spaces, so the above would turn ;A;;;B; into A;B, but VBA Trim doesn't:
[A1] = Replace(Trim(Replace([A1],";"," "))," ",";") ' ";A;;;B;" into "A;;;B"
If there are any spaces, they can be replaced with a different character, but it gets too messy:
=Substitute(Substitute(Trim(Substitute(Substitute(A1," ","_"),";"," "))," ",";"),"_"," ")

Excel VBA Using wildcard to replace string within string

I have a difficult situation and so far no luck in finding a solution.
My VBA collects number figures like $80,000.50. and I'm trying to get VBA to remove the last period to make it look like $80,000.50 but without using right().
The problem is after the last period there are hidden spaces or characters which will be a whole lot of new issue to handle so I'm just looking for something like:
replace("$80,000.50.",".**.",".**")
Is this possible in VBA?
I cant leave a comment so....
what about InStrRev?
Private Sub this()
Dim this As String
this = "$80,000.50."
this = Left(this, InStrRev(this, ".") - 1)
Debug.Print ; this
End Sub
Mid + Find
You can use Mid and Find functions. Like so:
The Find will find the first dot . character. If all the values you are collecting are currency with 2 decimals, stored as text, this will work well.
The formula is: =MID(A2,1,FIND(".",A2)+2)
VBA solution
Function getStringToFirstOccurence(inputUser As String, FindWhat As String) As String
getStringToFirstOccurence = Mid(inputUser, 1, WorksheetFunction.Find(FindWhat, inputUser) + 2)
End Function
Other possible solutions, hints
Trim + Clear + Substitute(Char(160)): Chandoo -
Untrimmable Spaces – Excel Formula
Ultimately, you can implement Regular expressions into Excel UDF: VBScript’s Regular Expression Support
How about:
Sub dural()
Dim r As Range
For Each r In Selection
s = r.Text
l = Len(s)
For i = l To 1 Step -1
If Mid(s, i, 1) = "." Then
r.Value = Mid(s, 1, i - 1) & Mid(s, i + 1)
Exit For
End If
Next i
Next r
End Sub
This will remove the last period and leave all the other characters intact. Before:
and after:
EDIT#1:
This version does not require looping over the characters in the cell:
Sub qwerty()
Dim r As Range
For Each r In Selection
If InStr(r.Value, ".") > 0 Then r.Characters(InStrRev(r.Text, "."), 1).Delete
Next r
End Sub
Shortest Solution
Simply use the Val command. I assume this is meant to be a numerical figure anyway? Get rid of commas and the dollar sign, then convert to value, which will ignore the second point and any other trailing characters! Robustness not tested, but seems to work...
Dim myString as String
myString = "$80,000.50. junk characters "
' Remove commas and dollar signs, then convert to value.
Dim myVal as Double
myVal = Val(Replace(Replace(myString,"$",""),",",""))
' >> myVal = 80000.5
' If you're really set on getting a formatted string back, use Format:
myString = Format(myVal, "$000,000.00")
' >> myString = $80,000.50
From the Documentation,
The Val function stops reading the string at the first character it can't recognize as part of a number. Symbols and characters that are often considered parts of numeric values, such as dollar signs and commas, are not recognized.
This is why we must first remove the dollar sign, and why it ignores all the junk after the second dot, or for that matter anything non numerical at the end!
Working with Strings
Edit: I wrote this solution first but now think the above method is more comprehensive and shorter - left here for completeness.
Trim() removes whitespace at the end of a string. Then you could simply use Left() to get rid of the last point...
' String with trailing spaces and a final dot
Dim myString as String
myString = "$80,000.50. "
' Get rid of whitespace at end
myString = Trim(myString)
' Might as well check if there is a final dot before removing it
If Right(myString, 1) = "." Then
myString = Left(myString, Len(myString) - 1)
End If
' >> myString = "$80,000.50"

How do I translate them to standard format 1234567-01 using vba?

How do I format these
123-4267-01
12-34-56-701
1234567-01
1-2345-6701
12345670-1
123456701
1234567_01
and more fromats, note it may have - or may be _ in between
Now I have to convert the above types to these standard
1234567-01
Probably I think i should go for find but what i have to use xlatwhole or xlat? Or are there any better solutions than find to achieve these because I have 4000 rows so I need some faster performance better than looping.
I may have other than numeric numbers.
With VBA, just replace the dodgy _ & - characters & reformat;
Public Function fixup(sValue As String) As String
fixup = Replace$(sValue, "_", "")
fixup = Replace$(fixup, "-", "")
fixup = Left$(fixup, Len(fixup) - 2) & "-" & Right$(fixup, 2)
End Function
Or to strip any non-numeric;
Public Function fixup(sValue As String) As String
Dim i As Long
For i = 1 To Len(sValue)
If Not IsNumeric(Mid$(sValue, i, 1)) Then Mid$(sValue, i, 1) = "!"
Next
fixup = Replace$(sValue, "!", "")
fixup = Left$(fixup, Len(fixup) - 2) & "-" & Right$(fixup, 2)
End Function
If you are looking for fast performance, you could meet your requirement using an Excel worksheet function rather than VBA.
=LEFT(SUBSTITUTE(SUBSTITUTE(A1,"_",""),"-",""),LEN(SUBSTITUTE(SUBSTITUTE(A1,"_",""),"-",""))-2)&"-"&RIGHT(SUBSTITUTE(SUBSTITUTE(A1,"_",""),"-",""),2)
Assuming your target range starts in Cell A1, type this into the first row and copy down the whole range. Excel on my pc did c. 45,000 rows in < 1 second.
(NB: I am only suggesting this approach because you have tagged your question as excel-vba)