I'm still new to VBA and couldn't find any solution using the search-function so far.
Problem:
I have (in this case ten sheets) a row with over 500 cells containing strings with 5-7 words.
Now I need to delete all columns where the searched word is not the last word,but the word is in all cells (in the row) at different positions in the string.
I tried this:
Dim examinee As Variant
Dim cell As Range
Dim word As String
Dim myCell As String
examinee = InputBox("How many sheets?")
word = InputBox("Looking for?")
For A = 1 To examinee
Sheets("sheet" & A).Select
On Error Resume Next
Range("A3", Range("A3").End(xlToRight)).Select
For Each Cell In Selection.Cells
myCell = Right(Cell, Len(Cell) - (InStrRev(Cell, " ") - 1))
MsgBox myCell ' just to be sure the word is found
If myCell Like word Then
Selection.Cells.Bold = False
Else
Delete.Column
End If
Next Cell
Next
I can find&identify the word and "If" works fine so far, just nothing happens to the selected cell and the column wasn't deleted.
With some changes I can only delete the entire row but it isn't what I need.
Any help appriciated.
Thx in advance.
This should work, but I'd recommend cleaning up the syntax. I've removed the code where you're selecting ranges (there's lots of info online about why you shouldn't do this).
An array is created to find the last word and that's tested against the search value.
Sub Test()
Dim examinee As Variant
Dim cell As Range
Dim word As String
Dim myCell As String
Dim arr() As String
Dim strLastWord As String
'How Many Sheets Should We Loop?
examinee = InputBox("How many sheets?")
'What Word Are We Searching For?
word = InputBox("Looking for?")
'Loop Sheets
For A = 1 To examinee
'Loop Cells In Row 3
For Each cell In Range("A3", Range("A3").End(xlToRight))
'Get The Value Of The Current Cell
myCell = Right(cell, Len(cell) - (InStrRev(cell, " ") - 1))
'Is It A Single Word?
If InStr(1, myCell, " ") Then
'Several Words. Create An Array Of Individual Words In The Cell
arr() = Split(myCell, " ")
'Get The Number Of The Last Word
strLastWord = arr(UBound(arr))
Else
'Single Word. Get The Word
strLastWord = myCell
End If
'Is The Last Word = The Search Word?
If strLastWord = word Then
'Yes. Make It Bold
cell.Font.Bold = True
Else
'No. Delete The Column
Columns(cell.Column).Delete
End If
Next cell
Next
End Sub
I think this will help you
Sub findtext()
Dim wsAkt As Worksheet
Dim i As Integer
Dim k As Integer
Dim x As Integer
Dim strWord As String
Dim intWord As Integer
'get the word
strWord = Application.InputBox("Looking for?")
'length of word
intWord = Len(strWord)
'loop through all worksheets
For i = 1 To ThisWorkbook.Worksheets.Count
'variable for selected worksheet
Set wsAkt = ThisWorkbook.Worksheets(i)
'get how many columns are in row 3
x = wsAkt.Cells(3, wsAkt.Columns.Count).End(xlToLeft).Column
'loop through row 3 columns
For k = 1 To x
'if last Word in cell = the word then it has to have the same length
If Right(wsAkt.Cells(3, k), intWord) <> strWord Then
'delete selected column
wsAkt.Columns(k).Delete
End If
Next k
Next i
End Sub
(Its not tested)
Related
I have strings stored in cells of a column in Excel that I would like to concatenate in several pieces, like sentences, with VBA. Here is an example:
Column A
Jack
learns
VBA
Jack
sits
on
a
couch
Jack
wants
chocolate
cake
I finally found a way to concatenate all strings and save the sentences to a cell:
Sub JACK()
Dim MP() As String
Dim Str As String
Dim i As Integer
For i = 2 To 10
ReDim Preserve MP(i)
MP(i) = Cells(i, 1).Value
Next i
Str = Join(MP)
Cells(1, 2).Value = Str
End Sub
But I would like to have the sentences that start with "Jack" and end with the row "Jack - 1", each saved in seperate cells.
Could anyone help me???
Thank you so much!
This is the code snippet that will do what you want:
Sub test_func()
' this is the starting cell (keep in mind that the first word in the cell is 'Jack' so the start cell is actually starting at C2)
Dim startCell As range
Set startCell = ThisWorkbook.ActiveSheet.range("B2")
' reading all the cells in the range
Dim wordRange As range
Set wordRange = ThisWorkbook.ActiveSheet.range("A2:A13")
' creating two variables row and col
Dim row As Long
Dim col As Long
' for each word in wordRange
Dim word As Variant
For Each word In wordRange
' as soon as we find the word 'Jack'
If word.Value = "Jack" Then
' move the cursor to row 0
row = 0
' move the cursor one cell to the right
col = col + 1
End If
' else if the word is not 'Jack', put the word on the cursor cell
startCell.Offset(row, col) = word
' then move the cursor one cell down
row = row + 1
Next
End Sub
The function is:
reading all the words from the column A into a range.
dumping the elements from the range (word) starting on B2, one by one
as soon as it finds the word 'Jack', it will start at row 0, move to the right and continue
The outcome looks like this:
This is the output of the script
Note that the words are starting on C2 even though you chose B2 to be the starting cell; this is because the first word in the list is 'Jack', so it is moving one cell to the right as soon as it starts.
EDIT:
Here might be the function that you are looking for:
Sub test_func()
' this is the starting cell (keep in mind that the first word in the cell is 'Jack' so the start cell is actually starting at C2)
Dim startCell As range
Set startCell = ThisWorkbook.ActiveSheet.range("B2")
' reading all the cells in the range
Dim wordRange As range
Set wordRange = ThisWorkbook.ActiveSheet.range("A2:A13")
' creating two variables row and col
Dim row As Long
Dim col As Long
' string that holds each sentence
Dim sentence As String
' for each word in wordRange
Dim word As Variant
For Each word In wordRange
' as soon as we find the word 'Jack' and the sentence is not empty, the sentence is complete
If word.Value = "Jack" And sentence <> "" Then
'printing out the whole sentence
startCell.Offset(row, col) = sentence
' emptying the sentence when 'Jack' is found
sentence = ""
' move the cursor one cell down
row = row + 1
End If
' else if the word is not 'Jack', concatenates the word into the sentence
sentence = sentence & " " & word
Next
' adding this again at the end of the loop because the last sentence is not outputted otherwise
startCell.Offset(row, col) = sentence
End Sub
This function differs from the previous one because it concatenates the words into a sentence before dumping it out. In this function, the start cell is correct and is not moving down or right when the program starts. This is because we can check whether the sentence that it is about to dump out is empty or not, if it is; then it means we did not finish our sentence.
Hope this helps!
This is the result screenshot of the second version of the code
Extract Sentences From Column
Sub JACK()
Const JackStart As String = "Jack"
Const JackEnd As String = "."
Const Delimiter As String = " "
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim slCell As Range: Set slCell = ws.Cells(ws.Rows.Count, "A").End(xlUp)
Dim srg As Range: Set srg = ws.Range("A2", slCell)
Dim dCell As Range: Set dCell = ws.Range("B2")
Dim sCell As Range
Dim JackString As String
Dim FoundFirst As Boolean
For Each sCell In srg.Cells
If sCell.Value = JackStart Then
If FoundFirst Then
dCell.Value = JackString & JackEnd
Set dCell = dCell.Offset(1) ' next row
Else
FoundFirst = True
End If
JackString = JackStart
Else
If FoundFirst Then JackString = JackString & Delimiter & sCell.Value
End If
Next sCell
dCell.Value = JackString & JackEnd
MsgBox "Jacks extracted.", vbInformation
End Sub
Dear experts in Excel and VBA!
Could you tell me how you can color a certain line (condition - the presence of a certain word) in a Comments?
Comment consists of several lines, separated by Chr (10).
Example in picture1:
the comment has 4 lines, the second line contains the word "VBA", so this line should be highlighted in red.
The main problem is that the test word "VBA" can be in any line, there can be from 1 to 10+ lines.
I assumed that:
can move data from comment to cell
replace Chr (10) with some character, for example, "_"
distribute the text of the cell into columns through the "column distribution wizard"
search for the desired word "VBA" in the received cells
determine the cell number and understand that this is the number of the required line in the comment
based on the cell number, paint over the line number in the comment
Can you please tell me if my action logic is correct? Am I heading in the right direction?
If so, what is the correct way to carry out points 4-6?
enter image description here
would this help?
"test" is the codename for the sheet I have set, change it according to your situation.
"i" will give you the line number, starting from 0. So in your example it would be 1.
Edit: Added Exit For in the if check.
Option Explicit
Sub test_note()
Dim strNote As String
Dim arrNote As Variant
Dim number_of_lines As Integer
strNote = test.Range("A5").NoteText
number_of_lines = Len(strNote) - Len(Replace(strNote, Chr(10), "")) + 1
ReDim arrNote(1 To number_of_lines) As String
arrNote = Split(strNote, Chr(10))
Dim i As Long
For i = LBound(arrNote) To UBound(arrNote)
If InStr(arrNote(i), "VBA") > 0 Then
Debug.Print i, arrNote(i)
Exit For 'If you are sure there won't be any other occurrence of VBA in there, why check the rest of the lines? Speeds code depending on circumstance.
End If
Next i
End Sub
Edit 2: Revised code to change the color of the comment line.
Sub test_note()
Dim strNote As String
Dim arrNote As Variant
Dim number_of_lines As Integer
strNote = test.Range("B5").NoteText
number_of_lines = Len(strNote) - Len(Replace(strNote, Chr(10), "")) + 1
ReDim arrNote(1 To number_of_lines) As String
arrNote = Split(strNote, Chr(10))
Dim i As Long
Dim startPos As Integer
Dim number_of_chars As Integer
startPos = 1
' Reset comment font color
test.Range("B5").Comment.Shape.TextFrame.Characters.Font.Color = 0
For i = LBound(arrNote) To UBound(arrNote)
If InStr(arrNote(i), "VBA") > 0 Then
number_of_chars = Len(arrNote(i))
test.Range("B5").Comment.Shape.TextFrame.Characters(startPos, number_of_chars).Font.Color = vbRed
Debug.Print i, arrNote(i), "startPos: " & startPos, "numChars: " & number_of_chars
Else
startPos = startPos + Len(arrNote(i)) + 1
End If
Next i
End Sub
Check this. Just running this VBA copies your comments to the cells
and highlights the lines containing "VBA", however, it does this for
all comments on all sheets
credit: https://martinbosanacvba.blogspot.com/2021/08/copying-comments-to-cells-and.html
Sub Demo()
Dim tnahqb1 As Range
Dim tnahqb2 As Range
Dim tnahqb3 As Workbook
Dim tnahqb4 As Worksheet
Dim tnahqb5 As Variant
Dim tnahqb6 As Integer
Dim tnahqb7 As Integer
Dim tnahqb8 As Integer
Dim tnahqb9 As Integer
For Each tnahqb10 In ActiveWorkbook.Worksheets
Set tnahqb1 = tnahqb10.Cells.SpecialCells(xlCellTypeComments)
If tnahqb1 Is Nothing Then
MsgBox "No comments in the sheet"
Else
For Each cell In tnahqb1
cell.Value = cell.Comment.Text
tnahqb5 = Split(cell.Comment.Text, Chr(10))
tnahqb6 = UBound(tnahqb5) - LBound(tnahqb5) + 1
For I = LBound(tnahqb5) To UBound(tnahqb5)
If InStr(tnahqb5(I), "VBA") > 0 Then
tnahqb8 = Len(tnahqb5(I))
With cell
tnahqb7 = InStr(cell.Comment.Text, tnahqb5(I))
tnahqb9 = tnahqb7 + tnahqb8
.Characters(tnahqb7, tnahqb8).Font.Color = vbRed
End With
End If
Next I
Next cell
End If
Next tnahqb10
End Sub
I have two sheets in a workbook. They are imported (connected) from two text file reports. Right now the code I'll post below deletes all duplicates between the two sheets and leaves me with the first sheet (today) with just unique rows left. The problem is Column A, which I use to compare and delete contains words on some lines (like "Category") and numbers on other lines. The only duplicates I really need deleted are the numeric duplicates. I would prefer the words get ignored. Is there a way to delete duplicate rows with numeric values and ignore letter values? I haven't been able to find anything and I honestly don't do this stuff often.
Sub CleanDupes()
Application.ScreenUpdating = False
Dim targetArray, searchArray, targetRange As Range, x As Long
'Update these 4 lines if your target and search ranges change
Dim TargetSheetName As String: TargetSheetName = "Today"
Dim TargetSheetColumn As String: TargetSheetColumn = "A"
Dim SearchSheetName As String: SearchSheetName = "Yesterday"
Dim SearchSheetColumn As String: SearchSheetColumn = "A"
'Load target array
With Sheets(TargetSheetName)
Set targetRange = .Range(.Range(TargetSheetColumn & "12"), _
.Range(TargetSheetColumn & Rows.Count).End(xlUp))
targetArray = targetRange
End With
'Load Search Array
With Sheets(SearchSheetName)
searchArray = .Range(.Range(SearchSheetColumn & "12"), _
.Range(SearchSheetColumn & Rows.Count).End(xlUp))
End With
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
'Populate dictionary from search array
If IsArray(searchArray) Then
For x = 1 To UBound(searchArray)
If Not dict.exists(searchArray(x, 1)) Then
dict.Add searchArray(x, 1), 1
End If
Next
Else
If Not dict.exists(searchArray) Then
dict.Add searchArray, 1
End If
End If
'Delete rows with values found in dictionary
If IsArray(targetArray) Then
'Step backwards to avoid deleting the wrong rows.
For x = UBound(targetArray) To 1 Step -1
If dict.exists(targetArray(x, 1)) Then
targetRange.Cells(x).EntireRow.Delete
End If
Next
Else
If dict.exists(targetArray) Then
targetRange.EntireRow.Delete
End If
End If
End Sub
I have a column with text (Words and numbers) separated by spaces. There are two cases:
Case 1 (3 words separated by 2 space): BALDOR 3 hp-4
Case 2(4 words separated by 3 space): US ELECTRICAL 75 hp-232
I need to extract the Bolded word(s) (they aren't bolded in the data i have, it's just to illustrate) so I figured I would reverse the order of the words then get rid of the first two (3 hp4 and 75 hp232) which will always output the bolded words.
I might be going about it the wrong way with reversing the order of the words so If you have another method that you think is better do tell.
This is what I have so far:
Sub ExtractMissingInfo2()
Dim TypeCell As Variant
Dim Manufacturer As String
Dim MFG As Variant
Dim MFGrev As Variant
Dim MFGout As Variant
Dim RowCount As Variant
Dim Rng As Range
Dim a As Variant
Dim I As Variant
Dim wbdata As Workbook
Dim wsData As Worksheet
Set wbdata = Workbooks("trial1")
Set wsData = wbdata.Worksheets("Final Data")
wsData.Activate
'Counts how many cells in the chosen column
RowCount = Cells(Rows.Count, 4).End(xlUp).Row
For a = 2 To RowCount
If Not IsEmpty(Cells(a, 4)) Then
TypeCell = wsData.Cells(a, 4).Text 'cells with information
MFG = Split(TypeCell, " ") 'separate them
'Reverse the order of the words
For I = UBound(MFG) To 0 Step -1
MFGrev = MFGrev + "" + MFG(I) + " "
'Use the last iteration which will include all the words in reverse order
If I = 0 Then
MFGout = MFGrev
End If
Next
'This part I am not sure about
Manufacturer = Split(MFGout.Text, " ")(0)
'Insert extracted words into new column
Cells(a, 16) = WorksheetFunction.Transpose(Manufacturer)
Else
MsgBox ("Is empty... row " & a)
End If
Next
End Sub
So my First issue is that when looping, it keeps adding every string of every cell to the next instead of going through each cell one by one and outputting the words in reverse order.
My second issue is that I am not sure how to delete the first two words after reversing the order.
This is my first question on here so if i made mistakes in the formatting let me know.
Thank you in advance for any help!
EDIT:
What I am trying to do is extract the manufacturers' names for a list of equipment. The names can have one or two words in it so that is what i need to extract. I then am pasting those in another column.
The cases I gave where just examples to show the two cases that arise in that list and ask how to deal with them.
I guess you're after this code (explanations in comments)
Option Explicit
Sub ExtractMissingInfo2()
Dim MFG As Variant
Dim cell As Range
With Workbooks("trial1").Worksheets("Final Data") 'reference your wanted workbook and worksheet
For Each cell In .Range("D2", .Cells(Rows.Count, 4).End(xlUp)).SpecialCells(xlCellTypeConstants) 'loop thorugh referenced sheet column D not empty cells from row 2 down to last not empty row
MFG = Split(cell.Text, " ") ' separate each word
If UBound(MFG) > 1 Then ReDim Preserve MFG(0 To UBound(MFG) - 2) ' if there were more than two words, keep all but the last two ones
cell.Offset(, 12).Value = Join(MFG, " ") ' write remaining words into column P same row of current cell
Next
End With
End Sub
try this code, it works for both cases :
Sub test()
Dim myarray As Variant
myarray = Array("US ELECTRICAL 3 hp-2", "BALDOR 3 hp-4")
For j = 0 To UBound(myarray)
x = ""
t = Split(myarray(j))
For i = 0 To UBound(t) - 2
x = x & " " & t(i)
Next i
MsgBox myarray(j) & " ---- " & x
Next j
End Sub
Assuming you want to remove the first 3 letters of a string in A1, give this a gander:
Dim n As Integer
n = 3
Cells(2, 2).Value = Right(Range("A1"), Len(Range("A1")) - n)
This assumes the length of the first part of the string is constant which it seems like it is from your example, though you may wish to clarify this. It's not too clear what you're after.
I'm looking for some sort of macro that deletes duplicate words within cells in a spreadsheet.
For instance, if cell A1 = "John John" I would like my macro to delete the duplicate "John". In other words A1 will become "John".
I have found a set of code that I have tweaked to some degree to fit my needs:
Sub Remove_DupesInString()
'this loops through the specified range and erases duplicates
Dim starval As String
Dim finval As String
Dim strarray() As String
Dim x As Long
Dim y As Long
Dim k As Long
' step through each cell in range
For Each cell In Sheets(5).Range("D2:D6507")
Erase strarray ' erase array
finval = "" ' erase final value"
starval = cell.Value
strarray = Split(starval, " ") 'Seperator is space
'Step through length of string and look for duplicate
For rw = 0 To UBound(strarray)
For k = rw + 1 To UBound(strarray)
If Trim(strarray(k)) = Trim(strarray(rw)) Then
strarray(k) = "" 'if duplicate clear array value
End If
Next k
Next rw
' combine all value in string less duplicate
For x = 0 To UBound(strarray)
If strarray(x) <> "" Then
finval = finval & Trim(strarray(x)) & ", "
End If
Next x
' remove last space and comma
finval = Trim(finval)
finval = Left(finval, Len(finval) - 1)
' Replaces cells with new values
cell.Value = finval
Next cell
End Sub
This set of code is sensitive to blank spaces in each cell. If, in cell D2, I have "John John" and in cell D3 have "Mary" it will produce the following:
D2 = "John", D3 = "Mary"
It does not seem to work, however, if I have blank cells in the column I'm running my macro in. I have worked around this issue by sorting on the cells with data inside them and only running my macro in this range.
I've tried tweaking the code further by adding different If cases with isEmpty(). My initial thought was that the the code above would only be executed If not isEmpty() Then but I've had no luck here. I'm not quite sure what to put inside the isEmpty function. Any ideas?
As you say, your only problem appears to be the handling of cells which are empty. That can easily be overcome by simply not processing any cells where the cell doesn't contain a space:
Sub Remove_DupesInString()
'this loops through the specified range and erases duplicates
Dim starval As String
Dim finval As String
Dim strarray() As String
Dim x As Long
Dim y As Long
Dim k As Long
' step through each cell in range
For Each cell In Sheets(5).Range("D2:D6507")
finval = "" ' erase final value"
starval = cell.Value
strarray = Split(starval, " ") 'Seperator is space
If UBound(strarray) > LBound(strarray) Then 'i.e. there was a space
'Step through length of string and look for duplicate
For rw = 0 To UBound(strarray)
For k = rw + 1 To UBound(strarray)
If Trim(strarray(k)) = Trim(strarray(rw)) Then
strarray(k) = "" 'if duplicate clear array value
End If
Next k
Next rw
' combine all value in string less duplicate
For x = 0 To UBound(strarray)
If strarray(x) <> "" Then
finval = finval & Trim(strarray(x)) & ", "
End If
Next x
' remove last space and comma
finval = Trim(finval)
finval = Left(finval, Len(finval) - 1)
' Replaces cells with new values
cell.Value = finval
End If
Next cell
End Sub