Невозможно сопоставить дату в диапазоне, используя функцию MATCH и VBA - PullRequest
1 голос
/ 03 июля 2019

Я хотел бы написать пользовательскую функцию, которая возвращает значение в диапазоне, заданном идентификатором серии и датой.

Диапазон выглядит примерно так

enter image description here

Я бы хотел, чтобы вызов функции =getParam("B",1/07/2005,Parameters) возвратил 22.

Для этого я использую пару функций =MATCH, чтобы найти правильную строкуи столбец, а затем будет использовать функцию =INDEX для возврата правильного значения.Моя функция (не полная) приведена ниже.

Проблема:

Когда я указываю =MATCH(1/07/2005,A1:A11,0) в обычной ячейке Excel, я получаю правильный индекс строки 6, но при включенииэто внутри моей функции VBA, как показано ниже, я получаю ошибку #VALUE!.

Есть идеи?

Function getParam(Series As String, StartDate As Date, Parameters As Range)

    Dim IndexRow, IndexColumn As Integer

    IndexRow = Application.WorksheetFunction.Match(StartDate, Parameters.Columns(1), 0)
    IndexColumn = Application.WorksheetFunction.Match(Series, Parameters.Rows(1), 0)

    getParam = IndexRow

End Function

1 Ответ

2 голосов
/ 03 июля 2019
  1. Вам необходимо преобразовать дату в двойную, чтобы соответствовать ей CDbl(StartDate)
  2. Метод WorksheetFunction.Match возвращает Double, поэтому

    Dim IndexRow As Double, IndexColumn As Double
    

    вам необходимо указать тип для обеих переменных, в противном случае первое автоматически Variant.

  3. Используйте процедуру теста для подачи вашего UDF (пользовательская функция), если вы хотите его отладить.

В итоге вы получите ...

Option Explicit

Public Sub Test_getParam()
    Debug.Print getParam("B", DateSerial(2019, 7, 5), Range("A1:E13"))
End Sub

Public Function getParam(Series As String, StartDate As Date, Parameters As Range) As Variant
    Dim IndexRow As Double, IndexColumn As Double

    IndexRow = Application.WorksheetFunction.Match(CDbl(StartDate), Parameters.Columns(1), 0)
    IndexColumn = Application.WorksheetFunction.Match(Series, Parameters.Rows(1), 0)

    getParam = Parameters.Cells(IndexRow, IndexColumn)
End Function

В вашей формуле вам нужно указать реальную дату DATE(2019,7,5)

=getParam("B",DATE(2019,7,5),A1:E13) 'returns 10 with the data below

потому что, если вы отправите =getParam("B",1/07/2005,Parameters), ваша "дата" будет 1/07/2005, что на самом деле означает 1, деленное на 7, деленное на 2005 с результатом 0.0000712504453153…, так что это значение, которое вына самом деле пытался соответствовать.Вы должны использовать DATE(2005,7,1), чтобы получить реальную дату.

enter image description here


В качестве окончательного улучшения я рекомендую включить обработку ошибок, чтобы вернутьсяошибка, если дата или серия не совпадают.

Это вернет ошибку #NA, если одна из них не совпадает.

Public Function getParam(Series As String, StartDate As Date, Parameters As Range) As Variant
    Dim IndexRow As Double, IndexColumn As Double

    On Error Resume Next
    IndexRow = Application.WorksheetFunction.Match(CDbl(StartDate), Parameters.Columns(1), 0)
    IndexColumn = Application.WorksheetFunction.Match(Series, Parameters.Rows(1), 0)
    On Error GoTo 0

    If IndexRow > 0 And IndexColumn > 0 Then
        getParam = Parameters.Cells(IndexRow, IndexColumn)
    Else
        getParam = CVErr(xlErrNA)
    End If
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...