in Excel VBA why does my code not work with SpecialCells type visible and work without it? - excel

In columns Bk and CB they both contain formula's that will result in a code. Now CB will also contain four codes and a remove statement which if they match with the cell in column BK in the same row then take the value from CB and paste over hence overriding the value in BK with that code and then paste it red.
the above should be done only on a filtered range though.
The ignore #N/A are in there as the overide column will error out on almost everyline except for when there is a code to overide.
This macro works perfectly without the visible cells statement at the end of my with range line but as soon as the visible cells statement is added the loop only goes up to #N/A and disregards the rest of the ElseIF statement.
Here is my code below:
Option Explicit
Sub Override()
Dim x As Workbook: Set x = ThisWorkbook
Dim rRange As Variant, fltrdRng As Range, aCell As Range, rngToCopy As Range
Dim ws As Worksheet
Dim LR As Long
Dim LR2 As Long
Dim SrchRng As Range, cel As Range
Dim mRow
mRow = 2
Set ws = x.Worksheets("Data")
LR = ws.Range("CB" & ws.Rows.Count).End(xlUp).Row
LR2 = ws.Range("BK" & ws.Rows.Count).End(xlUp).Row
'clears any filters on the sheet
ws.AutoFilterMode = False
' turns formula's to manual
Application.Calculation = xlManual
'copies down the formula in Column BK ignoring the last two rows as they have already been pasted over.
ws.Range("BK2:BK4 ").AutoFill Destination:=ws.Range("BK2:BK" & LR2 - 2)
'filters on N/A's and 10 as these are the codes we are interested in overiding
ws.Range("$A$1:$CB$1").AutoFilter Field:=19, Criteria1:=Array( _
"10", "N/A"), Operator:= _
xlFilterValues
' will loop through all cells in specified range and ignore any error's and #N/A's and will paste over the code overided in CB column to the BK column if conditions are met.
On Error Resume Next
While IsEmpty(ws.Range("CB" & mRow)) = False
With ws.Range("CB" & mRow).SpecialCells(xlCellTypeVisible)
If .Value = "#N/A" Then
ElseIf .Value = "1234" Then
.Offset(0, -17).Value = "1234"
.Offset(0, -17).Interior.Color = vbRed
ElseIf .Value = "1235" Then
.Offset(0, -17).Value = "1235"
.Offset(0, -17).Interior.Color = vbRed
ElseIf .Value = "1236" Then
.Offset(0, -17).Value = "1236"
.Offset(0, -17).Interior.Color = vbRed
ElseIf .Value = "Remove" Then
.Offset(0, -17).Value = "Remove"
.Offset(0, -17).Interior.Color = vbRed
ElseIf .Value = "1237" Then
.Offset(0, -17).Value = "1237"
.Offset(0, -17).Interior.Color = vbRed
End If
End With
mRow = mRow + 1
Wend
'turn Formula 's back to automatic
Application.Calculation = xlAutomatic
End Sub

With ws.Range("CB" & mRow).SpecialCells(xlCellTypeVisible)
Using SpecialCells on just one cell is problematic.
Instead, use it on the entire filtered column, like this, which will replace your entire While...Wend loop (by the way, While...Wend is obsolete):
On Error Resume Next
Dim visibleCells As Range
Set visibleCells = ws.Range("CB2:CB" & LR).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If visibleCells Is Nothing Then Exit Sub
Dim cell As Range
For Each cell In visibleCells
If Not IsError(cell.Value) Then
Select Case cell.Value
Case "1234", "1235", "1236", "1237", "Remove"
cell.Offset(0, -17).Value = cell.Value
cell.Offset(0, -17).Interior.Color = vbRed
End Select
End If
Next

Related

Find a string from Cell, and delete 4-5 rows attached to it and then move to next cell

What I'm looking for is, I need to find out if a cell contains ".L" in it, if yes, the entire row along with 4 more rows needs to be deleted and this series goes on until last set of data.
For example:
There would be hundreds of dataset like shown below, out of which "RIC" contains ".L".
TID: xxx, Symbol=xxx, Date=xxx, RIC=EPWN.L , CUSIP=xxx, SEDOL=xxx
DataStream: xxxx
Bloomberg.: xxxx
Market....: xxxx
TID: xxx, Symbol=xxx, Date=xxx, RIC=BAR.BR , CUSIP=xxx, SEDOL=xxx
DataStream: xxx
Bloomberg.: xxx
Market....: xxx
Need to delete the entire set if any RIC is having ".L". So in the end, what should I get is dataset without ".L"
Please help
Below is the vba but it is not working:
Range("b2:b2000").ClearContents
Dim rng As Range
Dim cell As Range
Dim serchstring As String
Set rng = ActiveSheet.UsedRange
searchstring = ".l"
On Error Resume Next
For Each cell In rng
If UCase(cell.Value) Like "*" & UCase(searchstring) Then
cell.Offset(0, 1).Value = "NA"
cell.Offset(1, 1).Value = "NA"
cell.Offset(2, 1).Value = "NA"
cell.Offset(3, 1).Value = "NA"
cell.Font.Bold = True
cell.Interior.Color = vbYellow
End If
Next cell
Cells.Select
With ActiveSheet
.AutoFilterMode = False
.Range("A:B").AutoFilter
.Range("A:B").AutoFilter field:=2, Criteria1:="NA"
Intersect(.UsedRange, .UsedRange.Offset(1)).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilterMode = False
End With
With ActiveSheet
.AutoFilterMode = False
.Range("A:B").AutoFilter field:=1, Criteria1:=""
Intersect(.UsedRange, .UsedRange.Offset(1)).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilterMode = False
End With
If your program is not erasing the row, I think the issue lies with these lines:
cell.Offset(0, 1).Value = "NA"
cell.Offset(1, 1).Value = "NA"
cell.Offset(2, 1).Value = "NA"
cell.Offset(3, 1).Value = "NA"
Offset is returning a single cell so you are only erasing a single cell. But your post says you want to erase the whole row. To reference the row, I suggest:
cell.Offset(0, 1).EntireRow.ClearContents
cell.Offset(1, 1).EntireRow.ClearContents
cell.Offset(2, 1).EntireRow.ClearContents
cell.Offset(3, 1).EntireRow.ClearContents
Which can be reduced to a single line like:
cell.Offset(0).Resize(4).EntireRow.ClearContents
Or if you don't want to leave blank rows behind you can directly delete the rows like:
cell.Offset(0).Resize(4).EntireRow.Delete
But if you do repetitive deleting, you'll notice that Excel stutters and the execution is slow. So I suggest saving the rows to be deleted into a range variable and then deleting them all at once at the end. Use Union() to add ranges together.
If rToBeDeleted Is Nothing Then
Set rToBeDeleted = cell.Offset(0).Resize(4).EntireRow
Else
Set rToBeDeleted = Union(rToBeDeleted, cell.Offset(0).Resize(4).EntireRow)
End If
'And then at the end
rToBeDeleted.Delete
And if you do it this way, you don't need to do any of that autofilter deleting.
Edit:
For clarity, here is how I suggest your code be structured after applying my suggestions:
Range("b2:b2000").ClearContents
Dim rng As Range
Dim cell As Range
Dim rToBeDeleted As Range
Dim serchstring As String
Set rng = ActiveSheet.UsedRange
searchstring = "*.L"
On Error Resume Next
For Each cell In rng
If UCase(cell.Value) Like searchstring Then
If rToBeDeleted Is Nothing Then
Set rToBeDeleted = cell.Offset(0).Resize(4).EntireRow
Else
Set rToBeDeleted = Union(rToBeDeleted, cell.Offset(0).Resize(4).EntireRow)
End If
End If
Next cell
rToBeDeleted.Delete

VBA: Looping a condition through a range that compares values from other columns until the list ends

Public Sub MainTOfomat()
Dim ShippingQty As Range
Dim ReceivedQty As Range
ActiveSheet.Columns("A:P").AutoFit
ActiveSheet.Range("A:P").AutoFilter Field:=13, Criteria1:="No"
ActiveSheet.Range("K:L").AutoFilter Field:=2, Criteria1:="<>"
Set ShippingQty = Range("K2")
Set ReceivedQty = ShippingQty.Offset(0, 1)
ShippingQty.Select
Do Until IsEmpty(ActiveCell)
If ShippingQty.Value = 0 Then
ShippingQty.Offset(0, 5) = "Needs Fulfillment"
ElseIf ShippingQty.Value > ReceivedQty.Value Then
ShippingQty.Offset(0, 5) = "Needs Receipt"
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
The code is program is supposed to loop though each row in the column and fill in the statement based on the result of the condition for values in two other columns. The problem is that the loop goes through, but only the first line actually changes, and the auto filter code before the loop gets skipped.
Here is your macro fixed up.
As mentioned before your ShippingQty range and ReceivedQty do not change with the activecell. When moving to the next cell, that is the activecell. The filter range need to be the same. A:P is filtered, when changing to K:L ,field 2 actually becomes column B, so if you want to filter out non-blanks in column L you need the field 12.
Sub YourMacro()
Dim ShippingQty As Range
Dim ReceivedQty As Range
ActiveSheet.Columns("A:P").AutoFit
With ActiveSheet.Range("A:P")
.AutoFilter Field:=13, Criteria1:="No"
.AutoFilter Field:=12, Criteria1:="<>"
End With
Set ShippingQty = Range("K2")
Set ReceivedQty = ShippingQty.Offset(0, 1)
ShippingQty.Select
Do Until IsEmpty(ActiveCell)
If ActiveCell.Rows.Hidden = False Then
If ActiveCell.Value = 0 Then
ActiveCell.Offset(0, 5) = "Needs Fulfillment"
ElseIf ActiveCell.Value > ActiveCell.Offset(, 1).Value Then
ActiveCell.Offset(0, 5) = "Needs Receipt"
End If
End If
ActiveCell.Offset(1, 0).Select
Loop
ActiveSheet.AutoFilterMode = 0
End Sub
You can use this option as well without using selects.
Sub Option1()
Dim rng As Range, c As Range
Dim ws As Worksheet
Set ws = ActiveSheet
Application.ScreenUpdating = 0
With ws
Set rng = .Range("K2:K" & .Cells(.Rows.Count, "K").End(xlUp).Row)
With .Range("A:P")
.AutoFilter Field:=13, Criteria1:="No"
.AutoFilter Field:=12, Criteria1:="<>"
End With
For Each c In rng.SpecialCells(xlCellTypeVisible)
If c = 0 Then c.Offset(, 5) = "Needs Fulfillments"
If c > c.Offset(, 1) Then c.Offset(, 5) = "Needs Receipts"
Next c
.AutoFilterMode = False
End With
End Sub

VBA copy data from different sheets from row above where cell text "subtotal"

Want to copy Data from Different worksheets to a sheet called
"Summary". Data needs to be copy from one Row above (where row has text
"subtotal") to Row/Column A2. Below is my VBA code, but getting error MESSAGE " Compiler error, Else without If ", not sure what i am missing.
please help me.
Sub CombineData()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "Summary" And Left(Sht.Name, 1) = "1" Or Left(Sht.Name, 1) = "4" Or Left(Sht.Name, 1) = "6" Or Left(Sht.Name, 1) = "7" Then
Sht.Select
'LastRow = Range("A65536").End(xlUp).Row
Set MyRng = Range(Cells(1, "d"), Cells(Rows.Count, "d").End(xlUp))
For Each cell In MyRng
If cell.Value = "Subtotal" Then cell.Value = cell.Offset(-1, 0).Value
.Range("A2", "M&MyRng").Copy
Sheets("Summary").Select
Range("A65536").End(xlUp).Offset(1, 0).Select
ActiveSheet.Paste
Sht.Select
Range("p1").ClearContents
Else
End If
Next Sht
End Sub
Your code has some flaws.
Identation. Code inside Sub, For, If needs to be identated with tab or 4 spaces.
End. Each Sub has End Sub, each If as and End If, each For has and End For
Values. Instead of copying and pasting, you can set .Range() = new_value
String comparison. If cell.Value = "Subtotal" will fail if the user writes subtotal or SUBTOTAL. That is why I prefer to lowercase the cell value using LCase() function.
You may want to use the following code
Sub CombineData()
Dim Sht As Worksheet
'Identify Sheet called Summary
Dim wsSummary As Worksheet
Set wsSummary = ActiveWorkbook.Sheets("Summary")
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "Summary" And (Left(Sht.Name, 1) = "1" Or Left(Sht.Name, 1) = "4" Or Left(Sht.Name, 1) = "6" Or Left(Sht.Name, 1) = "7") Then
For Each cell In Sht.UsedRange.Cells
If LCase(cell.Value) = "subtotal" Then
'Copy cell above subtotal to the last row in column A of Summary sheet
wsSummary.Range("A65536").End(xlUp).Offset(1, 0) = cell.Offset(-1, 0).Value
Sht.Range("p1") = cell.Offset(-1, 0).Value
End If
Next
End If
Next Sht
End Sub

Find duplicate macro not working

The following code works on worksheets labeled Walk INs
Sub Find_Duplicatel()
Dim wrkSht As Worksheet 'The worksheet that you're lookin for duplicates in.
Dim rng As Range 'The range containing the duplicates.
Dim Col As Long 'The last column containing data +1
Set wrkSht = ThisWorkbook.Worksheets("Walk INs")
With wrkSht
'Reference to whole data range.
Set rng = .Range("A5:L2003")
'If the sheet is blank an error will be thrown when trying to find the last column.
'This code looks for the last column - you could just set Col to equal the last column number + 1.
On Error Resume Next
Col = 12
Err.Clear
On Error GoTo 0
If Col = 0 Then Col = 0
'Place a COUNTIF formula in the last column.
rng.Offset(, Col).Columns(1).FormulaR1C1 = "=COUNTIF(" & rng.Columns(1).Address(ReferenceStyle:=xlR1C1) & ",RC" & rng.Column & ") & "" duplicates."""
With rng
'Add conditional formatting to first column in range: If the COUNTIF formula is showing >1 then highlight cell.
With .Columns(1)
'This formula is =VALUE(LEFT($M5,FIND(" ",$M5)-1))>1.
'It returns only the number from the duplicate count and checks it is higher than 1.
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=VALUE(LEFT(" & rng.Offset(, Col).Cells(1).Address(RowAbsolute:=False) & ",FIND("" ""," & _
rng.Offset(, Col).Cells(1).Address(RowAbsolute:=False) & ")-1))>1"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
.FormatConditions(.FormatConditions.Count).Interior.Color = RGB(0, 100, 255)
End With
'Apply filter to your range.
.AutoFilter
.AutoFilter Field:=12, Criteria1:="Yes"
End With
End With
End Sub`
However when I changed Walk INs to VOC_ASST It hangs up on .AutoFilter I am not certain why. Could you inform me what happened & how to fix it. Other than the sheet titles every thing is identical.
You can add some code it to check if there is an AutoFilter already.
If .AutoFilterMode = False Then
.AutoFilter
.AutoFilter Field:=12, Criteria1:="Yes"
End If
I found the following code on the ENCODEDNA website & after modifying it for my worksheet, it works exactly as I expected.
Sub FIND_DUPLICATE()
`Option Explicit
Dim myDataRng As Range
Dim cell As Range
' WE WILL SET THE RANGE (FIRST COLUMN).
Set myDataRng = Range("A1:A" & Cells(Rows.Count, "B").End(xlUp).Row)
For Each cell In myDataRng
cell.Offset(0, 0).Font.Color = vbBlack ' DEFAULT COLOR.
' LOCATE DUPLICATE VALUE(S) IN THE SPECIFIED RANGE OF DATA.
If Application.Evaluate("COUNTIF(" & myDataRng.Address & "," &
cell.Address & ")") > 1 Then
cell.Offset(0, 0).Font.Color = vbRed ' CHANGE FORE COLOR TO
RED.
End If
Next cell
Set myDataRng = Nothing
ErrHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub`
Thank you to the people that have assisted me.

Search through selected cells and hide them if they contain a letter

I want to loop through cells and look for letters. If they contain the letter hide the cell with NumberFormat. This works but how do I make this loop toggeable so i can hide/unhide.
Private Sub CommandButton1_Click()
Dim rng As Range, cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
For Each cell In rng
If InStr(1, cell.Value, "A") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "B") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "C") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "D") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "F") > 0 Then cell.NumberFormat = ";;;"
Next cell
End Sub
I'm not sure what you mean by "toggeable"
If you want to unhide everything, no matter what it contains, then just set the .numberformat property of the entire range to General.
If you mean that when you remove one of the target letters from the cell, that it should become unhidden, then try this macro below:
EDIT Edited to add what I think you mean by toggle.
========================================
Option Explicit
Option Compare Binary
Private Sub CommandButton1_Click()
Dim rng As Range, cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
Application.FindFormat.NumberFormat = ";;;"
Set cell = rng.Find(what:="*", searchformat:=True)
If Not cell Is Nothing Then
rng.NumberFormat = "General"
Exit Sub
End If
For Each cell In rng
If cell.Value Like "*[ABCDEF]*" Then
cell.NumberFormat = ";;;"
Else
cell.NumberFormat = "General"
End If
Next cell
End Sub
====================================
Try...
Private Sub CommandButton1_Click()
Dim rng As Range
Dim cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
For Each cell In rng
If cell.Value Like "*A*" Or cell.Value Like "*B*" Or cell.Value Like "*C*" Or cell.Value Like "*D*" Or cell.Value Like "*F*" Then
cell.NumberFormat = ";;;"
End If
Next cell
End Sub
Sub Macro1()
If cell.NumberFormat = ";;;" Then
cell.NumberFormat = "General"
End If
End Sub
The last part of the number format is for text - just remove that part from your custom number format to hide/show text.
Sub HideText()
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1") _
.Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
If rng.NumberFormat <> "#,##0;-#,##0;#,##0;" Then
rng.NumberFormat = "#,##0;-#,##0;#,##0;"
Else
rng.NumberFormat = "#,##0;-#,##0;#,##0;#"
End If
End Sub

Resources