How to put a line break in between each item in a merge field (for formatting purposes) - line-breaks

I have a Mail Merge attached to a SQL query that I need to reformat. The 'action_name' field was inserted and works properly. [EDIT: To clarify, all of the data appears under one mergefield name called "action_name"].
For example, it will appear in the letter like this:
PersonA, You are missing the following items: 'A, B, C, D, E and F.'
PersonB, You are missing the following items: 'A and B'
PersonC, You are missing the following items: 'A'
PersonD, You are missing the following items: 'A, B, C and D'
Of course each person receives their own letter, so they only see their own missing items.
When we give the letter to the other department, they have to manually hit enter on each time to reformat the letter and make it look like this:
PersonA, You are missing the following items:
'A,
B,
C,
D,
E,
F'
I will only do PersonA in this example. I think you get the idea.
How can I do this using code in a Mail Merge (or in the SQL code) so that others don't have to do this manually? I already know that the \v vertical formatting doesn't work for this. I read that it's for East Asian languages. Thanks for any tips!

From your description, "A, B, C, D, E and F" and "A and B" are each output via a single mergefield. Word has no field coding mechanism to insert breaks into such content. Inserting breaks would be trivial if the output was generated by separate mergefields. you could, of course, add a macro to the mailmerge main document to automate the post-merge processing. For example the following macro intercepts the 'Merge to Individual Docuemtns' action to do all the processing:
Sub MailMergeToDoc()
Application.ScreenUpdating = False
ActiveDocument.MailMerge.Execute
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchWildcards = True
.Text = "('[A-Z],)"
.Replacement.Text = "^l\1"
.Execute Replace:=wdReplaceAll
.Text = "([A-Z],) "
.Replacement.Text = "\1^l"
.Execute Replace:=wdReplaceAll
.Text = "([A-Z]) and ([A-Z])"
.Replacement.Text = "\1,^l\2"
.Execute Replace:=wdReplaceAll
End With
Application.ScreenUpdating = True
End Sub

You can use SQL to insert a line break character between each list item before it gets to Word. Depending on what system you are on, the syntax will be different but you should have a function to concatenate an ascii character code 10.
For example on Transact-SQL/SQL Server:
SELECT 'A' + char(10) + 'B' + char(10) + 'C'
or to replace commas with line breaks:
SELECT replace('A, B, C', ',', char(10))

Related

How to create a regex VBA macro for GIIN format validation

I'm trying to create a macro that will verify data in one column and then let me know if they are correctly formatted in the next column. I am very new to VBA so I apologize if my code is messy.
The format I am trying to verify is ABC123.AB123.AB.123 -- The first two sections can contain letters/numbers, the third section only letters, and the last section only numbers.
Any guidance would be greatly appreciated!
Function ValidGIIN(myGIIN As String) As String
Dim regExp As Object
Set regExp = CreateObject("VBScript.Regexp")
If Len(myGIIN) Then
.Global = True
.IgnoreCase = True
.Pattern = "[a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][.][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_][.][a-zA-z_][a-zA-z_][.][0-9][0-9][0-9]"
End With
If regExp.Test(myGIIN) = True Then
ValidGIIN = "Valid"
Else
ValidGIIN = "Invalid"
End If
End If
Set regExp = Nothing
End Function
Try the following pattern
[a-zA-Z0-9]{6}\.[a-zA-Z0-9]{5}\.[A-Za-z]{2}\.\d{3}
You could call your function in a loop over cells in a column and use offset(0,1) to write result to next column to right.

regex search nested dictionary and stop on first match (python)

I'm using a nested dictionary, which contains various vertebrates types. I can currently read the nested dictionary in and search a simple sentence for a keyword (e.g., tiger).
I would like to stop the dictionary search (loop), once the first match is found.
How do I accomplish this?
Example code:
vertebrates = {'dict1':{'frog':'amphibian', 'toad':'amphibian', 'salamander':'amphibian','newt':'amphibian'},
'dict2':{'bear':'mammal','cheetah':'mammal','fox':'mammal', 'mongoose':'mammal','tiger':'mammal'},
'dict3': {'anteater': 'mammal', 'tiger': 'mammal'}}
sentence = 'I am a tiger'
for dictionaries, values in vertebrates.items():
for pattern, value in values.items():
animal = re.compile(r'\b{}\b'.format(pattern), re.IGNORECASE|re.MULTILINE)
match = re.search(animal, sentence)
if match:
print (value)
print (match.group(0))
vertebrates = {'dict1':{'frog':'amphibian', 'toad':'amphibian', 'salamander':'amphibian','newt':'amphibian'},
'dict2':{'bear':'mammal','cheetah':'mammal','fox':'mammal', 'mongoose':'mammal','tiger':'mammal'},
'dict3': {'anteater': 'mammal', 'tiger': 'mammal'}}
sentence = 'I am a tiger'
found = False # Initialized found flag as False (match not found)
for dictionaries, values in vertebrates.items():
for pattern, value in values.items():
animal = re.compile(r'\b{}\b'.format(pattern), re.IGNORECASE|re.MULTILINE)
match = re.search(animal, sentence)
if match is not None:
print (value)
print (match.group(0))
found = True # Set found flag as True if you found a match
break # exit the loop since match is found
if found: # If match is found then break the loop
break

How can I remove multiple text within parentheses with a regex in VB ArcGIS field calculator?

The "Comment" field records include samples like:
"Line marker, Fence, Test station (Single: Struct P/S -1.2375V IRF -1.0976V) (ACV: 0.0412V)"
"Direction: DownStreamDate Collected: 5/8/2013:START POS RUN ON , Line marker, Test station, Fence, , Aerial marker , 222 MP 221.89 CALI 0.2 0.3 SUNNY END WARM"
I am attempting to omit all text within parentheses from Comments records in a "CrossingName" Field.
I am using:
Pre-Logic Script Code:
Set re = CreateObject("VBScript.RegExp")
With re
.Pattern = "\([^()]*\)"
.Global = False
.IgnoreCase = False
End With
CrossingName = re.Execute(targetString).Item(0)
The regular expression is not returning every instance of parentheses. I copied this to try and isolate the parentheses text. I want to omit every portion of text inside parentheses. Many records have two sets of parentheses. Other questions did not address this specific scenario. Thank you for your assistance.
Currently the script throws an error and only works on one record.
sample

how do i extract only 5-digit strings from cells in excel?

I have a bunch of data which contains any number of 5-digit strings in completely inconsistent formats, and i want to extract these 5-digit strings (in bold) out. I am not bothered about strings containing less than or more than 5-digits. as an example, this is the kind of data i have in my file
Cell A1: "1. 76589 - wholesale activities. 2. 33476 - general"
Cell A2: "WHOLESALE ACTIVITIES (76589). SHIPPING (12235). REAL
ESTATE ACTIVITIES (67333)"
Cell A3: "1. 33476 General. 658709 annual road. Unknown 563"
I've tried the usual SEARCH/FIND, MIN, LEFT/RIGHT/MID functions, but am not sure how to get them to produce the result i need, and even text-to-columns wasn't giving me a clean result
thanks in advance
Here is a macro that will split your line into the columns as you requested.
The range being processed is whatever you have selected.
The results are written into the adjacent columns on the same row.
Depending on your worksheet setup, you may want to "clear out" the rows where the results are going before executing the extraction code.
You can also write code to select the data to be processed automatically. Plenty of examples on this forum.
Option Explicit
Sub Extract5Digits()
Dim R As Range, C As Range
Dim RE As Object, MC As Object, M As Object
Dim I As Long
Set R = Selection
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = True
.Pattern = "\b\d{5}\b"
For Each C In R
If .test(C.Text) = True Then
I = 0
Set MC = .Execute(C.Text)
For Each M In MC
I = I + 1
C.Offset(0, I) = M
Next M
End If
Next C
End With
End Sub
Simply with Excel functions this is impossibile.
The best way for you is to use the Regex 55 library in VBA.
Let's consider this example:
+---+--------------------------------------------------------------+
| | A |
+---+--------------------------------------------------------------+
| 1 | Cell A3: "1. 33476 General. 658709 annual road. Unknown 563" |
| 2 | 33476 |
+---+--------------------------------------------------------------+
From the Excel file hit Alt + F11, then go to Tools => Reference and select "Microsoft VBScript Regular Expression 5.5".
Then you can use the following function definition:
Public Function Get5DigitsNumer(search_str As String)
Dim regEx As New VBScript_RegExp_55.RegExp
Dim matches
GetStringInParens = ""
regEx.Pattern = "[0-9]{5}"
regEx.Global = True
If regEx.test(search_str) Then
Set matches = regEx.Execute(search_str)
GetStringInParens = matches(0).SubMatches(0)
End If
End Function
At this time you can use the following code:
Sub PatternExtractor()
Range("A2").Value = Get5DigitsNumer(Range("A1"))
End Sub
which take the value of cell A1 and extract the 5 digits numer, thn the result is saved into cell A2.
At the time I don't have any idea how this code could work where the same cell contains more than one time; like "Cell A1: "1. 76589 - wholesale activities. 2. 33476 - general" in your example.
I suggest you to have a look at this answer. The pattern is different but the question is really similar to yours.
The only way that you can do it is by writing a regex in VBA. I would recommend you to look at this question.

Changing substring in a String

I've got a variable "Variable" in VBScript that will receive different values, based on names that come from xml files i don't trust. I can't let "Variable" have forbidden caracters on it (<, >, :, ", /, \, |, ?, * ) or characters with accents (I think they are called accent in english) like (Á, á, É, é, Â, â, Ê, ê, ñ, ã).
So, my question is: How can I create a script that studies and replace these possible multiple possible characters in the variable I have? I'm using a Replace function found in MSDN Library, but it won't let me alter many characters in the way I'm using it.
Example:
(Assuming a Node.Text value of "Example A/S")
For Each Node In xmlDoc.SelectNodes("//NameUsedToRenameFile")
Variable = Node.Text
Next
Result = Replace(Variable, "<", "-")
Result = Replace(Variable, "/", "-")
WScript.Echo Result
This Echo above returns me "Example A-S", but if I change my Replaces order, like:
Result = Replace(Variable, "/", "-")
Result = Replace(Variable, "<", "-")
I get a "Example A/S". How should I program it to be prepared to any possible characters? Thanks!
As discussed, it might be easier to do things the other way around; create a list of allowed characrters as VBScript is not so good at handling unicode like characters; whilst the characters you have listed may be fine, you may run into issues with certain character sets. here's an example routine that could help your cause:
Consider this command:
wscript.echo ValidateStr("This393~~_+'852Is0909A========Test|!:~#$%####")
Using the sample routine below, it should produce the following results:
This393852Is0909ATest
The sample routine:
Function ValidateStr (vsVar)
Dim vsAllowed, vscan, vsaScan, vsaCount
vsAllowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
ValidateStr = ""
If vartype(vsvar) = vbString then
If len(vsvar) > 0 then
For vscan = 1 To Len(vsvar)
vsValid = False
vsaCount = 1
Do While vsaValid = false and vsaCount <= len(vsAllowed)
If UCase(Mid(vsVar, vscan, 1)) = Mid(vsAllowed, vsaCount, 1) Then vsValid = True
vsaCount = vsaCount + 1
Loop
If vsValid Then ValidateStr = ValidateStr & Mid(vsVar, vscan,1)
Next
End If
End If
End Function
I hope this helps you with your quest. Enjoy!
EDIT: If you wish to continue with your original path, you will need to fix your replace command - it is not working because you are resetting it after each line. You'll need to pump in variable the first time, then use result every subsequent time..
You had:
Result = Replace(Variable, "/", "-")
Result = Replace(Variable, "<", "-")
You need to change this to:
Result = Replace(Variable, "/", "-")
Result = Replace(Result, "<", "-")
Result = Replace(Result, ...etc..)
Result = Replace(Result, ...etc..)
Edit: You could try Ansgar's Regex, as the code is by far more simple, but I am not sure it will work if as an example you had simplified Chinese characters in your string.
I agree with Damien that replacing everything but known-good characters is the better approach. I would, however, use a regular expression for this, because it greatly simplifies the code. I would also recommend to not remove "bad" characters, but to replace them with a known-good placeholder (an underscore for instance), because removing characters might yield undesired results.
Function SanitizeString(str)
Set re = New RegExp
re.Pattern = "[^a-zA-Z0-9]"
re.Global = True
SanitizeString = re.Replace(str, "_")
End Function