delete data in cell after specific character - vba

I have data in cells A1:A1000. It is a list of names followed by a small note, like this:
sam" fast
nick" long
tom" quick
They all have " and a space after the names and then the note. What I am trying to do is delete the everything after the name.
I was playing around with macros to try and do this, but could not get anything to work. Any idea how I might do this?

Here is a nifty trick without macros:
Select the proper range (or even just click on A to select the entire column) and then do Ctrl+F, click Replace, in Find write exactly "* and leave the Replace with box empty. Now click Replace all and tada !
It replaces everything after (and including) the quote with nothing because it uses * as a wildcard you left the replace box empty.
Edit: As suggested here is the VBA code for this:
Columns("A:A").Replace What:="""*", Replacement:="", LookAt:=xlPart

Easy! I don't know what version of Excel you are using, but in short you want to do a Convert Text to Columns and then split the cells using a delimiter of ". This will leave you with two columns, one of the data you want and one you can just delete.
Here is the walk through in Office 2010:
Highlight column A
find the Data menu
find the Convert Text to Columns menu
Pick Delimited and hit next
In the Other box, type "
hit Finish
Done! Now you have all your names in column A and you can just delete column B.
To sum up, do a "Convert Text to Columns" and then split the cells using a delimiter of ". Super easy and fast.

few options:
Replace
Range("A1:A1000").Replace """*", vbNullString
If you require to manipulate the value further then the below are more appropriate:
With Regex:
Dim str As String, strClean As String
Dim cell As Range
For Each cell In Range("A1:A1000")
With CreateObject("vbscript.regexp")
.Pattern = "\""(.*)"
.Global = True
cell = .Replace(cell, vbNullString)
End With
Next cell
Without Regex, splitting the string:
Dim strSplit() As String
Dim cell As Range
For Each cell In Range("A1:A1000")
If (cell.Value <> vbNullString) Then
cell.Value = Split(cell.Value, """")(0)
End If
Next cell

In case you want to keep your source data, you can also do it with a simple Excel formula in the next column. Assuming that your data is in column A, the following formula will return only the name: =LEFT(A1,SEARCH("""",A1)-1)

Sub Macro1()
For Row = 1 To 1000
S = Range("A" & Row).Cells.Value
Pos = InStr(S, Chr(34))
If Pos > 0 Then Range("A" & Row).Cells.Value = Left(S, Pos - 1)
Next
End Sub

Press ctrl + f, click on replace tab, type * in the find what box and then click on replace all. No need to put anything in replace box. Here you are replacing everything after ..

Related

Writing a formula with concatenated parts into a cell

Scenario: I have a code that should write a formula to a worksheet cells. This formula is for an API to retrieve some value. My formula is inside a loop (this is done for multiple columns) and references the first row for an identifier.
The original formula:
=FS(B1;"FI(DATE,,DATE)")
The modified formula with the floating reference (inside the loop):
For i = 1 To lColumn
If wb.Worksheets("Dates").Cells(i, 1).Value <> "" Then
wb.Worksheets("Dates").Cells(i,2).value = "=FS(" & i & "1;"FI(DATE,,DATE)")"
End If
Next i
Where lColumn is some pre-defined number.
Issue: I keep getting the "Unexpected end of statement" error in the formula part of the loop.
What I already tried: I tried different variations, repositioning the "s and 's, for example:
wb.Worksheets("Dates").Cells(i,2).value = "'"=FS(" & i & "1;"FI(DATE,,DATE)")""
or
wb.Worksheets("Dates").Cells(i,2).value = "'=FS(" & i & "1;"FI(DATE,,DATE)")"
or
wb.Worksheets("Dates").Cells(i,2).value = "'""=FS(" & i & "1;"FI(DATE,,DATE)")"
and so on. But the error still persists.
Question: What is the proper way to do this operation?
Working with formulas in VBA is a little bit tricky:
To write a formula, use the range.formula property, not the .value.
You have to write the formula as if you are using an english Excel. Parameter-separator is comma (not semicolon).
If a formula needs a quote, double it so that the VBA compiler understands that you want a quote within a string.
I find it helpfull to write a formula into a variable before assigning it - you can check in the debugger if it is exactly how it should before assigning it.
To check how the formula should look like, write it into a cell, change to the VBA-editor, open the immediate window and write ? activecell.formula
Try (untested as the formula you need is not valid to us):
with wb.Worksheets("Dates")
dim f as string, adr as string
adr = cells(i, 1).address(false, false) ' get rid of Dollar signs
f = "=FS(" & adr & ",""FI(DATE,,DATE)"")"
.Cells(i, 2).formula = f
end with
wb.Worksheets("Dates").Cells(i,2).formula = "=FS(" & Cells(1, i).Address(0,0) & ";""FI(DATE,,DATE)"")"
There may be a better way to convert the column number to a letter (which is the problem you are having, along with the double quotes)!

Saving number as text, how to automate it

I have a 7702216772 number inside a cell. If I put a ' before the fist digit and click Enter Excel transforms the number to a text and puts a green triangle at the left top of the cell:
I have many rows of similar numbers all of which need to be transformed into text. However clicking each and adding ' before the first symbol and clicking Enter would take a lot of time. Is there any way to do it programatically?
I tried using formula: ="'"&H4 but it doesn't do what's expected - the green triangle never appears on the result cell.
I also tried setting cell format to Text, but the green triangle doesn't appear in that case too.
I need the green triangle to appear at the upper left corner, just like at the picture!
If all your number are in a single column, the following code will do it:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your worksheet, amend as required
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A
For i = 1 To LastRow 'loop from row 1 to last
ws.Cells(i, "A").Value = "'" & ws.Cells(i, "A").Value 'add the ' before the number
Next i
End Sub
Change the "A" to whichever column you are using.
Just Select the cells you wish to process and run this short macro:
Sub Textify()
Dim rng As Range, r As Range
Set rng = Selection.Cells.SpecialCells(2, 1)
For Each r In rng
r.Value = "'" & r.Value
Next r
End Sub
Non VBA answer; I'm using Column G in this answer but it depends on where your numbers are. You'll have to change the cell but I think you will be ok with this.
In an empty cell, enter formula: ="'"&G4
Use the fill handle or Ctrl+D to fill it down to the length of Column G's values.
Select the whole of Column G's values and copy them to the clipboard
Select the same range in Column G, right-click, select Paste Special and choose Values
I have tested it now for several times and it worked always
Cells(xx, xx).FormulaR1C1 = "'" & Cells(xx, xx).Value
Same would work for ActiveCell or whatever you like.

Excel VBA code for MID/Splitting text in cell based on fixed width

I apologize if there is already the same question asked elsewhere with an answer however I have been unable to find it so here I go.
I will also mention that I am a VBA beginner, mostly playing around with codes obtained from other people to get what I want.
I currently have data in Columns A-D, with the information in column C being the important column. Everything else should be ignored.
I have a line of text in cell C1 of sheet1. It is 25 characters long and resembles the following:
4760-000004598700000000000
I have over ~970,000 rows of data and need to pull out the information found within each of these cells into two different cells in another sheet.
I cannot simply use a formula due to the number of records (excel crashes when I try).
If using the mid function for C1, I would enter something like (C1,2,3) and (C1,5,11). (except it would be for each cell in column C)
The leading zeroes between the + or - and the beginning of the first non-zero value are of no consequence but I can fix that part on my own if need be.
Ideally the information would be pulled into an existing sheet that I have prepared, in the A and B columns. (IE:sheet2)
For example, using the text provided above, the sheet would look like:
A|B
760|-0000045987 or -45987
I have looked into array, split and mid codes but I had troubles adapting them to my situation with my limited knowledge of VBA. I am sure there is a way to do this and I would appreciate any help to come up with a solution.
Thank you in advance for your help and please let me know if you need any additional information.
It sounds like what you're after could be achieved by the Text to Columns tool. I'm not sure whether you're trying to include this as a step in an existing macro, or if this is all you want the macro to do, so I'll give you both answers.
If you're just looking to split the text at a specified point, you can use the Text to Columns tool. Highlight the cells you want to modify, then go to the Data tab and select "Text to Columns" from the "Data Tools" group.
In the Text to Columns wizard, select the "Fixed Width" radio button and click Next. On step 2, click in the data preview to add breaks where you want the data to be split - so, in the example you gave above, click between "760" and "-". Click Next again.
On step 3, you can choose the format of each column that will result from the operation. This is useful with the leading zeroes you mentioned - you can set each column to "Text". When you're ready, click Finish, and the data will be split.
You can do the same thing with VBA using a fairly simple bit of code, which can be standalone or integrated into a larger macro.
Sub RunTextToColumns()
Dim rngAll As Range
Set rngAll = Range("A1", "A970000")
rngAll.TextToColumns _
DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 2), Array(3, 2))
With Sheets("Sheet4").Range("A1", "A970000")
.Value = Range("A1", "A970000").Value
.Offset(0, 1).Value = Range("B1", "B970000").Value
End With
End Sub
This takes around a second to run, including the split and copying the data. Of course, the hard-coded references to ranges and worksheets are bad practice, and should be replaced with either variables or constants, but I left it this way for the sake of clarity.
How about this:
Sub GetNumbers()
Dim Cel As Range, Rng As Range, sCode As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set Rng = Sheets("Sheet1").Range("C1:C" & Sheets("Sheet1").Range("C1048576").End(xlUp).Row)
For Each Cel In Rng
Sheets("Sheet2").Cells(Cel.Row, 1).Value = Mid(Cel.Value, 2, 3)
sCode = Mid(Cel.Value, 5, 11)
'Internale loop to get rid of the Zeros, reducing one-by-one
Do Until Mid(sCode, 2, 1) <> "0" And Mid(sCode, 2, 1) <> 0
sCode = Left(sCode, 1) & Right(sCode, Len(sCode) - 2)
Loop
Sheets("Sheet2").Cells(Cel.Row, 2).Value = sCode
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I think there's an array formula thing that would do this, but I prefer the brute force approach. There are two ways to fill in the fields, with a procedure or with a function. I've done both, to illustrate them for you. As well, I've purposely used a number of ways of referencing the cells and of separating the text, to illustrate the various ways of achieving your goal.
Sub SetFields()
Dim rowcounter As Long, lastrow As Long
lastrow = ActiveSheet.Cells(Rows.Count, 3).End(xlUp).Row 'get the last row in column "C"
For rowcounter = 1 To lastrow 'for each row in the range of values
'put the left part in column "D"
ActiveSheet.Range("D" & rowcounter) = FieldSplitter(ActiveSheet.Cells(rowcounter, 3).Text, True)
'and the right part in the column two over from colum "C"
ActiveSheet.Cells(rowcounter, 3).Offset(0, 2) = FieldSplitter(ActiveSheet.Cells(rowcounter, 3).Text, False)
Next rowcounter
End Sub
Function FieldSplitter(FieldText As String, boolLeft As Boolean) As String
If boolLeft Then
FieldSplitter = Mid(FieldText, 2, 3) 'one way of getting text from a string
Else
FieldSplitter = Left(Right(FieldText, 16), 5) ' another way
End If
'Another useful function is Split, as in myString = Split (fieldtext, "-")(0) This would return "4760"
End Function

Highlight cells + adjacent 2 cells if certain text if located

If any cell contains the text "example", this cell + the two cells on the same row to the right of, to be highlighted.
So for instance
B5 contains "example", b5,c5,d5 need to be highlighted orange
b9 contains "example", b9,c9,d9 need to be highlighted orange.
And so forth across the whole sheet. Multiple rows and multiple columns could contain the specific text.
Any assistance, examples appreciated.
Private Sub CommandButton1_Click()
row_number = 4
Do
DoEvents
row_number = row_number + 1
swing_data = Sheet1.Range("B" & row_number)
If InStr(swing_data, "Test") >= 1 Then
With Range("B" & row_number).Offset(, 2).Interior
.Pattern = x1solid
.PatternColorIndex = x1automatic
.Color = 65535
.PatternTintAndShade = 0
End With
End If
Loop Until swing_data = ""
End Sub
This is not highlighting the 2 cells to the right, and if there is a blank cell it's stopping. Also it's only working on one column. Needs to work on columns B, E, N, Q, Z, AC,
Changed this line
<<code>With Range("B" & row_number).Offset(, 2).Interiorcode>
To read <code>With Range("B" & row_number).resize(, 3).Interiorcode>
And it works.
Would the be an easier way to include multiple columns in this...?
Conditional formatting:
As multiple columns may contain your criteria you need a bit more complex formula (conditional formatting - use a formula...): =or(iferror(rc[-1]="example",false),iferror(rc[-2]="example",false),rc="example") - notes: I switch to R1C1 reference style before entering conditional formatting as I find it mite clear there; iferror is necessary to make formula working also in first and second columns.
VBA:
you can use VBA find object to cycle through all instances and change formatting there (I think built-in help and maybe recording some short macros give you enough information to create it)
You can do this with conditional formatting if you want to avoid VBA. Select the cells you want you want to apply the formatting to (say B1:D10), Click conditional formatting -> New Rule... -> Use a formula to determine which cells to format. Use this formula
=EXACT($B1,"example")
The $ in front of the column makes sure only that column is looked at, the row will be independent. You then need to change the formatting to whatever you want. In your case change the fill to orange.

How do I delete all characters after the first space in a cell?

I have a list of city names followed by the state in which they are located all in one column in Excel. How can I delete everything after the first space so that the city name is the only thing that's left in the cell?
example: A1 = "johnson TX"
should be just A1= "johnson"
I assume you want a VBA solution since you tagged your question excel-vba.
This works:
Sub KeepCity()
Dim strCityAndState As String
Dim strCityOnly As String
strCityAndState = Range("A1").Value
strCityOnly = Left(strCityAndState, InStr(strCityAndState, " ") - 1)
Range("A2").Value = strCityOnly
End Sub
If you don't want VBA and want a cell formula instead, then #JToland's answer works fine, though this one is more concise and doesn't keep the trailing space character:
=LEFT(A1, FIND(" ",A1)-1)
Well doing something like this
=Mid(A1, 1, Find(" ",A1))
in another column should grab all text before the " ". So you could build another column with just all the city names and then you could use that column for your purposes.
If you are looking for a VBA function, you can use Left and InStr as shown below.
Dim Temp As String: Temp = "Hello_World! This is my first answer here. :D"
Temp = Left(Temp, InStr(Temp, " ")-1)
In which case, Temp will be "Hello_World!"
Use of Split function
An elegant approach is to use the first token of the Split function:
Code Example extracting from cell A1 to A2
Option Explicit
Sub KeepCity()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("MySheet") ' << Change to your sheet name
ws.[A2] = Split(ws.[A1], " ")(0)
End Sub
Alternative Syntax
Instead of cell abbreviations [A2] or [A1] you can also use:
ws.Range("A2").Value = Split(ws.Range("A1").Value, " ")(0)
Note
The resulting split 1-dimensional array is zero based, so you get the first part (or token) of the original string via index (0).
If you are looking for a second part, I recommend adding an additional delimiter value (" ") to the original string, e.g. s: MsgBox split(s & " "," ")(1). By that way you avoid error number 9 "Subscript out of range", if there is no delimiter in between at all, thus no second part at all.