I'm not an advanced VBA programmer. I'm working on an excel macro which will allow me to select a range(using input box) to clean the data(makes consistent with mySQL schema) on worksheet. I get this file from anther team and
1.) the order of columns is not fixed
2) levels of categories(there are few columns for categories like level1 level2 etc.) can be anything between 3-10.
I want to concatenate the columns for categories(in image level 1, level 2 etc.) using | as a separator and put the values in first category column(level1) while deleting remaining columns(level 2, level 3...[level 10]).
I removed some code from the end to reduce the length here but it still makes sense:
Sub cleanData()
Dim rngMyrange As Range
Dim cell As Range
On Error Resume Next
Do
'Cleans Status column
Set rngMyrange = Application.InputBox _
(Prompt:="Select Status column", Type:=8)
On Error GoTo 0
'Is a range selected? Exit sub if not selected
If rngMyrange Is Nothing Then
End
Else
Exit Do
End If
Loop
With rngMyrange 'with the range just selected
.Replace What:="Dead", Replacement:="Inactive", SearchOrder:=xlByColumns, MatchCase:=False
'I do more replace stuff here
End With
rngMyrange.Cells(1, 1) = "Status"
Do
'Concatenates Category Columns
Set rngMyrange = Application.InputBox _
(Prompt:="Select category columns", Type:=8)
On Error GoTo 0
'Is a range selected? Exit sub if not selected
If rngMyrange Is Nothing Then
End
Else
Exit Do
End If
Loop
With rngMyrange 'with the range just selected
'Need to concatenate the selected columns(row wise)
End With
rngMyrange.Cells(1, 1) = "Categories"
End Sub
Please do not suggest a UDF, I want to do this with macro. I must do this on files before importing them on SQL database, so a macro will be handy. Please ask if I failed to mention anything else.
EDIT: Image attached for illustration
UPDATE:
I now have a working code with help from vaskov17 on mrexcel but it does not delete the columns from where the levels are picked-level 2, level 3...etc. to shift next columns to left and the major challenge for me is to implement that code in my existing macro using range type instead of long type. I do not want to enter start column and finish column separately, instead I should be able to select range like in my original macro. Code for that macro is below, please help me:
Sub Main()
Dim start As Long
Dim finish As Long
Dim c As Long
Dim r As Long
Dim txt As String
start = InputBox("Enter start column:")
finish = InputBox("Enter ending column:")
For r = 2 To Cells(Rows.Count, "A").End(xlUp).Row
For c = start To finish
If Cells(r, c).Text <> "" Then
txt = txt & Cells(r, c).Text & "|"
Cells(r, c).Clear
End If
Next
If Right(txt, 1) = "|" Then
txt = Left(txt, Len(txt) - 1)
End If
Cells(r, start) = txt
txt = ""
Next
End Sub
I have removed the inputbox for selection of the category columns. Since they are always named Level x»y it makes it easier to find them automatically. That's why added a FindColumns() Sub to your code. It assigns the first fCol and last lCol Category column to global variables.
The ConcatenateColumns() concatenates cells in each row using "|" as separator.
The DeleteColumns() deletes the other columns
Cells(1, fCol).Value = "Category renames Level 1 to Category and Columns.AutoFit resizes all columns widths to fit the text.
Code:
Option Explicit
Dim fCol As Long, lCol As Long
Sub cleanData()
Dim rngMyrange As Range
Dim cell As Range
On Error Resume Next
Do
'Cleans Status column
Set rngMyrange = Application.InputBox _
(Prompt:="Select Status column", Type:=8)
On Error GoTo 0
'Is a range selected? Exit sub if not selected
If rngMyrange Is Nothing Then
End
Else
Exit Do
End If
Loop
With rngMyrange 'with the range just selected
.Replace What:="Dead", Replacement:="Inactive", SearchOrder:=xlByColumns, MatchCase:=False
'I do more replace stuff here
End With
rngMyrange.Cells(1, 1) = "Status"
' Concatenate Category Columns
FindColumns
ConcatenateColumns
DeleteColumns
Cells(1, fCol).Value = "Category"
Columns.AutoFit
End Sub
Private Sub FindColumns()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim i As Long, j As Long
For i = 1 To ws.Cells(1, Columns.Count).End(xlToLeft).Column
If StrComp(ws.Cells(1, i).Text, "Level 1", vbTextCompare) = 0 Then
For j = i To ws.Cells(1, Columns.Count).End(xlToLeft).Column
If InStr(1, ws.Cells(1, j).Text, "Level", vbTextCompare) Then
lCol = j
End If
Next j
fCol = i
Exit Sub
End If
Next i
End Sub
Private Sub ConcatenateColumns()
Dim rng As Range
Dim i As Long, j As Long
For i = 2 To Cells(Rows.Count, fCol).End(xlUp).Row
Set rng = Cells(i, fCol)
For j = fCol + 1 To lCol
rng = rng & "|" & Cells(i, j)
Next j
rng = "|" & rng & "|"
Set rng = Nothing
Next i
End Sub
Private Sub DeleteColumns()
Dim i As Long
For i = lCol To fCol + 1 Step -1
Columns(i).Delete Shift:=xlToLeft
Next i
End Sub
Related
I am looking for some help in getting this code to run properly. I've gotten some help with the first part from some great people here!
Basically, the code I have now sets ranges in between cells formatted bold, as the bold represents a date. I am trying to find the individual segments in column A and copy the coresponding number in column D to another worksheet in column C. If the value is not found in the range, the row output should shift down one without filling in anything.
Here is what I have so far:
Public Sub DataBetween()
Dim thisWB As Workbook
Dim dataWS As Worksheet
Set thisWB = ThisWorkbook
Set dataWS = thisWB.sheets("FC01.RPT")
Set MoBWS = thisWB.sheets("Mix of Business")
'--- find the first bold cell...
Dim nextBoldCell As range
Set nextBoldCell = FindNextBoldInColumn(dataWS.range("A1"))
'--- now note the start of the data and find the next bold cell
Dim startOfDataRow As Long
Dim endOfDataRow As Long
Dim lastRowOfAllData As Long
startOfDataRow = 3
'Set lastRowOfAllData = dataWS.Cells(ws.Rows.Count, "A").End(xlUp).Row
'--- this loop is for all the data sets...
Do
endOfDataRow = EndRowOfDataSet(dataWS, startOfDataRow)
'--- this loop is to work through one data set
For i = startOfDataRow To endOfDataRow
sheets("FC01.RPT").Select
Cells.Find(What:="Individual return guest").Activate
range("D" & (ActiveCell.Row)).Select
Selection.copy
sheets("Plan").Select
range("C3").Select
ActiveSheet.Paste
Next i
startOfDataRow = endOfDataRow + 1
Loop
'Do While endOfDataRow < lastRowOfAllData
errhandler:
MsgBox "No Cells containing specified text found"
End Sub
Public Function FindNextBoldInColumn(ByRef startCell As range, _
Optional columnNumber As Long = 1) As range
'--- beginning at the startCell row, this function check each
' lower row in the same column and stops when it encounters
' a BOLD font setting
Dim checkCell As range
Set checkCell = startCell
Do While Not checkCell.Font.bold
Set checkCell = checkCell.Offset(1, 0)
If checkCell.Row = checkCell.Parent.Rows.Count Then
'--- we've reached the end of the column, so
' return nothing
Set FindNextBoldInColumn = Nothing
Exit Function
End If
Loop
Set FindNextBoldInColumn = checkCell
End Function
Private Function EndRowOfDataSet(ByRef ws As Worksheet, _
ByVal startRow As Long, _
Optional maxRowsInDataSet As Long = 50) As Long
'--- checks each row below the starting row for either a BOLD cell
' or, if no BOLD cells are detected, returns the last row of data
Dim checkCell As range
Set checkCell = ws.Cells(startRow, 1) 'assumes column "A"
Dim i As Long
For i = startRow To maxRowsInDataSet
If ws.Cells(startRow, 1).Font.bold Then
EndRowOfDataSet = i - 1
Exit Function
End If
Next i
'--- if we make it here, we haven't found a BOLD cell, so
' find the last row of data
EndRowOfDataSet = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
End Function
The code keeps crashing. How can I make it so the output line shifts down one when looping though a range, no matter if it finds the value or not?
Does anyone know what do to?
Here is a snapshot of the data I am working with:
Thanks for the help!!
I noticed all your "blocks" end with some "Summe" occurrence in column A, and data begins at row 14
then I'd go this way:
Sub mm()
Dim iArea As Long
With Worksheets("FC01.RPT")
With .Range("A14", .Cells(.Rows.Count, 1).End(xlUp))
.Cells(2, 1).Value = "Summe"
.AutoFilter field:=1, Criteria1:="Summe*"
With .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible) '.Offset(-1)
For iArea = 1 To .Areas.Count - 1
With .Parent.Range(.Areas(iArea).Offset(1), .Areas(iArea + 1).Offset(-1))
Worksheets("Plan").Cells(Rows.Count, "D").End(xlUp).Offset(1).Value = WorksheetFunction.SumIf(.Cells, "Individual*", .Offset(, 3))
End With
Next
End With
.Cells(2, 1).ClearContents
End With
.AutoFilterMode = False
End With
End Sub
I have if function that should check a few conditions in excel tab and if column B <> 0 and column C has "A" then it gives me "OK"
But it is not working. I tried to add .text, .value or whatever, still it doesnot see "A" in and gives me "Run-time error 424 Object required"
Could you please advise?
Sub test()
Dim varSheetA As Variant
Dim varSheetB As Variant
Dim strRangeToCheck As String
Dim iRow As Long
Dim iCol As Long
Dim iRow1 As Long
Dim iCol1 As Long
Dim jRow As Long
Dim jCol As Long
Dim i As Long
strRangeToCheck = "A1:V1000"
' If you know the data will only be in a smaller range, reduce the size of the ranges above.
Debug.Print Now
varSheetA = Worksheets("Sheet1").Range(strRangeToCheck)
varSheetB = Worksheets("Sheet2").Range(strRangeToCheck) ' or whatever your other sheet is.
Debug.Print Now
For iRow1 = LBound(varSheetA, 1) To UBound(varSheetA, 1)
For iCol1 = LBound(varSheetA, 2) To UBound(varSheetA, 2)
If varSheetB(iRow1, 2) <> 0 And varSheetB(iRow1, 3)="A" Then
MsgBox ("OK")
'Sheets("Sheet2").Select
'Cells(iRow1, iCol1).EntireRow.Copy
'Sheets("Sheet4").Select
'Range("A" & Rows.Count).End(xlUp).Offset(1).Select
'ActiveSheet.Paste
End If
Next iCol1
Next iRow1
MsgBox ("Done")
End Sub
Your code is hard to follow, but your description says you want to look in column C for the letter A and if found check if the value in column B is not 0.
I'm pretty sure you don't want to display 'OK' everytime a value is matched - that could be 1000 oks to ok, which is not ok (unless you're building some kind of torture program).
This code will return a single message box listing the row numbers that matched the criteria. No doubt you'll want to change the code to do something a bit more useful though.
Public Sub Test()
Dim SearchRange As Range
Dim FoundValue As Range
Dim FirstAddress As String
Dim Message As String
'Only going to search column C for the letter A.
Set SearchRange = ThisWorkbook.Worksheets("Sheet1").Range("C1:C1000")
With SearchRange
'Find the first value if it exists.
Set FoundValue = .Find("A", LookIn:=xlValues, LookAt:=xlWhole)
'Only continue if something was found.
If Not FoundValue Is Nothing Then
FirstAddress = FoundValue.Address
Do
'Record the row number if the value in column B is not 0.
If FoundValue.Offset(, -1) <> 0 Then
'Copy the row to Sheet2.
'Column C will have a value in each row (it will contain the letter A)
'so that can be used to find the next available row to copy to.
With ThisWorkbook.Worksheets("Sheet2")
FoundValue.EntireRow.Copy Destination:= _
.Cells(.Rows.Count, 3).End(xlUp).Offset(1, -2)
End With
Message = Message & FoundValue.Row & vbCrLf
End If
'Look for the next letter A.
Set FoundValue = .FindNext(FoundValue)
Loop While FoundValue.Address <> FirstAddress
End If
End With
MsgBox "Criteria met on these rows:" & vbCrLf & Message, vbOKOnly + vbInformation
End Sub
I have a large table and the information I'm wanting to add comments to falls within Range(D11:CY148). I have two tabs - "Finish Matrix" (main) and "list" (hidden - has 2 columns).
I have two issues.
First issue - Code works to a degree, after I type my values within a cell it automatically adds comments based off info in another sheet. The problem is there is too many cells to be manually typing into and if I copy and paste the code doesn't run. I created a CommandButton and wanted it to refresh the entire table with comments depending if the cells had the values that fall within "list". I tried to create a call out to Worksheet_Change but to no avail. (I'm a beginner so it'll help if you explain)
Second issue - I'm assuming it'll get fixed with whatever suggestion that works. Occasionally after typing into a cell I would get an error. Can't remember the error name but it is one of the common ones, atm the error isn't popping up but surely it'll come back since I didn't do anything different to the code.
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Columns("A:CX")) Is Nothing Then _
If Intersect(Target, Columns("CY")) Is Nothing Then Exit Sub
Dim lRow As Integer
lRow = Sheets("list").Range("A1").End(xlDown).Row
If Target.Value = vbNullString Then Target.ClearComments
For Each cell In Sheets("list").Range("A1:A" & lRow)
If cell.Value = Target.Value Then
Target.AddComment
Target.Comment.Text Text:=cell.Offset(0, 1).Value
End If
Next cell
End Sub
Thanks for any and all help!
You are basically missing the For Each Cell in Target part...
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim wsMain As Worksheet, wsList As Worksheet
Dim cell As Range
Dim vCommentList As Variant
Dim i As Long, lLastRow As Long
Dim sValue As String
On Error GoTo ErrHandler
Application.ScreenUpdating = False
Application.EnableEvents = False
Set wsMain = Target.Parent
Set Target = Intersect(Target, wsMain.Range("D11:CY148"))
If Target Is Nothing Then Exit Sub
Set wsList = wsMain.Parent.Sheets("list")
lLastRow = LastRow(1, wsList)
' Read Comment List into Variant (for speed)
vCommentList = wsList.Range("A1:B" & lLastRow)
Target.ClearComments
' This...For each Cell in Target...is what you were missing.
For Each cell In Target
sValue = cell
For i = 1 To UBound(vCommentList)
If sValue = vCommentList(i, 1) Then
AddComment cell, CStr(vCommentList(i, 2))
Exit For
End If
Next
Next
ErrHandler:
If Err.Number <> 0 Then Debug.Print Err.Description
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Proper way to find last row ...
Public Function LastRow(Optional Col As Integer = 1, Optional Sheet As Excel.Worksheet) As Long
If Sheet Is Nothing Then Set Sheet = Application.ActiveSheet
LastRow = Sheet.Cells(Sheet.Rows.Count, Col).End(xlUp).Row
End Function
Add Comment Sub the allows appending is needed...
Public Sub AddComment(Target As Range, Text As String)
If Target.Count = 1 Then
If Target.Comment Is Nothing Then
Target.AddComment Text
Else
Target.Comment.Text Target.Comment.Text & vbLf & Text
End If
End If
End Sub
Untested, but this will take all the values in Range(D11:CY148) and add a comment based on a lookup from Sheet "list".
Sub testy()
Dim arr As Variant, element As Variant
Dim i As Long, j As Long, listItems As Long, rwLast As Long, clLast As Long
Dim comm As String
Dim rng As Range, cell As Range
listItems = Sheets("list").Range("A1").End(xlDown).Row
rwLast = Cells.SpecialCells(xlCellTypeLastCell).Row ' Adjust to fit your needs
clLast = Cells.SpecialCells(xlCellTypeLastCell).Column 'Idem
Set rng = Sheets("list").Range("A1:A" & listItems)
arr = Range("D11:CY148").Value
With Worksheets("Finish Matrix")
For i = 1 To rwLast - 10 'Adjust to make it more general, this is pretty rough
For j = 1 To clLast - 3 'Idem
If i = 3 Then
End If
comm = ""
For Each cell In rng
If arr(i, j) = cell.Value Then
comm = comm & Chr(13) & cell.Offset(0, 1).Value
End If
Next cell
If Not (comm = "") Then
.Cells(10, 3).Offset(i, j).ClearComments
.Cells(10, 3).Offset(i, j).AddComment
.Cells(10, 3).Offset(i, j).Comment.Text Text:=comm
End If
Next j
Next i
End With
End Sub
Excel Macro that will do the following:
To Find All Duplicates in (ColumnA) and to see if (ColumnB) contains a certain value and run a code against that result.
How i would write the code if i could:
If (ColumnB) .value in that (group of duplicates_found) in any row is "R-".value then
Keep the row with "R-".value and delete the rest. Else if "R-".value not exist and "M-".value Exist, delete all duplicates except first "R-".value found.
Else
If duplicate group contains "R-".value more than once, keep first "R-".value row found and delete the rest
Endif
Continue to loop until all duplicates found and run through above code.
^^sorry if not making sense up there:
I guess we can select first group of duplicates and run check on it like described below.^^
in this group all would be deleted, except one row.
(in this group we could specify to keep first "R-".value found and delete rest)
(this group has a "R-".value so the "M-".value gets deleted.)
(this group has a "R-".value so the "M-".value gets deleted.)
Code I used once to delete all "M-".value(s), hoping to reverse to do above as described per a first group found and to continue:
Sub DeleteRowWithContents()
Dim rFnd As Range, dRng As Range, rFst As String, myList, ArrCnt As Long
myList = Array("M-")
For ArrCnt = LBound(myList) To UBound(myList)
With Range("B1:B" & Range("B" & Rows.Count).End(xlUp).Row)
Set rFnd = .Find(What:=myList(ArrCnt), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=True)
If Not rFnd Is Nothing Then
rFst = rFnd.Address
Do
If dRng Is Nothing Then
Set dRng = Range("A" & rFnd.Row)
Else
Set dRng = Union(dRng, Range("A" & rFnd.Row))
End If
Set rFnd = .FindNext(After:=rFnd)
Loop Until rFnd.Address = rFst
End If
Set rFnd = Nothing
End With
Next ArrCnt
If Not dRng Is Nothing Then dRng.EntireRow.Delete
End Sub
this code goes through column and finds duplicates and highlights them. Maybe this could be rewritten to highlight each duplicate a separate color?
Sub MarkDuplicates()
Dim iWarnColor As Integer
Dim rng As Range
Dim rngCell As Variant
Range(Range("A2"), Range("A2").End(xlDown)).Select ' area to check '
Set rng = Selection
iWarnColor = xlThemeColorAccent2
For Each rngCell In rng.Cells
vVal = rngCell.Text
If (WorksheetFunction.CountIf(rng, vVal) = 1) Then
rngCell.Interior.Pattern = xlNone
Else
rngCell.Interior.ColorIndex = iWarnColor
End If
Next rngCell
End Sub
this code Looks for colored cells a specific RGB color and selects them, maybe for each group that is colored differently select that color and do a function on it?
Sub SelectColoredCells()
Dim rCell As Range
Dim lColor As Long
Dim rColored As Range
'Select the color by name (8 possible)
'vbBlack, vbBlue, vbGreen, vbCyan,
'vbRed, vbMagenta, vbYellow, vbWhite
lColor = RGB(156, 0, 6)
'If you prefer, you can use the RGB function
'to specify a color
'Default was lColor = vbBlue
'lColor = RGB(0, 0, 255)
Set rColored = Nothing
For Each rCell In Selection
If rCell.Interior.Color = lColor Then
If rColored Is Nothing Then
Set rColored = rCell
Else
Set rColored = Union(rColored, rCell)
End If
End If
Next
If rColored Is Nothing Then
MsgBox "No cells match the color"
Else
rColored.Select
MsgBox "Selected cells match the color:" & _
vbCrLf & rColored.Address
End If
Set rCell = Nothing
Set rColored = Nothing
End Sub
This has had me tied down to the computer for a week now and i cant seem to resolve it.
Here's an answer, it's a complicated one, but I took the question as a challenge to improve my use of particular methods in VBA.
This goes through your cells and creates an array of the results as you like.
I was using numbers in my testing, so every time you see str(Key) you might just need to remove the str() function.
This results in printing the array to columns D:E rather than removing rows from your list. You could just clear columns A:B and then print to "A1:B" & dict.Count - that would have the same effect, essentially.
Sub test()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim lastrow As Integer
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Dim strA As String
For i = 1 To lastrow
strA = Cells(i, 1)
dict(strA) = 1
Next
Dim vResult() As Variant
ReDim vResult(dict.Count - 1, 1)
Dim x As Integer
x = 0
Dim strB As String
Dim strKey As String
For Each Key In dict.keys
vResult(x, 0) = Key
x = x + 1
For Each c In Range("A1:A" & lastrow)
strA = Str(c)
strB = c.Offset(0, 1).Value
If strA = Str(Key) Then
If Left(strB, 1) = "r" Then
vResult(x - 1, 1) = c.Offset(, 1)
GoTo label
End If
End If
Next
If vResult(x - 1, 1) = Empty Then
For Each c In Range("A1:A" & lastrow)
strA = Str(c)
If strA = Str(Key) Then
vResult(x - 1, 1) = c.Offset(, 1)
GoTo label
End If
Next
End If
label:
Next
Range("D1:E" & dict.Count).Value = vResult()
End Sub
I'm trying to find the LastRow in multiple column ranges ignoring certain columns... I have two attempts but can't get either working correctly:
BOTH Examples are ignoring columns N and O
My first attempt is the following, however it doesn't get the correct last range, if I have something in A15 for example and T10, it thinks the last row is 10 when it should be 15.
Sub LastRowMacro()
LastRowString = "A1:M" & Rows.Count & ", P1:Z" & Rows.Count
LastRowTest = Range(LastRowString).Find(What:="*", After:=[A1], SearchOrder:=xlByRows, searchDirection:=xlPrevious).Row
End Sub
My second attempt is as follows, but it seems rather long winded.
Sub LastRowMacro()
Dim i As Long
LastRow = 1
IgnoreColumnList = "N;O"
For i = 1 To Cells(1, Columns.Count).End(xlToLeft).Column
ColumnLetter = Split(Cells(1, i).Address(True, False), "$")(0)
For Each varFind In Split(IgnoreColumnList, ";")
If varFind = ColumnLetter Then
varNotFound = False
Exit For
End If
varNotFound = True
Next
If varNotFound Then
CurrentLastRow = Cells(Rows.Count, i).End(xlUp).Row
If CurrentLastRow >= LastRow Then
LastRow = CurrentLastRow
End If
varNotFound = False
End If
Next
End Sub
Ideally I'd like my first attempt to work however if it just doesn't work then someone surely can improve my second version...
Try this
*There is an ignoreList variable with all the columns that you want to ignore. Make sure you populate this correctly - currently ignoring N, O, P
*You may need to set the sh variable to the correct sheet - currently it's Sheet1
*btw. this snippet will always find the last last row on the spreadsheet. you can add another elseif to check whether there are 2 columns with the same high last row in case there was 2 columns with the highest lastRows.
Sub FindingLastRow() ' ignoring some columns
Dim ignoreList
ignoreList = Array("N", "O", "P") ' MODIFY IGNORE LIST
Dim sh As Worksheet
Set sh = Sheet1 ' SET CORRECT SHEET
Dim currentlast As Range
Set currentlast = sh.Cells(1, 1)
Dim iteratingCell As Range
With sh
For j = 1 To .UsedRange.Columns.Count
Set iteratingCell = .Cells(1, j)
If Not isIgnored(iteratingCell, ignoreList) Then
If iteratingCell.Cells(Rows.Count).End(xlUp).Row >= currentlast.Cells(Rows.Count).End(xlUp).Row Then
Set currentlast = iteratingCell
End If
End If
Next
Set currentlast = .Range("$" & Split(currentlast.Address, "$")(1) & "$" & currentlast.Cells(Rows.Count).End(xlUp).Row)
End With
MsgBox currentlast.Address
End Sub
Function isIgnored(currentlast As Range, ignoreList As Variant) As Boolean
Dim ignore As Boolean
Dim letter As Variant
For Each letter In ignoreList
If StrComp(Split(currentlast.Address, "$")(1), letter, vbTextCompare) = 0 Then
ignore = True
Exit For
End If
Next
isIgnored = ignore
End Function