Convert string to double in word (vba) - vba

I am trying to convert a text in a word document to be a double, so I can do currency formatting on it. I receive this text from a mail merge. How would I create a macro that can receive this text and return it as a number?
I'm unfamiliar with word, and VBA script. What I have made so far is
Function stringToDouble(baseString As String)
Dim num As Double
num = Val(baseString)
stringToDouble = num
End Function
I'm not sure how I would call this macro. Because it takes a parameter it does not show up in the macro table.
I may be completely off on how to convert text to a double in word, but any help is appreciated.
Thanks. Please comment for any clarifications.

You don't need a macro for this!!! All you need do is learn how to use formatting switches in Word fields.
To control number & currency formatting in Word, add a numeric picture switch to the mergefield. To do this:
select the mergefield;
press Shift-F9 to reveal the field coding. It should look something like {MERGEFIELD MyData};
edit the field so that you get {MERGEFIELD MyData # $,0.00} (or whatever other numeric format you prefer - see below);
position the cursor anywhere in this field and press F9 to update it.
Note 1: The '# $,0.00' in the field is referred to as a numeric picture switch. Other possibilities include:
# 0 for rounded whole numbers
# ,0 for rounded whole numbers with a thousands separator
# ,0.00 for numbers accurate to two decimal places, with a thousands separator
# $,0 for rounded whole dollars with a thousands separator
# "$,0.00;($,0.00);'-'" for currency, with brackets around negative numbers and a hyphen for 0 values
Note 2: The precision of the displayed value is controlled by the '0.00'. You can use anything from '0' to '0.000000000000000'.
If you use a final ';' in the formatting switch with nothing following, (eg # "$,0.00;($,0.00);") zero values will be suppressed. Note that this suppresses 0s resulting from empty fields and from fields containing 0s.
Note 3: If you use a decimal tab or right-aligned tab to align the values, wrap the switch in quotes (i.e. # "$,0.00") and insert a tab into the field code after the $ sign, you can have the values output with the decimal alignment occurring after the $ sign.
For more Mailmerge Tips & Tricks, see: https://www.msofficeforums.com/mail-merge/21803-mailmerge-tips-tricks.html

If you want to convert the number to a Double data type then try this:
Function StringToDouble(ByVal baseString As String) As Double
StringToDouble = VBA.CDbl(baseString)
End Function
If you're only concerned about formatting currency, convert the string to the Currency data type like this:
Function StringToCurrency(ByVal baseString As String) As Currency
StringToCurrency = VBA.CCur(baseString)
End Function
You will still need to format the number but both functions give you a number that can be formatted.
Here's an example that also gives you a string formatted as USD (e.g. $4,999.75). It requires the StringToCurrency function above.
Sub test()
Dim stringNum As String
stringNum = "4,999.754501"
Debug.Print "stringNum=" & stringNum ' outputs 4,999.754501
Dim currencyNum As Currency
currencyNum = StringToCurrency(stringNum) ' outputs 4999.7545
Debug.Print "currencyNum=" & currencyNum
Dim formattedString As String
formattedString = Format$(currencyNum, "$#,##0.00")
Debug.Print "formattedString=" & formattedString ' outputs $4,999.75
End Sub

Related

Formatting Main Part of Number While Keeping the decimal part untouched in VBA

I need to format the main part (whole) of a number without touching or affecting the decimal part:
12345.123456 becomes 12,345.123456
123.123 becomes 123.123
12345678.123 becomes 12,345,678.123
123 becomes 123
The fractional part length is variable in length of decimal places and need to be kept untouched (as is).
The formatting applies only to the whole number. Formatting the whole number is simple, but how to not affect the decimal part.
The Format parameter should work with any length of decimal places.
I am using the following:
Format(123456789.12345,"#,#.#############################")
However, the only problem with this solution is:
There is always an assumption on the maximum possible number of decimal places by the number of # used.
If the number is without a fraction say "123.0" or "123", the output will be "123." always with a decimal separator (dot).
Thanks
Like #nicomp said you'll want to break this into two parts.
dim num as string 'or a double converted to a string
dim nums() as string 'array
num = 123456789.123456
nums = split(num, ".") 'break into array at decimal
nums(0) = format(nums(0), "###,###") 'format whole numbers
num = nums(0) & "." & nums(1) 'recombine
This should add a comma after every three whole numbers

extract airlines from flight numbers strings in excel

I have problem of extracting two-character code from the string format like:
"VA198-VA200-VA197"
I just want to get the string:
"VA-VA-VA"
Also the data I have are not just in one format, some data is like:
"DL123-DL245"
or
"DL123-VA345-HU12-OZ123"
Does anyone know how to do it fast in excel? Thanks.
With data in A1, in B1 enter the array formula:
=TEXTJOIN("",TRUE,IF(ISERR(MID(A1,ROW(INDIRECT("1:100")),1)+0),MID(A1,ROW(INDIRECT("1:100")),1),""))
NOTE:
The formula strips out all numeric characters, leaving only the alphas and the dash.
Array formulas must be entered with Ctrl + Shift + Enter rather than just the Enter key. If this is done correctly, the formula will appear with curly braces around it in the Formula Bar.
There are a couple of ways you can approach this depending on how many possible segments their are in your string. If we assume your flight number is in A1:
First Segment: =LEFT(A1,2)
Second Segment: =MID(A1,FIND("-",A1)+1,2)
Third Segment: =MID(A1,FIND("-",A1,FIND("-",A1)+1)+1,2)
You could then concatenate the three expressions together and add a fourth with some conditionals. The problem is that based on your information you can have anywhere from 1 to 4 (at least) names which means you'll need a conditional:
Second Segment: =IF(ISERR(FIND("-",A1)),"",MID(A1,FIND("-",A1)+1,2))
Adding in the separators we end up with something like this for up to four segements:
=CONCATENATE(LEFT(A1,2),IF(ISERR(FIND("-",A1)),"",CONCATENATE("-",MID(A1,FIND("-",A1)+1,2))),IF(ISERR(FIND("-",A1,FIND("-",A1)+1)),"",CONCATENATE("-",MID(A1,FIND("-",A1,FIND("-",A1)+1)+1,2))),IF(ISERR(FIND("-",A1,FIND("-",A1,FIND("-",A1)+1)+1)),"",CONCATENATE("-",MID(A1,FIND("-",A1,FIND("-",A1,FIND("-",A1)+1)+1)+1,2))))
This will give you everything in one field.
Here is a VBA type answer.Assuming all strings are structured in the same way. Meaning Two letters followed by numbers and separated with "-". If one such string is A1, and you want to write the result to B1:
Sub BreakStrings()
d = Split(Range("A1"), "-")
For i = LBound(d) To UBound(d)
d(i) = Left(d(i), 2)
Next i
strg = Join(d, "-")
Range("B1") = strg
End Sub
User-defined function (UDF):
Function GetVal(cell)
With CreateObject("VBScript.RegExp")
.Global = True: .Pattern = "(\w{2})(.+?)(?=-|$)"
GetVal = .Replace(cell, "$1")
End With
End Function

convert an integer variable to a string with leading zeros in VBA

For starters, there are LOTS of questions that have been asked with this topic. However all the ones I kept clicking on were in languages other than VBA and I did not understand the syntax of those languages.
When I did a google search I found this answer which seemed promising. AH FIDDLE STICKS! I just realized that answer for VB and probably explains why its not working in my VBA
Situation
I have a variable called DimScale that is an integer. I want to create a string called DimName that will start with "mm-" and be following by the integer from DimScale with leading 0s such that there are a minimum of characters after "mm-".
IF DimScale = 25
Then DimName = "mm-0025"
IF DimScale = 235
Then DimName = "mm-0235"
Note Dimscale >=1 and <= 9999
What I have tried
Dim Dimscale as Integer
Dim Dimension_Style_Name as String
String.Format("{0:0000}", DimScale)
Dimension_Style_Name = DimScale$
Dimension_Style_Name.Format("{0:0000}", DimScale)
I have read the gist too that Dimscale get converted to a string and then is sent through a loop of adding a leading zero until the length of the string equals the 4 characters in my case for the integer part.
I have also seen the case with IF statments where IF Dimscale <10 then "000"& If Dimscale <100 then "00"& etc.
Is there a way to do it like like the VB method in VBA?
maybe:
DimName = "mm-" & format(DimScale,"0000")
As per #MathieuGuindon valuable (as usual) contribution:
Format (fully-qualified VBA.Strings.Format) takes a Variant parameter, and returns a Variant - you can also use its little brother Format$, which takes a String and returns a String, eliminating implicit conversions along the way
I had a similar need to apply leading zeros ( 12 to 00012 ) to a specified range. But everything I'd found thus-far used an iterative cell-by-cell approach. I found an older but still valuable posting from SiddHarth Rout. His posting pertains to case conversion ( lower to upper case ) but I found it adapted nicely to applying leading zeros.
Here is link to SiddHarth's posting:
Convert an entire range to uppercase without looping through all the cells
Here is the adaptation for applying leading zeros to a specified range:
Sub rngLeadingZeros(rng As Range, nbrZeros As Integer)
' Add leading zeros to a specified range.
Dim strZeros As String
Dim x As Integer
'build string as required for text() function:
For x = 1 To nbrZeros
strZeros = strZeros & "0"
Next
'make sure the range is formatted as text:
rng.NumberFormat = "#"
'apply the format to the range:
rng = Evaluate("index(text(" & rng.Address & ", """ & strZeros & """),)")
End Sub
Sub testZ()
With ActiveSheet
rngLeadingZeros .Range("e3:e9"), 5
End With
End Sub

Convert string a double in a word macro

I am trying to create a macro for Word 2013 that does the following: the macro should capture the value of a cell of a word table and then add another value and paste the result in another cell of the same table.
My code so far is:
Sub prueba()
Dim a As String, b As String, c As String
Dim entero1 As Double, entero2 As Double
Dim resultado As Double
Dim tabla1 As Table
Set tabla1 = ActiveDocument.Tables(1)
a = tabla1.Cell(Row:=1, Column:=3).Range
entero1 = CDbl(a)
End Sub
But when I run it I get an error 13
To evaluate the error add the following two lines to validate if the data type obtained in "a" was a string
MsgBox (TypeName(a))
MsgBox (a)
And I got the following
I believe that the CDbl function does not finish converting the string to double because as they see the chain has a small square, what is not like to erase it so that the conversion is achieved.
Thank you very much for your help.
One way of extracting just the numeric portion of the Range would be to use the Val function, e.g.
entero1 = Val(a)
If the string a contained, for instance, 123.23XYZ4567 then Val(a) would return the number 123.23.
That should ensure that the non-numeric character that you are getting at the end of your Range is removed.
The answer provided by YowE3K is elegant and has my vote. For further information:
That 'small square' is the end of cell marker which is part of Cell.Range.Text (.Text is the default property returned when returning a range object is inappropriate).
To actually remove the end of cell marker (Chr(13) & Chr(7)) you can use something like this:
?CDbl(Replace$(Selection.Range.Cells(1).Range.Text, Chr(13) & Chr(7), vbNullString))
A possible advantage of this approach is that it may provide better opportunity to trap errors if you are only expecting numeric characters.

Copying a specfic line within a cell into another cell

I have a spreadsheet that has multiple lines within a cell, all with line breaks.
e.g.
Name: a
Age: 1
University: 1
Degree: 3
Year: 3
I am looking to extract (in this example) the University infomation that is contained within the cell and copy it into another cell in another column.
There are about 1000 records in my document so to copy and paste by hand will be time consuming.
Any help will be appreciated
Cheers
Joe
You could do this with an Excel formula.
Assuming your data is in column A, and you want the extraction in column B, and assuming you put a title in row 1, you could do as in the following image:
(Note that I have a semi-colon in the formula as list separator, use comma instead)
The formula in B2 is:
=MID($A2, FIND(B$1, $A2) + LEN(B$1),
FIND(CHAR(10), $A2 & CHAR(10), FIND(B$1, $A2)) - FIND(B$1, $A2) - LEN(B$1))
The formula has some duplication; here are some of the parts explained:
FIND(B$1, $A2) returns the position of the title in the text
FIND(B$1, $A2) + LEN(B$1) returns the position of what follows that title in the text
FIND(CHAR(10), $A2 & CHAR(10), FIND(B$1, $A2)) returns the position of a newline character following the title, making sure that if none is present, a position beyond the string length is returned
As long as you put the column titles to whatever sub-string you are looking for, you can copy/drag the same formula to other columns and rows.
If there is a single break between each line, then in B1 enter:
=TRIM(MID(SUBSTITUTE($A1,CHAR(10),REPT(" ",999)),COLUMNS($A:C)*999-998,999))
This assumes that:
the university line is the third line
you want the entire line
I'm providing an answer even though you haven't provided what attempts you've made so far, which is how questions on this site usually work...but today I'm feeling generous :)
Use a combination of MID and FIND formulas, like the following:
=MID(A1,FIND("University",A1),FIND("Degree",A1)-FIND("University",A1)-2)
I put your example text in Cell A1 for my test, and it returned University: 1. This however will only work if University is always followed by Degree in the text strings.
The other method would be to replace the last part of your MID statement (the part asking for length to return) with the exact number of characters to return, which in this case would be 13, like the following:
=MID(A1,FIND("University",A1),13)
This assumes that the integer associated with University is always 1 character in length.
Either way, a combination of the above two formulas should get you what you need. VBA should not be necessary in this case.
Lines in a cell value are separated by the line feed character vbLf, so to extract the information out of the cell value you can use String-Functions Mid(...) and InStr(...):
Dim cellValue as String
Dim extracedValue as String
Dim keyWord as String
Dim posStart as Integer, posEnd as Integer
extractedValue = "" ' Not necessary, but I prefer initialized variables
cellValue = ActiveSheet.Cells(1,1).Value ' Put your cell here
keyWord = "University" ' Put your keyword here
posStart = InStr(1, cellValue, keyWord) ' Find keyword in the string
If (posStart > 0) Then
posEnd = InStr(posStart, cellValue, vbLf) ' Find next line feed after the keyword
If (posEnd > 0) Then
extractedValue = Mid(cellValue, posStart, posEnd - posStart) ' Extract the value
End If
End If
I haven't tested the code, but you should get the idea.