Excel VBA: Input box with control characters - excel

I'm using an input box to retreieve QR-codes from reader.
Unfortunately, the parameters in the QR-code are separated by group separator characters (decimal ASCII code 29) and these characters are being omitted.
The read in string contains all the data, but I can't distinguish the single parameters anymore.
What can I do? Is there another way to read in a string WITH all the control characters?
Thank you for your help!

Without further action your inputbox result indeed gets displayed as string without (visible) Chr(29) group separators ... even though the InputBox string result still contains those characters.
Therefore you need to convert the input eventually; the following Example demonstrates possible ways:
Sub testInput()
'a) Provide for QR results
Dim qr(0 To 2) As Variant
'b) Provide for default using Chr(29) group delimiters
Dim DefaultInput
DefaultInput = "a" & Chr(29) & "b" & Chr(29) & "c" & vbNewLine
'c) Execute InputBox (and assign to first QR result)
qr(0) = "0. Visible Input: " & InputBox("Enter QR", "QR input", DefaultInput)
'd) Convert visible inputs to 2nd and 3rd QR result
qr(1) = "1. Replaced Chr(29): " & Replace(qr(0), Chr(29), ",")
qr(2) = "2. Splitted Chr(29): " & Join(Split(qr(0), Chr(29)), "|")
'e) Show all three QR results
MsgBox Join(qr, vbNewLine)
End Sub
Further hint
If you need to get the different group results separately, I'd choose the split function (without joining the 0-based 1-dimensional array elements immediately, which was only done for display in the messagebox).

Related

VBA Dynamically Building A Formula From An Array

I am trying to dynamically construct a formula based on an array that I have generated from a cell (separated by commas), as there is a varying amount of elements in the array I need to append a new "formula block" with the updated element to use in a if statement that is generated after the for each loop. VBA is throwing a type mismatch error in the InvestigateFormula = line, here is my code:
For Each Type In ToIgnore()
InvestigateFormula = "(ISNUMBER(SEARCH(*" & ToIgnore(Type) & "*," & _
AssetTypesCol & "2)),"
FullFormula = InvestigateFormula & FullFormula
Next Asset
FinalInvestigateFormula = "=IF(OR" & FullFormula & "),""Ignore"", """")"
ActiveCell.Formula = FinalInvestigateFormula
Please let me know if there is an easier way of doing this or how I might be able to correct the above code. Btw I am not declaring a variant I am simply declaring ToIgnore() as String and using the split function from the variable which contains the comma separated values to generate the array/items to loop over.
"Type" is a reserved name? Try strType instead?

Custom number (price) format independent of localization

I am wondering is it possible to have custom number format using Excel formula that will not be dependent on localization of Excel application (EU/US)?
For example I have value 1291660.
Then using formula =TEXT(A1;"# ##0,00"). I get as an output 1 291 660,00. The target is to have in any case 1.291.660,00 as an output. Any Excel professional to give an advice?
I have tried =TEXT(A1;"#.##0,00") - This didn't work
I think VBA is the only solution to this. I have found my old question about the same topic, but it seems that solution provided is not working for some reason?
Ultimate 1000 separator using VBA
Function CustomFormat(InputValue As Double) As String
Dim sThousandsSep As String
Dim sDecimalSep As String
Dim sFormat As String
sThousandsSep = Application.International(xlThousandsSeparator)
sDecimalSep = Application.International(xlDecimalSeparator)
' Up to 6 decimal places
sFormat = "#" & sThousandsSep & "###" & sDecimalSep & "######"
CustomFormat = Format(InputValue, sFormat)
If (Right$(CustomFormat, 1) = sDecimalSep) Then
CustomFormat = Left$(CustomFormat, Len(CustomFormat) - 1)
End If
' Replace the thousands separator with a space
' or any other character
CustomFormat = Replace(CustomFormat, sThousandsSep, " ")
End Function
By replacing CustomFormat = Replace(CustomFormat, sThousandsSep, " ") with CustomFormat = Replace(CustomFormat, sThousandsSep, ".") output is .1 291 660
You may use:
=SUBSTITUTE(SUBSTITUTE(FIXED(A1,2,0),",","."),".",",",INT(LEN(A1)/3)+1)
The way it works is that on an EU-system FIXED() will return: 1.291.660,00 but on an US-system it should return 1,291,660.00. To create the same output-string, we can SUBSTITUTE() all comma's to dots. A 2nd SUBSTITUTE() will then replace only the last dot back to a comma. To find the right index I used INT(LEN(A1)/3)+1 which works well on itegers like 1291660. If you happen to have decimal values, you can change this to:
=SUBSTITUTE(SUBSTITUTE(FIXED(A1,2,0),",","."),".",",",INT(LEN(INT(A1))/3)+1)
EDIT:
The above should always return the desired format, but it's a string. To return the numeric value in any further calculations, you can use NUMBERVALUE():
=NUMBERVALUE(C1,",",".")
Go to excel file tab, click options and then the following options as desired
Uncheck use system separators and define your own
You don't need VBA for this. You can use SUBSTITUTE to replace the default separator characters, and you can detect what these are by cutting them out from the formatted string of a known number. I use ASCII 1 (SOH) character to avoid replacing twice (e.g. replacing thousands separator from " " to ".", than replacing decimal separators from "." to "," would cause that thousands separators appear as ","):
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(TEXT(1234567.89,"# ##0.000"),MID(TEXT("# ##0",1000),2,1),CHAR(1)&" "),MID(TEXT("0.0",0.1),2,1),CHAR(1)&","),CHAR(1)&" ","."),CHAR(1)&",",",")
This will output "1.234.567,890".
This output will appear as a string (you cannot add numbers to it, and it is left adjusted by default), and you cannot change this behavior if you don't use Excels local settings for separators.
BTW, using " " for thousands separator and either "." or "," for decimals is the clearest way of displaying numbers.

Validation of a dialog box for the update of fields "Mailmerge Fillin"

I'm looking for a way to validate those dialog boxes that pop up while updating a word document via excel vba.
The type of fields that I use is MailMerge Fields type "Fillin"
WordObj.ActiveDocument.MailMerge.Fields.AddFillIn
I'd like to write in them if possible too.
Update operation
Dialog box
It is by no means clear what you're trying to achieve. When you use:
ActiveDocument.MailMerge.Fields.AddFillIn
the resulting field doesn't show up in the document until something is done to cause it to update (e.g. performing the mailmerge). If you want the field to show up, use something like:
Dim wdFld As Object
With WordObj.ActiveDocument
Set wdFld = .Fields.Add(.Range.Characters.Last, -1, "QUOTE ""Default Text""", False)
wdFld.Code.Text = "FILLIN ""Some prompt"" \d ""Default Text"" \o"
End With
Other than that, you really do need to both explain how and why you're using a FILLIN field and post the code that updates it when the mailmerge is executed. After all, the use of a FILLIN field typically means the user is supposed to both make an input and press the OK/Cancel button.
To allow the specification of different ranges, prompts and defaults, you might use something like:
Sub FILLIN(StrBkMk As String, StrPrmpt As String, StrDflt As String)
Dim wdFld As Object
Dim quote As String
quote = char(34)
With WordObj.ActiveDocument
Set wdFld = .Fields.Add(.Bookmarks(StrBkMk).Range, -1, "QUOTE " & quote & StrDflt & quote, False)
wdFld.Code.Text = "FILLIN " & StrPrmpt & " \d " & StrDflt & " \o \* MERGEFORMAT "
End With
End Sub
where 'StrBkMk' is the name of a bookmark you want to position the field at. You'd then call the above code with something like:
Call FILLIN("FILLIN1", nom_signet, nouveau_texte_signet)
Or, if you're passing multi-word strings:
Call FILLIN("FILLIN1", "" & nom_signet & "", "" & nouveau_texte_signet & "")

Why does Excel treat double spaces as a comma?

I wrote an export to CSV file in my vb.net application, and I then exported it into Outlook.
The issue I've got, is that when the CSV file is being written, my code is checking for a comma in the current field, but while doing this, it also mistakes a double space for a comma, or space followed by 'Enter' key being pressed (for multiline textboxes)
An example would be if in the notes section of the customer, there is 4 lines of text, and one ends in a space - The user has then pressed enter to go to the next line, however the program is taking the next line of text and creating a new record for it, as it thinks it's a comma...
What is the reason for this? This means that data has to be super validated (ie checking for no double spaces etc) before it can be exported, which is far too time consuming.
Hopefully this makes sense!
This is the code:
Dim result As Boolean = True
Try
Dim sb As New StringBuilder()
Dim separator As String = ","
Dim group As String = """"
Dim newLine As String = Environment.NewLine
For Each column As DataColumn In dtable.Columns
sb.Append(wrapValue(column.ColumnName, group, separator) & separator)
Next
sb.Append(newLine)
For Each row As DataRow In dtable.Rows
For Each col As DataColumn In dtable.Columns
sb.Append(wrapValue(row(col).ToString(), group, separator) & separator)
Next
sb.Append(newLine)
Next
The code for wrapValue
Function wrapValue(value As String, group As String, separator As String) As String
If value.Contains(separator) Then
If value.Contains(group) Then
value = value.Replace(group, group + group)
End If
value = group & value & group
End If
Return value
End Function
Based on the fact that it's shortening it by 430 lines, I'd suggest it's something to do with the fact you're adding a load of "" before and after the value variable.
If it's removing a value at the start, then it will be removing a " before the first column header. As to why it's importing one record as you mentioned in the comments, I'm not entirely sure, however, I would suggest the issue lies in your wrapValue code.
Can you try changing
value = group & value & group
to
value = value
and see if that changes anything?

Finding multiple instance of a variable length string in a string

I'm trying to extract my parameters from my SQL query to build my xml for an SSRS report. I want to be able to copy/paste my SQL into Excel, look through the code and find all instances of '#' and the appropriate parameter attached to it. These paramaters will ultimately be copied and pasted to another sheet for further use. So for example:
where DateField between #FromDate and #ToDate
and (BalanceFiled between #BalanceFrom and #BalanceTo
OR BalancdField = #BalanceFrom)
I know I can use Instr to find the starting position of the first '#' in a line but how then do I go about extracting the rest of the parameter name (which varies) and also, in the first two lines of the example, finding the second parameter and extracting it's variable lenght? I've also tried using the .Find method which I've been able to copy the whole line over but not just the parameters.
I might approach this problem like so:
Remove characters that are not surrounded by spaces, but do not
belong. In your example, the parentheses need to be removed.
Split the text using the space as a delimiter.
For each element in the split array, check the first character.
If it is "#", then the parameter is found, and it is the entire value in that part of the array.
My user-defined function looks something like this:
Public Function GetParameters(ByRef rsSQL As String) As String
Dim sWords() As String
Dim s As Variant
Dim sResult As String
'remove parentheses and split at space
sWords = Split(Replace(Replace(rsSQL, ")", ""), "(", ""), " ")
'find parameters
For Each s In sWords
If Left$(s, 1) = "#" Then
sResult = sResult & s & ", "
End If
Next s
'remove extra comma from list
If sResult <> "" Then
sResult = Left$(sResult, Len(sResult) - 2)
End If
GetParameters = sResult
End Function

Resources