VBA Excel Application.Match returning error unexpectedly - excel

I'm using Application.Match and expecting
Application.Match(["Search Term"],["Search Array"],["-1 Optional Argument
to show the first result higher than 'Search Term'"]
I'm getting a type mis-match error, despite the fact that manually searching that same array will show up a number of examples that I believe should satisfy the script!
For Example:
Sheets("StockPointsLog").Range("E75").Value = 853.45
ReferenceTargetSell = 850.605
I've tried using '''Application.WorksheetFunction.Match''' to see if this fixes the problems that I'm suffering, but this doesn't seem to be a 100% reliable method, so I would prefer to abandon it in favour of an actual solution.
I've tried encapsulating this line in '''CDbl()''' which simply converts the error code into a number.
I have also tried to manually edit values in the array, in order to confirm that I DEFINITELY have a valid result to show, but to no avail.
As you can see I'm error handling for if there is no result (which for the sake of the rest of my Sub is a valid outcome). Which means that the actual outcome for me is that the .match result comes out to = 0, rather than N/A.
I've been googling madly now for 2 days, and I am having to resort to begging you, my dear smart friends for your help and experience!
i = 2
Do While i <= (TotalTrades + 1)
ReferenceDateRow = Application.Match(ReferenceDate,
Sheets("StockPointsLog").Range("A1:A1000"), 0)
ReferenceTargetSell = Sheets("Trades").Range("B" & i).Value
On Error Resume Next
NewTradeDate = Application.Match(ReferenceTargetSell,
Sheets("StockPointsLog").Range("E" & ReferenceDateRow & ":E1001"), -1)
NewTradeDate = Sheets("StockPointsLog").Range("A" & NewTradeDate).Value
ReferenceDateRow comes back with a legitimate and correct value. Happy with that.
ReferenceTargetSell also works as expected.
The issue starts when I'm trying to set NewTradeDate

Related

Run-Time Error 1004 VBA - VLookup on second instance of for loop?

I am having an issue with VLookup in my VBA code. When I didn't have the range as a dynamic size using CurrentRegion it worked flawlessly, now for whatever reason, it only works for a single loop over and fails at the first VLookup. I have tried with and without the with block. I have a variable that will replace the 5 in the for loop and works but have kept it as its original so that isn't affecting it.
I apologize if this is a duplicate but I could not find an answer. Any help would be appreciated.
Set jobTypeData = Worksheets("JobType").Range("A1").CurrentRegion
For i = 1 To 5
jobTypeTemp = Worksheets("Employees2").Cells(i + 1, 16).Value
jobRoleTemp = Worksheets("Employees2").Cells(i + 1, 17).Value
'Creates variables relevant to the job type
With Worksheets("JobType")
minHours = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 2))
maxHours = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 3))
minShift = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 5))
maxShift = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 6))
shiftGap = CDec(WorksheetFunction.VLookup(jobTypeTemp, jobTypeData, 7))
End With
There is more code under this but it all works a-okay and worked fine before using the dynamic data size.
The code that works does not change the contents or size of jobTypeData.
I have also checked the values VLookup returns and they are all correct. The only thing I can think of is that it can't find the second jobType however I have checked and they are identical (no hidden spaces).
The answer appears to be related to the way VLookup uses 'approximate match'.
I always thought VLookup would still provide the exact match if it was an option and because I had strict data validation I never thought using approximate match would be a problem. However, turns out, it's not just mildly unpredictable, but actually unreliable.
After checking it was assuming "Role Name" was a closer match to "Team Manager" than "Team Manager". Upon changing it to using 'exact match', everything worked fine. No changes to the code which worked before either.
Well, lesson learned...
When you have an exact match ALWAYS use (no matter how confident you are, use me as an example):
VLOOKUP(arg1, arg2, arg3, FALSE)
Not:
VLOOKUP(arg1, arg2, arg3)

Excel VBA On Error error

I am rather new at programming, and while learning Python also started experimenting with Excel VBA. I have an issue with the last one.
I have some large Excel sheets and tried to validate that data in specific columns matches data on another sheet in certain columns as they will be supposed to relate to each other by these values (and will be connected by a third value). To make this a bit more difficult, both of these columns may contain more than one value separated by "|". So, I have split these values in a list and I try to iterate through them to make sure all these values are set correctly, the connection will work fine.
All is fine as long as all is fine :) I have however an issue where there are two values in one of those columns and only one in the other. I would like this discrepancy to be noted on a sheet and then proceed to the next item.
The way that seemed to be applicable for me is to use "On Error GoTo ErrHandler", then note error on another sheet, and then user Resume to proceed.
Here is what I came up with:
For h = 0 To UBound(Split1())
For j = 1 To GetMaxRow("SpecificSheet", A)
On Error GoTo ErrHandler:
If Sheets("SpecificSheet").Cells(j, 1).Value = Split1(h) And Sheets("SpecificSheet").Cells(j, 2).Value = Split2(h) Then
DependencyOk = DependencyOk + 1
End If
Next j
Next h
ErrProceed:
Also ErrHandler is:
ErrHandler:
Sheets("Issues").Cells(x, 1) = "IssueDescription"
GoTo ErrProceed
It stops at line 2 with Subscript out of range for Split2(h) rather than moving on to ErrHandler and then ErrProceed. I have the feeling this must be something very obvious but I am just unable to get this working, and I am not able to find other way (like a try/except) in Excel VBA.
UPDATE:
Trying to clarify things a bit. The root of the issue is, that the Split2 list is shorter than Split1 - which is an issue with the input data and I'd like to capture this. I get the Split values from cells, where the values are separated by "|" characters:
CellValue = Sheets("SomeSheet").Cells(RowNumber, ColumNumber)
CellValueSplit() = Split(CellValue, "|")
And then iterate as:
For h = 0 To UBound(Split1())
So as Split1 moves on to the for example 3rd value, Split2 throws error and script stops. The best I was able to do so far was, that I let it proceed with the loop, but as this is a rather large sheet, it will fill the same error report ca. 200k times in this case, which I'd like to avoid. So I'd prefer it to proceed from after this loop once it hits out of range error, and proceed examining the next value.
Thank you for your help so far and in advance!
You have an issue with your syntax. The proper Error statement syntax is:
On Error GoTo <string>
On Error Resume Next
On Error GoTo 0
When using On Error GoTo <string> there is no ":" at the end. The ":" doesn't come into play until you create the target location. Example:
On Error GoTo Here
'// ---- Do something ---- //
Here:
'// ---- Handle the error ---- //
If you use On Error Resume Next, then you're telling the machine to ignore errors and proceed on to the next line of code.
When you useOn Error Return To 0, VBA will reset its error handling back to default. It's a good habit when using On Error Resume Next to insert On Error Return To 0 as soon as you no longer need it. On Error Resume Next has a real potential to break your code and make it behave strangely. Not to mention debugging can be a real nightmare. Check out the VBA manual from Microsoft for a more detailed explanation.
Finally, if your question is answered, you should mark it as answered.
vba-excelvbaexcel
The short and quick version is that VBA Error Handling Routine's only handle errors in the actual code execution, they do not fire when conditions expressed by the code are not met.
In your case, you do not need any error handling at all. In most cases it is actually best to avoid On Error GoTo .... There are cases where it's inevitable, but they are rare.
Try this IF THEN ELSE block:
If Sheets("SpecificSheet").Cells(j, 1).Value = Split1(h) And Sheets("SpecificSheet").Cells(j, 2).Value = Split2(h) Then
DependencyOk = DependencyOk + 1
Else
Sheets("Issues").Cells(x, 1) = "IssueDescription"
End If
Actually I have just found the issue. It was caused by a ":" left after an If statement a few rows earlier. I still don't really understand what it did, but I suggest not to reproduce it :)

VBScript - Either getting object required or type mismatch errors

I have scoured the web and this site looking for an answer on this, so I would really appreciate some help.
I'm creating a VBScript to do some modifications to a user-specified Excel spreadsheet. I have the first part of my script working fine, but the second part is driving me nuts. I need it to search the first column for a value and, if found, delete the row. Right now I'm not worrying about the deletion statement--I'm doing testing by seeing if I can get the For Each statement to run properly as well as the If Then statement. Here's the specific block of code:
For Each cell in objSheet.Columns("A:A").Cells
Set cell = objSheet.Columns("A:A").Cells
If cell.Value = "60802400040000" then
cell.font.bold = True
End If
Next
I have tried many variations of this and cannot find the right combination. Initially I was getting an "Object Required" messages, and after reading a number of posts, found that I needed to put in a Set statement for cell, which I did. Now I am getting a Mismatch Type error message.
The funny thing is, before I put in the Set statement, the code would execute, but it would throw the Object Required error when I closed the spreadsheet. After adding it, the error for the Type Mismatch pops up immediately.
Most examples I keep finding on the web are for VBA, and I try to modify them for VBS, which I don't know very well. Any assistance anyone can give me will be greatly appreciated.
You are redefining cell, cell is defined automatically in the For Each statement.
Delete this line
Set cell = objSheet.Columns("A:A").Cells
This is an example from Help, unfortunately Help doesn't have any examples that uses For Each, only For x = n to n and other means. For Each is the right thing to do.
Set r = Range("myRange")
For n = 1 To r.Rows.Count
If r.Cells(n, 1) = r.Cells(n + 1, 1) Then
MsgBox "Duplicate data in " & r.Cells(n + 1, 1).Address
End If
Next n
For vba to vbs, you have to create the object and use, as some objects are automatically available in VBA (like app object) - Set exceldoc = CreateObject("c:\blah\blah.xls) then to use Set r = exceldoc.worksheets(0).range("MyRange").
Also you have to use constant values not names as vbscript can't look them up.

I'm getting a runtime errror 438 when trying to format a column in a spreadsheet

Sheets("Reformatted").Column("F").NumberFormat = "$#,##0.000"
To better debug a complex expression, break it into smaller parts. In your case:
Set sh = Sheets("Reformatted")
Set rg = sh.Column("F")
Let rg.NumberFormat = "$#,##0.000"
Broken into multiple statements, you can step using the debugger, and figure out exactly which piece part of the larger statement is causing the problem. Since the error happens on the Column statement, you can deduce that the error message is referring to Column.

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