I've seen a few posts on this problem. I know what's causing it but I'm trying to figure a way to stop it from appearing.
What it is there is one excel file called Main which I have to keep open and it updates automatically using every 20 mins using:
Application.OnTime
In the VBA formula there is a call for
Loc = Range("location").Value
So if I have another excel file open I get the range error when it auto-updates.
Is there something I can put in before to check that the value isn't right and ignore that one error? I've tried a few things and looked around but nothing really works.
Thanks for any help.
I know what the problem is, I'm trying to find a way to block or check for an empty value while in another file.... Demas 5 mins ago
I agree with Tim here. If you can fully qualify your range then do that. Else read on :)
Is this what you want?
Dim rng As Range
'
'~~> Rest of the code
'
On Error Resume Next
Set rng = Range("location")
On Error GoTo 0
If Not rng Is Nothing Then
Loc = Range("location").Value
'
'~~> Rest of the code
'
End If
Related
I have a made a VBA based complaints form that keeps track of a number of details about a complain. One feature that i added lately is that it is now possible to add a picture to the report/form.
When the form is submitted all the filled cells are copied to a seperate spreadsheet and the form itself needs to wiped and the pictures need to be removed so that a new report can be filled if neccessary. It is like a reset.
In order to remove the pictures I copied the below piece of script. About 90% of the time it works perfectly fine and the images are removed and the form is back to it's original form however every once in a while for unknown reason i get a Error 1004 "Application Defined or Object Defined Error". When i receive this error i am unable to remove the pictures and need to restart the excel file.
Within VBA highlighted in yellow it says that the k.TopLeftCell is the cause of it.
With Sheets("Klachtformulier")
Dim k As Shape, rng As Range
Set rng = Sheets("Klachtformulier").Range("A43:H47")
For Each k In ActiveSheet.Shapes
If Intersect(k.TopLeftCell, rng) Is Nothing Then
Else
k.Delete
End If
Next k
I tried to change activesheets to the sheet("name"), tried change the range, tried to change shape dim into a picture dim and tried to exit the for after one loop however all without succes so far. Most of the time these changes cause the pictures from not being removed anymore.
Any idea what could be the cause or the solution?
I think the problem is likely that you are deleting members of a collection (the Shapes collection) while iterating over it using 'For ... Each'. When deleting, you should use 'For ... Next' and loop from the end of the collection to the start:
Dim k As Shape, rng As Range
Dim i As Long
Set rng = Sheets("Klachtformulier").Range("A43:H47")
For i = ActiveSheet.Shapes.Count To 1 Step -1
Set k = ActiveSheet.Shapes.Item(i)
If Not Intersect(k.TopLeftCell, rng) Is Nothing Then
k.Delete
End If
Next i
I tweaked the logic of your If statement and removed the With line as (in the code you posted) it isn't doing anything useful.
I want to convert a string into a range variable that I will use somewhere else. My first idea was to create a text-to-range function and to avoid dealing with the sintaxis ever again. I know it is probably a very basic question but I couldn't figure it.
My first attempt was this. It prints "indirect" were I want to (this was just a test), but running the macro step by step I see that there is an error 91 at the time to "exit" the function.
Dim rng As Range
rng = TXT2RNG(Range("A1").Value)
'This is the function, located in Modulo1
'Function TXT2RNG(text As String) As Range
'Set TXT2RNG = Range(text)
'TXT2RNG.Value = "indirect"
'End Function
End Sub
I have attempted the same but without the function, and it works as I expected.
Dim rng As Range
Set rng = Range(Range("A2").Value)
'Set rng = Range(Range("A1").Value)
rng.Value = "direct"
End Sub
Summary: The second code works as a workaround but I want to know why the first one doesn't so can learn from it and use similar structures in the future. Thank you
Basically, you are simply missing a Set when assigning the result from the function to your variable - you do it correct in your direct example.
Whenever you are dealing with objects (eg worksheet, range), you need to use Set when assigning it to a variable. A good explanation can be found at https://stackoverflow.com/a/18928737/7599798
Omitting the Set will cause an error 91 when assigning it to an object variable. However, if you would declare your rng-variable as Variant, you wouldn't get a runtime error. Instead, VBA would use the so called default property, for a Range this is the Value, so you would end up having the content of the Range in your variable ("indirect" in your example). This is the reason to use the data type Variant only if really needed.
That said, there are at least 2 issues you should take care about:
when you use the Range-function as you do, it refers to ActiveSheet, which is the sheet that currently has the focus. When coding, that's not always what you want, so think about if you need to approve your function. You should really take the time to read the answers of How to avoid using Select in Excel VBA to get an understanding.
You should think about what should happen when the text you pass to your function doesn't contain a valid range-address. Currently, you would get a runtime error (1004). Error handling in VBA is done with On Error-statements. You should avoid On Error Resume Next.
You could change your function to:
Function TXT2RNG(ws as Worksheet, text As String) As Range
On Error Goto InvalidRange
Set TXT2RNG = ws.Range(text)
' TXT2RNG.Value = "indirect"
Exit Function
InvalidRange:
' Think about what to do here, show a message, simply ignore it...
Set TXT2RNG = Nothing
End Function
And the call to it would be
Dim rng as Range, address as string
address = Range("A1").Value
Set rng = TXT2RNG(activeSheet, address)
if not rng is Nothing then
(...)
Welcome to stack overflow.
From walking through your code, you're not declaring "text" as anything.
If you use the "Watches" feature, you can see it's a blank string
I believe you need to have a function that pulls the range, then a second function to pull the string of that. A Private Sub is much better
See this answer https://stackoverflow.com/a/2913690/2463166
Can anyone advise on how to handle a "no cells were found" error with the following code. This is a part of a larger sub that may often return no values, however handling the error as follows (which works for many of my other scenarios) still returns "Run-time error '1004': No cells were found". What am I doing wrong?
On Error GoTo Error_Exit_3
Range("Q:Q").SpecialCells(xlCellTypeFormulas, 16).EntireRow.Delete
Error_Exit_3:
What I Would do:
Dim RowsWithFormulas As Long
On Error Resume Next
RowsWithFormulas = Range("Q:Q").SpecialCells(xlCellTypeFormulas, 16).Rows.Count
On Error GoTo 0
If RowsWithFormulas > 0 Then
Range("Q:Q").SpecialCells(xlCellTypeFormulas, 16).EntireRow.Delete
End If
You can also set this as a Range:
Sub t()
Dim cellsWithErroringFormulas As Range
On Error Resume Next
Set cellsWithErroringFormulas = Range("Q:Q").SpecialCells(xlCellTypeFormulas, 16)
On Error GoTo 0
If cellsWithErroringFormulas Is Nothing Then
' Do whatever
MsgBox ("No formulas result in an error!")
Exit Sub
ElseIf cellsWithErroringFormulas.Rows.Count > 0 Then
cellsWithErroringFormulas.SpecialCells(xlCellTypeFormulas, 16).EntireRow.Delete
' Now, if you call `cellsWithErroringFormulas` again, it will error since you removed all those references.
' So to be explicit, let's clear that variable.
Set cellsWithErroringFormulas = Nothing
End If
End Sub
I tweaked the variable name, just because you're not technically looking for rows with formulas, but rather cells with formulas that result in an error. It's a little clunky here, so rename as desired. Just wanted to point that out.
Also, since I don't know what you plan on doing next, I added the Set cellsWithErroringFormulas = Nothing, since we can't use that reference after you delete the erroring rows. You may not need that, but I just wanted to include to point that out also.
Please check the link below. its already answered in this forum.
Also, Please visit the rules for this forum.. :)
1004 Error: No cells were found, easy solution?
When using Range.SpecialCells with a range that doesn't contain cells that match the criteria an error is thrown saying that no cells were found.
The most common solution to this issue is letting it happen and using an error handler to deal with it.
Is that the best known way to solve it or is there other solutions that might be as good or better which avoid using an error handler?
The only thing I can think of would be saving the first cell's value, then changing its value to one that matches the criteria so it avoids the error making it always match at least that one cell, then change the value back to its original value and check the matched range's address to see if it matched that one cell only or more.
A bad/slow solution would be to not make use of it at all and just use loops with checks.
Here's some simple sample code to demostrate a little how it works with the error handler:
Private Sub Procedure()
Dim OriginalRange As Excel.Range
Dim NewRange As Excel.Range
Set OriginalRange = ThisWorkbook.Worksheets(1).Range("A1:C4")
On Error GoTo ErrorHandler
Set NewRange = OriginalRange.SpecialCells(Type:=Excel.XlCellType.xlCellTypeConstants, Value:=Excel.XlSpecialCellsValue.xlNumbers)
Exit Sub
ErrorHandler:
If (VBA.Err.Number <> 1004) Then VBA.Err.Raise VBA.Err.Number
End Sub
Yes it is perfectly normal (I prefer this way) to use the error handler. What I do is, I sandwhich it between On Error Resume Next and On Error GoTo 0 and then check If NewRange is Nothing
See this example
On Error Resume Next
Set NewRange = OriginalRange.SpecialCells(Type:=Excel.XlCellType.xlCellTypeConstants, _
Value:=Excel.XlSpecialCellsValue.xlNumbers)
On Error GoTo 0
If NewRange Is Nothing Then
MsgBox "Your message here informing the USER that desired cells were not found"
Else
'
'~~> Do whatever you want with the range
'
End If
Trying to activate the cell in my column A which says "Generator loading".
I have been trying the 'With' and 'End With' commands and other suggested formats posted on the net. However, I keep getting the same error- Run-time Error 91.
From my various trials I am very sure that there is something wrong within the "Find" command, but I cannot figure out what... I have been filling it using the format on the MSDN page.
Do you have any suggestions?
Dim findstring As String
findstring = "Generator loading"
Sheets("Summary").Columns(1).Find(What:=findstring, After:=Cells(9,1)).Activate
The error commonly arises if the result of the .Find method is Nothing, because you can't do Nothing.Activate
First, you have to check for Nothingness
Dim rng as Range
Set rng = Sheets("Summary").Columns(1).Find(What:=findstring, After:=Cells(9,1))
If rng Is Nothing Then
MsgBox findString & " not found!!", vbCritical
Exit Sub
End If
rng.Activate
'the rest of your code goes here...
I don't like to work with columns, so instead of it, I used a range.
For me to work, I just replaced the reference of the sheet
Sheets(1).Range("A:A").Find(What:=findstring, After:=Cells(9, 1)).Activate
See if this works. If not, you could send me the sheet if you want :)