I am using VBA in my excel sheet and it gives me an overlfow error. When I checked I found out that it was related to data error which shows unilmited "#" character in one cell.
All values in each cell is assigned to a string variable and when this cell comes in generates an overflow error. I tried to validate this using an if condition, but whenever we check cell.value this generates an overflow error. Is there any way to fix this?
You will not get a runtime error if you just read the cell text:
s = Range("C2").Text
Debug.Print s
' returns: "###########"
If you really want to read the cell value, and not the cell text (why you would need this, I have no idea, since you're stuffing it in a String anyway) then this is a workaround, assuming the #### are caused by dates Jan 1, 10,000 AD or later.
Const MaxDateSerial As Double = 2958466
Dim s As String
Dim dbl As Double
Dim nf As Variant
' Save original number format
nf = Range("C2").NumberFormat
' Use read-safe number format to read cell content
Range("C2").NumberFormat = "General"
dbl = Range("C2").Value
' Restore original number format
Range("C2").NumberFormat = nf
If dbl < MaxDateSerial Then
s = Range("C2").Value
Else
s = "Date overflow!"
End If
If you are doing something like
Dim s as string
Dim cl as Range
...
s = cl
' or
s = cl.value
s will be set to the value as diplayed on the sheet, which includes an error
(in the form "Error <Error Code>" if that's what the sheet displays
If the underlying cell value is valid, you should be able to access if using cl.value2
If you are doing somthing like
Dim v as Variant
Dim s as string
Dim r as Range
...
Set r = <SomeRange>
v = r
...
And one or more cells in range r are an error, then Runtime Error 6 Overflow will occur
To advise further, please post details of the code, where the error occurs, cell value and cell formatting
The ############### display for dates occurs if the date serial is before 1/1/1900 (negative) or after 1/1/9999 (> 2958101) EDIT actually 31/12/9999 = 2958465
Try using the "ISERROR()" function to filter out the invalid values.
IF(ISERROR(A1),0,A1)
Related
Im trying to evaluate Formula array to find a value from sheet with multiple criteria. The sheet name is Holiday_master
So in another sheet Temp_data I tried to exceute the following code to set that value in that cell using formula array
Public Function getCostMultiplier(dt As Date, wt As String) As Double 'dt is the date of entry, wt working time name "India Full Time","Singapore f........
Dim lRow As Integer
Dim we As Boolean
we = IsWeekend(dt)
Dim nhRange As Range
Dim d As Double
d = CDbl(dt)
Dim location As String
Select Case LCase(Trim(wt))
Case "india full time 45"
location = "INDIA"
Case "singapore full time 40"
location = "SINGAPORE"
Case "uk full time 40"
location = "UK"
End Select
Dim n As Integer
'n = Application.Evaluate()
lRow = Sheets("Holiday_master").Range("A1000").End(xlUp).Row + 1
Dim formula As String
Dim s As String
s = Application.Evaluate("RC11")
formula = printf("{=INDEX( Holiday_master!R2C3:R{0}C3,MATCH(1,(""{1}""=Holiday_master!R2C2:R{0}C2)*({2}=Holiday_master!R2C1:R{0}C1),0),1)}", lRow, location, d)
''''INDEX( Holiday_master!R2C3:R11C3,MATCH(1,("INDIA"=Holiday_master!R2C2:R11C2)*(43126=Holiday_master!R2C1:R11C1),0),1)
n = Application.Evaluate(formula)
getCostMultiplier = n
End Function
Public Function printf(mask As String, ParamArray tokens()) As String
Dim i As Long
For i = 0 To UBound(tokens)
mask = Replace$(mask, "{" & i & "}", tokens(i))
Next
printf = mask
End Function
So in Temp_data sheet in a cell I set the formula as getCostMultiplier(RC11,RC4)', so obviously it reaches my function with parameters26-01-2018andINDIA`
So in the code we have a final formula which is I commented there INDEX( Holiday_master!R2C3:R11C3,MATCH(1,("INDIA"=Holiday_master!R2C2:R11C2)*(43101=Holiday_master!R2C1:R11C1),0),1)
But its not evaluating as I expected or this could not be the way for evaluation of formula array.
If I execute that formula in that cell manually and on submitting (ctrl+shift+enter) it executes properly and returning the value.
So I didnt understand how to do that same from VBA or how to do that Evaluation. I never used Evaluation before
Convert the formula from xlR1C1 to xlA1 syntax.
n = Application.Evaluate(Application.ConvertFormula(formula, xlR1C1, xlA1))
Using Evaluate within VBA should be done with xlA1 syntax.
I got it working with R1C1 itself. The issue was, I specified curly braces there in the formula array which is not required in the case of Evaluate
So here is my modified formula code with error validation also added
formula = printf("=IFERROR(INDEX(Holiday_master!R2C3:R{0}C3,MATCH(1,(""{1}""=Holiday_master!R2C2:R{0}C2)*({2}=Holiday_master!R2C1:R{0}C1),0),1),1)", lRow, location, CStr(d))
My problem is, that when using the VlookUp I do get the Error:
The VLookup-Property of the WorksheetFunction-Object could not be assigned
' LookUp missing Data
Dim lookupRange As Range
Set lookupRange = Sheets("Kundenlisten HLK 2018").Range("A1:Y10354")
' Fill in Companyname
Dim tmp As String
tmp = Values(0)
tmp = TrueTrim(tmp)
testing.Cells(8, counter) = Application.WorksheetFunction.VLookup(tmp, lookupWS.Range("A2:Y10354"), 2, False)
Values = None
counter = counter + 1
lookupWS is the Name of the Worksheet
As you can see the table I am trying to lookup is filled with values from A to Y. The first column is the key I am trying to look up, but then the error from above occurs. The tmp variable is a String with a unique ID to look up the missing values, while the "2" is supposed to be the company name in the second column of the Range.
I looked up on the docs, but the types and everything are fine, I even checked while debugging.
testing.Cells(8, counter) can't be the source of the problem aswell, since I am using it before like this
testing.Cells(28, counter) = Left(mail.ReceivedTime, 10)
and it works
It's difficult to know what the problem is without any data, but here's something to help you in the right direction.
It's better to use Find and Offset than
WorksheetFunction.Vlookup in VBA
Something like this gives you exactly the same result, but you have much more control:
Sub Test()
Dim valueFound As Range
Set valueFound = lookupWS.Range("A2:A10354").Find(What:="Something", lookat:=xlWhole) 'xlWhole is equivalent to FALSE in VLOOKUP
If valueFound Is Nothing Then
MsgBox "Nothing found"
Else
MsgBox valueFound.Offset(0, 1) 'offsetting by 1 is equivalent to using 2 in a VLOOKUP
End If
End Sub
I have a little problem with a VBA range being used in excel:
dim frameRefPoint As String
frameRefPoint = "4,4"
range(Cells(frameRefPoint).Offset(0,0), Cells(frameRefPoint).Offset(7, 7)).Interior ...
This isn't behaving as I expect it to. I think that the first cell in the specified Range(Cells(4,4).Offset(0,0)) should be "D4", but when I use the range in a code, the first cell of the range is "D1" ~ cells(1,4).
The address property of cells(frameRefPoint) returns $D$1. What am I missing here?
You cannot span two paramters (e.g. .Cells(<row>, <column>)) by concatenating the values with an interim comma. Just making it 'look' like what you code is not the same as legitimate code. You can however, use variables for each parameter.
dim r as long, c as long, frameRefPoint As string
r = 4
c = 4
cells(r, c).resize(7, 7) = "this works"
frameRefPoint = "4,4"
'split the string on the comma and convert teh text-that-looks-numbers to actual numbers
cells(int(split(frameRefPoint, ",")(0))), int(split(frameRefPoint, ",")(1)).resize(7, 7) = "this also works"
Range(Cells(CInt(Split(frameRefPoint, ",")(0)), CInt(Split(frameRefPoint, ",")(1))).Offset(0, 0), Cells(CInt(Split(frameRefPoint, ",")(0)), CInt(Split(frameRefPoint, ",")(1))).Offset(7, 7)).Interior....
I am trying to add the data in the two cells of the excel sheet but even if the excel cell is of the type number it does not add up the cells. It seems that there is space infornt of the number that it does not add....image is below.
Is there a vba code to remove this space from each of the cell if its presesnt.
I have exported the excel from a pdf.
Excel will attempt to convert any value to a number if you apply an operator to it, and this conversion will handle spaces. So you can use =A1*1 or A1+0 to convert a value in A1 to a number, or something like this within a function =SUM(IFERROR(A1*1,0)).
That kind of implicit conversion automatically performs a trim(). You can also do this conversion explicitly by using the funciton N(), or NumberValue() for newer versions of Excel. However, as others have pointed out, many characters won't be automatically handled and you may need to use Substitute() to remove them. For instance, Substitute(A1,160,"") for a non-breaking space, a prime suspect because of its prevalence in html. The Clean() function can give you a shortcut by doing this for a bunch of characters that are known to be problematic, but it's not comprehensive and you still need to add your own handling for a non-breaking space. You can find the ASCII code for any specific characters that are grieving you by using the Code() function... for instance Code(Mid(A1,1,1))
Character Handling UDF
The UDF below gives flexibility to the character handling approach by allowing multiple characters to be removed from every cell in a range, and produces a result that can be used as an argument. For example, Sum(RemoveChar(A1:A5,160)) would remove all non-breaking spaces from the range being summed. Multiple characters can removed by being specified in either a range or array, for example Sum(RemoveChar(A1:A5,B1:B3)) or Sum(RemoveChar(A1:A5,{160,150})).
Function RemoveChar(R As Range, ParamArray ChVal() As Variant)
Dim x As Variant
Dim ResVals() As Variant
ReDim ResVals(1 To R.Count)
'Loop through range
For j = 1 To R.Count
x = R(j).Value2
If x <> Empty Then
'Try treating character argument as array
'If that fails, then try treating as Range
On Error Resume Next
For i = 1 To UBound(ChVal(0))
x = Replace(x, Chr(ChVal(0)(i)), "")
Next
If Err = 92 Then
Err.Clear
For Each Rng In ChVal(0)
x = Replace(x, Chr(Rng.Value2), "")
Next
End If
Err.Raise (Err)
On Error GoTo 0
'If numeric then convert to number
'so that numbers will be treated as such
'when array is passed as an argument
If IsNumeric(x) Then
ResVals(j) = Val(x)
Else
ResVals(j) = x
End If
End If
Next
'Return array of type variant
RemoveChar = ResVals
End Function
Numeric Verifying UDF
The drawback with replacing characters is that it's not comprehensive. If you want something that's more of a catch-all, then perhaps something like this.
Function GetNumValues(R As Range)
Dim c, temp As String
Dim NumVals() As Double
ReDim NumVals(1 To R.Count)
'Loop through range
For j = 1 To R.Count
'Loop through characters
'Allow for initial short-circuit if already numeric
For i = 1 To Len(R(j).Value2)
c = Mid(R(j).Value2, i, 1)
'If character is valid for number then include in temp string
If IsNumeric(c) Or c = Application.DecimalSeparator Or c = Application.ThousandsSeparator Then
temp = temp + c
End If
Next
'Assign temp string to array of type double
'Use Val() function to convert string to number
NumVals(j) = Val(temp)
'Reset temp string
temp = Empty
Next
'Return array of type double
GetNumValues = NumVals
End Function
Running the code below and what I'm hoping to see as a result is to have all columns with 0s on row 27 hidden - but depending on the frequency of the data, the range for those columns to be hidden is different. Basically anything that is in a sheet that starts with Daily/monthly/weekly will have to have columns hidden, all the rest of the sheets should be left alone.
It worked on a simple workbook using an if statement (sheets starting with X vs. all other), but when I added the case statement it broke...
The line marked down with bold is the one where I get an error:
Run-time error '1004'
Application-defined or object-defined error
I'm new to this, so please feel free to suggest a good vba tutorials website/book.
Sub Hide_Zero_Columns()
Dim WS As Worksheet
Dim Col_to_hide As Range
Dim Range_to_hide As Range
Dim X As Integer
For Each WS In ThisWorkbook.Sheets
Worksheets(WS.Name).Activate
With WS
Select Case Data_Frequency_Sheets
Case Left(WS.Name, 5) = "Daily"
Set Range_to_hide = Range("BDV$27:CWH$27")
Case Left(WS.Name, 5) = "Month"
Set Range_to_hide = Range("AY$27:CO$27")
Case Left(WS.Name, 5) = "Weekl"
Set Range_to_hide = Range("HF$27:NN$27")
Case Else
Set Range_to_hide = Range("A1:B1")
End Select
Select Case Data_Condition
Case Left(WS.Name, 5) = "Daily"
X = 1
Case Left(WS.Name, 5) = "Month"
X = 30
Case Left(WS.Name, 5) = "Weekl"
X = 7
Case Else
X = 999
End Select
If X <> 999 Then
For Each Col_to_hide In ActiveSheet.Range(Range_to_hide) '<-- Error here
If UCase(Col_to_hide) = 0 Then
Col_to_hide.EntireColumn.Hidden = True
Else: Col_to_hide.EntireColumn.Hidden = False
End If
Next Col_to_hide
End If
End With
Next
ActiveWorkbook.Worksheets("Registrations").Activate
End Sub
Since you have already defined a Range, you the problem is you are trying to evaluate: Sheet.Range(Range) which throws the error you are getting.
Since it appears you are wanting to iterate across the columns, all you need to do is change the line to this:
' Iterate across the columns in the defined range.
For Each Col_to_hide In Range_to_hide.Columns
' Each "Col_to_hide" will represent all cells within the column.
MsgBox Col_to_hide.Address
The error you're getting is because you're passing a Range object as the argument to Activesheet.Range() and it doesn't accept that because of the Range object's default value. It would be like doing this in the Immediate Window
?Range(Range("A1")).Address
You'll get the same error. Whereas with
?Range("A1").Address
You don't. You could do this too
?Range(Range("A1").Address).Address
So the thing is that when you don't specify a property for an object, like Range("A1") instead of Range("A1").Address, then the default property is used. The Range object is a bit strange, but in this case its default property is the Value property. So Activesheet.Range(Range_to_hide) is the same as Activesheet.Range(Range_to_hide.Value). And if Range_to_hide is a multi-cell range, then it's Value property returns an array, which you definitely can't pass into a Range's argument.
That's the explanation, the short answer is simply to use Range_to_hide, like
For Each Col_to_hide in Range_to_hide.Columns
Why the .Columns. Remember when I said that the Range object was a little strange. Well, unlike most objects, it has two default properties based on the context you're using it in. Earlier, the default property was Value, but in the context of a For..Each, the default value is Cells. If you don't specify .Columns in your For..Each, then it will loop through every cell in the Range. In fact, I always specify how the range is aggregated, even if it's the default Cells.