Range.Find-Function - different results for similar values - excel

I have written a Function to return the Long name of a 3 character string, so in Worksheet "List" there's 2 columns:
Column 1: List Short
Column 2: List Long
Similar to a VLOOKUP, my function shall find the Short and return the Long name.
However, there's something really strange happening:
Line 683 has Short = "Hlm" - and the function returns the correct Long from Lists Column B
Line 684 has Short = "Hlm" - but the function returns a runtime error 91.
Function GetList(ByRef ListShort, DataSource As Workbook)
Dim Lists As Worksheet, ListShort As String
Set Lists = DataSource.Worksheets("Lists")
GetList = Lists.Cells.Find(ListShort, After:=Lists.Cells(1, 1), LookIn:=xlValues, SearchOrder:=xlByColumns).Offset(0, 1)
End Function
The error occurs in Line 4 of my code, runtime error 91 means that GetFile could not be declared.
Someone an idea what's the cause of this?
TIA! Marvin
Checked official documentation, revewed code w debugger, tried If commands to work around "Hml" value...

Related

#value error returns with excel user defined function

i have created user defined function to calculate football match results.
My Root Function looks that:
Function calculatePoints(personTypes As Range, matchesResults As Range) As Integer
calculatePoints = getAllPersonPoints(personTypes, matchesResults)
End Function
getAllPersonPoints function:
Private Function getAllPersonPoints(personTypes As Range, matchesResults
AsRange) As Integer
Dim x As Long
Dim y As Long
Dim isTheSurest As Boolean
getAllPersonPoints = 0
For x = 1 To personTypes.Rows.Count
For y = 1 To personTypes.Columns.Count
isTheSurest = isTheSurestResult(personTypes.Cells(x,
y).DisplayFormat.Interior.PatternColorIndex)
getAllPersonPoints = getAllPersonPoints +
getPoints(matchesResults.Cells(x, y).Value, personTypes.Cells(x, y).Value,
isTheSurest)
Next y
Next x
End Function
When i am trying to call this function by setting manually parameters: personTypes range and matchesResults ragne - everythink works fine.
But when i am trying to call it from sheet i got #VALUE error in selected cell.
But at function form there is correct result:
A have been trying to debug return value and always i got correct value. I have problem only with error in return cell.
Any ideas ?
The issue is that DisplayFormat object does not work with UDF's
See MSDN article
The usual solution to this is to evaluate the Conditional Format conditions to determine which one is active. For example, see cpearson.com
I resolved problem by code:
personTypes.Cells(x, y).Interior.ColorIndex
instead of:
personTypes.Cells(x,y).DisplayFormat.Interior.PatternColorIndex
This solution works.

LibreOffice Basic Ignoring “some” of my Type...End Type Definition

I'm using LibreOffice Version: 4.4.3.2 Build ID: 40m0(Build:2) Locale: en_AU
I have a Basic Module
At the top of this module before any sub or functions I have
Type InitHeadings
MySort_By As Integer
MyCharacter As Integer
MyInitiative As Integer
MyRolled As Integer
MyTotal As Integer
End Type
...
Global InitiativeColumn As New InitHeadings
But when I run a sub, set a breakpoint and 'watch' the InitiativeColumn Object only the first two fields are shown.
The rest of my code relevant to this struct as the documentation calls them is below. I don't reference it anywhere else. Can anyone tell me why the first two would work but not the rest? I have two other structs in this code and both also ignore the last three fields. Is this a Bug?
Sub Main
'Initialise Doc and Sheet Objects
Dim Doc As Object
Doc = ThisComponent
StatsSheet = Doc.Sheets.getByName("Stats")
InitiativeSheet = Doc.Sheets.getByName("Initiative")
CombatSheet = Doc.Sheets.getByName("Combat")
'LOAD HEADING NAMES
'Initiative Sheet
For Column = 0 to 25 'Columns A to Z
MyHeadingName = InitiativeSheet.getCellByPosition(Column,0).String
Select Case MyHeadingName
Case "Sort By"
InitiativeColumn.MySort_By = Column
Case "Character"
InitiativeColumn.MyCharacter = Column
Case "Initiative"
InitiativeColumn.MyInitiative = Column
Case "Rolled"
InitiativeColumn.MyRolled = Column
Case "Total"
InitiativeColumn.MyTotal = Column
End Select
Next Column
End Sub
Sub MyInitiativeButton
'Iterate over a range of cells:
For Row = 1 To 25 'Rows 2 to 26
'Column 3 is column D the "Rolled" column
InitiativeSheet.getCellByPosition(InitiativeColumn.MyRolled,Row).VALUE = Roledice(1,20,0)
Next Row
End Sub
It looks like a bug, and seems to have been reported here. The problem did not occur when I tested it in a newer version (LO 5.1.0.3).
This is only an issue for the debugger window. The values are still there:
Sub TestStructs
InitiativeColumn.MySort_By = 5
InitiativeColumn.MyCharacter = 5
InitiativeColumn.MyTotal = 5
InitiativeColumn.DoesntExist = 5
End Sub
This code works fine until the line InitiativeColumn.DoesntExist = 5, whereupon it crashes.
Now the Global problem that you mentioned in the comments is really a problem. Considering the standard programming advice that global variables are bad, I think it's wise to consider alternatives.
Instead of a subroutine, could you perhaps use a Function that returns InitiativeColumn? If not, then assigning the variable as you suggested seems a viable workaround. Personally for LO macros I prefer Python or Java since they have classes.

Run-time error '438' Object doesn't support this property or method - At rowcount 0

I wrote a VBA script that runs through a bank statement finding payments of a certain value. This code ran when I wrote it, but a couple of months later I get Run-time error '438' Object doesn't support this property or method; here is an extract of the code.
Set bankWB = ActiveWorkbook
Set bankWS = ActiveSheet
For rowcount = 0 To 250
skipline = False
If bankWS.Cells(rowcount, paidcol) = 5 Then
payee = Trim(bankWS.Cells(rowcount, payeecol))
paid = "5"
The error occurs on the 'if' line.
I've found various examples that reference cell values in the same way and this worked previously. If you Google this error there are lots of results and I see that using 'range' is more common than using 'cell' to reference a single cell, but it's not obvious to me how to easily translate my (x,y) cell variables/loop into a range "A1" type value so I've not tried rewriting the code to use range instead yet.
I assume that the object is bankWS.Cells and it's the property rather than the method that is the problem. I want to know what the value of the object is (=property), I'm not trying to do anything with the object (=method)
I've seen lots of different ways of writing the cell object, and tried various permutations, none of which make a difference. eg.
If worksheet.bankWS.Cells(rowcount, paidcol) = 5 Then
If bankWS.Cells.item(rowcount, paidcol) = 5 Then
If bankWS.Cells(rowcount, paidcol).value = 5 Then
I'm thinking that the code is ok, and that something else has changed.
Solved
Thanks to #99moorem my row count loop should have started at 1, not 0, there will be no cell(0,1).

Passing a range from one VB function to another

I'm writing a few VBA functions for work and ran into a problem that should be easy to solve, but somehow I can't manage to, despite my best attempts at finding an answer here and on Google. I wrote a function that should give me the range between two strings in a column:
Function FindRng(StartRng As String, EndRng As String) As Variant
Dim TopOfRange As Single
Dim BottomOfRange As Single
TopOfRange = WorksheetFunction.Match(StartRng, Sheets("InfCom").Range("B:B"), 0)
BottomOfRange = WorksheetFunction.Match(EndRng, Sheets("InfCom").Range("B:B"), 0)
FindRng = Range(Sheets("InfCom").Cells(TopOfRange, 2), Sheets("InfCom").Cells(BottomOfRange, 2))
End Function
So if the inputs A and B are on rows 100 and 105, it should return B100:B105. When I test this by adapting the code to read FindRng = Range(...).Address, I indeed get $B$100:$B$105.
However, when I then input the result of FindRng into a customized Index Match function, I get an error. The function is as follows:
Function subsetPBPC(rngReturn As Range, LookupValueH As Variant, TopOfRange As String, BottomOfRange As String, LookupValueV As Variant) As Variant
subsetPBPC = sPBPC(rngReturn, LookupValueH, FindRng(TopOfRange, BottomOfRange), LookupValueV)
End Function
The problem is that it seems to read the output of FindRng not as a range, but as the content of that range: when I use the Evaluate Formula tool on FindRng embedded in another formula, it shows the output of FindRng as {A,B,C,D,E} instead of $B$100:$B$105, where A to E are the contents of the cells in the range. I have the feeling the solution is really simple, but I don't see it. The functions underlying the customized Index Match function have been tested and all work like a charm.
Set instead of let. Let assigns the value of an expression to a variable. Set assigns an object reference to a variable. You want to return a reference to the range object, not return the value produced by the range object's default property.
In VBA writing
FindRng = Range(...)
is implicitly writing
Let FindRng = Range(...)
However you want
Set FindRng = Range(...)
Edit 1:
It is quite important to understand the difference between an object reference and a value in VBA. This is a similar concept to passing arguments by value or by reference. Hopefully these two links help some:
The Let statement on MSDN
The Set statement on MSDN
Edit 2:
Oh, and I guess I should touch on default properties! Some objects like range have default properties. If you treat the range as a value instead of an object, it uses the default property instead of throwing an error because it's an object not a value. In the case of range the default property is Value. So if you say A = Range("A1") what you're actually saying is Let A = Range("A1").Value when you might mean Set A = Range("A1"). So you're getting the value contained in the cell A1, instead of a range object representing that cell.
Picking up that your current code should both
use Set as per AndADM's commnet
dimension SetRng as a Range rather than Variant
you can simplify your function as below (which may save time if you are calling it repetitively)
Also, you could test for this range being Nothing (if your two strings werent found), whereas you current code will error out if either string is missing.
Function SetRng(str1 As String, str2 As String) As Range
With Sheets("infCom").Columns(2)
Set SetRng = Range(.Find(str1, , xlValues, xlWhole), .Find(str2, , xlValues, xlWhole))
End With
End Function

Excel error 1004 "Unable to get .... property of WorksheetFunction class" appearing inconsistently

I have a VBA function within a spreadsheet which operates on another spreadsheet that is opened in an earlier stage of my macro. The macro used to work fine but just recently has started causing a 1004 error ("Unable to get RoundDown property of the WorksheetFunction class") when it runs.
I believe I understand what the error would be caused by (a problem running RoundDown) but I cannot see why it is getting triggered in my macro and the odd part is that when I go into Debug mode and step through the code in the VBE the error does not recur (despite nothing obviously changing).
Does anyone have a similar experience of this sort of error occuring inconsistently and know what I could do to resolve it?
I'm reasonably VBA/Excel-savvy, but any suggestions on further steps to diagnose it would be appreciated. I am wondering if there is some issue with the opened spreadsheet not being ready but I cannot see how.
The code is here. The error occurs on the line marked with a comment.
Public Function GetDatesA(sWorkbookname As String, sSheetname As String, sCell As String) As Variant
Dim vDateList() As Variant
Dim currentCell As Range
Dim n As Long
Set currentCell = Workbooks(sWorkbookname).Worksheets(sSheetname).Range(sCell)
n = 0
Do
If Trim(currentCell.Value) = "" Then
Exit Do
Else
ReDim Preserve vDateList(0 To 1, 0 To n)
vDateList(0, n) = WorksheetFunction.RoundDown(currentCell.Value, 0) 'error occcurs on this line
vDateList(1, n) = currentCell.Column
'Debug.Print currentCell.Value
End If
Set currentCell = currentCell.Offset(0, 1)
n = n + 1
Loop While currentCell.Column < XL_LAST_COLUMN
GetDatesA = vDateList
End Function
Other details are:
Excel version: 2010
File being opened resides locally on my C: drive; my macro is in a spreadsheet on the network
File format for both files is .xls (i.e. Excel 2003) - I don't have the option of changing this
Windows 7 (not that I think it would be relevant)
Two points I've tried already are:
Substitute a different worksheet function (e.g. Min(currentCell)) and that also causes the same problem
Having the file open already seems to stop the problem - I wonder if there is some way that the workbook which is being opened (rather than my main workbook with the macro in it) is not enabled for macros and this is interfering. But even if this is the cause I'm not sure how to get around it!
Any ideas?
This error occurs often when any argument passed to the worksheet function is not of the correct type or simply doesn't make sense.
For example, I've had this problem when calling WorksheetFunction.Asin with an argument bigger than 1. In your case, I'd guess currentCell.Value is a non-numeric value or one not according to your region settings regarding numbers.
Yes, the error message is really misguiding.
I got the "Unable to get * property of WorksheetFunction Class" error using Transpose, MMult,MDterm, and MInverse functions.
I was able to get my code to run by putting "Option Base 1" in the Declarations (before the actual code) section of the particular Module in the Editer.
Excel assumes "Option Base 0" which will add an extra row and column of empty cells. This will cause the error to occur and isn't immediately obvious to see.
I have come accross this before, and for me it was becase the criteria range made no sense, as Andre said above.
See example formula below:
.Cells(11, i).Formula = Application.WorksheetFunction.CountIfs(Sheets("Sheet1").Range("AC8:C" & n), "S")
Have a look at the Range... it makes no sense. Amended the range from "AC8:C" to "AC8:AC" and it will work perfectly

Resources