Я был в тупике по этой проблеме уже несколько дней:
"Run-time error '13': Type mismatch"
когда я пытаюсь сравнить даты. Я просмотрел свою проблему, чтобы узнать, сталкивался ли кто-нибудь еще с такими же проблемами, и нашел это. Я безуспешно пытался реализовать решение этого вопроса.
Я работаю с пользовательской формой, называемой календарем, которая содержит даты в метках, наложенных на коррелирующие текстовые поля, которые пользователь может редактировать, и помещать в них заметки, как показано здесь.

Я сохраняю примечания в столбце 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")
Но у него та же проблема: будет работать до первого совпадения, а затем выдаст ошибку времени выполнения.
У меня такое чувство, что решение - это что-то очевидное, чего я не вижу, потому что я смотрел на это уже несколько дней ...
Если что-то нужно уточнить, дайте мне знать.
Примечание. Не используйте Integer для переменных подсчета строк. В Excel больше строк, чем может обработать Integer. В VBA рекомендуется использовать всегда использовать Long вместо Integer, поскольку в Integer нет никаких преимуществ.
Убедитесь, что ваши ячейки имеют значение даты. Все ваши функции Year(), Month(), Day() ожидают ввода даты. Попробуйте проверить значения ячеек с помощью функции IsDate().
@Vityata - это нормально - показывает все правильные даты и тому подобное, но как только 'curDate' = wsDate 'выдает ошибку.
@court_k - это ошибка в аргументе или истинный случай?
@ Pᴇʜ - Я знаю, но этим учебником долго не пользоваться! Поэтому я не ожидаю, что пользователь создаст достаточно заметок (или строк), чтобы потребовать отмены строки как «Длинная», но я все равно внесу изменения.
@nagarajannd Я только что проверил, являются ли «wsDate» и «curDate» датами с использованием isDate (согласно вашему предложению), и они оба являются датами.
@court_k поместите часть If wsDate = curDate Then в одну строку и закройте ее после командной строки с помощью End If, затем повторно проверьте, в какой строке возникает ошибка.
@ Сирил, что ты имеешь в виду?
@court_k оператор if, в котором вы ловите первое совпадение ... является ли ошибочной частью аргумента (Если wsDate = curDate) или частью истинного случая (Затем Controls (...)? При возникновении ошибки текст должен быть отмечен в VBA. Я просто хочу проверить, что мы хотим исправить, являются ли даты проблемой или то, как вы пишете в текстовое поле, является проблемой. Первоначально у меня был комментарий, спрашивающий, пробовали ли вы .Value вместо .Text для истинного случая, но удалил его, потому что хотел знать, с чем мы на самом деле имеем дело.
@ Сирил, ну ладно! Я не совсем уверен, как это проверить, поэтому я сделал следующее: если 'wsDate = curDate', это изменит цвет ячейки. Это дало тот же результат, что и тест окна сообщения, который я сделал. Он меняет цвет ячейки первого совпадения, а затем выдает ошибку. Не могли бы вы предоставить лучший способ проверить это, если вы не возражаете? :)
@court_k Редактор VBA по умолчанию (через alt + F11 из Excel) выделит строку кода желтым цветом при отладке после сообщения об ошибке. Вы сможете увидеть, какая часть оператора if отмечена желтым цветом. Если помечается вся строка (это не должно быть, но если), то вы можете полностью выписать yoru if выражение, чтобы строка 1 была если ххх, то, строка 2 была истинным случаем, а строка 3 была Конец, если, что должно сделать это очень ясно.
Что в .Cells(row, 2).Value?
@Cyril, о, отладчик! Да, я воспользуюсь этим и дам вам знать, что происходит.
@DavidZemens, это заметка, связанная с днем (например, 31.07.2018 | Встреча с Томом).
Вопрос: вы записываете данные из ColB в текстовое поле или перемещаете данные текстового поля в ячейку в ColB? Если вы перемещаете данные текстового поля в определенную ячейку в ColB, ваша последняя строка неверна.
@Cyril, спасибо тебе большое! Я понял свою проблему. Программа ломалась на curDate = ... . Это потому, что некоторые ярлыки пусты. Итак, я сделал неверное предположение! Я просматриваю ВСЕ ярлыки, но не все они содержат даты! Теперь я реализовал цикл, чтобы проверить, является ли метка vbNull, а затем, если это выход из этого цикла, сохраните счетчик «length» (минус 1) и используйте его для моей верхней границы.
@court_k Интерпретация отладчика ... лучшая часть кодирования, за исключением того, что что-то работает с первой попытки. Пожалуйста, либо ответьте самому себе, указав вопрос, чтобы его можно было закрыть, чтобы этот вопрос не оставался открытым, либо я могу сделать его для вас ... самостоятельные ответы обычно занимают некоторое время, прежде чем они могут быть приняты.
@GMalc Я перемещаю данные colB в текстовое поле.
@ Сирил, если ты не против, можешь сделать такой? Заранее спасибо! :) И спасибо за помощь !! Я очень ценю это!! :)





Я не совсем понимаю, как вы ссылаетесь на «workheet.Cells (row, col) .Value», потому что я всегда использую свойство .formula или .text ячейки. Но предположим, что свойство .Value дает числовое значение, а затем присваивает его непосредственно .Text, который, как я предполагаю, ожидает, что тип String может быть причиной этой ошибки?
Нет, числа автоматически / незаметно преобразуются в строки.
Согласно это говорит, что поддерживает его формат, если я что-то не понимаю.
Это должно помочь вам в отладке. Я подозреваю, что есть какая-то проблема со значением .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, пожимать плечами
Убедитесь, что вы используете отладчик, чтобы проверить, где возникает ошибка.
Судя по комментариям, ваша ошибка была в currDate = ..., которую вы, похоже, исправили, исправив диапазон, в котором выполняется итерация кода.
Этот комментарий существует, чтобы закрыть вопрос, ответ на который был дан в разделе комментариев, чтобы он не задерживался.
Напишите
MsgBox curDateиMsgBox wsDateв двух строках перед ошибкой. Что происходит?