Between columns F and BM of the sheet, if any value within those columns is equal to "NULL" then don't hide, otherwise hide that column, the column before and column after. The loop should evaluate every other 3rd starting at column G and ending at column BM.
For example, if column G contains the value "NULL" then do nothing and go to column J (three columns forward). If column J now has no cells with value NULL then hide that column, the column before (column I), and the column after (column K).
This is what Im having trouble with. I am able to hide a column based on if the column contains the value NULL or not.
This is the code variations that I have attempted.
Sub SuspenseReport()
Dim allColumns As Range
Dim cell As Range
Dim col As Range
Dim x As Integer
Dim i As Integer
Application.ScreenUpdating = False
Set allColumns = Columns("C:E")
allColumns.Hidden = True
Set allColumns = Columns("BN:DY")
allColumns.Hidden = True
Set allColumns = Columns("EB:EU")
allColumns.Hidden = True
Dim rng1 As Range: Set rng1 = Application.Range("G2:BO8") 'maybe limit the range to just one column and range.offet at the end?
For Each col In rng.Columns
If cell.Value = "NULL" Then
cell.EntireColumn.Hidden = False
GoTo ExitIfStat
Else: cell.EntireColumn.Hidden = True
End If
Next col
ExitIfStat:
Next x
'below is another variation I attempted but the for loop would iterate on cell not column
'Dim i As Integer
'i = -1
'For Each col In Range("G1:BO8")
' i = i + 1
' If i Mod 3 = 0 Then
' If col.Value = "NULL" Then
' col.EntireColumn.Hidden = False
' Else: col.EntireColumn.Hidden = True
'col.Offset(0, -1).EntireColumn.Hidden = True
'col.Offset(0, 1).EntireColumn.Hidden = True
' End If
Application.ScreenUpdating = True
End Sub
Maybe something like:
Sub HideColumnWithoutNullString()
Dim range, colCount, rowCount, hasNull, rowsToCheck
Dim firstColumn, currentColumn, lastColumn
Set range = Application.range("G:BM")
firstColumn = range.Columns(0).Column
lastColumn = range.Columns(range.Columns.Count).Column
currentColumn = 0
rowsToCheck = 1
For colCount = firstColumn To lastColumn Step 1
hasNull = False
For rowCount = 1 To range.Rows.Count Step 1
If Application.Cells(rowCount, colCount).Value = "NULL" Then
hasNull = True
Exit For
End If
If rowCount >= rowsToCheck Then
Exit For
End If
Next
If Not hasNull Then
range.Columns(currentColumn).Hidden = True
Else
range.Columns(currentColumn).Hidden = False
End If
currentColumn = currentColumn + 1
Next
End Sub
Where rowsToCheck is the number of rows the script has to check for "NULL" on each column, if it only has to check the first row set its value to 1.
This one follows the same logic as Octavio's answer, but will check for an empty column or the value of "NULL".
Sub SuspenseReport()
Dim col As Range
Application.ScreenUpdating = False
Set Rng = Application.Range("G2:BO8")
vLr = ActiveCell.SpecialCells(xlLastCell).Row
For Each col In Rng.Columns
vFlag = False
For vrow = 2 To vLr
vX = Cells(vrow, col.Column).Value
If vX = "" Or vX = "NULL" Then
vFlag = True
End If
Next
If vFlag Then
col.EntireColumn.Hidden = False
Else
col.EntireColumn.Hidden = True
End If
Next col
Application.ScreenUpdating = True
End Sub
Related
I have written the following code for one of my worksheets.
Sub Hide_Projects()
Application.ScreenUpdating = False
i = 6
For i = 6 To 350
Cells(9, i).Select
If Selection.Value = "Project" Then
ActiveCell.EntireColumn.Hidden = True
Else
ActiveCell.EntireColumn.Hidden = False
End If
Next i
Application.ScreenUpdating = True
End Sub
It works fine, does exactly what I need it to every time without crashing or lagging. However, when I use a similar code on a different worksheet, only this time applied to rows rather than columns, it either crashes my Excel or takes about 2 minutes to run, even though the code is identical. This is the second code:
Sub Hide_Projects_5yr()
Application.ScreenUpdating = False
i = 6
For i = 6 To 350
Cells(i, 7).Select
If Selection.Value = "Project" Then
ActiveCell.EntireRow.Hidden = True
Else
ActiveCell.EntireRow.Hidden = False
End If
Next i
Application.ScreenUpdating = True
End Sub
Does anyone have any idea why this is the case?
Thank you!
Obviously columns are times faster to hide than rows. I have tried this:
Option Explicit
Public Sub TestingSpeed()
Dim lngCount As Long
Dim dtTime As Date
Columns.Hidden = False
rows.Hidden = False
dtTime = Now
For lngCount = 1 To 300
rows(lngCount).Hidden = True
Next lngCount
Debug.Print "Rows: -> "; DateDiff("s", dtTime, Now())
dtTime = Now
For lngCount = 1 To 300
Columns(lngCount).Hidden = True
Next lngCount
Debug.Print "Cols: -> "; DateDiff("s", dtTime, Now())
End Sub
The result is the following (in seconds):
Rows: -> 9
Cols: -> 2
And the difference grows somehow exponentially.
With 1.000 samples it is like this:
Rows: -> 11
Cols: -> 1
With 10.000 like this:
Rows: -> 19
Cols: -> 10
It is very likely that your active sheet is not the one you intend to work on. It is always best to avoid Select and ActiveCell, because you are dependent on the cursor location. Not sure you need the false case, unless you use the same sheet over and over again and it may be hidden.
Sub Hide_Projects_5yr()
Application.ScreenUpdating = False
Dim ws as Worksheet
Set ws = Sheets("YourSheetName")
For i = 6 To 350
If ws.Cells(i, 7).Value = "Project" Then
ws.Cells(i, 7).EntireRow.Hidden = True
Else
ws.Cells(i, 7).EntireRow.Hidden = False
End If
Next i
Application.ScreenUpdating = True
End Sub
Could you try giving your code full addresses to your cells? Besides, it is a good idea not using the select command. Here's my modifications to your code:
Sub Hide_Projects()
Application.ScreenUpdating = False
With ThisWorkbook.Sheets("Put the name of your sheet here")
For i = 6 To 350
If .Cells(9, i).Text = "Project" Then
.Columns(i).Hidden = True
Else
.Columns(i).Hidden = False
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
Your second code would look like this:
Sub Hide_Projects_5yr()
Application.ScreenUpdating = False
With ThisWorkbook.Sheets("Put the name of your second sheet here")
For i = 6 To 350
If .Cells(i, 7).Text = "Project" Then
.Rows(i).Hidden = True
Else
.Rows(i).Hidden = False
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
Let me know if the error message keeps appearing.
Your main slowdown is a result of reading data from the worksheet too many times. Load the cell values into an array first, then loop through that.
You can also gain a bit of speed by unhiding the rows all at once at the outset, then hiding if the "="Project" condition is true. Again, this reduces the number of calls to the worksheet; your current version sets the ".Hidden" property of each row one-by-one.
Application.ScreenUpdating = False
Dim i As Long
Dim j As Long
Dim tempArr As Variant
tempArr = Range(Cells(6, 7), Cells(350, 7)).Value
Rows("6:350").Hidden = False
j = 1
For i = LBound(tempArr, 1) To UBound(tempArr, 1)
If tempArr(i, 1) = "Project" Then
Rows(j + 5).Hidden = True
End If
j = j + 1
Next
Application.ScreenUpdating = True
If you're really concerned about speed, you could also reduce the number of trips to the worksheet by checking for consecutive rows containing "Project". This version runs ~2x as fast as the other one (tested on a sample of 200k rows). It makes the code a lot more complex, though.
Application.ScreenUpdating = False
Dim i As Long
Dim j As Long
Dim k As Long
Dim tempArr As Variant
Dim consBool As Boolean
tempArr = Range(Cells(6, 7), Cells(350, 7)).Value
Rows("6:350").Hidden = False
j = 1
For i = LBound(tempArr, 1) To UBound(tempArr, 1)
consBool = True
If tempArr(i, 1) = "Project" Then
k = i
Do Until consBool = False
If k = UBound(tempArr, 1) Then
consBool = False
ElseIf tempArr(k + 1, 1) = "Project" Then
k = k + 1
Else
consBool = False
End If
Loop
Rows(j + 5 & ":" & k + 5).Hidden = True
j = j + 1 + (k - i)
i = k
Else
j = j + 1
End If
Next
Application.ScreenUpdating = True
Here's what it'd look like if I were going to implement this in a larger project. Among other optimizations, I've added some features (it can check for partial matches, check multiple columns for your criteria, and do an "inverted" mode that hides all rows not containing your criteria) and made sure that you're required to specify your worksheet.
Option Explicit
Sub exampleMacro()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Call hideRows(ThisWorkbook.Sheets("Example WS"), 6, 350, "Project", 7, 7)
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Sub hideRows(ws As Worksheet, startRow As Long, endRow As Long, valCrit As String, Optional startCol As Long = 1, Optional endCol As Long = 1, Optional invert As Boolean = False, Optional checkAll As Boolean = False)
'Hides rows in a range (startRow to endRow) in a worksheet (ws)
'Hides when row contains a value (valCrit; partial strings are accepted) in a column or series of columns (startCol to endCol)
'In inverted mode (invert), hides rows that do *not* contain value
'If (checkAll) is True, all columns must contain value to be hidden/unhidden
'Usage examples:
'Call hideRows(exampleWS, 1, 1000, "Foo", 1, 10) -> hides rows that contain a cell in columns 1-10 with exact value "Foo"
'Call hideRows(exampleWS, 1, 1000, "*Foo*", 1, 10) -> hides rows that contain a cell in columns 1-10 that contains partial string "*Foo*"
'Call hideRows(exampleWS, 1, 1000, "Foo", 1, 10, True) -> hides rows that contain no cells in columns 1-10 with exact value "Foo"
'Call hideRows(exampleWS, 1, 1000, "Foo", 1, 10, False, True) -> hides rows in which all cells in columns 1-10 contain the exact value "Foo"
'Call hideRows(exampleWS, 1, 1000, "Foo", 1, 10, True, True) -> hides rows in which no cells in columns 1-10 contain the exact value "Foo"
Dim loopCounter As Long
Dim rowCounter As Long
Dim colCounter As Long
Dim endConsRow As Long
Dim tempArr As Variant
Dim toAdd As Long
Dim toHide As String
Dim consBool As Boolean
Dim tempBool As Boolean
Dim rowStr As String
Dim goAhead As Boolean
Dim i As Long
If startRow > endRow Then
toAdd = endRow - 1
Else
toAdd = startRow - 1
End If
ws.Rows(startRow & ":" & endRow).Hidden = False
tempArr = ws.Range(ws.Cells(startRow, startCol), ws.Cells(endRow, endCol)).Value
loopCounter = 1
For rowCounter = LBound(tempArr, 1) To UBound(tempArr, 1)
For colCounter = LBound(tempArr, 2) To UBound(tempArr, 2)
goAhead = False
If tempArr(rowCounter, colCounter) Like valCrit Then
If (Not checkAll) Or (colCounter = UBound(tempArr, 2)) Then
If invert Then
loopCounter = loopCounter + 1
Exit For
End If
goAhead = True
End If
ElseIf checkAll Or colCounter = UBound(tempArr, 2) Then
If Not invert Then
loopCounter = loopCounter + 1
Exit For
End If
goAhead = True
End If
If goAhead Then
endConsRow = rowCounter
consBool = True
Do Until consBool = False
tempBool = False
For i = LBound(tempArr, 2) To UBound(tempArr, 2)
If endConsRow = UBound(tempArr, 1) Then
Exit For
ElseIf tempArr(endConsRow + 1, i) Like valCrit Then
If (Not checkAll) Or (i = UBound(tempArr, 2)) Then
If Not invert Then
endConsRow = endConsRow + 1
tempBool = True
End If
Exit For
End If
ElseIf checkAll Or i = UBound(tempArr, 2) Then
If invert Then
endConsRow = endConsRow + 1
tempBool = True
End If
Exit For
End If
Next
If Not tempBool Then
consBool = False
End If
Loop
rowStr = loopCounter + toAdd & ":" & endConsRow + toAdd
If toHide = "" Then
toHide = rowStr
ElseIf Len(toHide & "," & rowStr) > 255 Then
ws.Range(toHide).EntireRow.Hidden = True
toHide = rowStr
Else
toHide = toHide & "," & rowStr
End If
loopCounter = loopCounter + 1 + (endConsRow - rowCounter)
rowCounter = endConsRow
Exit For
End If
Next
Next
If Not toHide = "" Then
ws.Range(toHide).EntireRow.Hidden = True
End If
End Sub
I can not manage to cleanse my data of the "empty" rows. There is no problem in deleting the "0" but those cells which are empty are not empty but have something like "null strings" in it.
Sub Reinigung()
Application.ScreenUpdating = False
Application.EnableEvents = False
ListeEnde3 = ThisWorkbook.Sheets("input").Cells(Rows.Count, 1).End(xlUp).Row
For Zeile1 = 2 To ListeEnde3
If ThisWorkbook.Sheets("input").Cells(Zeile1, 14) = "0" Or ThisWorkbook.Sheets("2018").Cells(Zeile1, 14) = "" Then
ThisWorkbook.Sheets("input").Rows(Zeile1).Delete
Zeile1 = Zeile1 - 1
Else
End If
Next
' ThisWorkbook.Sheets("import").Columns(14).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
That code just freezes my excel, if i leave out the
thisWorkbook.Sheets("2018").Cells(Zeile1, 14) = ""
part, it works and deletes all rows, where colum 14 contains a "0".
If I check the cells which appear blank with =isblank it returns "false". There is no "space" in the cell and no " ' ".
What to do?
edit
After the first tips my code looks like this now:
Sub Reinigung()
Dim ListeEnde3 As Long
Dim Zeile1 As Long
Application.ScreenUpdating = False
Application.EnableEvents = False
ListeEnde3 = ThisWorkbook.Sheets("import").Cells(Rows.Count, 1).End(xlUp).Row
For Zeile1 = ListeEnde3 To 2 Step -1
Set rngX = ThisWorkbook.Sheets("import").Cells(Zeile1, 14)
If (rngX = "0" Or rngX = "") Then 'or rngY = vbNullString
ThisWorkbook.Sheets("import").Rows(Zeile1).Delete
End If
Next Zeile1
' ThisWorkbook.Sheets("import").Columns(14).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Excel still crashes / freezes (I waited for 5 minutes) but since the code runs "smoothly" with F8 I wanted to give it a shot with less data: It works!
If I am not reducing the data there are ~ 70000 rows to check. I let it run on 720 rows and it worked.
Any way to tweak the code in a way that it can handle the 70000+ rows? I didn't think that it would be too much.
Thanks!
You can use AutoFilter and delete the visible rows (not tested) :
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("import")
ws.UsedRange.AutoFilter 14, Array("=0", "="), xlFilterValues
ws.UsedRange.Offset(1).EntireRow.Delete
ws.AutoFilterMode = False
Another way is to simply use internal arrays and write out the new data set which has valid rows.
It is very fast.
If your dataset has formulas then you'll have to use extra code, but if it's constants only, then the below should do:
Sub Reinigung()
'Here I test with column E to Z, set Ranges appropriately
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim ListeEnde3 As Long, x As Long, y As Long
'last row of data - set to column of non-blank data
ListeEnde3 = ThisWorkbook.Sheets("import").Cells(Rows.Count, 5).End(xlUp).Row
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("import")
Dim startCell As Range
'set to whatever cell is the upper left corner of data
Set startCell = ThisWorkbook.Sheets("import").Range("E1")
Dim arr As Variant, arrToPrint() As Variant
'Get rightmost column of data instead of hardcoding to "Z"
'write dataset into an array
arr = ws.Range(startCell, ws.Range("Z" & ListeEnde3)).Value
x = UBound(arr) - LBound(arr) + 1 'num of rows of data
y = UBound(arr, 2) - LBound(arr, 2) + 1 'num of columns of data
ReDim arrToPrint(1 To x, 1 To y) 'array to hold valid/undeleted data
Dim i As Long, j As Long, printCounter As Long, arrayColumnToCheck as Long
arrayColumnToCheck = 14 - startCell.Column + 1 '14 is column N
For i = 1 To x
If arr(i, arrayColumnToCheck ) <> 0 And arr(i, arrayColumnToCheck ) <> vbNullString Then
printCounter = printCounter + 1
For j = 1 To y
'put rows to keep in arrToPrint
arrToPrint(printCounter, j) = arr(i, j)
Next j
End If
Next i
'Print valid rows to keep - only values will print - no formulas
startCell.Resize(printCounter, y).Value = arrToPrint
'Delete the rows with zero & empty cells off the sheet
startCell.Offset(printCounter).Resize(ListeEnde3 - printCounter, y).Delete xlShiftUp
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
You can add IsEmpty to your code to check the cells filling
Sub Reinigung()
Application.ScreenUpdating = False
Application.EnableEvents = False
ListeEnde3 = ThisWorkbook.Sheets("input").Cells(Rows.Count, 1).End(xlUp).Row
For Zeile1 = 2 To ListeEnde3
Set rngX = ThisWorkbook.Sheets("input").Cells(Zeile1, 14)
Set rngY = ThisWorkbook.Sheets("2018").Cells(Zeile1, 14)
If (rngX = "0" And (Not IsEmpty(rngX))) Or (rngY = "") Then
ThisWorkbook.Sheets("input").Rows(Zeile1).Delete
Zeile1 = Zeile1 - 1
End If
Next
' ThisWorkbook.Sheets("import").Columns(14).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
NEVER a good idea to alter a loop counter: Zeile1 = Zeile1 - 1
Instead start at the end and use Step -1 in your loop to work backward.
You are in a infinite loop because the loop doesnt move forward. If Zeile=3 and there is a "" in row3 in the '2018' sheet, then it will always be stuck on the Zeile1 = 3 line. You will always be coming back to that "" on row 3 in '2018'sheet.
For Zeile1 = ListeEnde3 To 2 Step -1
Set rngX = ThisWorkbook.Sheets("input").Cells(Zeile1, 14)
Set rngY = ThisWorkbook.Sheets("2018").Cells(Zeile1, 14)
If (rngX = "0" Or rngY = "") Then 'or rngY = vbNullString
ThisWorkbook.Sheets("input").Rows(Zeile1).Delete
End If
Next Zeile1
I have the following basic script that merges cells with the same value in Column R
Sub MergeCells()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim rngMerge As Range, cell As Range
Set rngMerge = Range("R1:R1000")
MergeAgain:
For Each cell In rngMerge
If cell.Value = cell.Offset(1, 0).Value And IsEmpty(cell) = False Then
Range(cell, cell.Offset(1, 0)).Merge
GoTo MergeAgain
End If
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
What I would like to do is repeat this in columns A:Q and S:T but, I would like these columns to be merged in the same merged cell ranges as column R, i.e. if R2:R23 is merged then A2:A23, B2:B23, C2:C23 etc. will also be merge.
Columns A:Q do not contain values, column S:T have values but, these will be the same values throughout the range.
Any ideas
Apols for the earlier edit - this now deals with more than one duplicate in col R.
Note that this approach will work on the current (active) sheet.
Sub MergeCells()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim cval As Variant
Dim currcell As Range
Dim mergeRowStart As Long, mergeRowEnd As Long, mergeCol As Long
mergeRowStart = 1
mergeRowEnd = 1000
mergeCol = 18 'Col R
For c = mergeRowStart To mergeRowEnd
Set currcell = Cells(c, mergeCol)
If currcell.Value = currcell.Offset(1, 0).Value And IsEmpty(currcell) = False Then
cval = currcell.Value
strow = currcell.Row
endrow = strow + 1
Do While cval = currcell.Offset(endrow - strow, 0).Value And Not IsEmpty(currcell)
endrow = endrow + 1
c = c + 1
Loop
If endrow > strow+1 Then
Call mergeOtherCells(strow, endrow)
End If
End If
Next c
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Sub mergeOtherCells(strw, enrw)
'Cols A to T
For col = 1 To 20
Range(Cells(strw, col), Cells(enrw, col)).Merge
Next col
End Sub
You can try the below code as well. It would require you to put a 'No' after the last line in column R (R1001) so as to end the while loop.
Sub Macro1()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
flag = False
k = 1
While ActiveSheet.Cells(k, 18).Value <> "No"
i = 1
j = 0
While i < 1000
rowid = k
If Cells(rowid, 18).Value = Cells(rowid + i, 18).Value Then
j = j + 1
flag = True
Else
i = 1000
End If
i = i + 1
Wend
If flag = True Then
x = 1
While x < 21
Range(Cells(rowid, x), Cells(rowid + j, x)).Merge
x = x + 1
Wend
flag = False
k = k + j
End If
k = k + 1
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I have a big Excel sheet containing +100k rows and have an autofilter on one column of text values with category numbers and descriptions. There are thousands of different values in column F, so updating the autofilter is very impractical via using the standard UI.
How can I create a macro that removes the currently active cell's value from the autofilter that is active on the same column?
With the help of an expert, we came to a working solution for my case.
Just posting this as solution for others:
Sub Clear_Filter_and_Value()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim w As Worksheet
Dim filterArray()
Dim currentFiltRange As String
Dim col As Integer
Dim flag As Boolean
Set w = ActiveSheet
If w.AutoFilterMode = False Then Selection.AutoFilter
flag = False
On Error GoTo exit1
With w.AutoFilter
currentFiltRange = .Range.Address
With .Filters
For f = 1 To .Count
With .Item(f)
If .On Then
If ActiveCell.Column = f Then
ReDim filterArray(1 To .Count)
If .Count = 2 Then
filterArray(1) = .Criteria1
filterArray(2) = .Criteria2
Else
filterArray(1) = .Criteria1
End If
End If
ElseIf ActiveCell.Column = f Then
tR = Cells(Rows.Count, ActiveCell.Column).End(xlUp).Row
ReDim filterArray(1 To tR - 1)
For i = 2 To tR
filterArray(i - 1) = Cells(i, ActiveCell.Column).Value
flag = True
Next i
End If
End With
Next f
End With
End With
w.AutoFilterMode = False
j = 1
ReDim newArray(1 To UBound(filterArray))
If flag = False Then
On Error GoTo 1
For i = 1 To UBound(filterArray(1))
On Error GoTo 1
If InStr(1, filterArray(1)(i), ActiveCell.Value) = 0 Then
newArray(j) = filterArray(1)(i)
j = j + 1
End If
Next i
Else
1:
Err.Clear
For i = 1 To UBound(filterArray)
If InStr(1, filterArray(i), ActiveCell.Value) = 0 Then
newArray(j) = filterArray(i)
j = j + 1
End If
Next i
End If
For col = 1 To 1
If Not IsEmpty(filterArray(1)) Then
w.Range(currentFiltRange).AutoFilter Field:=ActiveCell.Column, Criteria1:=newArray, Operator:=xlFilterValues
End If
Next col
exit1:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I am looking for a method to compare a list of cell values to a certain reference value. If I would only need to compare the values I'd know how to achieve that. But here is the kicker: How can I look for a partial match? e.g.: the reference value should be "good". If the value of those cells would be "good" as well it should be considered a match. If the cell value is "Mr. goodcat" it should also be considered a match. My best guess would be to reference the original value to a string variable and put in some "*" if that would be possible.
Since I am not able to post some code, I don't need you to give me the whole answer, but a point in the right direction would be very nice. Thanks in advance guys.
edit: I have put in my final code. A short explaination: It loops through values in Sheet2 and compares them to values in column J in Sheet 1. If it finds a (partial) match, it highlights the cell.
Sub CompareValues()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws1Lrow As Long
Dim ws2Lrow As Long
Dim i As Integer
Dim x As Integer
Dim k As Integer
Dim reference As String
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
ws1Lrow = Worksheets("Sheet1").Range("A" & Worksheets("Sheet1").Rows.Count).End(xlUp).Row
ws2Lrow = Worksheets("Sheet2").Range("A" & Worksheets("Sheet2").Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
For i = 1 To ws2Lrow Step 1
ws2.Select
Cells(i, 1).Select
reference = ActiveCell
ws1.Select
For x = 2 To ws1Lrow
k = InStr(1, Cells(x, 10), reference, vbTextCompare)
If k > 0 Then
Cells(x, 10).Interior.ColorIndex = 6
End If
Next x
Next i
End Sub
How about this?
Dim I As Integer
I = InStr(1, "Mr. goodcat", "good", vbTextCompare)
If I > 0 Then
' Match
Else
' No Match
End
Here's more advanced function which allows wildcards in the middle:
Function PatternMatch(ByVal SearchIn As String, ByVal Pattern As String) As Boolean
If Len(SearchIn) = 0 Or Len(Pattern) = 0 Then
PatternMatch = False
Exit Function
End If
Dim Position As Integer
Dim MatchFirst As Boolean
Dim MatchLast As Boolean
Dim Chunks() As String
MatchFirst = (Left(Pattern, 1) <> "*")
MatchLast = (Right(Pattern, 1) <> "*")
Chunks = Split(Pattern, "*")
LastChunkIndex = UBound(Chunks)
If MatchFirst Then
If Not (Left(SearchIn, Len(Chunks(0))) = Chunks(0)) Then
PatternMatch = False
Exit Function
End If
End If
If MatchLast Then
If Not (Right(SearchIn, Len(Chunks(LastChunkIndex))) = Chunks(LastChunkIndex)) Then
PatternMatch = False
Exit Function
End If
End If
Position = 1
For Each Chunk In Chunks
ChunkLength = Len(Chunk)
If ChunkLength > 0 Then
NextPosition = InStr(Position, SearchIn, Chunk, vbTextCompare)
If NextPosition > 0 And NextPosition >= Position Then
Position = NextPosition + ChunkLength
Else
PatternMatch = False
Exit Function
End If
End If
Next Chunk
PatternMatch = True
End Function