How cut a substring? - excel

I have a lot of string which can contain italic font. I want to copy this string with this font. In each new string I have bold word
Example:
BIG STRING:
I tried:
Public Function GetDefinition(ByVal rngText As Range) As String
Dim theCell As Range
Set theCell = rngText.Cells(1, 1)
For I = 1 To Len(theCell.Value)
If theCell.Characters(I, 1).Font.Bold = False Then
If theCell.Characters(I + 1, 1).Text = " " Then
theChar = theCell.Characters(I, 1).Text
Else
theChar = theCell.Characters(I, 1).Text
End If
Results = Results & theChar
End If
Next I
GetDefinition = Results
End Function

I think you could use this:
Option Explicit
Sub test()
Dim LastRow As Long, i As Long, j As Long, PositionOfDot As Long
With ThisWorkbook.Worksheets("Sheet1")
'Find last row of column A
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
'Loop from row 1 to lastrow
For i = 1 To LastRow
'Copy paste from column A to C keeping formatting
.Range("A" & i).Copy .Range("C" & i)
'Find the position of "."
PositionOfDot = InStr(1, .Range("A" & i), ".")
'Delete characters starting from the first one up to PositionOfDot+1
.Range("C" & i).Characters(1, PositionOfDot + 1).Delete
Next i
End With
End Sub
Results:

If your bold string always ends with a dot this will do it for you:
Option Explicit
Public Function GetDefinition(ByVal rngText As Range) As String
Dim SplitBold As Variant
SplitBold = Split(rngText, ". ")
GetDefinition = Trim(SplitBold(1))
End Function

Related

Convert date list into date ranges [duplicate]

I have a data like this :
A049
A050
A051
A053
A054
A055
A056
A062
A064
A065
A066
And I want the output like :
As you can see, I want the ranges which are in consecutive order
I am trying some thing like this:
Private Sub CommandButton1_Click()
Set wb = ThisWorkbook
lastRow = wb.Sheets("Sheet1").Range("A" & wb.Sheets("Sheet1").Rows.Count).End(xlUp).Row
For i = 2 To lastRow
r = wb.Sheets("Sheet1").Range("A" & i).Value
If wb.Sheets("Sheet1").Range("A" & i).Value = wb.Sheets("Sheet1").Range("A" & i+1).Value
Next i
End Sub
But not helping me
Am feeling charitable so have tried some code which should work. It assumes your starting values are in A1 down and puts results in C1 down.
Sub x()
Dim v1, v2(), i As Long, j As Long
v1 = Range("A1", Range("A" & Rows.Count).End(xlUp)).Value
ReDim v2(1 To UBound(v1, 1), 1 To 2)
For i = LBound(v1, 1) To UBound(v1, 1)
j = j + 1
v2(j, 1) = v1(i, 1)
If i <> UBound(v1, 1) Then
Do While Val(Right(v1(i + 1, 1), 3)) = Val(Right(v1(i, 1), 3)) + 1
i = i + 1
If i = UBound(v1, 1) Then
v2(j, 2) = v1(i, 1)
Exit Do
End If
Loop
End If
If v1(i, 1) <> v2(j, 1) Then v2(j, 2) = v1(i, 1)
Next i
Range("C1").Resize(j, 2) = v2
End Sub
Try the below code
Private Sub CommandButton1_Click()
Set wb = ThisWorkbook
lastRow = wb.Sheets("Sheet1").Range("A" & wb.Sheets("Sheet1").Rows.Count).End(xlUp).Row
Dim lastNum, Binsert As Integer
Dim firstCell, lastCell, currentCell As String
Binsert = 1
lastNum = getNum(wb.Sheets("Sheet1").Range("A1").Value)
firstCell = wb.Sheets("Sheet1").Range("A1").Value
For i = 2 To lastRow
activeNum = getNum(wb.Sheets("Sheet1").Range("A" & i).Value)
currentCell = wb.Sheets("Sheet1").Range("A" & i).Value
If (activeNum - lastNum) = 1 Then
'nothing
Else
lastCell = wb.Sheets("Sheet1").Range("A" & (i - 1)).Value
wb.Sheets("Sheet1").Range("B" & Binsert).FormulaR1C1() = firstCell
If (firstCell <> lastCell) Then
wb.Sheets("Sheet1").Range("C" & Binsert).FormulaR1C1() = lastCell
End If
Binsert = Binsert + 1
firstCell = wb.Sheets("Sheet1").Range("A" & i).Value
End If
lastNum = activeNum
Next i
'last entry
wb.Sheets("Sheet1").Range("B" & Binsert).FormulaR1C1() = firstCell
If (firstCell <> currentCell) Then
wb.Sheets("Sheet1").Range("C" & Binsert).FormulaR1C1() = currentCell
End If
End Sub
Public Function getNum(ByVal num As String) As Integer
getNum = Val(Mid(num, 2))
End Function
Another solution. It loops backwards from last row to first row.
Option Explicit
Public Sub FindConsecutiveValues()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lRow As Long 'find last row
lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Dim lVal As String 'remember last value (stop value)
lVal = ws.Range("A" & lRow).Value
Const fRow As Long = 2 'define first data row
Dim i As Long
For i = lRow To fRow Step -1 'loop from last row to first row backwards
Dim iVal As Long
iVal = Val(Right(ws.Range("A" & i).Value, Len(ws.Range("A" & i).Value) - 1)) 'get value of row i without A so we can calculate
Dim bVal As Long
bVal = 0 'reset value
If i <> fRow Then 'if we are on the first row there is no value before
bVal = Val(Right(ws.Range("A" & i - 1).Value, Len(ws.Range("A" & i - 1).Value) - 1)) 'get value of row i-1 without A
End If
If iVal - 1 = bVal Then
ws.Rows(i).Delete 'delete current row
Else
If lVal <> ws.Range("A" & i).Value Then 'if start and stop value are not the same …
ws.Range("B" & i).Value = lVal 'write stop value in column B
End If
lVal = ws.Range("A" & i - 1).Value 'remember now stop value
End If
Next i
End Sub

VBA Search row changed and code needs update

Below is a code that I am now using to automatically insert numbers to a cell that has todays date on Column A and the correct name on the first row of that column.
However, I can't seem to make it work if the names are in any other row than 1.
What changes do I need to make if I want it to search matches on row 2 or multiple rows?
Sub SyöttöEriVälilehti()
Application.ScreenUpdating = False
On Error GoTo M
Dim i As Long
Dim Lastrow As Long
Dim col As Long
col = 0
Dim LastColumn As Long
Dim DateLastrow As Long
Dim ans As String
Dim LString As String
Dim LArray() As String
Dim anss As String
Dim ansss As String
With Sheets("Malli2Data") ' Sheet name
DateLastrow = .Cells(Rows.Count, "A").End(xlUp).Row
Set SearchRange = .Range("A1:A" & DateLastrow).Find(Date)
If SearchRange Is Nothing Then MsgBox Date & " No matches", , "Oops!": Exit Sub
Lastrow = SearchRange.Row
LastColumn = .Cells(1, Columns.Count).End(xlToLeft).Column
ans = InputBox("Input name and number like so: Tom,5")
LString = ans
LArray = Split(LString, ",")
anss = LArray(0)
ansss = LArray(1)
For i = 2 To LastColumn
If .Cells(1, i).Value = anss Then col = Cells(1, i).Column
Next
If col = 0 Then MsgBox anss & " No matches": Exit Sub
.Cells(Lastrow, col).Value = ansss
End With
Application.ScreenUpdating = True
Exit Sub
M:
MsgBox "Error" & vbNewLine _
& "Check input" & _
vbNewLine & "You typedt: " & ans & vbNewLine & "Correct input type: " & vbNewLine & "Name" & ",Number" & _
vbNewLine & vbNewLine & "Try again"
End Sub
The snippet:
For i = 2 To LastColumn
If .Cells(1, i).Value = CDec(anss) Then col = Cells(1, i).Column
Next
Is searching row 1 for your name
If you want to change it and make it a variable, something like
For i = 2 To LastColumn
If .Cells(xRow, i).Value = CDec(anss) Then col = Cells(1, i).Column
Next
With xRow being your defined row to search will work.
At the same time, you could sub out the last bit within the loop and use
For i = 2 To LastColumn
If .Cells(xRow, i).Value = CDec(anss) Then col = i
Next
As they are the same thing.
edit 20201-04-23A: Use of CDec(anss) will convert the string (as gathered from "ans") into a decimal number - which can then be compared against the .Value taken out of the cell.

Updating For Each loop variable

The aim is to find the circularity between value in column c and all values obtained from updated "firstvalue" variable which are comma separated and stored in column "M".
Sub circular()
Dim rng As Range, rng2 As Range, firstvalue As String, secondvalue As String
Set sh = ThisWorkbook.Worksheets("Sheet1")
lr = sh.Range("C" & Rows.Count).End(xlUp).Row
For Each rng In sh.Range("C5:C" & lr) 'iterating over each cell in column "c" from C5 till lastrow "lr".
firstvalue = rng.Offset(0, 10).value 'Corresponding cell value which is comma seperated in column
"M" i:e after 10 columns from "C".
Dim n As Variant
For Each n In Split(firstvalue, ",") 'Looping through each value obtained from split function.
Set rng2 = sh.Range("C5:C" & lr).Find(Trim(n), LookIn:=xlValues) 'Finding that split value again
in column "C".
If Not rng2 Is Nothing Then 'if exists in column c then get.
secondvalue = rng2.Offset(0, 10).value 'corresponding cell values.
firstvalue = firstvalue & "," & secondvalue 'now first value is concatnated
with initial firstvalue
End If
Next n
MsgBox firstvalue
'Now i want to itterate over updated "firstvalue" in split function and this goes on in circular
fashion until rng value exists in firstvalue.
Next rng 'then change next rng and continue the above whole process for this value and so on.
End Sub
This code is working for initial firstvalue, can any one suggest any method to iterate over updated first value.
I'm not sure if I understand your goal exactly, but this code should find all predecessors for each task:
Sub circular()
Dim sh As Worksheet
Dim rTask As Range
Dim oCell As Range
Dim oFound As Range
Dim lr As Long, j As Long
Dim aPredecessors As Variant
Dim sCurTask As String
Dim secondValue As String
Set sh = ThisWorkbook.Worksheets("Sheet1")
lr = sh.Range("C" & Rows.Count).End(xlUp).Row
Set rTask = sh.Range("C5:C" & lr)
For Each oCell In rTask
sCurTask = Trim(oCell.Text)
aPredecessors = getPredecessors(Trim(oCell.Offset(0, 10).Text))
j = LBound(aPredecessors)
Do Until j > UBound(aPredecessors)
secondValue = aPredecessors(j)
If sCurTask = secondValue Then
ReDim Preserve aPredecessors(j)
Debug.Print "Task '" & sCurTask & "': Cyclic link '" & secondValue & "' for '" & Join(aPredecessors, ",") & "'!"
aPredecessors(j) = aPredecessors(j) & " !!!"
Else
If secondValue <> vbNullString Then
Set oFound = rTask.Find(secondValue, LookIn:=xlValues)
If oFound Is Nothing Then
ReDim Preserve aPredecessors(j)
Debug.Print "Task '" & sCurTask & "': Task '" & secondValue & "' for '" & Join(aPredecessors, ",") & "' not found!"
aPredecessors(j) = aPredecessors(j) & " ???"
Else
Call addNewTasks(aPredecessors, Trim(oFound.Offset(0, 10).Text))
End If
End If
End If
j = j + 1
Loop
oCell.Offset(0, 11).Value = Join(aPredecessors, ",")
Next oCell
End Sub
Function getPredecessors(sPredecessors As String)
Dim i As Long
Dim aTemp As Variant, sRes As String
Dim sTest As String
sRes = vbNullString
aTemp = Split(sPredecessors, ",")
For i = LBound(aTemp) To UBound(aTemp)
sTest = Trim(aTemp(i))
If InStr("," & sRes & ",", "," & sTest & ",") = 0 Then sRes = sRes & sTest & ","
Next i
If Len(sRes) > 1 Then sRes = Left(sRes, Len(sRes) - 1)
getPredecessors = Split(sRes, ",")
End Function
Sub addNewTasks(aData As Variant, sPredecessors As String)
Dim i As Long, uB As Long
Dim aTemp As Variant
Dim sTest As String, sValid As String
aTemp = Split(sPredecessors, ",")
If UBound(aTemp) >= 0 Then ' Not empty
sValid = "," & Join(aData, ",") & ","
For i = LBound(aTemp) To UBound(aTemp)
sTest = Trim(aTemp(i))
If sTest <> vbNullString Then
If InStr(sValid, "," & sTest & ",") = 0 Then
uB = UBound(aData) + 1
ReDim Preserve aData(uB)
aData(uB) = sTest
sValid = "," & Join(aData, ",") & ","
End If
End If
Next i
End If
End Sub

How to check for duplicate on specific column?

Im trying to detect duplicates on column("G") of my input workbook and by using lastrow of its data at column("E") to merge upwards by using & "" & after which it will delete the entireRow and this process continue until there are no more duplicates.
I tried and also look up for many codes including delete and duplicates but I am still having trouble.
Dim myCell As Range, myRow As Integer, myRange As Range, myCol As Integer, X As Integer
'Count number column
Set wsInput = Workbooks("InputB.xls").Worksheets("HC_MODULAR_BOARD_20180112")
myCol = Range(Cells(3, 7), Cells(3, 7).End(xlDown)).Count
'Loop each column to check duplicate values & highlight them.
For X = 3 To myRow
Set myRange = Range(Cells(2, X), Cells(myRow, X))
For Each myCell In myRange
If Workbooks("InputB.xls").Worksheets("HC_MODULAR_BOARD_20180112").CountIf(myRange, myCell.Value) > 1 Then
myCell.Interior.ColorIndex = 3
End If
Next
Next
' allow values at Column"E" to merge upwards and delete all duplicate and its row (missing)
I have no clue how to delete after copying data on top of the column. Someone please help.
Many Thanks,
Adrian
You could try:
Option Explicit
Sub test()
Dim LastRow As Long, i As Long, y As Long, Counter As Long
Dim SearchValue As String, AddValue As String
With ThisWorkbook.Worksheets("Sheet1") ' Always select your worksheet name
LastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
Counter = 0
AddValue = ""
SearchValue = ""
For i = LastRow To 3 Step -1
SearchValue = .Range("C" & i).Value
If SearchValue <> "" Then
If Application.WorksheetFunction.CountIf(.Range("C3:C" & LastRow), SearchValue) > 1 Then
For y = i To 3 Step -1
If .Range("C" & y).Value = SearchValue Then
If AddValue = "" Then
AddValue = .Range("E" & y).Value
Else
AddValue = AddValue & ", " & .Range("E" & y).Value
.Rows(y).EntireRow.Delete
Counter = Counter + 1
End If
End If
Next y
.Range("E" & i - Counter).Value = AddValue
AddValue = ""
SearchValue = ""
Counter = 0
End If
End If
Next i
End With
End Sub

How to insert character in middle of cell strings loop

Sub Button1_Click()
Dim Data1 As String
Dim Data2 As String
Dim sFinal As String
Dim sLeft As String
Dim sRight As String
'For i = 1 To Range("A" & Rows.Count).End(xlUp).Row
Data1 = Range("A1").Value
Data2 = "-"
sLeft = Left(Data1, 2)
sRight = Right(Data1, Len(Data1) - 2)
sFinal = sLeft & Data2 & sRight
Range("A1").Value = sFinal
'Next i
End Sub
I am trying to loop trough values of column A to insert "-" after two characters in every cells... but my "For Next i" loop has error, how can I fix it?
This is better:
Sub Button1_Click()
Dim i As Long
Application.ScreenUpdating = False
i = 1
Do Until i > Range("A1048576").End(xlUp).Row
Range("A" & i).Value = Left(Trim(Range("A" & i).Value), 2) & "-" & Right(Trim(Range("A" & i).Value), Len(Trim(Range("A" & i).Value)) - 2)
i = i + 1
Loop
Application.ScreenUpdating = True
End Sub

Resources