Excel-VBA: ошибка времени выполнения при сравнении дат

Я был в тупике по этой проблеме уже несколько дней:

"Run-time error '13': Type mismatch"

когда я пытаюсь сравнить даты. Я просмотрел свою проблему, чтобы узнать, сталкивался ли кто-нибудь еще с такими же проблемами, и нашел это. Я безуспешно пытался реализовать решение этого вопроса.

Я работаю с пользовательской формой, называемой календарем, которая содержит даты в метках, наложенных на коррелирующие текстовые поля, которые пользователь может редактировать, и помещать в них заметки, как показано здесь. Excel-VBA: ошибка времени выполнения при сравнении дат

Я сохраняю примечания в столбце B на листе, а дату примечания в столбце A.

Прямо сейчас я пытаюсь вытащить заметки с листа и поместить их в текстовые поля, сравнивая даты, и здесь у меня возникают проблемы. Когда я сравниваю даты, я вытаскиваю подпись метки и сохраняю ее как дату curDate, а затем вытаскиваю дату рабочего листа и сохраняю ее как wsDate. Изначально у меня было окно сообщения в операторе if (теперь закомментировано), чтобы увидеть, работает ли код ... и это вроде как. Он будет работать до первого совпадения, а затем выдаст ошибку времени выполнения.

Dim ws As Worksheet

Dim lrow As Integer 'last row
Dim row As Integer 'used for looping through rows

Dim wsDate As Date 'worksheet date
Dim curDate As Date 'label date

Dim i As Integer

Set ws = Sheets("Hidden Information")

lrow = ws.Range("A" & ws.Rows.Count).End(xlUp).row

With ws 'Hidden Information worksheet

    For i = 1 To 38 'number of labels

        For row = 2 To lrow 'runs til the last row on the worksheet

            wsDate = DateSerial(Year(.Cells(row, 1).Value), _
                Month(.Cells(row, 1).Value), Day(.Cells(row, 1).Value))

            curDate = DateSerial(Year(Controls("Label" & i).Caption), _
                Month(Controls("Label" & i).Caption), Day(Controls("Label" & i).Caption))

            If wsDate = curDate Then Controls("TextBox" & i).Text = vbNewLine & _
                vbNewLine & .Cells(row, 2).Value 'MsgBox "it's a match!"

        Next row

    Next i

End With

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

        temp = CDate(.Cells(row, 1).Value)
        wsDate = Format(temp, "mm/dd/yy")

        temp = CDate(Controls("Label" & i).Caption)
        curDate = Format(temp, "mm/dd/yy")

Но у него та же проблема: будет работать до первого совпадения, а затем выдаст ошибку времени выполнения.

У меня такое чувство, что решение - это что-то очевидное, чего я не вижу, потому что я смотрел на это уже несколько дней ...

Если что-то нужно уточнить, дайте мне знать.

Напишите MsgBox curDate и MsgBox wsDate в двух строках перед ошибкой. Что происходит?

Vityata 31.07.2018 15:36

Примечание. Не используйте Integer для переменных подсчета строк. В Excel больше строк, чем может обработать Integer. В VBA рекомендуется использовать всегда использовать Long вместо Integer, поскольку в Integer нет никаких преимуществ.

Pᴇʜ 31.07.2018 15:38

Убедитесь, что ваши ячейки имеют значение даты. Все ваши функции Year(), Month(), Day() ожидают ввода даты. Попробуйте проверить значения ячеек с помощью функции IsDate().

nagarajannd 31.07.2018 15:39

@Vityata - это нормально - показывает все правильные даты и тому подобное, но как только 'curDate' = wsDate 'выдает ошибку.

court_k 31.07.2018 15:42

@court_k - это ошибка в аргументе или истинный случай?

Cyril 31.07.2018 15:42

@ Pᴇʜ - Я знаю, но этим учебником долго не пользоваться! Поэтому я не ожидаю, что пользователь создаст достаточно заметок (или строк), чтобы потребовать отмены строки как «Длинная», но я все равно внесу изменения.

court_k 31.07.2018 15:44

@nagarajannd Я только что проверил, являются ли «wsDate» и «curDate» датами с использованием isDate (согласно вашему предложению), и они оба являются датами.

court_k 31.07.2018 15:50

@court_k поместите часть If wsDate = curDate Then в одну строку и закройте ее после командной строки с помощью End If, затем повторно проверьте, в какой строке возникает ошибка.

Pᴇʜ 31.07.2018 15:51

@ Сирил, что ты имеешь в виду?

court_k 31.07.2018 15:51

@court_k оператор if, в котором вы ловите первое совпадение ... является ли ошибочной частью аргумента (Если wsDate = curDate) или частью истинного случая (Затем Controls (...)? При возникновении ошибки текст должен быть отмечен в VBA. Я просто хочу проверить, что мы хотим исправить, являются ли даты проблемой или то, как вы пишете в текстовое поле, является проблемой. Первоначально у меня был комментарий, спрашивающий, пробовали ли вы .Value вместо .Text для истинного случая, но удалил его, потому что хотел знать, с чем мы на самом деле имеем дело.

Cyril 31.07.2018 15:57

@ Сирил, ну ладно! Я не совсем уверен, как это проверить, поэтому я сделал следующее: если 'wsDate = curDate', это изменит цвет ячейки. Это дало тот же результат, что и тест окна сообщения, который я сделал. Он меняет цвет ячейки первого совпадения, а затем выдает ошибку. Не могли бы вы предоставить лучший способ проверить это, если вы не возражаете? :)

court_k 31.07.2018 16:02

@court_k Редактор VBA по умолчанию (через alt + F11 из Excel) выделит строку кода желтым цветом при отладке после сообщения об ошибке. Вы сможете увидеть, какая часть оператора if отмечена желтым цветом. Если помечается вся строка (это не должно быть, но если), то вы можете полностью выписать yoru if выражение, чтобы строка 1 была если ххх, то, строка 2 была истинным случаем, а строка 3 была Конец, если, что должно сделать это очень ясно.

Cyril 31.07.2018 16:10

Что в .Cells(row, 2).Value?

David Zemens 31.07.2018 16:17

@Cyril, о, отладчик! Да, я воспользуюсь этим и дам вам знать, что происходит.

court_k 31.07.2018 16:27

@DavidZemens, это заметка, связанная с днем ​​(например, 31.07.2018 | Встреча с Томом).

court_k 31.07.2018 16:27

Вопрос: вы записываете данные из ColB в текстовое поле или перемещаете данные текстового поля в ячейку в ColB? Если вы перемещаете данные текстового поля в определенную ячейку в ColB, ваша последняя строка неверна.

GMalc 31.07.2018 16:34

@Cyril, спасибо тебе большое! Я понял свою проблему. Программа ломалась на curDate = ... . Это потому, что некоторые ярлыки пусты. Итак, я сделал неверное предположение! Я просматриваю ВСЕ ярлыки, но не все они содержат даты! Теперь я реализовал цикл, чтобы проверить, является ли метка vbNull, а затем, если это выход из этого цикла, сохраните счетчик «length» (минус 1) и используйте его для моей верхней границы.

court_k 31.07.2018 16:34

@court_k Интерпретация отладчика ... лучшая часть кодирования, за исключением того, что что-то работает с первой попытки. Пожалуйста, либо ответьте самому себе, указав вопрос, чтобы его можно было закрыть, чтобы этот вопрос не оставался открытым, либо я могу сделать его для вас ... самостоятельные ответы обычно занимают некоторое время, прежде чем они могут быть приняты.

Cyril 31.07.2018 16:36

@GMalc Я перемещаю данные colB в текстовое поле.

court_k 31.07.2018 16:39

@ Сирил, если ты не против, можешь сделать такой? Заранее спасибо! :) И спасибо за помощь !! Я очень ценю это!! :)

court_k 31.07.2018 16:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
20
288
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я не совсем понимаю, как вы ссылаетесь на «workheet.Cells (row, col) .Value», потому что я всегда использую свойство .formula или .text ячейки. Но предположим, что свойство .Value дает числовое значение, а затем присваивает его непосредственно .Text, который, как я предполагаю, ожидает, что тип String может быть причиной этой ошибки?

Нет, числа автоматически / незаметно преобразуются в строки.

Pᴇʜ 31.07.2018 15:50

Согласно это говорит, что поддерживает его формат, если я что-то не понимаю.

court_k 31.07.2018 15:56

Это должно помочь вам в отладке. Я подозреваю, что есть какая-то проблема со значением .Cells(row,2). Итак, давайте изолировать это и убедиться, что мы выполняем преобразование в строку. Это все равно может вызвать ошибку, если, например, эта ячейка содержит значение ошибки, но, по крайней мере, это должно помочь выявить проблему:

Dim thisCaption as String, newText as String
For i = 1 To 38 'number of labels

    For row = 2 To lrow 'runs til the last row on the worksheet

        wsDate = DateSerial(Year(.Cells(row, 1).Value), _
            Month(.Cells(row, 1).Value), Day(.Cells(row, 1).Value))
        thisCaption = Controls("Label" & i).Caption
        curDate = DateSerial(Year(thisCaption), Month(thisCaption), Day(thisCaption))

        If wsDate = curDate Then 
            newText = vbNewLine & vbNewLine & CStr(.Cells(row, 2).Value)
            Controls("TextBox" & i).Text = newText
        End If
    Next row

Next i

NB: Я считать, но не проверял, что ваши вызовы DateSerial избыточны и, вероятно, могут быть удалены, вместо этого используя:

wsDate = CDate(.Cells(row, 1).Value)
curDate = CDate(thisCaption)

Думаю, я понял свою проблему, но спасибо за помощь! :) Я буду реализовывать это, потому что мне нравится, как он явно показывает тип вместо sorta, пожимать плечами

court_k 31.07.2018 16:41
Ответ принят как подходящий

Убедитесь, что вы используете отладчик, чтобы проверить, где возникает ошибка.

Судя по комментариям, ваша ошибка была в currDate = ..., которую вы, похоже, исправили, исправив диапазон, в котором выполняется итерация кода.

Этот комментарий существует, чтобы закрыть вопрос, ответ на который был дан в разделе комментариев, чтобы он не задерживался.

Другие вопросы по теме