How to replace all spaces with new lines? - vba

I have a table that contains spaces in its headers
First Name Last Name Average Level Degree
_________________________________________________
Mike Lowel 25
Stan Wilson 35
Papa Peterson 15
I need it to look like this
First Last Average
Name Name Level
Degree
_____________________________________________
Mike Lowel 25
Stan Wilson 35
Papa Peterson 15
Here is what I tried
Sub test()
myString = ThisWorkbook.Worksheets(1).Range("a1").Value
ThisWorkbook.Worksheets(1).Range("a1").Value = Replace(myString, " ", CHAR(10))
ThisWorkbook.Worksheets(1).Range("a1").WrapText = True
ThisWorkbook.Worksheets(1).Range("a1").EntireRow.AutoFit
myString = ThisWorkbook.Worksheets(1).Range("b1").Value
ThisWorkbook.Worksheets(1).Range("b1").Value = Replace(myString, " ", CHAR(10))
ThisWorkbook.Worksheets(1).Range("b1").WrapText = True
ThisWorkbook.Worksheets(1).Range("b1").EntireRow.AutoFit
End Sub
However, it throws an error. In addition, I am not sure how to loop over all letters. Is there any more efficient way. I need those headers to look nice: I need to get the same effect as if I click Alt+Enter. Each word should appear on a separate line

You can do this with one line of code:
Range("A1:C1").Replace " ",vblf
In the range it replaces all spaces with a VB Line Feed (Return)

Related

Excel filter and regex match numbers to another worksheet

I'm a bit of an Excel noob so bear with me here. I have the following abridged sheet:
Sheet1
H AP AO
1 Transaction Description Employee Name Type
2 ER 12345678 blank blank
3 ER 13182984 blank blank
4 ER 18213289 blank blank
5 ER 13829429 blank blank
6 ER 89234024 blank blank
And another sheet in the same file to reference the names against:
Sheet2
E I
1 Expense Report Number Employee Name
2 12345678 Chris Rock
3 13182984 Hank Hill
4 18213289 Tom Sawyer
5 13829429 Elon Musk
6 89234024 Tupac Shakur
And I was wondering how to efficiently fill in the first excel sheet's Employee Name and Type columns from the matching report number of the second sheet as such:
Sheet1
H AP AO
1 Transaction Description Employee Name Type
2 ER 12345678 Chris Rock A
3 ER 13182984 Hank Hill A
4 ER 18213289 Tom Sawyer A
5 ER 13829429 Elon Musk A
6 ER 89234024 Tupac Shakur A
My attempt so far:
Set RE = CreateObject("vbscript.regexp")
RE.pattern = "(\d{8})"
Set allMatches = RE.Execute(ActiveSheet.Region ("H:H") #extract the 8 numbers
#somehow extract the 8 numbers to reference against the second sheet
With .Columns(AP)
.Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible).Formula = "=IF(ISERROR(VLOOKUP(reference number,EEM BI + mapping!I:I,2,0)),""Check employee ID"",VLOOKUP(reference number,EEM BI + mapping!I:I,2,0))"
As you can see I'm pretty lost in this code.. Any help is much appreciated
try this test code
Sub Test()
Dim ddd As Variant ' convert sheet1.columnH into an array
ddd = Sheets("Sheet1").Range("h2:h6").Value ' 2D array 1 x N
ddd = Application.Transpose(ddd) ' 2D array N x 1
ddd = Application.Transpose(ddd) ' this changes to 1D array
Dim i As Integer
For i = 0 To UBound(ddd) ' remove the "ER" from each member of the array
ddd(i) = Split(ddd(i))(1)
Next i
Dim findMe As String
Dim rng As Range
For Each rng In Sheets("Sheet2").Range("e2:e6")
findMe = rng.Value
For i = 1 To UBound(ddd)
If StrComp(findMe, ddd(i), vbTextCompare) = 0 Then
Sheets("Sheet1").Range("ap1").Offset(i) = rng.Offset(0, 4).Value
Sheets("Sheet1").Range("ao1").Offset(i) = "A"
End If
Next i
Next rng
End Sub
In your table in Sheet1 if the 8 digit number always starts at position 4, as you show, you can use the MID function seen in the formula below. If not, we would merely have to change MID to something a bit more complex, depending on the real data. No need for REGEX unless the text analysis is complex.
Given the order of Employee Name and Expense Report Number in your lookup table, INDEX(MATCH(... would be one solution.
Although you could use LOOKUP, it may be more efficient to use INDEX(MATCH.... LOOKUP, among other things, to work properly, requires that your lookup table be sorted. That is not necessary with INDEX/MATCH.
Something like
=INDEX(EmployeeName,MATCH(--MID(H2,4,8),ExpenseReportNumber,0))
For efficiency, the references to the two columns (EmployeeName and ExpenseReportNumber) should be as short as possible. Whole column references (eg: $E:$E and $I:$I will work, but will take longer to execute.

Split string into chucks at the end of any blank line breaks

I want to split a string into separate chunks in VB.Net after each empty line break.
For example if I have the following single string :
Jason Smith
Steve
Mary
Harry
Larry
I want the first set of names from Jason to Mary in array(0) & the next set in array(1). So the logic should be to split at the empty line break between the 2 sets.
I tried the below code :
Dim lines As String() = nameList.Split(New String() {vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
But this just breaks every name into a separate item on the array.
First split using vbCrLf + vbCrLf to get the different sets. Then split each of those with a single vbCrLf for the values in each array.

Excel separating data into different columns

I have an Excel workbook I imported with 24,000 business names and addresses. I can't figure out how to separate them into different cells because no commas exist and the some businesses have multiple spaces in the name. Here is an example of what is in each column. Each line is in a separate row.
P & S DELI GROCERY 730 COLUMBUS AVENUE New York NY 10025
ANGELIKA FILM CENTER 18 WEST HOUSTON STREET New York NY 10012
SHASHEMENE INT'L RESTAURA 195 EAST 56 STREET New York NY 11203
CARVEL ICE CREAM 1006 EAST 233 STREET New York NY 10466
LEXLER DELI 405 LEXINGTON AVENUE New York NY 10174
SNACK TIME GRILL 87-69 LEFFERTS BOULEVARD New York NY 11418
MITCHEL LONDON FOODS 22 EAST 65 STREET New York NY 10065
SPOON BREAD CATERING 364 WEST 110 STREET New York NY 10025
TERMINAL CAFE/YANKEE CLIPPER 0 GUARDIA AIRPORT PARKING New York NY 11371
PLAZA BAGELS & DELI 73 NEW DORP PLAZA New York NY 10306
B & M HOT BAGEL & GROCERY 203 GIFFORDS LANE New York NY 10308
TEXAS ROTISSERIE 94 FULTON STREET New York NY 10038
One easy way to get going is to use the `Text to Columns function under the Data tab.
Highlight your cells that you want to split up, and click "Text to Columns". Choose a Delimiter, click "Next", then choose "Space".
Now, it'll take a word, put it in a cell, then take the next word (after a space), and put it in the cell next to that, etc.
The problem I forsee is this isn't going to be a one shot solution. As you mention, the restaurant names can be one word, of up to infinity words. Unless you see some logic in how it's spread out, I think this is your best bet.
For instance, is it safe to assume that if we are reading from left to right, and come across a number, that number starts the address and all preceding text is the restaurant name? ...I doubt it actually, what if my restaurant is called "Bruce's 21 Jump Street Eatery"? As #Johankr points out, this is probably more rare, but you should be aware of this possibility if you're just going to run the macro, save and close (without any human review). You could get a list of major cities, zip codes, etc. and use that to help parse through though and determine where the address starts/ends.
Copy it an paste into Google Spreadsheet and then use regular expressions (REGEXEXTRACT).
So for example to extract everything before the number use:
=REGEXEXTRACT(A1, "(\D*)\d")
It will extract P & S DELI GROCERY. Then to get the number use:
=REGEXEXTRACT(A1, "\D+(\d+)\D*")
It will get you 730. And so on...
This vba Should work for most of what you want:
Sub splitaddress()
Dim ws As Worksheet
Dim rng As Range
Dim oArr() As Variant
Dim lastrow As Long
Dim spltstr() As String
Dim i As Long
Dim j As Long
Dim h As Boolean
Set ws = Sheets("Sheet1")'Change to your sheet name.
lastrow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ReDim oArr(1 To lastrow, 1 To 5)
j = 1
h = False
For Each rng In ws.Range("A1:A" & lastrow)
spltstr = Split(rng)
For i = LBound(spltstr) To UBound(spltstr)
If i = UBound(spltstr) Then
oArr(j, 5) = spltstr(i)
ElseIf i = UBound(spltstr) - 1 Then
oArr(j, 4) = spltstr(i)
ElseIf Not h And spltstr(i) = UCase(spltstr(i)) And InStr("1234567890", Left(spltstr(i), 1)) = 0 Then
oArr(j, 1) = oArr(j, 1) & spltstr(i) & " "
ElseIf InStr("1234567890", Left(spltstr(i), 1)) > 0 Or (h And spltstr(i) = UCase(spltstr(i))) Then
h = True
oArr(j, 2) = oArr(j, 2) & spltstr(i) & " "
ElseIf spltstr(i) <> UCase(spltstr(i)) Then
oArr(j, 3) = oArr(j, 3) & spltstr(i) & " "
End If
Next i
oArr(j, 1) = Trim(oArr(j, 1))
oArr(j, 2) = Trim(oArr(j, 2))
oArr(j, 3) = Trim(oArr(j, 3))
h = False
j = j + 1
Next rng
ws.Range("B1").Resize(lastrow, 5).Value = oArr
End Sub
If the street address does not start with a number it will not work.
If all the contacts only exists as a string, i.e. all data in the same cell, no solution is likely to be able to be able to split all contacts properly.
Here are some starting points though, all based on the assumption that the rest of the data looks fairly similar at least.
Very few business are likely to contain numbers in the names, so you can probably safely split address using the first occurance of a number as the divider between name and adress.
Create a lookup table for State and abbreviation. Should be possible to split the adress part of the string into two parts/lines using that.
Assumptions: The City is always = "New York"; the State is always =
"NY".
Place your data in column A starting at row 2.
In columns C thru L, at row 1, type numbers 0 to 9, where each column
gets 1 of the digits (0,1,2 ... 9).
Paste the following into cell C2:
=IF(TYPE(FIND(C$1,$A2,1))=16,LEN($A2),FIND(C$1,$A2,1))
Select and copy cell C2, select range D2:L2 and paste the copied
formula from cell B2.
Paste the following into cell B2: =MIN(C2:L2)
Paste the following into cell M2: =TRIM(MID(A2,1,B2-1))
Paste the following into cell N2: =TRIM(MID(A2,B2,FIND("New York_
NY",A2,1)-1-B2))
Type "New York" in cell O2.
Type "NY" in cell P2.
Paste the following into cell Q2: =RIGHT(A2,5)
Next select copy range B2:Q2 and paste it in rows B3 to end of your
data.

Retrieve starting positions of the titles in the string

I have a line of seven different titles that can consist of one or two words with at least 3 or 4 spaces between the title.
" Company Name Contact Name Address City State Zip Phone"
I need to retrieve the position in the line where each title begins. I use indexOf:
pos1 = line.IndexOf("company", System.StringComparison.InvariantCultureIgnoreCase)
This method works fine but is not that efficient for retrieving positions since the line comes from text documents and there is a great variability, for example I might have something like this:
" C0mpany Name C0ntact Name Address NCity St)te Zip Phone"
So the wording is not always exact. All I know is that there are 7 columns. What is the best way to retrieve 7 beginning positions of those columns programmatically?
This works quite well
Dim s As String
Dim v As Object
Dim tok As Object
s = " C0mpany Name C0ntact Name Address NCity St)te Zip Phone"
v = Split(s, " ")
For Each tok In v
If Len(Trim(tok)) > 0 Then
Debug.Print(tok & vbTab & InStr(s, tok))
End If
Next
output:
C0mpany Name 3
C0ntact Name 23
Address 41
NCity 60
St)te 69
Zip 78
Phone 85
The above is in Access VBA, but here is the SAME code after a cut + paste into VB.net

Generate Multiple page document from multiple line in excel

In my excel I have multiple line like this:
Name Age Tel
John 5 12345677
Peter 10 4547567
Mary 6 46u7687867
I am wondering How can I generate multiple document from excel to multiple invoice like this:
page1:
Certification of XXXXX
John Age 5
page2:
Certification of XXXXX
Peter Age 10
page3:
Certification of XXXXX
Mary Age 6
Thanks!
Assuming the above input & comments, the following code will do the job:
Sub ListPrinting()
Dim i As Long
i = 1
For i = 2 To ThisWorkbook.Sheets(1).Range("A1").CurrentRegion.Rows.Count
ThisWorkbook.Sheets("Invoice").Range("F40").Formula = ThisWorkbook.Sheets(1).Cells(i, 1).Formula
ThisWorkbook.Sheets("Invoice").Range("I38").Formula = ThisWorkbook.Sheets(1).Cells(i, 2).Formula
ThisWorkbook.Sheets("Invoice").Range("I9").Formula = ThisWorkbook.Sheets(1).Cells(i, 3).Formula
ThisWorkbook.Sheets("Invoice").PrintOut Copies:=1, ActivePrinter:="pdfFactory Pro on FPP4:" 'Specify your printer
Next i
MsgBox i - 2 & " invoice(s) printed."
End Sub
Please note:
You should specify the name of desired printer - use macro-recorder and just select it in the list of available printers on Print dialog.
The amount of records in list is practically unlimited... well, paper and ink / toner are not))) All of them will be printed starting row 2 and up to the last non-empty string found on the list sheet.
Test the code on 1-2 items to avoid paper loss)
Sample file is shared (code tested as well): https://www.dropbox.com/s/296e200496gd7gb/ListPrinting.xlsm
P.S. Perhaps you should reformat the Date field as you desire - it uses regional settings and therefore will be displayed for you differently.
For generating multiple page document lines from multiple line in excel you should flow
some steps and for knowing that you can visit http://fetchflow.com/support/question/How-do-I-create-a-new-purchase-order.html