Excel - Find & Replace Part of String But in Same Cell? - vba

I have
Column A
Red-US
Blue-INT
Purple-INT
White-US-CA
Trying remove -us, int, ca, etc.
So it's just Red, Blue, Purple, etc.
Can't use Trim or Substitute formula because I want it to change directly in Column A (replace)
Thank you!

If the "-" is a consistent separator then it should be pretty simple.
Here are some commands you could use:
Strings and Manipulations
Edit: Added simple code
Sub textuptodash()
i = 1 'start on row 1
Do While Not IsEmpty(Cells(i, 1)) 'do until cell is empty
If Not InStr(1, Cells(i, 1), "-") = 0 Then 'if dash in cell
Cells(i, 1) = Left(Cells(i, 1), InStr(1, Cells(i, 1), "-") - 1) 'change cell contents
End If
i = i + 1 'increment row
Loop
End Sub

Try using Split as follows:
Sub MySplit()
Dim rngMyRange As Range, rngCell As Range
Dim strTemp() As String, strDel As String, strTest As String
Dim lngCnt As Long
Set rngMyRange = Range("A1:A4")
For Each rngCell In rngMyRange
' Split the test based on the delimiter
' Store entries in a vector of strings
strTemp = Split(rngCell.Text, "-")
' Reset cell value and intermmediate delimiter
rngCell.Value = vbNullString
strDel = vbNullString
' Scan all entries. store all of them but not the last -* part
For lngCnt = LBound(strTemp) To UBound(strTemp) - 1
rngCell = rngCell & strDel & strTemp(lngCnt)
' If we enter the loop again we will need to apend a "-"
strDel = "-"
Next lngCnt
Next rngCell
End Sub
Output:
Red
Blue
Purple
White-US
It is not entirely clear how you want the last entry to be split: assumed that you want to remove the last "-*" bit only. To keep the first part only, comment out the For lngCnt loop.
I hope this helps!

Related

vba combine a few lines in one cell

I have a three columns in excel with data such as
section1 section2 section3
no no er3
er1 no er3
no no no
how to write macros to Combine the data in the on column such as:
section_error
er3
er1,er3
no
So if there are only "no" then it should be once "no"
if there is something else besides "no", like "er1"or "er3" then only list of others signs.
it is not exactly to join or to CONCATENATE (
So, this might be a bit overkill depending on how many rows you have. But, using arrays is going to be a lot faster if you start getting up in the thousands.
Anyway, we define two named ranges, input and output. We then place the values of the input range into an array.
We loop through the array, checking the values of those spots in the array (which corresponds to the values in the cells now). When we find something, we append that something to the end of our output value for that row. When we don't find anything, we set that value to no.
At the end, we set the values of the output range (resized for our array) equal to our output array values.
Make sure you define those named ranges (and change their names too!).
Let me know if you have questions.
Option Explicit
Sub combineColumns()
Dim combineRange As Range, pasteRange As Range
Dim inputArr() As Variant, outputArr() As Variant, i As Long, j As Long, numberOfRows As Long
Dim currentOutputvalue As String
'Named range with values to combine, don't include header
Set combineRange = Range("yourNamedRangeToCombineHere")
'only need to set the top of the range to paste
Set pasteRange = Range("theCellAtTheTopOfWhereYouWantToPaste")
'put the values of the range you want to combine into the input array
inputArr = combineRange.Value2
'find the size of the array
numberOfRows = UBound(inputArr, 1)
'dimension the output array, same number of rows, but only one column
ReDim outputArr(1 To numberOfRows, 1 To 1)
'loop through our rows
For i = 1 To numberOfRows
'set the current output value to a blank
currentOutputvalue = ""
'loop through our three columns
For j = 1 To 3
'if cell value is not no, append the value to the end of current output value
'also append a comma
If inputArr(i, j) <> "no" Then
currentOutputvalue = currentOutputvalue & inputArr(i, j) & ","
End If
Next
If currentOutputvalue = "" Then
'all columns in this row were "no", so change value to "no"
currentOutputvalue = "no"
Else
'there was at least one not no
'trim off the end comma
currentOutputvalue = Left(currentOutputvalue, Len(currentOutputvalue) - 1)
End If
'assign the value to the spot in the array
outputArr(i, 1) = currentOutputvalue
Next
'resize the pasterange to the size of the array, and
'set the values of the range to those in the output array
pasteRange.Resize(numberOfRows, 1).Value2 = outputArr
End Sub
Here's a macro solution, just looping through the rows/columns:
Sub Test()
Dim i As Long, j As Long, lastrow As Long
Dim mystring As String
lastrow = Worksheets("ICS Analysis").Cells(Worksheets("ICS Analysis").Rows.Count, 1).End(xlUp).Row
For i = 2 To lastrow
For j = 1 To 3
If InStr(Worksheets("ICS Analysis").Cells(i, j).Value, "er") > 0 Then
If mystring = "" Then
mystring = Worksheets("ICS Analysis").Cells(i, j).Value
Else
mystring = mystring & "," & Worksheets("ICS Analysis").Cells(i, j).Value
End If
End If
Next j
If mystring <> "" Then
Worksheets("ICS Analysis").Cells(i, 4).Value = mystring
mystring = ""
Else
Worksheets("ICS Analysis").Cells(i, 4).Value = "no"
End If
Next i
End Sub

Remove or add text after a specific character in Excel

I have lot of data in my excel sheet , i want to remove all text after Last (-) character .
Here is sample data like in my sheet
"This-is-car-44"
"This-is-my-school-ok"
I want look like this
"This-is-car"
"This-is-my-school"
i want to remove all text after lats - , so is their any formula to do this.
and one thing more if possible can i do like this in excel
"This-is-car-44"
"This-is-my-school-ok"
to look like this
"This-is-car/"
"This-is-my-school/"
i mean after last - remove all text and add this / in end .
thanks.
If you are OK with excel formulas, please try this,
=SUBSTITUTE(A1,"-"&TRIM(RIGHT(SUBSTITUTE(A1,"-",REPT(" ",LEN(A1))),LEN(A1))),"/")
You can do something like this.
Sub RemoveLastStingPart()
Dim rng As Range
Dim intLastRow As Long
Dim strTemp As String
Dim aryTemp() As String
With ActiveSheet
intLastRow = .UsedRange.Rows.Count
Set rng = .Range(Cells(1, 1), Cells(intLastRow, 1))
For Each cell In rng
strTemp = cell.Value
aryTemp = Split(strTemp, "-")
strTemp = ""
For i = 0 To UBound(aryTemp) - 1
strTemp = strTemp & aryTemp(i) & "-"
Next i
strTemp = Left(strTemp, Len(strTemp) - 1)
cell.Offset(0, 1).Value = strTemp
Next cell
End With
End Sub

Concatenate Columns Of Data

*Edited To Add: Current error I'm receiving. See bottom of this post for screenshot.
I have text in column D. The macro should find blank cells, and then concatenate the text from all cells below it.
Example
Text starting in D2, displaying like this...
Blank Cell
SampleText1
SampleText2
SampleText3
Blank Cell
SampleText4
SampleText5
SampleText6
The macro should display the text in D2...
SampleText1, SampleText2, SampleText3
and then in D6, like this...
SampleText4, SampleText5, SampleText6
..and so on.
This only needs to work in column D, so I'm guessing I can write it to that range.
The closest answer I've come across is here:
Excel Macro to concatenate
Here is the code I'm currently working with...
Sub ConcatColumns()
Do While ActiveCell <> "" 'Loops until the active cell is blank.
'The "&" must have a space on both sides or it will be
'treated as a variable type of long integer.
ActiveCell.Offset(0, 1).FormulaR1C1 = _
ActiveCell.Offset(0, -1) & " " & ActiveCell.Offset(0, 0)
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Edit: Now using great code from #jeeped but receiving an error, seen in the below screenshot
Start from the bottom and work up, building an array of the strings. When you reach a blank cell, Join the strings using your preferred deliminator.
Sub build_StringLists()
Dim rw As Long, v As Long, vTMP As Variant, vSTRs() As Variant
Dim bReversedOrder As Boolean, dDeleteSourceRows As Boolean
ReDim vSTRs(0)
bReversedOrder = False
dDeleteSourceRows = True
With Worksheets("Sheet4")
For rw = .Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1
If IsEmpty(.Cells(rw, 1)) Then
ReDim Preserve vSTRs(0 To UBound(vSTRs) - 1)
If Not bReversedOrder Then
For v = LBound(vSTRs) To UBound(vSTRs) / 2
vTMP = vSTRs(UBound(vSTRs) - v)
vSTRs(UBound(vSTRs) - v) = vSTRs(v)
vSTRs(v) = vTMP
Next v
End If
.Cells(rw, 1) = Join(vSTRs, ", ")
.Cells(rw, 1).Font.Color = vbBlue
If dDeleteSourceRows Then _
.Cells(rw, 1).Offset(1, 0).Resize(UBound(vSTRs) + 1, 1).EntireRow.Delete
ReDim vSTRs(0)
Else
vSTRs(UBound(vSTRs)) = .Cells(rw, 1).Value2
ReDim Preserve vSTRs(0 To UBound(vSTRs) + 1)
End If
Next rw
End With
End Sub
I've left options for reversing the string list as well as removing the original rows of strings.
                  Before build_StringLists procedure
                  After build_StringLists procedure

VBA to find the font color of a string

I am new to VBA..I am writing a macro for some file comparison..My requirement is if a string has red color font,that string should be ignored for iteration and code should move to next iteration..I have tried the following code.
Dim compare = {"test1","test2","test3",.....etc}
i=0
For j=1 to Ubound(compare)
j=1
If compare.Characters(j,Len(compare(i))).Font.Color <> vbRed Then
' Some Code
End If
i=i+1
Next
However during the execution I am getting runtime error 424 "Object Required.Please help me to complete this task
Thanks in advance.
Say we have cells A1 thru A4 like:
Then this code will find the non-red characters:
Sub ColorTest()
Dim I As Long, J As Long
For I = 1 To 4
For J = 1 To Len(Cells(I, 1).Value)
If Cells(I, 1).Characters(Start:=J, Length:=1).Font.Color <> vbRed Then
MsgBox "non-red found at cell A" & I & " position " & J
End If
Next J
Next I
End Sub
May I assume that the source for your data is an excel-sheet (as pointed out by previous comments, a pure string does not hold information on colours), and for one reason or another you want to use an array. Then this might be a way to solve the problem (prerequisite: full string is in one colour only)
(Just saw that there's a solution provided by Gary's student without using arrays as well...AND providing for cases where only part of the string is red...nice one!)
Sub colour()
Dim arr_DB As Variant
Dim i As Long
ReDim arr_DB(1, 1) 'Array size to be adjusted as needed, Base 0 !
For i = 1 To 2
arr_DB(i - 1, 0) = ActiveSheet.Cells(i, 1).Value 'Value of Cell
arr_DB(i - 1, 1) = ActiveSheet.Cells(i, 1).Font.Color 'Colour of Font in Cell
Next
If arr_DB(i - 1, 1) = 255 Then ' No. 255 is colour RED
'skip.....
End If
End Sub

Possible combinations of values

I'm trying to adapt the Sub + Function from this thread to my need:
write all possible combinations
Tim Williams solution.
It works fine since all columns have at least 2 values. I'm after if there is a workaround to make it work even if some of the columns have just one value in it.
In the Sub command I could change to
col.Add Application.Transpose(sht.Range(Cells(3, c.Column), Cells(Rows.Count, c.Column).End(xlUp)))
and it goes fine.
But the Function is crashing at this line:
ReDim pos(1 To numIn)
just when processing the column that has just one value in it.
Thaks in advance for any help.
I have a more elegant solution with following assumptions:
The data and write to cells are on the same activesheet
Start combination from a cell you specify and going downward then right
Stops going rightward as soon as the cell of the same row is empty
writes the combination from a cell you specify going downwards
Screenshots after the code (Bug fixed on 1 row only on a data column):
Private Const sSEP = "|" ' Separator Character
Sub ListCombinations()
Dim oRngTopLeft As Range, oRngWriteTo As Range
Set oRngWriteTo = Range("E1")
Set oRngTopLeft = Range("A1")
WriteCombinations oRngWriteTo, oRngTopLeft
Set oRngWriteTo = Nothing
Set oRngTopLeft = Nothing
End Sub
Private Sub WriteCombinations(ByRef oRngWriteTo As Range, ByRef oRngTop As Range, Optional sPrefix As String)
Dim iR As Long ' Row Offset
Dim lLastRow As Long ' Last Row of the same column
Dim sTmp As String ' Temp string
If IsEmpty(oRngTop) Then Exit Sub ' Quit if input cell is Empty
lLastRow = Cells(Rows.Count, oRngTop.Column).End(xlUp).Row
'lLastRow = oRngTop.End(xlDown).Row ' <- Bug when 1 row only
For iR = 0 To lLastRow - 1
sTmp = ""
If sPrefix <> "" Then
sTmp = sPrefix & sSEP & oRngTop.Offset(iR, 0).Value
Else
sTmp = oRngTop.Offset(iR, 0).Value
End If
' No recurse if next column starts empty
If IsEmpty(oRngTop.Offset(0, 1)) Then
oRngWriteTo.Value = sTmp ' Write value
Set oRngWriteTo = oRngWriteTo.Offset(1, 0) ' move to next writing cell
Else
WriteCombinations oRngWriteTo, oRngTop.Offset(0, 1), sTmp
End If
Next
End Sub