Remove reference errors autmatically - vba

i have designed a few codes to help remove reference errors however it does not automatically delete until i assign the macro to a button. i do not want it that way as it would seem unpleasant when i want to present the programme to my team members, and having to remove the errors on the spot with a button. I thought of combining my delete cells code and remove reference cell codes together so that they would run simultaneously but to no avail. Is it possible to combine these two codes to achieve my objective or are there any solutions or coding to remove/hide reference errors automatically? Here are the two codes. All of your help would be very much appreciated!
Sub deletetry2()
Dim R As Range
Set rng = Nothing
On Error Resume Next
Set R = Application.InputBox("Select cells To be deleted", Type:=8)
If TypeName(R) <> "Range" Then
Exit Sub
Else
R.Delete
End If
End Sub
Sub Check_ReferenceDeletecolumn()
Dim rng As Range
Dim rngError As Range
Set rng = Sheets("Sheet3").Range("A1:G100")
On Error Resume Next
Set rngError = rng.Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If Not rngError Is Nothing Then
rngError.EntireColumn.Delete
'delete means cells will move up after deleting that entire row
End If
End Sub

If the objective is to remove all rows containing errors, from a user defined range, this should work:
Option Explicit
Public Sub cleanUserDefinedRange()
Dim response As Range
On Error Resume Next
Set response = Application.InputBox("Select range to clean up errors", Type:=8)
If Not response Is Nothing Then cleanUpErrors response
On Error GoTo 0
End Sub
'------------------------------------------------------------------------------------------
Private Sub cleanUpErrors(ByRef rng As Range)
Application.ScreenUpdating = False
rng.SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Delete
Application.ScreenUpdating = True
End Sub

Related

Worksheet_Change setting target range is slow

I have an excel macro used to manage button visibility in Excel in the "Worksheet_Change" function based from another SO question here.
The problem is the although the macro works it makes updating the Excel sheet rather laggy. I have managed to pin down the slowness to a single line:
Set rUpdated = Range(Target.Dependents.Address)
This sets the range of cells updated to a variable to be iterated through later in the script. If I call a script with just this line I found this is where all the delay is. It seems a rather simple line, but is there a better way to do it?
Full disclosure:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rUpdated As Range
Dim shp As Shape
Dim rCell As Range
Set rUpdated = Range(Target.Dependents.Address)
If Not rUpdated Is Nothing Then
For Each rCell In rUpdated
If rCell.Column = 1 Then
'Look at each shape in the sheet and cross-reference with rCell.
For Each shp In Target.Parent.Shapes
If shp.TopLeftCell.Row = rCell.Row Then
shp.Visible = (rCell.Value <> "")
Exit For 'Exit the loop - the correct button has been found.
End If
Next shp
End If
Next rCell
End If
End Sub
So if i understood it correctly you want to make a button visible if the cell in the row as been changed. The only things i can think of to slow it down are, that is has to check many rCell or Shapes. I dont know what the structure of your document is. So my Idea would be: instead of going through all shapes every time, i would name them in a pattern that you can identify them with the row they are in so you use the name to address them (i.e Row2 for the Button in Row 2).
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rUpdated As Range
Dim shp As Shape
Dim rCell As Range
Dim obj As OLEObject
Set rUpdated = Range(Target.Dependents.Address)
If Not rUpdated Is Nothing Then
For Each rCell In rUpdated
If rCell.Column = 1 Then
On Error Resume Next
Set obj = ActiveSheet.OLEObjects("Row" & rCell.Row)
If Err.Number = 0 Then
obj.Visible = (rCell.Value <> "")
End If
End If
Next rCell
End If
End Sub
I replaced that config with the following single line (and companion line):
On Error Resume Next
ActiveSheet.Shapes("buttonRow" & Target.Row).Visible = (ActiveSheet.Cells(Target.Row, 1).Value <> "")
However to get this to work I first needed to rename all my shapes. I used this function to do that:
Function renamebuttons()
For Each shp In ActiveSheet.Shapes
shp.name = "buttonRow" & shp.TopLeftCell.Row
Next shp
End Function
I ran that function once and deleted it. Once done my shapes can now be referred to by name and I no longer incur the delay of cycling through every shape and every target dependent. The delay experienced in the worksheet is now minimal.

VBA Code to Prevent Users input wrong data into cells Excel

Hi everyone I am trying to figure out how to write a code where users can only input the exact same data into cells from a list I created. I want the code to validate the user entry and see if the entry is on the list and if is not to erase the data the user enter and give him a message. I am almost there but I don't seem to make my Vlook work. Any help would be very much appreciate it. below is the code I wrote
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim rng As Range
Dim aCell As Range
Dim LU As Range
Dim Celda As Range
'
On Error GoTo Whoa
Application.EnableEvents = False
'~~> This is the range of cells where I want the user to input the data
Set rng = Range("A1:A15")
'THis is the range where I want the macro to look if the data the user entered is in the list
Set LU = Application.WorksheetFunction.VLookup(aCell.Value, Range("F1:F5"), 1, False)
On Error GoTo MyErrorHandler:
If Not Application.Intersect(Target, rng) Is Nothing Then
'~~> Loop through all cells in the range
For Each aCell In rng
If aCell.Value <> "" Then
If aCell.Value <> LU Then
aCell.ClearContents
MyErrorHandler:
If Err.Number = 1004 Then
aCell.ClearContents
MsgBox "Item Number es Incorrecto - Error en la celda " & aCell.Address
End If
End If
End If
Next
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Use Data - Data Validation, set to Allow by List. For source place =$F$1:$F$5. Customize options to your needs. No VBA needed.

Type Missmatch when copy/pasting to visible cells only

I'm trying to copy and paste a list into visible cells only. For some reason I'm getting a type miss-match error and I don't understand why. When debugging the error occurs on the third line.
Sub Copy_Filtered_Cells()
Set from = Sheets(Sheet2).Range("I16831:I20610")
Set too = Application.InputBox("J4:J16821", Type:=8)
For Each Cell In from
Cell.Copy
For Each thing In too
If thing.EntireRow.RowHeight > 0 Then
thing.PasteSpecial
Set too = thing.Offset(1).Resize(too.Rows.Count)
Exit For
End If
Next
Next
End Sub
Best to use Option Explicit at top of module, I am guessing at what you are trying to achieve. Here is a stab...
Option Explicit
Sub Copy_Filtered_Cells()
Dim from As Excel.Range
Set from = Sheets("Sheet2").Range("I16831:I20610")
Dim too As Excel.Range
Set too = Sheets("Sheet2").Range("J4:J16821") 'Application.InputBox("J4:J16821", Type:=8)
Dim Cell As Excel.Range
For Each Cell In from
Cell.Copy
Dim thing As Excel.Range
For Each thing In too
If thing.EntireRow.RowHeight > 0 Then
thing.PasteSpecial
Set too = thing.Offset(1).Resize(too.Rows.Count)
Exit For
End If
Next
Next
End Sub

Nested loop does not run properly

I have a nested loop which first changes all ref cells to white font using a for loop and in a sub for loop the ref cells are deleted. The code runs but has still one or two cells with reference errors. Would need help to sort out the code so that it can remove all reference errors instead of most of it! Thank you .
Sub Delete_ref_basedontextcondition()
Dim R As Range
Dim w As Long, ref As Range
Dim refi As Range
On Error Resume Next
'Set rng = Nothing
On Error Resume Next
Set R = Application.InputBox("Select cells To be deleted", Type:=8)
Dim rng As Range
If TypeName(R) <> "Range" Then
Exit Sub
Else
R.Delete
End If
For w = 1 To Worksheets.Count
With Worksheets(w)
For Each ref In .Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
If ref.Text = "#REF!" Then
ref.Font.ColorIndex = 2
For Each refi In .Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
If refi.Text = "#REF!" Then
refi.Delete
End If
Next refi
End If
Next ref
End With
Next w
End Sub
I'm believe that the rogue #REF! is actually created by refi.Delete so it is missed by the loop that was defined prior to its creation. Use refi.Clear instead. You just want to remove the bad formula; you do not want to delete the cell and shift other cells around it (thereby creating new #REF! errors).
Think of it as a Pez dispenser full of #REF! errors. Every time you pop one out, another comes in to take its place. Close the lid with .Clear instead of spiralling through popping them out with .Delete.

How to delete all blank rows

This code makes Excel non-responsive. Anyone know why that might be?
Sub delblank()
On Error Resume Next
ActiveSheet.UsedRange.Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
If Err Then
MsgBox "No blank cells"
End If
End Sub
The problem is that UsedRange won't accept Range("A:A") as a property because the used range in your sheet does not contain an entire column from top to bottom of the Excel sheet, i.e. from row 1 to row 1048756.
What you want instead is to refer to the first column of UsedRange: replace Range("A:A") by Columns(1) like this:
ActiveSheet.UsedRange.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Now it works.
When you have a long chain of methods and properties giving you trouble like that, it's easier to break it down into its constituents in order to find the source of the error. That's what I did:
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
Dim sh As Worksheet
Set sh = ActiveSheet
Set r1 = sh.UsedRange
Set r2 = r1.Range("A:A") ' Aha, error occurs here! Wow, that was easy to find.
Set r3 = r1.SpecialCells(xlCellTypeBlanks)
r3.EntireRow.Delete
When the error is gone, it's fine to put the chain back together again to get rid of the clutter.
Also don't use On Error Resume Next unless you're absolutely certain that this is what you want, because it will just swallow errors and not tell you where they came from.
Try something like this:
Public Sub Tester()
On Error Resume Next
Columns(1).SpecialCells(xlBlanks).EntireRow.Delete
On Error GoTo 0
End Sub
Try below code
Sub delblank()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim rng As Range
On Error Resume Next
Set rng = ActiveSheet.UsedRange.Range("A:A").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "No cells found"
Else
rng.EntireRow.Delete
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub